summaryrefslogtreecommitdiff
path: root/reference/C/CONTRIB/SNIP/getopts.c
diff options
context:
space:
mode:
Diffstat (limited to 'reference/C/CONTRIB/SNIP/getopts.c')
-rwxr-xr-xreference/C/CONTRIB/SNIP/getopts.c193
1 files changed, 193 insertions, 0 deletions
diff --git a/reference/C/CONTRIB/SNIP/getopts.c b/reference/C/CONTRIB/SNIP/getopts.c
new file mode 100755
index 0000000..92c2d32
--- /dev/null
+++ b/reference/C/CONTRIB/SNIP/getopts.c
@@ -0,0 +1,193 @@
+/*
+** GETOPTS.C - Universal command line options parser
+**
+** Original Copyright 1993 by Bob Stout as part of
+** the MicroFirm Function Library (MFL)
+**
+** This subset version is hereby donated to the public domain.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "portable.h"
+#include "getopts.h"
+
+#define NUL '\0'
+#define MAX_XARGS 512
+
+int xargc;
+char *xargv[MAX_XARGS];
+
+/*
+** getopts()
+**
+** Parameters: 1 - argc from main()
+** 2 - argv from main()
+** 3 - your program's options[] array
+**
+** Returns: Number of options specified or -1 if error
+**
+** Note: Your program should declare the global options[] array which
+** specifies all options recognized by getopts().
+*/
+
+int getopts(int argc, char *argv[])
+{
+ int i, count, argidx = 0;
+ char *argp;
+ FILE *argfile;
+ char argline[256];
+ struct Option_Tag *ptr;
+
+ xargc = argc;
+ xargv[argidx++] = argv[0];
+ for (i = 1, count = 0; i < argc; ++i)
+ {
+ if (strchr("-/", argv[i][0]) && !strchr("-/", argv[i][1]))
+ {
+ /*
+ ** Found a switch - If the 2nd character is also a switch
+ ** character. If so, then it's a literal and is skipped
+ */
+
+ if (strchr("-/", argv[i][1]))
+ continue;
+
+ for (ptr = options; ptr->buf; ++ptr)
+ {
+ if ((int)argv[i][1] == ptr->letter) switch (ptr->type)
+ {
+ case Boolean_Tag:
+ if ('-' == argv[i][2])
+ *((Boolean_T *)(ptr->buf)) = FALSE;
+ else *((Boolean_T *)(ptr->buf)) = TRUE;
+ ++count;
+ --xargc;
+ break;
+
+ case Word_Tag:
+ sscanf(&argv[i][2], "%hd", (short *)(ptr->buf));
+ ++count;
+ --xargc;
+ break;
+
+ case DWord_Tag:
+ sscanf(&argv[i][2], "%ld", (long *)(ptr->buf));
+ ++count;
+ --xargc;
+ break;
+
+ case Double_Tag:
+ sscanf(&argv[i][2], "%lg", (double *)(ptr->buf);
+ ++count;
+ --xargc;
+ break;
+
+ case String_Tag:
+ strcpy(ptr->buf, &argv[i][2]);
+ ++count;
+ --xargc;
+ break;
+
+ default:
+ return ERROR;
+ }
+ }
+ }
+ else /* It must be a file name */
+ {
+ DOSFileData ffblk;
+
+ /* Set argp to point to the filename */
+
+ if (strchr("-/", argv[i][0]))
+ argp = &argv[i][1];
+ else argp = argv[i];
+
+ /* If no wildcards, just copy it */
+
+ if (!strchr(argp, '*') && !strchr(argp, '?'))
+ {
+ xargv[argidx++] = argp;
+ continue;
+ }
+
+ /* Expand wildcards, if possible */
+
+ if (0 == FIND_FIRST(argp, 0xff, &ffblk))
+ {
+ char path[FILENAME_MAX], *p;
+
+ /* Save the path for re-attachment */
+
+ if (NULL == (p = strrchr(argp, '\\')))
+ p = strrchr(argp, '/');
+ if (p)
+ {
+ char ch = *p;
+
+ *p = NUL;
+ strcat(strcpy(path, argp), "\\");
+ *p = ch;
+ }
+ else *path = NUL;
+ --xargc;
+ do
+ {
+ xargv[argidx] = malloc(strlen(ffblk.name)
+ + strlen(path) + 2);
+ strcat(strcpy(xargv[argidx], path), ffblk.name);
+ ++argidx;
+ ++xargc;
+
+ } while (0 == FIND_NEXT(&ffblk));
+ }
+ }
+ }
+ return count;
+}
+
+#ifdef TEST
+
+#include <stdlib.h>
+
+Boolean_T test1 = TRUE, test2 = FALSE;
+int test3 = -37;
+long test4 = 100000L;
+char test5[80] = "Default string";
+
+struct Option_Tag options[] = {
+ {'A', Boolean_Tag, &test1 }, /* Valid options */
+ {'B', Boolean_Tag, &test2 },
+ {'C', Word_Tag, &test3 },
+ {'D', DWord_Tag, &test4 },
+ {'E', String_Tag, test5 },
+ {'\0', ERROR, NULL } /* Terminating record */
+};
+
+#define TFprint(v) ((v) ? "TRUE" : "FALSE")
+
+int main(int argc, char *argv[])
+{
+ int i;
+
+ printf("Defaults:\ntest1 = %s\ntest2 = %s\ntest3 = %d\ntest4 = %ld\n"
+ "test5 = \"%s\"\n\n", TFprint(test1), TFprint(test2), test3,
+ test4, test5);
+
+ printf("getopts() returned %d\n", getopts(argc, argv));
+
+ printf("Options are now:\ntest1 = %s\ntest2 = %s\ntest3 = %d\n"
+ "test4 = %ld\ntest5 = \"%s\"\n\n", TFprint(test1),
+ TFprint(test2), test3, test4, test5);
+
+ puts("Hit any key to continue");
+ getch();
+ for (i = 0; i < xargc; ++i)
+ printf("xargv[%d] = \"%s\"\n", i, xargv[i]);
+ printf("\nxargc = %d\n", xargc);
+ return 0;
+}
+
+#endif