[net.sources] wp - a programmers text & comment formatter

pete@kvvax4.UUCP (Peter J Story) (01/13/87)

This article header:

> Subject: It's hard to edit Ada comments and then reformat (FILL) them

in comp.lang.ada, prompted me to finally send what I consider to be one of
the most useful tools in my toolbox  ...  the article contains the full
sources for wp(1) - a simple programmer's text formatter.  As well as
handling normal text it also knows about comments in programs.  For the
first time you can edit your comments (in almost any language), and get
them reformatted easily and neatly afterwards.  How about changing:
   /* this is a lump of comment     */
   /* text that has been horribly hacked about and
   /* changed */
into this:
   /* this is a lump of comment text that has been horribly      */
   /* hacked about and changed                                   */
easily?  Or this:
   -- this is a comment
   -- which looks pretty untidy, but can be made 
   -- to look nicer
into this:
   -- this is a comment which looks pretty untidy,
   -- but can be made to look nicer

Like it?  Then wp(1) is the thing for you!  It runs on both Ultrix
and System V machines.  I suppose this will qualify it for most
Unices, since it does nothing especially non portable.  The source
bears marks of its stepwise development (ie no serious design!) but
the result is pretty handy anyway.


# ----------------------- cut here ----------------------------------
#! /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
#	wp.1
#	wp.c
#	string.h
#	getopt.c
#	strspn.c
#	strtok.c
#	Makefile
# This archive created: Wed Oct  1 10:05:16 1986
export PATH; PATH=/bin:$PATH
echo shar: extracting "'README'" '(1279 characters)'
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
sed 's/^	X//' << \SHAR_EOF > 'README'
	XTue Sep 30 15:48:26 EET 1986
	X============================
	X
	Xwp(1) - the programmer's text formatter.  Not another one?  Well, this one
	Xis really for programmers.  As well as handling normal text it also knows
	Xabout comments in programs.  For the first time you can edit your comments,
	Xand get them reformatted easily and neatly afterwards.  How about changing
	X
	X   /* this is a lump of comment     */
	X   /* text that has been horribly hacked about and
	X   /* changed */
	X
	Xinto this:
	X
	X   /* this is a lump of comment text that has been horribly      */
	X   /* hacked about and changed                                   */
	X
	Xeasily?  Like it?  Then read on.  You can handle almost any comment
	Xconvention.  Of course wp handles normal text as well.  It understands
	Xnroff commands (like Berkeleys fmt command), so you can use it on document
	Xinput as well.  It knows about first and subsequent line indents in
	Xparagraphs (like INed's ffill command) so you won't miss that feature.  It
	Xeven handles them inside comments.
	X
	XThis program is available for distribution to anyone for any purpose. But
	Xplease do me the courtesy of retaining my credit line!
	X
	X---
	XPete Story, Avd FF441, A/S Kongsberg Vaapenfabrikk
	XPO Box 25, N3601 Kongsberg, Norway.
	XTel: (+47 3) 739480  Uucp:    mcvax!kvvax4!pete
SHAR_EOF
if test 1279 -ne "`wc -c < 'README'`"
then
	echo shar: error transmitting "'README'" '(should have been 1279 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'wp.1'" '(4698 characters)'
if test -f 'wp.1'
then
	echo shar: will not over-write existing file "'wp.1'"
else
sed 's/^	X//' << \SHAR_EOF > 'wp.1'
	X'\" SCCS id: @(#)wp.1	1.2
	X'\" page setup for European paper
	X.nr )O 1.5c
	X.nr )L 12i
	X.nr LL 6.5i
	X.pl \n()Lu
	X.ll \n(LLu
	X.lt \n(LLu
	X.po \n()Ou
	X'\" actual manual page
	X.TH WP 1
	X.SH NAME
	Xwp \- reformat text to even right margin
	X.SH SYNOPSIS
	X.B wp
	X.RB [ \-c " commentstring [" \-bBfs "] ]"
	Xlinelength
	X.SH DESCRIPTION
	X.I Wp
	Xfilters standard input to standard output reformatting the text to
	Xlines approximately equal to
	X.I linelength
	X(default 67).
	X.PP
	XThe text is regarded as "paragraphs", defined to be sections of text
	Xseparated by one or more empty lines (including lines containing only
	Xwhite space - that is, spaces and tabs).  The output paragraphs are indented
	Xsuch that the first line indentation is the same as that of the first
	Xline of the input paragraph, and
	Xsecond and subsequent lines are indented to the level of the second
	Xinput line of the paragraph.  The indentation of the third and
	Xsubsequent lines of the input paragraph is thus ignored.
	X.PP
	XSince text lines rarely begin with the character ".", such a line will
	Xhave the same effect on the line counting as does a blank line [ie,
	Xlike fmt(1), wp can be used to reformat nroff input].
	X.PP
	XA "word" is defined to be all characters between white space.
	XThe lines are "turned" at word boundaries - no hyphenation is
	Xattempted.  The characters ".", "!", and "?" are regarded as sentence
	Xendings, and will be followed by two spaces instead of the normal one
	Xspace between words.
	X.PP
	XThe option
	X.B \-c
	Xspecifies that the following argument is to be treated as a comment
	Xprefix.  This prefix is stripped off input lines before reformatting.
	XThe prefix is then added to the beginning of
	X.I all
	Xnon blank output lines, regardless of whether they originally started with the
	Xcomment prefix or not.  This facility is intended to ease the inclusion or
	Xreformatting of comments in programs and shell procedures.
	X.PP
	XAny indentation preceding a comment symbol on the
	X.I first
	Xline of a paragraph will be retained for all the output lines.  This
	Xis reset only by a genuine blank line in the text.
	X.PP
	XThe text
	Xindentation within the comment symbols is controlled as for normal
	Xtext paragraphs, with indentations relative to the comment symbol if
	Xit is present in the input text, otherwise relative to the beginning
	Xof the line.
	X.PP
	XIf
	X.B \-b
	Xis specified in addition, then "block commenting" is used.  The
	Xspecified comment prefix with the character order reversed and
	X"paired" characters
	X.BR [ "(), [], {}" ]
	Xinverted is assumed to be a comment suffix.
	XAny existing suffix is removed from input lines before reformatting. All
	Xoutput lines, including blank lines, will be preceded by the comment
	Xprefix, and terminated by the comment suffix after padding with spaces
	Xto
	X.IR linelength .
	X.PP
	XOption
	X.B \-B
	Xalso produces block commenting, but no linelength padding is
	Xdone, and blank lines remain blank.
	X.PP
	XIt can be difficult to understand the exact interplay of comment
	Xindentations and text indentations.  The basic rule is to make the
	Xindentations and comment prefix correct on the first two lines of your
	Xparagraph - wp will handle the rest.
	X.PP
	XOption
	X.B \-f
	Xwill "frame" paragraphs with lines of dashes, inside comment
	Xsymbols.  This option implies
	X.BR \-b .
	XThe behaviour is currently rather unsatisfactory on more than single
	Xparagraphs, but extremely useful for those!
	X.PP
	XOption
	X.B \-s
	Xmay be used to strip off comment symbols (including dashed lines if -f
	Xis specified), without replacing them after reformatting.  Either
	Xleading or both leading and trailing comments are stripped, depending
	Xon the absence or presence of a block comment option.
	X.SH EXAMPLES
	X.I wp
	Xis typically used within vi(1) to reformat text while editing. The
	Xcommand:
	X.sp
	X   !}wp
	X.PP
	Xreplaces the paragraph starting at the cursor with a reformatted
	Xversion.
	X.PP
	X.sp
	X   !}wp -c '\e#\ ' 55
	X.PP
	Xreplaces the paragraph with a version reformatted to lines of not more
	Xthan 55 characters, each line commencing with "#\ ".  Observe the
	Xnecessity to use both quotes and the backslash in the case of the "#" character,
	Xbecause this character is special to both vi(1) and to sh(1).
	X.PP
	X.sp
	X   !}wp -c '(* ' -b 
	X.PP
	Xreplaces the paragraph with a reformatted version, 
	Xwith preceding and trailing comment markers (* and *) -
	XPascal block commenting.
	X.PP
	X.I wp
	Xcan also be used with INed.  The command:
	X.PP
	X.sp
	X   <enter>wp -c '(* ' -b<do>
	X.PP
	Xhas the same effect as the previous example.
	X.SH BUGS
	XInput lines are silently limited to 512 characters.
	X.PP
	XIf the first line of a paragraph is long enough to create more than
	Xone line in the output, then the indentation of the second input line
	Xis ignored.  Workaround: divide the first line!
	X.PP
	XOthers, probably - mail kvvax6!pete
