Path: seismo!harvard!talcott!panda!sources-request From: sources-request@panda.UUCP Newsgroups: mod.sources Subject: Two tools for organizing sources from USENET Message-ID: <1744@panda.UUCP> Date: 25 Apr 86 12:02:35 GMT Sender: jpn@panda.UUCP Lines: 1306 Approved: jpn@panda.UUCP Mod.sources: Volume 4, Issue 77 Submitted by: decvax!utzoo!toram!chris #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # README # note # note.1 # savesrc # savesrc.1 # This archive created: Fri Apr 25 06:58:31 1986 export PATH; PATH=/bin:$PATH echo shar: extracting "'README'" '(1027 characters)' if test -f 'README' then echo shar: will not over-write existing file "'README'" else cat << \SHAR_EOF > 'README' Here are two shell programs, "saversc" and "note" (plus manual pages), for organizing sources from Usenet. I wrote them to deal sensibly with my ever-growing "miscellaneous net sources" directory, and have found them enormously useful. I expect other folks will find them helpful too. Basically, "savesrc" will take a single program source file or a shell archive, place it in a designated source directory or sub-directory thereof, unshar it if necessary, generate a Makefile entry if necessary, prompt for a half-line description of what the program does, attempt to compile it, give the user a shell to twiddle it when it doesn't work, and add entries to a file of notes indicating what it is, where and whom it came from, when it arrived, and whether or not it works. It will also deal sensibly with header files, bugs/fixes, and manual pages. It can be used directly from "rn" as "| savesrc destination". "Note" manages the files of notes on the sources. Christine Robertson {ihnp4,linus,decvax}!utzoo!toram!chris SHAR_EOF if test 1027 -ne "`wc -c < 'README'`" then echo shar: error transmitting "'README'" '(should have been 1027 characters)' fi fi echo shar: extracting "'note'" '(2285 characters)' if test -f 'note' then echo shar: will not over-write existing file "'note'" else cat << \SHAR_EOF > 'note' #!/bin/sh # # Note: manage notes on program sources # # Copyright (c) Chris Robertson 1985 # # This script adds lines from standard input to a file called NOTES # in the current directory, or views/edits the file. It is intended # for keeping notes on software slurped from the net. # The format of NOTES is: # # progname: [date] comments ... # (1 tab) more comments # (blank line) # # Usage: note [-e] [-s] [-r [program ...]] # # No options: add a NOTE. # -e: edit the NOTES file. # -r: show all notes on the given program(s), or the entire # NOTES file (unsorted) if no program is given. # -s: show the entire NOTES file, sorted so all notes on a # given program occur together. # PAGER=${PAGER-/usr/local/bin/more} case "$PAGER" in "") # in case it's explicitly set to nothing PAGER=cat ;; esac case "$VISUAL" in "") case "$EDITOR" in "") ;; *) VISUAL=$EDITOR ;; esac ;; esac VISUAL=${VISUAL-/usr/bin/vi} case "$VISUAL" in "") # in case it's explicitly set to nothing VISUAL=/bin/ed ;; esac trap "rm -f /tmp/note$$;exit" 0 1 2 3 # find which echo we're using case "`echo -n foo`" in -n*) c="\c" n="" ;; foo) c="" n="-n" ;; *) echo "Your echo command is broken!" c= n= ;; esac usage="Usage: $0 [-e] [-s] [-r [prog ...]]" case "$#" in 0) ;; 1) case "$1" in -r) $PAGER NOTES exit 0 ;; -s) list="`sed -e '/^ /d' -e 's/:.*//' NOTES | sort -u`" for i in $list do note -r $i >> /tmp/note$$ done $PAGER /tmp/note$$ rm -f /tmp/note$$ exit 0 ;; -e) $VISUAL NOTES exit 0 ;; *) echo $usage exit 1 ;; esac ;; *) case "$1" in -r) shift for prog in $* do case "$PAGER" in *cat) sed -n -e "/^${prog}:/,/^\$/p" NOTES ;; *) sed -n -e "/^${prog}:/,/^\$/p" NOTES | $PAGER ;; esac done exit 0 ;; *) echo $usage exit 1 ;; esac ;; esac date="`set - \`date\`;echo $2 $3 $6`" echo $n "Program name: $c" read prog echo $n "> $c" read line echo "${prog}: [$date] $line" >> NOTES line= while : do echo $n "> $c" read line case "$line" in .) break ;; esac echo " $line" >> NOTES done echo "" >> NOTES SHAR_EOF if test 2285 -ne "`wc -c < 'note'`" then echo shar: error transmitting "'note'" '(should have been 2285 characters)' fi fi echo shar: extracting "'note.1'" '(1623 characters)' if test -f 'note.1' then echo shar: will not over-write existing file "'note.1'" else cat << \SHAR_EOF > 'note.1' .ls 1 .TH NOTE 1 LOCAL .SH NAME note \- manage notes on program sources .SH SYNOPSIS \fBnote\fR [\fB\-e\fR] [\fB\-s\fR] [\fB\-r\fR [program ...]] .SH DESCRIPTION \fINote\fR is a shell script designed to manage notes on sources, such as what they are, where and whom they came from, when they were received/created, and whether or not they work. It is primarily intended for keeping track of software recived via the Usenet news network. .sp With no options, \fInote\fR appends lines from standard input to a file called ``NOTES'' in the current directory. The format of a NOTES file is: .sp .nf .in +0.7i .ta 0.8i program: [Mmm dd yy] comments ... <\fI1 tab\fR> more comments <\fIblank line\fR> .sp .fi .in -0.7i .TP \fB\-e\fR edit the NOTES file using $VISUAL as the editor. If VISUAL is not set, \fInote\fR looks for $EDITOR, and if that is also not set, defaults to ``/usr/bin/vi''. .TP \fB\-r\fR show all notes on the given program(s), or the entire NOTES file (unsorted) if no program is given, piped through $PAGER (unless PAGER is \fIcat\fR). .TP \fB\-s\fR show the entire NOTES file, sorted so all notes on a given program occur together, piped through $PAGER. .SH ENVIRONMENT VARIABLES .ta 1.3i 3i .nf \fBName Default Purpose\fR .sp PAGER /usr/local/bin/more Used to page output VISUAL /usr/bin/vi Used to edit the NOTES file EDITOR none Used if VISUAL is not set .fi .SH FILES .ta 1.3i ./NOTES file where notes are kept .br /tmp/note$$ temporary files .SH SEE ALSO \fIsavesrc(1L)\fR .SH AUTHOR Written by Christine Robertson 1986 .SH BUGS Please send all bug reports to {linus, ihnp4, decvax}!utzoo!toram!chris. SHAR_EOF if test 1623 -ne "`wc -c < 'note.1'`" then echo shar: error transmitting "'note.1'" '(should have been 1623 characters)' fi fi echo shar: extracting "'savesrc'" '(14268 characters)' if test -f 'savesrc' then echo shar: will not over-write existing file "'savesrc'" else cat << \SHAR_EOF > 'savesrc' #!/bin/sh # # Savesrc: Unpack program sources from news in a sensible manner. # # Copyright (c) Chris Robertson 1986 # # Savesrc will put a C source file into a default sources # directory, or make a new directory (subdirectory by default) for # a shar-ed source and unpack it. It will make an entry # in a Makefile (or a whole basic Makefile, if necessary), # take a shot at compiling the thing if you want it to, give # you a shell to diddle the source when it won't compile, prompt # you for a short blurb about what it does, and create a note # as to where it came from and when, and whether it compiles # and works, so you have some chance of remembering what state this # stuff is in next time you look at it. A simple auxilliary program, # note, goes with this and is used for adding/reading notes on # sources. Prompts are deliberately rather terse for those folks who # read news at slow baud rates. # # Usage: from rn, | savesrc dest # otherwise, savesrc dest [sourcefile ... ] # # Savesrc expects at least one argument, the name of a C source file # (in "foo.c" form), or the name of a directory to put a bunch # of stuff in, and may have several other arguments which are # used as the program source input files. It is normally not # very sensible to give it more than one source file, however. # # Use QUIT to abort it, not DEL. # # Assumptions: # /bin/[ exists -- replace with "test" if necessary # unshar exists -- replace with "sh" if necessary # note exists -- replace with "cat >> NOTES" if necessary # # Editing Note: # This is set up for vi with tabstop=4 and shiftwidth=4. # Indenting will look funny otherwise. # trap '' 2 trap "rm -f /tmp/newsrc$$;exit" 0 1 3 case "$VISUAL" in "") case "$EDITOR" in "") ;; *) VISUAL=$EDITOR ;; esac ;; esac VISUAL=${VISUAL-/usr/bin/vi} case "$VISUAL" in "") # in case it's explicitly set to nothing VISUAL=/bin/ed ;; esac SHELL=${SHELL-/bin/sh} PAGER=${PAGER-/usr/local/bin/more} case "$PAGER" in "") # in case it's explicitly set to nothing PAGER=cat ;; esac srcdir=${srcdir-$HOME/src} # where source is kept -- overidden by # a full pathname for dest mandir=${mandir-$HOME/man} # where src manual pages go catdir=${catdir-$HOME/man} # where formatted manual pages go CFLAGS=${CFLAGS--O} # used in generating a Makefile ls="ls -F" # replace with your favourite # find which echo we're using, thanks to Larry Wall for the idea case "`echo -n foo`" in -n*) c="\c" n="" ;; foo) c="" n="-n" ;; *) echo "Your echo command is broken!" c= n= ;; esac # find what we want to call it and save the article (read standard input # if no filename given) case "$#" in 0) echo "Usage: savesrc dest [sourcefile ...]" > /dev/tty exit 1 ;; esac dest=$1 shift cat $* > /tmp/newsrc$$ # if what we've saved was a news article, strip off the header, but # remember the date, path, and poster. If you have 'bm', you may want # to replace 'grep' with it for speed. date="`set - \`date\`;echo $2 $3 $6`" case "`egrep 'Posting-Version|Relay-Version:|^From:' /tmp/newsrc$$`" in "") # not a news article path= poster= ;; *) path="`grep '^Path:' /tmp/newsrc$$`" poster="`grep '^From:' /tmp/newsrc$$`" sed -e '1,/^$/d' /tmp/newsrc$$ > /tmp/strip$$ mv /tmp/strip$$ /tmp/newsrc$$ ;; esac # set up standard input and output to be /dev/tty, in case this is invoked # via a pipe from rn exec < /dev/tty > /dev/tty # see if we got a full pathname as 'dest', otherwise cd to source dir case "$dest" in /*) ;; *) cd $srcdir || exit 0 ;; esac # file names known about are *.?, *.[1-8], *.fix, *.bug, *.patch, & READ* -- # anything else is assumed to be a directory name case "$dest" in *.[1-8]) # manual pages until [ ! -s "$dest" ] do echo $n "\nOverwrite '$dest'? [n] $c" read answer case "$answer" in q*|Q*) exit 0 ;; y*|Y*) break ;; *) echo $n "New name: $c" read dest ;; esac done mv /tmp/newsrc$$ $dest echo $n "\nEdit ${dest}? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) trap '' 2 3 ($VISUAL $dest) trap 3 ;; esac section=`expr "$dest" : '.*\.\(.*\)'` case "`file $dest`" in *roff*) echo $n "\n$dest -- man page source. Move to $mandir/man${section}? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) if [ ! -d $mandir/man$section ] then if (mkdir $mandir/man$section > /dev/null 2>&1) then mv $dest $mandir/man$section dest=$mandir/man$section/$dest else echo "Can't make directory $mandir/man$section -- can't move $dest." fi else mv $dest $mandir/man$section dest=$mandir/man$section/$dest fi ;; esac echo $n "\nNroff it to $catdir/cat${section}? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) if [ ! -d $catdir/cat$section ] then if (mkdir $catdir/cat$section > /dev/null 2>&1) then nroff -man $dest > $catdir/cat$section/$dest $PAGER $catdir/cat$section/$dest else echo "Can't make directory $catdir/cat$section -- can't nroff $dest." fi else nroff -man $dest > $catdir/cat$section/`basename $dest` $PAGER $catdir/cat$section/`basename $dest` fi ;; esac ;; *) echo $n "\nMove $dest to $catdir/cat${section}? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) if [ ! -d $catdir/cat$section ] then if (mkdir $catdir/cat$section > /dev/null 2>&1) then mv $dest $catdir/cat$section/$dest else echo "Can't make directory $catdir/cat$section -- can't move $dest." fi fi ;; esac ;; esac ;; READ*|*.?|*.fix|*.bug|*.patch) # we are dealing with a single, (relatively!) short program copy=yes until [ ! -s "$dest" ] do echo $n "\nOverwrite '$dest'? [n] $c" read answer case "$answer" in q*|Q*) exit 0 ;; y*|Y*) break ;; *) echo $n "Append to '$dest'? [n] $c" read answer case "$answer" in q*|Q*) exit 0 ;; y*|y*) cat /tmp/newsrc$$ >> $dest copy=no ;; *) echo $n "New name: $c" read dest ;; esac ;; esac done case "$copy" in yes) cp /tmp/newsrc$$ $dest ;; esac echo $n "\nEdit ${dest}? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) echo $n "Want a shell? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) $SHELL ;; esac ;; *) trap '' 2 3 ($VISUAL $dest) trap 3 ;; esac case "$dest" in READ*|*.h) exit 0 ;; *.fix|*.bug|*.patch) echo $n "Want a shell? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) $SHELL ;; esac exit 0 ;; esac # set up a summary for later use echo $n "\n1/2-line program summary: $c" read blurb # if "makefile" exists, add it to "Makefile", for consistency if [ -s "makefile" ] then cat makefile >> Makefile rm makefile ed - Makefile << ++++ g/makefile/s//Makefile/g w ++++ fi # add a Makefile entry if there isn't one there already bname=`basename $dest .c` case "`grep \"^${bname}: \" Makefile`" in "") echo $n "Want a Makefile entry? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) echo "\n# $bname -- $blurb\n" >> Makefile echo "Default:\n\n$bname: $bname.o\n cc \$(CFLAGS) $bname.o -o $bname" echo $n "\nOK as the Makefile entry? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; y*|Y*|"") echo "$bname: $bname.o" >> Makefile echo " cc \$(CFLAGS) $bname.o -o $bname" >> Makefile ;; *) echo $n "\nComplete Makefile entry (. to end)\n> $c" read instruct echo "$instruct" >> Makefile instruct= while : do echo $n "> $c" read instruct case "$instruct" in .) break ;; esac echo " $instruct" >> Makefile # tab is essential done ;; esac ;; esac ;; esac ;; *) # we are probably going to make a new directory for this one newdir=true if [ -d "$dest" ] then echo $n "\n$dest already exists -- put the stuff there? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) echo $n "New directory name: $c" read dest ;; *) newdir=false ;; esac fi if ($newdir) then until ( mkdir "$dest" > /dev/null 2>&1 ) do echo $n "Can't make '$dest'.\nNew name: $c" read dest done fi cd $dest || exit 1 # set up a summary for later use echo $n "\n1/2-line program description: $c" read blurb echo $n "\nUnshar it? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) echo $n "\nEdit it? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) echo $n "Want a shell? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) $SHELL ;; esac ;; *) trap '' 2 3 ($VISUAL /tmp/newsrc$$) trap 3 ;; esac $ls echo $n "\ncp /tmp/newsrc$$ what? [RETURN = no copy] $c" read name case "$name" in "") ;; *) cp /tmp/newsrc$$ $name ;; esac ;; *) unshar /tmp/newsrc$$ $ls echo $n "\nDid that extract OK? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) echo "Starting a shell." trap '' 2 3 ($SHELL) trap 3 $ls echo $n "\ncp /tmp/newsrc$$ what? [RETURN = no copy] $c" read name case "$name" in "") ;; *) cp /tmp/newsrc$$ $name ;; esac ;; esac ;; esac if [ -s "README" -o -s "READ_ME" ] then echo $n "\nSee the README? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) $PAGER READ* ;; esac else echo $n "\nEdit a README? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) trap '' 2 3 ($VISUAL README) trap 3 ;; esac fi # manual pages for i in `ls *.[1-8] 2> /dev/null` do page=$i case "`file $i`" in *roff*) section=`expr "$i" : '.*\.\(.*\)'` echo $n "\n$i -- man page source. Copy to $mandir/man${section}? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) if [ ! -d $mandir/man$section ] then if (mkdir $mandir/man$section > /dev/null 2>&1) then cp $i $mandir/man$section page=$mandir/man$section/$i else echo "Can't make directory $mandir/man$section -- can't move $dest." fi else cp $i $mandir/man$section page=$mandir/man$section/$i fi ;; esac echo $n "\nNroff it to $catdir/cat${section}? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) if [ ! -d $catdir/cat$section ] then if (mkdir $catdir/cat$section > /dev/null 2>&1) then nroff -man $page > $catdir/cat$section/$i $PAGER $catdir/cat$section/$i else echo "Can't make directory $catdir/cat$section -- can't nroff $dest." fi else nroff -man $page > $catdir/cat$section/$i $PAGER $catdir/cat$section/$i fi ;; esac ;; esac done # if "makefile" exists, move it to "Makefile", for consistency if [ -s "makefile" ] then cat makefile >> Makefile rm makefile ed - Makefile << ++++ g/makefile/s//Makefile/g w ++++ fi if [ ! -s "Makefile" ] then echo $n "\nGot a Makefile somewhere? [n] $c" read answer case "$answer" in q*|Q*) exit 0 ;; y*|y*) echo $n "What's it called? $c" read name cp $name Makefile ;; *) echo $n "Generating basic Makefile ... $c" echo "# $dest -- $blurb\n" > Makefile echo $n "\nCFILES = $c" >> Makefile for i in `ls *.c 2> /dev/null` do echo $n "$i $c" >> Makefile done echo $n "\n\nOFILES = $c" >> Makefile for i in `ls *.c 2> /dev/null` do echo $n "`basename $i .c`.o $c" >> Makefile done echo "\n\nCFLAGS = $CFLAGS" >> Makefile echo "\n${dest}: \$(OFILES)" >> Makefile echo " cc \$(CFLAGS) \$(OFILES) -o $dest" >> Makefile echo "\nclean:\n rm -f *.o" >> Makefile echo "Done." ;; esac fi ;; esac echo $n "\nEdit Makefile? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) trap '' 2 3 ($VISUAL Makefile) trap 3 ;; esac # create basic NOTES entry for it echo $n "\nCreate basic NOTES entry? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) echo "`basename $dest .c`: [$date] ${blurb}" >> NOTES case "$poster" in "") # not a net article ;; *) echo " $poster" >> NOTES echo " $path" >> NOTES ;; esac echo "" >> NOTES ;; esac echo $n "\nCompile ${dest}? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) make $bname ;; esac echo $n "\nWant a shell? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) trap '' 2 3 ($SHELL) trap 3 ;; esac echo $n "\nAny NOTES? [y] $c" read answer case "$answer" in q*|Q*) exit 0 ;; n*|N*) ;; *) note ;; esac SHAR_EOF if test 14268 -ne "`wc -c < 'savesrc'`" then echo shar: error transmitting "'savesrc'" '(should have been 14268 characters)' fi fi echo shar: extracting "'savesrc.1'" '(12044 characters)' if test -f 'savesrc.1' then echo shar: will not over-write existing file "'savesrc.1'" else sed 's/^X//' << \SHAR_EOF > 'savesrc.1' .ls 1 .vs 11.5 .TH SAVESRC 1 LOCAL .SH NAME savesrc \- organize program sources from Usenet .SH SYNOPSIS \fBsavesrc\fR destination [source file ...] .SH DESCRIPTION \fISavesrc\fR is a shell program designed to simplify the retrieval, testing, documentation, and storage of program sources from the Usenet news network, although it can be used with any source files. .sp 0.13i \fISavesrc\fR will read standard input if no source files are given, so a news article may be piped to it conveniently from newsreaders with this facility, such as \fIrn(1)\fR. This makes it much easier to save sources in a standard manner and test them out while actually reading news, rather than accumulating messy directories of miscellaneous sources to be organized Real Soon Now. .sp 0.13i Basically, \fIsavesrc\fR will take a single program source file or a shell archive, place it in a designated source directory or sub-directory thereof, unshar it if necessary, generate a Makefile entry if necessary, prompt for a half-line description of what the program does, attempt to compile it, give the user a shell to twiddle it when it doesn't work, and add entries to a file of notes indicating what it is, where and who it came from, when it arrived, and whether or not it works. It will also deal sensibly with header files and manual pages. .sp 0.13i \fISavesrc\fR is interactive. It may be terminated by typing ``q'' in response to any question, but cannot be aborted with an interrupt. If panic stikes, \fIquit\fR (normally CTRL-\e) will produce a graceful exit. .sp 0.2i \fBDirectory Structures Etc.\fR .sp 0.13i \fISavesrc\fR assumes that all sources will be placed in a \fImain sources directory\fR, or in sub-directories under it. It will look for an environment variable ``srcdir'' giving the full pathname of this directory; the default value is ``$HOME/src''. .sp 0.13i Manual page sources are assumed to live in a directory with subdirectories named ``man1'' through ``man8'', and manual pages which have been formatted using \fInroff -man\fR are assumed to live in a directory with subdirectories named ``cat1'' through ``cat8''. \fISavesrc\fR looks for two environment variables, ``mandir'' and ``catdir'', which give the full pathnames of these directories. ``Mandir'' and ``catdir'' may be the same; the default value for each is ``$HOME/man''. .sp 0.13i \fISavesrc\fR further assumes that there will be a Makefile in the main sources directory; one will be created if it does not exist. Incidentally, if a ``makefile'' is found anywhere, it is appended to ``Makefile'' and then removed, in the interests of consistency. (The Makefile is then edited to change all references to ``makefile'' into ``Makefile''.) .sp 0.13i A file called ``NOTES'' is also expected in any source directory, and will be created if it does not exist. This file contains short notes on what the programs in the directory do, where and whom they came from (if known), when they were received, and any other relevant information (such as if they work and actually seem to be useful). \fISavesrc\fR will create a basic NOTES entry for any program it deals with if the user so desires. The NOTES file is intended to be manipulated by a another program, \fInote(1L)\fR, but since it is a ordinary ASCII file, it may be attacked with any of the normal Unix utilities. .sp 0.13i The \fBdestination\fR names that \fIsavesrc\fR knows about are ones ending in ``.?'', ``.fix'', ``.bug'', ``.patch'', ``.[1-8]'', and ``READ*'', which are assumed to be source (C, YACC, lex, etc.) or header files, bug fixes, manual pages, or README's. (The ``.bug'', ``.fix'', and ``.patch'' suffixes exist to allow convenient saving of bugs, patches, and fixes in a general sources directory.) Any other destination name is assumed to be a sub-directory under the main sources directory, unless it is a full pathname. .sp 0.2i \fBSingle Source Programs, Header Files, and README's\fR .sp 0.13i \fISavesrc\fR tries to put single-file sources, header files, and README's in the main sources directory. If the destination name already exists, the user is given the choice of overwriting it, appending to it, or specifying a new destination (which is also checked). The user is given a chance to edit the file or start up a shell for further twiddling. At this point \fIsavesrc\fR will terminate for header files and README's; for bugs, fixes, and patches, the user will be offered a shell before \fIsavesrc\fR terminates. .sp 0.2i \fBSource Programs\fR .sp 0.13i For sources, the user is prompted for a half-line description of the program, and a check is made to see if a Makefile entry already exists for the program. If not, and the user indicates he wants one, a default entry of the form: .sp 0.13i .nf .in +0.7i program: program.o cc $(CFLAGS) program.o -o program .fi .in -0.7i .sp 0.13i is presented for his approval. If he approves, this is appended to the Makefile. If not, he is prompted for the complete Makefile entry. In either case, the Makefile entry is preceded by a blank line and the half-line program description as a comment. The user is then given a chance to edit the Makefile. .sp 0.13i Next, the user is prompted for adding a basic NOTES entry, asked if the program should be compiled, offered a shell to twiddle or test it, and finally prompted for any further NOTES entries (\fIe.g.\fR, ``Compiled OK but removed /unix when I ran it. Must remember to sue author.''). If the program came from a netnews article, the basic NOTES entry will include the author and the posting path, if possible, as well as the program name, the current date, and the half-line program description. (In compiling the program, the command used is in effect ``make \(gabasename destination .c\(ga''.) .sp 0.2i \fBManual Pages\fR .sp 0.13i Manual pages are placed in the main sources directory, first checking that they will not overwrite a previous copy unless the user wishes to. The user may then edit them. For manual page sources (as opposed to pre-formatted pages), the user is asked if he wishes to move them to the appropriate section of the manual source directory, and if he wants a formatted copy made and filed. If a formatted copy is made, it will also be shown on the terminal. If the correct directory for the source or formatted page does not exist, \fIsavesrc\fR attempts to create it. For pre-formatted manual pages, the user is given the option of moving them to the appropriate directory. (As yet there is no utility to generate source from formatted manual pages, but stay tuned...) .sp 0.2i \fBLarge (Multi-File) C Programs\fR .sp 0.13i When \fIsavesrc\fR cannot recognize the destination name as a single source program, a manual page, a header file, a bug, fix, or patch, or a README, it looks for a subdirectory of the main sources directory with that name (unless the destination is a full pathname, in which case it looks for that directory). If the directory exists, the user is given the option of working in that directory, or of specifying a different directory (which is also checked). .sp 0.13i Once the working directory has been found and made the current directory, the user is prompted for a half-line description of what the program does. If no description is wanted (\fIe.g.\fR, a new version is being saved), just hitting \s8RETURN\s10 will have no ill effects. .sp 0.13i The user is asked if he wants to use \fIunshar(1L)\fR to unpack the sources. If he opts for \fIunshar\fR, he is asked if it worked; if not, a shell is started automatically. If he does not want to use \fIunshar\fR, he may edit the sources or start a shell, is then shown a listing of the directory, and finally prompted for a name to copy the temporary file where \fIsavesrc\fR first puts the sources (``/tmp/newsrc$$'') to. .sp 0.13i Once the files are unpacked, \fIsavesrc\fR looks for a README or READ_ME file, and offers to show it to the user. If it cannot find one, it asks if the user wants to edit one. .sp 0.13i Next, \fIsavesrc\fR deals with any manual pages just as described above, except that they are copied to the main manual page directories, rather than moved there. The rationale for this is that while one does not usually want lots of manual pages cluttering up a general source directory, for larger software packages which merit directories of their own it is best to keep the original distribution together, as this simplifies packaging for re-distribution. The option of copying the manual pages to a central location is given because it is also convenient to have a canonical collection of manual pages. .sp 0.13i The question of a Makefile comes next. \fISavesrc\fR turns any ``makefile'' into ``Makefile'' as mentioned before. If no Makefile is present, the user is asked if one is hiding somewhere (\fIe.g.\fR, ``Makefile.bsd''), and this is copied to Makefile. If no Makefile at all can be found, a basic Makefile is generated automatically, using the one-line program description and simple-mindedly assuming that all the .c files are compiled up together. For example, suppose we have a new game of pacman, being placed in a directory called ``pacman''. The one-line description we have given it is ``a new, improved version of pacman'', and we have unshared four files, \fIpac.c\fR, \fIpac.h\fR, \fIscore.c\fR, and \fItty.c\fR. The default Makefile will contain: .sp 0.13i .ne 14 .in +0.7i .nf .ta 0.4i 0.8i # pacman -- a new, improved version of pacman .sp 0.2i CFILES = pac.c score.c tty.c .sp 0.13i OFILES = pac.o score.o tty.o .sp 0.13i CFLAGS = -O .sp 0.13i pacman: $(OFILES) cc $(CFLAGS) $(OFILES) -o pacman .sp 0.13i clean: rm -f *.o .sp 0.2i .fi .in -0.7i (Note that CFLAGS may be set in the environment or adjusted by editing \fIsavesrc\fR; its default is ``-O''.) No attempts to include libraries are made; the above example would almost certainly need `` -ltermcap'' added to the ``cc'' line. .sp 0.13i The user is next offered a chance to edit the Makefile (which it is sensible to accept). .sp 0.13i Finally, as for a single C program, the user is prompted for adding a basic NOTES entry, asked if the program should be compiled (using just ``make''), offered a shell to twiddle or test it, and prompted for any further NOTES entries. If the program came from a netnews article, the basic NOTES entry will include the author and the posting path, if possible, as well as the program name, the current date, and the half-line program description. .SH EXAMPLES XFrom \fIrn(1)\fR, ``| savesrc pacman'' will unpack a (presumably shar-ed) article into $HOME/src/pacman, and prompt the user for the steps necessary to compile and test it. .sp 0.13i ``savesrc /usr/joe/mung.c mungstuff'' will save the file ``mungstuff'' as ``/usr/joe/mung.c'', and prompt for compiling etc. .SH ENVIRONMENT VARIABLES .ta 1i 3i .nf .sp 0.13i \fBName Default Description\fR .sp 0.13i VISUAL /usr/bin/vi Used to edit files EDITOR none Used if VISUAL is not set SHELL /bin/sh Used to start a shell PAGER /usr/local/bin/more Used to page output srcdir $HOME/src Main sources directory mandir $HOME/man Main manual page source directory catdir $HOME/man Main pre-formatted manual page directory CFLAGS -O Compiler options for Makefile entries .fi .SH FILES /tmp/newsrc$$ .SH SEE ALSO \fInote(1L), shar(1L), unshar(1L), rn(1), readnews(1)\fR .SH AUTHOR Written by Christine Robertson, 1986. .SH WARNINGS \fISavesrc\fR assumes that `` [ '' exists as a synonym for \fItest(1)\fR. If you don't have it, either link \fItest\fR to it, or replace the `` [ ... ] '' constructs with ``test ...''. .sp 0.13i The utilities \fIunshar(1L)\fR and \fInote(1L)\fR are also assumed; they may be replaced with ``sh'' and ``cat >> NOTES'', respectively. .sp 0.13i If your shell does not support # as the comment character, remove all the # comments. .sp 0.13i This program was written to organize sources in the way the author likes them. There is no guarantee \fIyou\fR will like this too. .SH BUGS Please send all bug reports to {linus, ihnp4, decvax}!utzoo!toram!chris. SHAR_EOF if test 12044 -ne "`wc -c < 'savesrc.1'`" then echo shar: error transmitting "'savesrc.1'" '(should have been 12044 characters)' fi fi exit 0 # End of shell archive