]> git.kaiwu.me - klib.git/commitdiff
split ketopt.h into two files
authorHeng Li <lh3@me.com>
Thu, 30 Aug 2018 05:27:58 +0000 (19:27 -1000)
committerHeng Li <lh3@me.com>
Thu, 30 Aug 2018 05:27:58 +0000 (19:27 -1000)
ketopt.c [new file with mode: 0644]
ketopt.h
test/Makefile

diff --git a/ketopt.c b/ketopt.c
new file mode 100644 (file)
index 0000000..aa6685c
--- /dev/null
+++ b/ketopt.c
@@ -0,0 +1,74 @@
+#include <string.h> /* for strchr() and strncmp() */
+#include "ketopt.h"
+
+ketopt_t KETOPT_INIT = { 1, 0, 0, 1, 0, 0 };
+
+static void ketopt_permute(char *argv[], int j, int n) /* move argv[j] over n elements to the left */
+{
+       int k;
+       char *p = argv[j];
+       for (k = 0; k < n; ++k)
+               argv[j - k] = argv[j - k - 1];
+       argv[j - k] = p;
+}
+
+/* WARNING: O(mn) algorithm; m=#main arguments before options; n=#options after main arguments; no trial fix */
+int ketopt(ketopt_t *s, int argc, char *argv[], int permute, const char *ostr, const ko_longopt_t *longopts)
+{
+       int opt = -1, i0, j;
+       if (permute) {
+               while (s->i < argc && (argv[s->i][0] != '-' || argv[s->i][1] == '\0'))
+                       ++s->i, ++s->n_args;
+       }
+       s->arg = 0, i0 = s->i;
+       if (s->i >= argc || argv[s->i][0] != '-' || argv[s->i][1] == '\0') {
+               s->ind = s->i - s->n_args;
+               return -1;
+       }
+       if (argv[s->i][0] == '-' && argv[s->i][1] == '-') { /* "--" or a long option */
+               if (argv[s->i][2] == '\0') { /* a bare "--" */
+                       ketopt_permute(argv, s->i, s->n_args);
+                       ++s->i, s->ind = s->i - s->n_args;
+                       return -1;
+               }
+               s->opt = 0, opt = '?', s->pos = -1;
+               if (longopts) { /* parse long options */
+                       int k, n_matches = 0;
+                       const ko_longopt_t *o = 0;
+                       for (j = 2; argv[s->i][j] != '\0' && argv[s->i][j] != '='; ++j) {} /* find the end of the option name */
+                       for (k = 0; longopts[k].name != 0; ++k)
+                               if (strncmp(&argv[s->i][2], longopts[k].name, j - 2) == 0)
+                                       ++n_matches, o = &longopts[k];
+                       if (n_matches == 1) {
+                               s->opt = opt = o->val;
+                               if (argv[s->i][j] == '=') s->arg = &argv[s->i][j + 1];
+                               if (o->has_arg == 1 && argv[s->i][j] == '\0') {
+                                       if (s->i < argc - 1) s->arg = argv[++s->i];
+                                       else opt = ':'; /* missing option argument */
+                               }
+                       }
+               }
+       } else { /* a short option */
+               char *p;
+               if (s->pos == 0) s->pos = 1;
+               opt = s->opt = argv[s->i][s->pos++];
+               p = strchr(ostr, opt);
+               if (p == 0) {
+                       opt = '?'; /* unknown option */
+               } else if (p[1] == ':') {
+                       if (argv[s->i][s->pos] == 0) {
+                               if (s->i < argc - 1) s->arg = argv[++s->i];
+                               else opt = ':'; /* missing option argument */
+                       } else s->arg = &argv[s->i][s->pos];
+                       s->pos = -1;
+               }
+       }
+       if (s->pos < 0 || argv[s->i][s->pos] == 0) {
+               ++s->i, s->pos = 0;
+               if (s->n_args > 0) /* permute */
+                       for (j = i0; j < s->i; ++j)
+                               ketopt_permute(argv, j, s->n_args);
+       }
+       s->ind = s->i - s->n_args;
+       return opt;
+}
index 8fe2a8a648fdbe06b7f03981cb499fe97c4abbc2..8b72efe5f5c0b73903ac73148b73f13e15d4181b 100644 (file)
--- a/ketopt.h
+++ b/ketopt.h
@@ -1,8 +1,6 @@
 #ifndef KETOPT_H
 #define KETOPT_H
 