SHAR_EOF
if test 4698 -ne "`wc -c < 'wp.1'`"
then
	echo shar: error transmitting "'wp.1'" '(should have been 4698 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'wp.c'" '(11514 characters)'
if test -f 'wp.c'
then
	echo shar: will not over-write existing file "'wp.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'wp.c'
	X/* SCCS id : @(#)wp.c	1.11 (Peter J Story)                                 */
	X
	X/* ------------------------------------------------------------- */
	X/* Copyright: P J Story, Eikervn 67, 3600 KONGSBERG, Norway 1986 */
	X/*   This program may be copied for any purpose, as long as the  */
	X/*   above credit line is retained				 */
	X/* ------------------------------------------------------------- */
	X
	X/* trivial text formatter, operating as a filter, to enable me   */
	X/* to format text into roughly equal length lines.  Most often   */
	X/* used from vi(1).  Getting less trivial and messier, but still */
	X/* useful                                                        */
	X
	X/* will run on System V systems, and 4.x BSD if you have the     */
	X/* missing System V getopt, strtok, strspn routines or           */
	X/* equivalents which are usually packaged with my source,        */
	X/* courtesy of Henry Spencer                                     */
	X
	X/* modified: Sun Sep 22 14:54:10 GMT+1:00 1985, by KVVAX6!pete	 */
	X/*   -s option strips comment symbols and doesnt put them back   */
	X/*   return 0 on exit, so it works from mail                     */
	X/* modified: Fri Sep 6 10:00:06 GMT+1:00 1985, by KVVAX6!esa     */
	X/*   -f option for framing (adopted into my version as is,       */
	X/*   though I don't like its behaviour wrt more than one         */
	X/*   paragraph)                                                  */
	X/* modified: Fri May 24 18:16:27 GMT+1:00 1985, by kvvax6!pete   */
	X/*  even more corrections to comment feature - comment indents   */
	X/*  are handled, and non padded block comments                   */
	X/* modified: Mon May 20 16:43:01 GMT+1:00 1985, by kvvax6!pete   */
	X/*  to correctly handle leading tabs (simply replacing by        */
	X/*  spaces) to add the -b option for block commenting            */
	X/* modified: Wed Apr 24 08:57:33 MET 1985, by olhqmc!pete        */
	X/*  Rewritten from awk to C.  Indenting facilities added, so     */
	X/*  that output paragraphs retain the first and second line      */
	X/*  indents of the input para for the first and subsequent lines */
	X/*  of the output para.                                          */
	X/* modified: Fri Jun 22 08:04:40 CET 1984, by pete @ Olivetti HQ */
	X/* To give me formatting of 'commented' lines.  Normal text will */
	X/* be made into comments with the given comment symbol.          */
	X/* Existing comment text will be reformatted.                    */
	X
	X
	X#include <stdio.h>
	X
	X#define LINELENGTH 67
	X#define WHITE " 	"
	X#define DASH '-'
	X
	Xchar buf[512];
	Xchar revcomment[20];	/* comment symbol reversed */
	Xchar *progname;
	Xchar *commentstart;
	Xchar *ipline;
	X
	Xint oplth;		/* current length output on this line */
	Xint iplth;
	Xint fplth;
	Xint initblanks;		/* actual number of WHITE chars at start of ipline */
	Xint oplinenum;		/* in the output paragraph */
	Xint iplinenum;		/* in the input paragraph */
	Xint spacesbefore;	/* the next word */
	Xint commenting = 0;	/* on if lines are to be preceded by comment symbol */
	Xint commentlth = 0;
	Xint blocking = 0;	/* on if lines are to be succeeded by comment symbol
	X			   reversed */
	Xint framing = 0;	/* will be blocking and framing */
	Xint padding = 1;	/* on if block commented lines are padded out */
	Xint stripping = 0;      /* on if comment symbols are to be stripped off */
	X			/*  and left off */
	Xint comindent = 0;	/* comment indent on all lines in para */
	Xint linelength = LINELENGTH;	/* output length to aim at */
	X
	X
	X/* BEWARE, this program grew like topsy, and most of these have  */
	X/* side effects.  Sorry about that!                              */
	X
	Xint	chkblank();	/* return true if line is blank */
	Xvoid	dash();		/* output this many dashes */
	Xvoid	dashline();	/* block out the line with dashes */
	Xvoid	emptyline();	/* output empty line */
	Xint	initcount();	/* how many effective initial spaces are there */
	Xvoid	newline();	/* clear off this op line, init for next */
	Xint	prefix();	/* return true if pre is prefix in s */
	Xvoid	space();	/* output this many spaces */
	Xvoid	usage();
	X
	Xchar	*gets();
	Xchar	*strtok();
	Xint	strcmp();
	Xint	strlen();
	Xint	strspn();
	X
	X
	Xmain(argc,argv)
	X   char **argv;
	X{
	X   extern char *optarg;
	X   extern int optind;
	X
	X   int c;
	X   int errflg = 0;
	X   int indent;		/* text indent on the current line */
	X   int indent1;		/* text indent on 1st o/p line in para */
	X   int indent2;		/* text indent on subs o/p line in para */
	X
	X   progname=argv[0];
	X
	X   while ((c=getopt(argc, argv, "Bbc:fs")) != EOF) {
	X      switch (c) {
	X	 case 'B':	/* block commenting, do not pad to full lth */
	X	    padding = 0;
	X	    blocking++;
	X	    break;
	X	 case 'f':	/* framing, which implies a block comment */
	X	    framing++;
	X	    blocking++;
	X	    break;
	X	 case 'b':	/* block commenting */
	X	    blocking++;
	X	    break;
	X	 case 's':      /* stripping comments */
	X	    stripping++;
	X	    break;
	X	 case 'c':
	X	    commenting++;
	X	    commentstart = optarg;
	X	    commentlth = strlen(commentstart);
	X	    break;
	X	 case '?':
	X	    errflg++;
	X	    break;
	X      }
	X   }
	X   argc -= optind;
	X   argv = &argv[optind];
	X
	X   if ((blocking || stripping) && ! commenting) errflg++;
	X
	X   if (errflg) usage();
	X
	X   if (argc > 0) {
	X      if ((linelength = atoi(*argv)) <= 0 ) {
	X	 usage();
	X      }
	X   }
	X
	X   if (blocking) {
	X      /* this section attempts a reasonable inverse of the comment string */
	X      char *s = commentstart + commentlth - 1;
	X      char *d = &revcomment[0];
	X      while (s >= commentstart) {
	X	 char c = *s--;
	X	 switch (c) {
	X	 case '(':
	X	    c = ')'; break;
	X	 case '{':
	X	    c = '}'; break;
	X	 case '[':
	X	    c = ']'; break;
	X	 case '<':
	X	    c = '>'; break;
	X	 }
	X	 *d++ = c;
	X      }
	X      *d = '\0';
	X      linelength -= commentlth;
	X   }
	X
	X   iplinenum = 0;
	X   oplinenum = 0;
	X
	X   while ((ipline = gets(buf)) != NULL) {
	X      int initspaces;	/* number of spaces equivalent */
	X
	X      iplth = strlen(ipline);
	X      initblanks = strspn(ipline,WHITE);
	X
	X      if (iplth == initblanks) { /* current line is really empty */
	X	 if (oplth) newline();
	X	 emptyline();
	X	 comindent = 0;
	X      } else if ((*ipline == '.') && ! commenting) {
	X	 /* current line is an nroff command */
	X	 if (oplth) newline();
	X	 /* Yugh, this really uses a side effect of emptyline */
	X	 printf("%s",ipline);
	X	 oplth += iplth;
	X	 emptyline();
	X	 comindent = 0;
	X      } else {			/* current line is non empty */
	X	 char *word;
	X
	X	 iplinenum++;
	X
	X	 if (blocking) {
	X	    /* strip trailing comment marker */
	X	    char *p = ipline + strlen(ipline) - commentlth;
	X	    if (strcmp(p,revcomment) == 0) {
	X	       *p = '\0';
	X	    }
	X	    if (chkblank()) continue; /* resets iplth and initblanks */
	X	 }
	X
	X	 initspaces = initcount(ipline,initblanks,0);
	X
	X	 if (commenting) {
	X	    if (prefix(commentstart,ipline + initblanks)) {
	X	       int offset;
	X	       if (iplinenum == 1) {
	X		  comindent = initspaces;	/* comment indentation */
	X	       }
	X
	X	       /* strip leading comment marker */
	X	       offset = initblanks + commentlth;
	X	       ipline += offset;
	X	       if (chkblank()) continue; /* sets iplth and initblanks */
	X
	X	       /* now reset for text indents inside the comments */
	X	       initspaces = initcount(ipline,initblanks,offset);
	X	    } else {
	X	       if (iplinenum == 1) {
	X		  comindent = 0;	/* comment indentation */
	X	       }
	X	    }
	X         }
	X
	X	 if (iplinenum <= 2) {
	X	    if (iplinenum == 1) {
	X	       if (framing) {
	X		  space(comindent);
	X		  dashline();
	X	       }
	X	       indent2 = indent1 = initspaces;	/* 1st line indent */
	X	    } else {
	X	       indent2 = initspaces;		/* subs line indent */
	X	    }
	X	 }
	X
	X         while ((word = strtok(ipline,WHITE)) != NULL) {
	X	    int wordlth = strlen(word);
	X	    char lastchar = word[wordlth - 1];
	X
	X	    if ((oplth + spacesbefore + wordlth) > linelength) {
	X	       newline();
	X	    }
	X
	X            if (oplth == 0) {	/* start of new line */
	X	       if (oplinenum < 2) {
	X		  indent = (oplinenum == 1) ? indent2 : indent1;
	X	       }
	X	       if (commenting) {
	X		  space(comindent);
	X		  if (!stripping) {
	X		     printf("%s",commentstart);
	X		     oplth += commentlth;
	X		  }
	X	       }
	X	       space(indent);
	X            }
	X
	X	    space(spacesbefore);
	X	    printf("%s",word);
	X	    oplth += wordlth;
	X
	X	    spacesbefore =
	X	       ((lastchar=='.') || (lastchar=='!') || (lastchar=='?')) ? 2 : 1;
	X
	X	    ipline = (char *) NULL;
	X	 }
	X      }
	X   }
	X   if (oplth) newline();
	X   if (framing && !stripping) {
	X      space(comindent);
	X      dashline();
	X   }
	X   return(0);
	X}
	X
	X/* ------------------------------------------------------------- */
	X/* output routines of various kinds 				 */
	X/* ------------------------------------------------------------- */
	X
	Xvoid
	Xspace(howmany)
	X   register int howmany;
	X{
	X   register int t;
	X   t = howmany;
	X   while (t-- > 0) putchar(' ');
	X   oplth += howmany;
	X}
	X
	Xvoid
	Xdash(howmany)
	X   register int howmany;
	X{
	X   register int t;
	X   t = howmany;
	X   while (t-- > 0) putchar(DASH);
	X   oplth += howmany;
	X}
	X
	Xvoid
	Xnewline()
	X{
	X   if (blocking) {
	X      if (padding) {
	X	 space(linelength - oplth);
	X      }
	X      if (!stripping) {
	X	 printf("%s",revcomment);
	X	 oplth += commentlth;
	X      }
	X   }
	X   putchar('\n');
	X   oplth = 0;
	X   spacesbefore = 0;
	X   oplinenum++;
	X}
	X
	Xvoid
	Xemptyline()
	X{
	X   if (blocking && padding) {
	X      /* need comment start and end as well */
	X      space(comindent);
	X      if (!stripping) {
	X	 printf("%s",commentstart);
	X	 oplth += commentlth;
	X      }
	X      newline();
	X   } else {
	X      /* ordinary text or start only commenting just get blank lines */
	X      putchar('\n');
	X      oplth = 0;
	X      spacesbefore = 0;
	X   }
	X   iplinenum = 0;
	X   oplinenum = 0;
	X}
	X
	Xvoid
	Xdashline(len)  		/* block out the line with a dash comment */
	X   int len;
	X{
	X   if (!stripping) {
	X      printf("%s",commentstart);
	X      oplth += commentlth;
	X   }
	X   dash(linelength - oplth);
	X   newline();
	X   oplinenum--; /* messy - dashlines shouldn't count */
	X}
	X
	X/* ------------------------------------------------------------- */
	X/* input routines of various kinds 				 */
	X/* ------------------------------------------------------------- */
	X
	Xint
	Xprefix(pre, s)			/* return true if pre is prefix in s */
	X   register char *pre, *s;
	X{
	X   register char c;
	X   while ((c = *pre++) == *s++)
	X   if (c == '\0')
	X       return(1);
	X   return((c == '\0')?1:0);
	X}
	X
	Xint
	Xchkblank()	/* return true if line is blank, with side effects */
	X		/* like the line is output as well!		   */
	X{
	X   /* any comment symbols should already have been stripped */
	X   iplth = strlen(ipline);
	X   initblanks = strspn(ipline,WHITE);
	X   if (iplth == initblanks) { /* current text is empty */
	X      if (oplth) newline();
	X      emptyline();
	X      return(1);	/* was blank, indicate to caller */
	X   }
	X   if (framing) { /* then a line of dashes should be lost */
	X      char *s = ipline + initblanks;
	X      char *e = ipline + iplth;
	X      while (s < e && *s++ == DASH) ;
	X      if (s == e) {
	X	 /* effectively an empty line, but don't output it */
	X	 iplinenum = 0;
	X	 oplinenum = 0;
	X	 return(1);
	X      }
	X   }
	X   return(0);
	X}
	X
	Xint
	Xinitcount(line,blanks,offset)	 /* count initial tabs into spaces */
	X   char* line;			 /* return effective blank length */
	X   int blanks;
	X   int offset;
	X{  
	X   char *s,*e;
	X   int spaces;
	X   s = line;
	X   e = line + blanks;
	X   spaces = 0;
	X   while (s < e) {
	X      if (*s++ == '\t') {
	X	 spaces += (8 - ((offset + spaces + 8) % 8));
	X      } else {
	X	 spaces++;
	X      }
	X   }
	X   return(spaces);
	X}
	X
	X/* ------------------------------------------------------------- */
	X/* miscellaneous routines 					*/
	X/* ------------------------------------------------------------- */
	X
	Xvoid
	Xusage()
	X{
	X   fprintf(stderr, "usage: %s [-c commentchar [-bBfs] ] linelength\n",progname);
	X   exit(1);
	X}
