]> git.sur5r.net Git - cc65/commitdiff
Added getopt. The implementation is based on a public domain source,
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 10 Jul 2010 11:28:02 +0000 (11:28 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 10 Jul 2010 11:28:02 +0000 (11:28 +0000)
originally written by Henry Spencer and supplied by Harald Arnesen.

git-svn-id: svn://svn.cc65.org/cc65/trunk@4737 b7a2c559-68d2-44c3-8de9-860c34a00d81

doc/funcref.sgml
libsrc/common/Makefile
libsrc/common/getopt.c [new file with mode: 0644]
testcode/lib/getopt-test.c [new file with mode: 0644]

index 409eefc877dc1e4d528ccb2d8d8d4854f877022d..fa764129fb35a7d04c8ce06d667f7d7941c76cf1 100644 (file)
@@ -568,6 +568,7 @@ It does not declare any functions.
 <itemize>
 <!-- <item><ref id="chdir" name="chdir"> -->
 <!-- <item><ref id="getcwd" name="getcwd"> -->
+<item><ref id="getopt" name="getopt">
 <!-- <item><ref id="lseek" name="lseek"> -->
 <!-- <item><ref id="mkdir" name="mkdir"> -->
 <!-- <item><ref id="read" name="read"> -->
@@ -704,7 +705,7 @@ id="malloc" name="malloc"> may still return <tt/NULL/.
 <sect1>_poserror<label id="_poserror"><p>
 
 <quote>
-<descrip>                                                 
+<descrip>
 <tag/Function/Print an error message for the error in <tt/_oserror/.
 <tag/Header/<tt/<ref id="stdio.h" name="stdio.h">/
 <tag/Declaration/<tt/void __fastcall__ _poserror (const char* msg);/
@@ -2188,6 +2189,28 @@ header files define constants that can be used to check the return code.
 </quote>
 
 
+<sect1>getcpu<label id="getcpu"><p>
+
+<quote>
+<descrip>
+<tag/Function/Determine on which CPU the program is running.
+<tag/Header/<tt/<ref id="6502.h" name="6502.h">/
+<tag/Declaration/<tt/unsigned char getcpu (void);/
+<tag/Description/The function checks on which CPU the code is running. It
+returns one of the constants<itemize>
+<item><tt/CPU_6502/
+<item><tt/CPU_65C02/
+<item><tt/CPU_65816/
+</itemize>
+<tag/Limits/<itemize>
+<item>Other, more exotic CPU types are not disinguished.
+</itemize>
+<tag/Availability/cc65
+<tag/Example/None.
+</descrip>
+</quote>
+
+
 <sect1>getenv<label id="getenv"><p>
 
 <quote>
@@ -2211,23 +2234,32 @@ be used in presence of a prototype.
 </quote>
 
 
-<sect1>getcpu<label id="getcpu"><p>
+<sect1>getopt<label id="getopt"><p>
 
 <quote>
 <descrip>
-<tag/Function/Determine on which CPU the program is running.
-<tag/Header/<tt/<ref id="6502.h" name="6502.h">/
-<tag/Declaration/<tt/unsigned char getcpu (void);/
-<tag/Description/The function checks on which CPU the code is running. It
-returns one of the constants<itemize>
-<item><tt/CPU_6502/
-<item><tt/CPU_65C02/
-<item><tt/CPU_65816/
-</itemize>
-<tag/Limits/<itemize>
-<item>Other, more exotic CPU types are not disinguished.
+<tag/Function/Parse command line options.
+<tag/Header/<tt/<ref id="unistd.h" name="unistd.h">/
+<tag/Declaration/<tt/int __fastcall__ getopt (int argc, char* const* argv,
+const char* optstring);/
+<tag/Description/The function parses command line arguments, <tt/argc/ and 
+<tt/argv/ are the argument count and array passed to <tt/main/. <tt/optstring/
+is a string that contains command line option characters. If a character in
+<tt/optstring/ is followed by a colon, the option requires an argument. An
+option on the command line is recognized if it is one of the option characters
+preceeded by a '-'.
+<tt/getopt/ must be called repeatedly. It will return each option character
+found on the command line and <tt/EOF/ (-1) if there is no other option. An
+option argument is placed in <tt/optarg/, the index of the next element on the
+command line to be processed is placed in <tt/optind/.
+<tag/Limits/<itemize>
+<item>The implementation will not reorder options. A non option on the command
+line will terminate option processing. All remaining arguments are not
+recognized as options, even if the start with a '-' character.
+<item>The function is only available as fastcall function, so it may only
+be used in presence of a prototype.
 </itemize>
-<tag/Availability/cc65
+<tag/Availability/POSIX.2
 <tag/Example/None.
 </descrip>
 </quote>
index b779cf97fce18a98a069d44fd15f4e09f33c2d2d..37888b9e8c7f3d17cbe7a4d0be5a65c1a926c819 100644 (file)
@@ -59,6 +59,7 @@ C_OBJS =      _afailed.o              \
                fsetpos.o               \
                ftell.o                 \
                getchar.o               \
+                getopt.o                \
                gets.o                  \
                 gmtime.o                \
                locale.o                \
diff --git a/libsrc/common/getopt.c b/libsrc/common/getopt.c
new file mode 100644 (file)
index 0000000..9faca33
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * This is part of a changed public domain getopt implementation that
+ * had the following text on top:
+ *
+ *      I got this off net.sources from Henry Spencer.
+ *      It is a public domain getopt(3) like in System V.
+ *      I have made the following modifications:
+ *
+ *      A test main program was added, ifdeffed by GETOPT.
+ *      This main program is a public domain implementation
+ *      of the getopt(1) program like in System V.  The getopt
+ *      program can be used to standardize shell option handling.
+ *              e.g.  cc -DGETOPT getopt.c -o getopt
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define ARGCH    ':'
+#define BADCH    '?'
+#define EMSG     ""
+
+int opterr = 1;                 /* useless, never set or used */
+int optind = 1;                 /* index into parent argv vector */
+int optopt;                     /* character checked for validity */
+
+char *optarg;                   /* argument associated with option */
+
+#define tell(s) fputs(*argv,stderr);fputs(s,stderr); \
+                fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);
+
+int __fastcall__ getopt (int argc, char* const* argv, const char* optstring)
+/* Get option letter from argument vector */
+{
+    static char *place = EMSG;  /* option letter processing */
+
+    register char *oli;         /* option letter list index */
+
+    if (!*place) {              /* update scanning pointer */
+        if (optind >= argc || *(place = argv[optind]) != '-' || !*++place) {
+            return (EOF);
+        }
+        if (*place == '-') {
+            /* found "--" */
+            ++optind;
+            return (EOF);
+        }
+    }
+
+    /* option letter okay? */
+    if ((optopt = (int) *place++) == ARGCH ||
+        !(oli = strchr (optstring, optopt))) {
+        if (!*place) {
+            ++optind;
+        }
+        tell (": illegal option -- ");
+    }
+    if (*++oli != ARGCH) {
+        /* don't need argument */
+        optarg = NULL;
+        if (!*place) {
+            ++optind;
+        }
+    } else {
+        /* need an argument */
+        if (*place) {
+            /* no white space */
+            optarg = place;
+        }
+        else if (argc <= ++optind) {   /* no arg */
+            place = EMSG;
+            tell (": option requires an argument -- ");
+        } else {
+            /* white space */
+            optarg = argv[optind];
+        }
+        place = EMSG;
+        ++optind;
+    }
+    return (optopt);            /* dump back option letter */
+}
+
diff --git a/testcode/lib/getopt-test.c b/testcode/lib/getopt-test.c
new file mode 100644 (file)
index 0000000..28dbd02
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * This is part of a changed public domain getopt implementation that
+ * had the following text on top:
+ *
+ *      I got this off net.sources from Henry Spencer.
+ *      It is a public domain getopt(3) like in System V.
+ *      I have made the following modifications:
+ *
+ *      A test main program was added, ifdeffed by GETOPT.
+ *      This main program is a public domain implementation
+ *      of the getopt(1) program like in System V.  The getopt
+ *      program can be used to standardize shell option handling.
+ *              e.g.  cc -DGETOPT getopt.c -o getopt
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define ARGCH    ':'
+#define BADCH    '?'
+#define ENDARGS  "--"
+
+int main (int argc, char **argv)
+{
+    char *optstring = argv[1];
+
+    char *argv0 = argv[0];
+
+    int opterr = 0;
+
+    int C;
+
+    char *opi;
+
+    if (argc == 1) {
+        fprintf (stderr, "Usage: %s optstring args\n", argv0);
+        exit (1);
+    }
+    argv++;
+    argc--;
+    argv[0] = argv0;
+    while ((C = getopt (argc, argv, optstring)) != EOF) {
+        if (C == BADCH)
+            opterr++;
+        printf ("-%c ", C);
+        opi = strchr (optstring, C);
+        if (opi && opi[1] == ARGCH)
+            if (optarg)
+                printf ("\"%s\" ", optarg);
+            else
+                opterr++;
+    }
+    printf ("%s", ENDARGS);
+    while (optind < argc)
+        printf (" \"%s\"", argv[optind++]);
+    putchar ('\n');
+    return opterr;
+}
+