-#include <string.h> /* for strchr() and strncmp() */
-
 #define ko_no_argument       0
 #define ko_required_argument 1
 #define ko_optional_argument 2
@@ -21,75 +19,16 @@ typedef struct {
        int val;
 } ko_longopt_t;
 
-static ketopt_t KETOPT_INIT = { 1, 0, 0, 1, 0, 0 };
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-static void ketopt_permute(char *argv[], int j, int n) /* move argv[j] over n elements to the left */
-{
-       int k;
-       char *p = argv[j];
-       for (k = 0; k < n; ++k)
-               argv[j - k] = argv[j - k - 1];
-       argv[j - k] = p;
-}
+extern ketopt_t KETOPT_INIT;
 
-static int ketopt(ketopt_t *s, int argc, char *argv[], int permute, const char *ostr, const ko_longopt_t *longopts)
-{
-       int opt = -1, i0, j;
-       if (permute) {
-               while (s->i < argc && (argv[s->i][0] != '-' || argv[s->i][1] == '\0'))
-                       ++s->i, ++s->n_args;
-       }
-       s->arg = 0, i0 = s->i;
-       if (s->i >= argc || argv[s->i][0] != '-' || argv[s->i][1] == '\0') {
-               s->ind = s->i - s->n_args;
-               return -1;
-       }
-       if (argv[s->i][0] == '-' && argv[s->i][1] == '-') { /* "--" or a long option */
-               if (argv[s->i][2] == '\0') { /* a bare "--" */
-                       ketopt_permute(argv, s->i, s->n_args);
-                       ++s->i, s->ind = s->i - s->n_args;
-                       return -1;
-               }
-               s->opt = 0, opt = '?', s->pos = -1;
-               if (longopts) { /* parse long options */
-                       int k, n_matches = 0;
-                       const ko_longopt_t *o = 0;
-                       for (j = 2; argv[s->i][j] != '\0' && argv[s->i][j] != '='; ++j) {} /* find the end of the option name */
-                       for (k = 0; longopts[k].name != 0; ++k)
-                               if (strncmp(&argv[s->i][2], longopts[k].name, j - 2) == 0)
-                                       ++n_matches, o = &longopts[k];
-                       if (n_matches == 1) {
-                               s->opt = opt = o->val;
-                               if (argv[s->i][j] == '=') s->arg = &argv[s->i][j + 1];
-                               if (o->has_arg == 1 && argv[s->i][j] == '\0') {
-                                       if (s->i < argc - 1) s->arg = argv[++s->i];
-                                       else opt = ':'; /* missing option argument */
-                               }
-                       }
-               }
-       } else { /* a short option */
-               char *p;
-               if (s->pos == 0) s->pos = 1;
-               opt = s->opt = argv[s->i][s->pos++];
-               p = strchr(ostr, opt);
-               if (p == 0) {
-                       opt = '?'; /* unknown option */
-               } else if (p[1] == ':') {
-                       if (argv[s->i][s->pos] == 0) {
-                               if (s->i < argc - 1) s->arg = argv[++s->i];
-                               else opt = ':'; /* missing option argument */
-                       } else s->arg = &argv[s->i][s->pos];
-                       s->pos = -1;
-               }
-       }
-       if (s->pos < 0 || argv[s->i][s->pos] == 0) {
-               ++s->i, s->pos = 0;
-               if (s->n_args > 0) /* permute */
-                       for (j = i0; j < s->i; ++j)
-                               ketopt_permute(argv, j, s->n_args);
-       }
-       s->ind = s->i - s->n_args;
-       return opt;
+int ketopt(ketopt_t *s, int argc, char *argv[], int permute, const char *ostr, const ko_longopt_t *longopts);
+
+#ifdef __cplusplus
 }
+#endif
 
 #endif
index 44d9eab9e518431f98b93acde16416558306b1a4..8036a28cbe66c0e973f19362f927c2f43f7c7552 100644 (file)
@@ -61,3 +61,6 @@ kthread_test:kthread_test.c ../kthread.c
 
 kthread_test2:kthread_test2.c ../kthread.c
                $(CC) $(CFLAGS) -o $@ kthread_test2.c ../kthread.c
+
+ketopt_test:ketopt_test.c ../ketopt.c
+               $(CC) $(CFLAGS) -o $@ ketopt_test.c ../ketopt.c