SHAR_EOF
if test 11514 -ne "`wc -c < 'wp.c'`"
then
	echo shar: error transmitting "'wp.c'" '(should have been 11514 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'string.h'" '(1431 characters)'
if test -f 'string.h'
then
	echo shar: will not over-write existing file "'string.h'"
else
sed 's/^	X//' << \SHAR_EOF > 'string.h'
	X/*
	X * String functions.
	X */
	X
	Xchar *memcpy(/*char *dst, const char *src, int size*/);
	Xchar *memccpy(/*char *dst, const char *src, int ucharstop, int size*/);
	Xchar *strcpy(/*char *dst, const char *src*/);
	Xchar *strncpy(/*char *dst, const char *src, int size*/);
	Xchar *strcat(/*char *dst, const char *src*/);
	Xchar *strncat(/*char *dst, const char *src, int size*/);
	Xint memcmp(/*const char *s1, const char *s2, int size*/);
	Xint strcmp(/*const char *s1, const char *s2*/);
	Xint strncmp(/*const char *s1, const char *s2, int size*/);
	Xchar *memchr(/*const char *s, int ucharwanted, int size*/);
	Xchar *strchr(/*const char *s, int charwanted*/);
	Xint strcspn(/*const char *s, const char *reject*/);
	Xchar *strpbrk(/*const char *s, const char *breakat*/);
	Xchar *strrchr(/*const char *s, int charwanted*/);
	Xint strspn(/*const char *s, const char *accept*/);
	Xchar *strstr(/*const char *s, const char *wanted*/);
	Xchar *strtok(/*char *s, const char *delim*/);
	Xchar *memset(/*char *s, int ucharfill, int size*/);
	Xint strlen(/*const char *s*/);
	X
	X/*
	X * V7 and Berklix compatibility.
	X */
	Xchar *index(/*const char *s, int charwanted*/);
	Xchar *rindex(/*const char *s, int charwanted*/);
	Xint bcopy(/*const char *src, char *dst, int length*/);
	Xint bcmp(/*const char *s1, const char *s2, int length*/);
	Xint bzero(/*char *dst, int length*/);
	X
	X/*
	X * Putting this in here is really silly, but who am I to argue with X3J11?
	X */
	Xchar *strerror(/*int errnum*/);
