]> git.mdlowis.com Git - projs/opts.git/commitdiff
Added comments to the posix-style opt.h header
authorMichael D. Lowis <mike@mdlowis.com>
Mon, 7 Dec 2015 03:16:25 +0000 (22:16 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Mon, 7 Dec 2015 03:16:25 +0000 (22:16 -0500)
source/opt.h

index 5e64c3fbfb66942059956a9a3896a239ac770fec..126fcbeb45d87310d8b6661fe134e1d846986727 100644 (file)
@@ -1,9 +1,41 @@
+/* This file implements a simple POSIX-style option parsing implementation as
+ * a set of macros. The file is heavily influenced and inspired by the arg.h
+ * file from suckless.org (http://git.suckless.org/libsl/tree/arg.h). That file
+ * is in turn inspired by the corresponding macros defined in plan9.
+ *
+ * The interface in this file assumes that the main function will have the
+ * following prototype:
+ *
+ * int main(int argc, char** argv);
+ *
+ * An example usage of the interface would look something like the follwoing:
+ *
+ * char* ARGV0;
+ * int main(int argc, char** argv) {
+ *     OPTBEGIN {
+ *         case 'a': printf("Simple option\n"); break;
+ *         case 'b': printf("Option with arg: %s\n", OPTARG()); break;
+ *         default:  printf("Unknown option!\n");
+ *     } OPTEND;
+ *     return 0;
+ * }
+ */
 #ifndef OPT_H
 #define OPT_H
 
+/* This variable contains the value of argv[0] so that it can be referenced
+ * again once the option parsing is done. This variable must be defined by the
+ * program.
+ *
+ * NOTE: Ensure that you define this variable with external linkage (i.e. not
+ * static)
+ */
 extern char* ARGV0;
 
-static inline char* getarg(int* p_argc, char*** p_argv) {
+/* This is a helper function used by the macros in this file to parse the next
+ * option from the command line.
+ */
+static inline char* getopt(int* p_argc, char*** p_argv) {
     if (!(*p_argv)[0][1] && !(*p_argv)[1]) {
         return (char*)0;
     } else if ((*p_argv)[0][1]) {
@@ -15,15 +47,15 @@ static inline char* getarg(int* p_argc, char*** p_argv) {
     }
 }
 
-/* use main(int argc, char *argv[]) */
+/* This macro is almost identical to the ARGBEGIN macro from suckless.org. If
+ * it ain't broke, don't fix it. */
 #define OPTBEGIN                                                              \
     for (                                                                     \
         ARGV0 = *argv, argc--, argv++;                                        \
         argv[0] && argv[0][1] && argv[0][0] == '-';                           \
         argc--, argv++                                                        \
     ) {                                                                       \
-        char argc_ , **argv_, *optarg_;                                       \
-        int brk_;                                                             \
+        int brk_; char argc_ , **argv_, *optarg_;                             \
         if (argv[0][1] == '-' && !argv[0][2]) {                               \
             argv++, argc--; break;                                            \
         }                                                                     \
@@ -32,17 +64,25 @@ static inline char* getarg(int* p_argc, char*** p_argv) {
             argc_ = argv[0][0];                                               \
             switch (argc_)
 
+/* Terminate the option parsing. */
 #define OPTEND }}
 
+/* Get the current option chracter */
 #define OPTC() (argc_)
 
+/* Get an argument from the command line and return it as a string. If no
+ * argument is available, this macro returns NULL */
 #define OPTARG() \
-    (optarg_ = getarg(&argc,&argv), brk_ = (optarg_!=0), optarg_)
+    (optarg_ = getopt(&argc,&argv), brk_ = (optarg_!=0), optarg_)
 
+/* Get an argument from the command line and return it as a string. If no
+ * argument is available, this macro executes the provided code. If that code
+ * returns, then abort is called. */
 #define EOPTARG(code) \
-    (optarg_ = getarg(&argc,&argv), \
+    (optarg_ = getopt(&argc,&argv), \
      (!optarg_ ? ((code), abort(), (char*)0) : (brk_ = 1, optarg_)))
 
+/* Helper macro to recognize number options */
 #define OPTNUM \
     case '0':  \
     case '1':  \
@@ -55,6 +95,7 @@ static inline char* getarg(int* p_argc, char*** p_argv) {
     case '8':  \
     case '9'
 
+/* Helper macro to recognize "long" options ala GNU style. */
 #define OPTLONG \
     case '-'