ajs@hpfcla (03/22/86)
Here's a C program template I use as the starting point for most new programs. (Other ones are either throwaways or are stolen from other code.) I mentioned this in a net.unix-wizards response, and one person asked for a copy, then suggested I post it. What the heck, it's short, and it does represent a fair amount of iterative refinement. I'm not trying to sell you on my perfectionist but arcane coding style, no flames please; just "take what you can use and let the rest go by" (-- Ken Kesey, and I'm beginning to think THAT should be the USENET motto). Alan Silverstein, Hewlett-Packard Fort Collins Systems Division, Colorado {ihnp4 | hplabs}!hpfcla!ajs, 303-226-3800 x3053, N 40 31'31" W 105 00'43" # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by ajs at hpfcla on Fri Mar 21 14:31:07 1986 # # This archive contains: # template.c # # Error checking via wc(1) will be performed. echo x - template.c cat >template.c <<'@EOF' /* * Generic C-source program template. * See the manual entry for details. */ #include <stdio.h> /********************************************************************* * MISCELLANEOUS GLOBAL VALUES: */ #define PROC /* null; easy to find procs */ #define FALSE 0 #define TRUE 1 #define CHNULL ('\0') #define CPNULL ((char *) NULL) #define REG register char *usage[] = { "usage: %s xxx", "-b xxx", CPNULL, }; char *myname; /* how program was invoked */ int bflag = FALSE; /* -b (xxx) option */ /************************************************************************ * M A I N */ PROC main (argc, argv) int argc; char **argv; { extern int optind; /* from getopt() */ extern char *optarg; /* from getopt() */ REG int option; /* option "letter" */ /* * BASENAME: Full string, or past '/' if any: */ char *cpBNTemp; /* temporary pointer */ #define CPBASENAME(cp) \ (((cpBNTemp = strrchr (cp, '/')) == CPNULL) ? cp : (cpBNTemp + 1)) /* * PARSE ARGUMENTS: */ myname = *argv; while ((option = getopt (argc, argv, "xxx")) != EOF) { switch (option) { case 'b': bflag = TRUE; break; default: Usage(); } } argc -= optind; /* skip options */ argv += optind; /* * READ FROM LIST OF FILES OR STDIN: */ char *defargv[] = { "-" }; /* argument list */ REG FILE *filep; /* open input file */ char *filename; /* name to use */ if (argc < 1) /* no file names */ { argc = 1; argv = defargv; /* use default */ } while (argc-- > 0) { if (strcmp (*argv, "-") == 0) /* read stdin */ { filename = "<stdin>"; filep = stdin; } else if ((filep = fopen ((filename = *argv), "r")) == FILENULL) Error ("can't open file \"%s\" to read it", filename); ReadFile (filename, filep); if (ferror (filep)) Error ("read failed from file \"%s\"", filename); if (filep != stdin) fclose (filep); /* assume it works */ argv++; } /* * FINISH UP: */ exit (0); } /* main */ /************************************************************************ * U S A G E * * Print usage messages (char *usage[]) to stderr and exit nonzero. * Each message is followed by a newline. */ PROC Usage() { REG int which = 0; /* current line */ while (usage [which] != CPNULL) { fprintf (stderr, usage [which++], myname); putc ('\n', stderr); } exit (1); } /* Usage */ /************************************************************************ * E R R O R * * Print an error message to stderr and exit nonzero. Message is preceded * by "<myname>: " using global char *myname, and followed by a newline. */ /* VARARGS */ PROC Error (message, arg1, arg2, arg3, arg4) char *message; long arg1, arg2, arg3, arg4; { fprintf (stderr, "%s: ", myname); fprintf (stderr, message, arg1, arg2, arg3, arg4); putc ('\n', stderr); exit (1); } /* Error */ char *malloc(); char *Malloc(); /************************************************************************ * M A L L O C * * Do a malloc with error checking. */ PROC char * Malloc (size) int size; /* bytes to get */ { char *cp; /* pointer to memory */ if ((cp = malloc (size)) == CPNULL) Error ("malloc %d bytes failed", size); return (cp); } /* Malloc */ @EOF if test "`wc -lwc <template.c`" != ' 177 518 3281' then echo ERROR: wc results of template.c are `wc -lwc <template.c` should be 177 518 3281 fi chmod 444 template.c exit 0