SHAR_EOF
if test 1431 -ne "`wc -c < 'string.h'`"
then
	echo shar: error transmitting "'string.h'" '(should have been 1431 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'getopt.c'" '(1161 characters)'
if test -f 'getopt.c'
then
	echo shar: will not over-write existing file "'getopt.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'getopt.c'
	X/*LINTLIBRARY*/
	X
	X#ifdef BSD
	X/* fix differences in string routine names */
	X#define	strchr	index
	X#endif
	X
	X#include	<stdio.h>
	X#define ERR(s, c)	if(opterr){\
	X	fputs(argv[0], stderr);\
	X	fputs(s, stderr);\
	X	fputc(c, stderr);\
	X	fputc('\n', stderr);}
	X
	Xint	opterr = 1;
	Xint	optind = 1;
	Xint	optopt;
	Xchar	*optarg;
	Xchar	*strchr();
	X
	X
	Xint
	Xgetopt (argc, argv, opts)
	Xchar **argv, *opts;
	X{
	X	static int sp = 1;
	X	register c;
	X	register char *cp;
	X
	X	if (sp == 1)
	X		if (optind >= argc ||
	X		   argv[optind][0] != '-' || argv[optind][1] == '\0')
	X			return EOF;
	X		else if (strcmp(argv[optind], "--") == NULL) {
	X			optind++;
	X			return EOF;
	X		}
	X	optopt = c = argv[optind][sp];
	X	if (c == ':' || (cp=strchr(opts, c)) == NULL) {
	X		ERR (": illegal option -- ", c);
	X		if (argv[optind][++sp] == '\0') {
	X			optind++;
	X			sp = 1;
	X		}
	X		return '?';
	X	}
	X	if (*++cp == ':') {
	X		if (argv[optind][sp+1] != '\0')
	X			optarg = &argv[optind++][sp+1];
	X		else if (++optind >= argc) {
	X			ERR (": option requires an argument -- ", c);
	X			sp = 1;
	X			return '?';
	X		} else
	X			optarg = argv[optind++];
	X		sp = 1;
	X	}
	X	else {
	X		if (argv[optind][++sp] == '\0') {
	X			sp = 1;
	X			optind++;
	X		}
	X		optarg=NULL;
	X	}
	X	return c;
	X}
