/*---------------------------------------------------------------------- File : skeleton.c Contents: command line program skeleton Author : Christian Borgelt History : 11.11.1997 file created from skel1.c 16.02.1999 argument evaluation improved ----------------------------------------------------------------------*/ #define _POSIX_SOURCE #include #include #include /*---------------------------------------------------------------------- Preprocessor Definitions ----------------------------------------------------------------------*/ /* --- error codes --- */ #define OK 0 /* no error */ #define E_NONE 0 /* no error */ #define E_NOMEM (-1) /* not enough memory */ #define E_FOPEN (-2) /* file open failed */ #define E_FREAD (-3) /* file read failed */ #define E_FWRITE (-4) /* file write failed */ #define E_OPTION (-5) /* unknown option */ #define E_OPTARG (-6) /* missing option argument */ #define E_ARGCNT (-7) /* wrong number of arguments */ #define E_UNKNOWN (-8) /* unknown error */ /*---------------------------------------------------------------------- Constants ----------------------------------------------------------------------*/ const char *errmsgs[] = { /* error messages */ /* E_NONE 0 */ "no error\n", /* E_NOMEM -1 */ "not enough memory\n", /* E_FOPEN -2 */ "cannot open file `%s'\n", /* E_FREAD -3 */ "read error on file `%s'\n", /* E_FWRITE -4 */ "write error on file `%s'\n", /* E_OPTION -5 */ "unknown option -%c\n", /* E_OPTARG -6 */ "missing option argument\n", /* E_ARGCNT -7 */ "wrong number of arguments\n", /* E_UNKNOWN -8 */ "unknown error\n" }; /*---------------------------------------------------------------------- Global Variables ----------------------------------------------------------------------*/ static char *prgname; /* program name for error messages */ /*---------------------------------------------------------------------- Functions ----------------------------------------------------------------------*/ static void error (int code, ...) { /* --- print error message */ va_list args; /* list of variable arguments */ const char *msg; /* buffer for error message */ if ((code > 0) || (code < E_UNKNOWN)) code = E_UNKNOWN; /* check error code */ msg = errmsgs[-code]; /* get error message */ if (!msg) msg = errmsgs[-E_UNKNOWN]; fprintf(stderr, "\n%s: ", prgname); /* print program name */ va_start(args, code); /* get variable arguments */ vfprintf(stderr, msg, args); /* print error message */ va_end(args); /* end variable argument evaluation */ /* >>> clean up code goes here <<< */ exit(code); /* abort programm */ } /* error() */ /*--------------------------------------------------------------------*/ int main (int argc, char *argv[]) { /* --- main function */ int i, k = 0; /* loop variables, counters */ char *s; /* to traverse options */ char **optarg = NULL; /* option argument */ int flag = 0; /* an optional switch */ int intnum = 0; /* an optional integer */ double fltnum = 0.0; /* an optional float */ char *string = "default"; /* an optional string */ char *arg1 = NULL; /* fixed argument 1 */ char *arg2 = NULL; /* fixed argument 2 */ prgname = argv[0]; /* get program name for error msgs. */ /* --- print startup/usage message --- */ if (argc > 1) { /* if arguments given */ printf("%s - command line program skeleton", argv[0]); fflush(stdout); } /* print startup message */ else { /* if no argument given */ printf("usage: %s [options] arg1 arg2\n", argv[0]); printf("-g sets an optional flag in the program\n"); printf("-i# passes an optional integer to the program\n"); printf("-f# passes an optional float to the program\n"); printf("-s# passes an optional string to the program\n"); printf("arg? fixed arguments\n"); return 0; /* print a usage message */ } /* and abort the program */ /* --- evaluate arguments --- */ for (i = 1; i < argc; i++) { /* traverse arguments */ s = argv[i]; /* get option argument */ if (optarg) { *optarg = s; optarg = NULL; continue; } if (*s == '-') { /* -- if argument is an option */ if (!*++s) error(E_OPTION, ' '); while (1) { /* traverse characters */ switch (*s++) { /* evaluate option */ case 'g': flag = 1; break; case 'i': intnum = (int)strtol(s, &s, 10); break; case 'f': fltnum = strtod(s, &s); break; case 's': optarg = &string; break; default : error(E_OPTION, *(--s)); break; } /* set option variables */ if (!*s) break; /* if at end of string, abort loop */ if (optarg) { *optarg = s; optarg = NULL; break; } } } /* get option argument */ else { /* -- if argument is no option */ switch (k++) { /* evaluate non-option */ case 0: arg1 = argv[i]; break; case 1: arg2 = argv[i]; break; default: error(E_ARGCNT); break; } /* note fixed arguments */ } } if (optarg) error(E_OPTARG); /* check option argument */ if (k != 2) error(E_ARGCNT); /* check number of arguments */ printf("\n"); /* terminate startup message */ /* >>> application specific code goes here <<< */ printf("flag : %d\n", flag); printf("intnum: %d\n", intnum); printf("fltnum: %f\n", fltnum); printf("string: %s\n", string); printf("arg1 : %s\n", arg1); printf("arg2 : %s\n", arg2); return 0; /* return 'ok' */ } /* main() */