SHAR_EOF
if test 1161 -ne "`wc -c < 'getopt.c'`"
then
	echo shar: error transmitting "'getopt.c'" '(should have been 1161 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'strspn.c'" '(460 characters)'
if test -f 'strspn.c'
then
	echo shar: will not over-write existing file "'strspn.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'strspn.c'
	X/*
	X * strspn - find length of initial segment of s consisting entirely
	X * of characters from accept
	X */
	X
	XSIZET
	Xstrspn(s, accept)
	XCONST char *s;
	XCONST char *accept;
	X{
	X	register CONST char *sscan;
	X	register CONST char *ascan;
	X	register SIZET count;
	X
	X	count = 0;
	X	for (sscan = s; *sscan != '\0'; sscan++) {
	X		for (ascan = accept; *ascan != '\0'; ascan++)
	X			if (*sscan == *ascan)
	X				break;
	X		if (*ascan == '\0')
	X			return(count);
	X		count++;
	X	}
	X	return(count);
	X}
SHAR_EOF
if test 460 -ne "`wc -c < 'strspn.c'`"
then
	echo shar: error transmitting "'strspn.c'" '(should have been 460 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'strtok.c'" '(1103 characters)'
if test -f 'strtok.c'
then
	echo shar: will not over-write existing file "'strtok.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'strtok.c'
	X/*
	X * Get next token from string s (NULL on 2nd, 3rd, etc. calls),
	X * where tokens are nonempty strings separated by runs of
	X * chars from delim.  Writes NULs into s to end tokens.  delim need not
	X * remain constant from call to call.
	X */
	X
	X#define	NULL	0
	X
	Xstatic char *scanpoint = NULL;
	X
	Xchar *				/* NULL if no token left */
	Xstrtok(s, delim)
	Xchar *s;
	Xregister CONST char *delim;
	X{
	X	register char *scan;
	X	char *tok;
	X	register CONST char *dscan;
	X
	X	if (s == NULL && scanpoint == NULL)
	X		return(NULL);
	X	if (s != NULL)
	X		scan = s;
	X	else
	X		scan = scanpoint;
	X
	X	/*
	X	 * Scan leading delimiters.
	X	 */
	X	for (; *scan != '\0'; scan++) {
	X		for (dscan = delim; *dscan != '\0'; dscan++)
	X			if (*scan == *dscan)
	X				break;
	X		if (*dscan == '\0')
	X			break;
	X	}
	X	if (*scan == '\0') {
	X		scanpoint = NULL;
	X		return(NULL);
	X	}
	X
	X	tok = scan;
	X
	X	/*
	X	 * Scan token.
	X	 */
	X	for (; *scan != '\0'; scan++) {
	X		for (dscan = delim; *dscan != '\0';)	/* ++ moved down. */
	X			if (*scan == *dscan++) {
	X				scanpoint = scan+1;
	X				*scan = '\0';
	X				return(tok);
	X			}
	X	}
	X
	X	/*
	X	 * Reached end of string.
	X	 */
	X	scanpoint = NULL;
	X	return(tok);
	X}
SHAR_EOF
if test 1103 -ne "`wc -c < 'strtok.c'`"
then
	echo shar: error transmitting "'strtok.c'" '(should have been 1103 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Makefile'" '(906 characters)'
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^	X//' << \SHAR_EOF > 'Makefile'
	X# @(#)Makefile	1.6
	X# modified: Tue Sep 30 15:41:23 EET 1986, by kvvax6!pete
	X#   include Henry Spencers public domain string handling
	X# modified: Mon Jul  1 08:43:55 GMT+1:00 1985, by KVVAX6!pete
	X#   actually I didn't modify the makefile, but I should note
	X#   somewhere that the version of getopt is now the public domain
	X#   one from the network, not the system V version
	X# created : Mon Jul  2 13:53:50 CET 1984, by pete @ Olivetti HQ Milan
	X
	X# for System V:
	X# CFLAGS = -Dindex=strchr -O $(CONF) -DUNIXERR -I.
	X
	XSIZET = int
	XVOIDSTAR = char *
	XCONST = 
	XCONF = -DSIZET=$(SIZET) -DVOIDSTAR='$(VOIDSTAR)' -DCONST='$(CONST)'
	X
	XCFLAGS = -DBSD -O $(CONF) -DBERKERR -I.
	X
	XOBJS = wp.o 
	XUTIL = getopt.o strspn.o strtok.o 
	XUTILSRC = string.h getopt.c strspn.c strtok.c 
	X
	Xwp: $(OBJS) $(UTIL)
	X	$(CC) $(OBJS) $(UTIL) -o wp
	X
	Xman:
	X	@nroff -man wp.1
	X
	Xclean:
	X	rm -f *.o wp
	X
	Xshar:
	X	@shar -a README wp.1 wp.c $(UTILSRC) Makefile
SHAR_EOF
if test 906 -ne "`wc -c < 'Makefile'`"
then
	echo shar: error transmitting "'Makefile'" '(should have been 906 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0
-- 
Pete Story	      {decvax,philabs}!mcvax!kvport!kvvax4!pete
A/S Kongsberg Vaapenfabrikk, PO Box 25, N3601 Kongsberg, Norway
Tel:  + 47 3 739480   Tlx:  71491 vaapn n