diff options
author | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2003-06-20 09:01:58 +0000 |
---|---|---|
committer | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2003-06-20 09:01:58 +0000 |
commit | 3b4406c151cabd47b24d309dbbd9c5b19e9d6b33 (patch) | |
tree | f67de9320202043aca8ded20fb80d668c3b0c2d8 /libbb | |
parent | 90e9e2c71f1e3ed8031334106594ef7fa9e0173b (diff) | |
download | busybox-w32-3b4406c151cabd47b24d309dbbd9c5b19e9d6b33.tar.gz busybox-w32-3b4406c151cabd47b24d309dbbd9c5b19e9d6b33.tar.bz2 busybox-w32-3b4406c151cabd47b24d309dbbd9c5b19e9d6b33.zip |
last_patch89 from vodz:
Manuel,
I rewrite bb_getopt_ulflags() function for more universal usage.
My version support now:
- options with arguments (optional arg as GNU extension also)
- complementaly and/or incomplementaly and/or incongruously and/or list
options
- long_opt (all applets may have long option, add supporting is trivial)
This realisation full compatibile from your version.
Code size grow 480 bytes, but only coreutils/* over compensate this size
after using new function. Last patch reduced over 800 bytes and not full
applied to all. "mkdir" and "mv" applets have long_opt now for demonstrate
trivial addition support long_opt with usage new bb_getopt_ulflags().
Complementaly and/or incomplementaly and/or incongruously and/or list options
logic is not trivial, but new "cut" and "grep" applets using this logic
for examples with full demostrating. New "grep" applet reduced over 300
bytes.
Mark,
Also. I removed bug from "grep" applet.
$ echo a b | busybox grep -e a b
a b
a b
But right is printing one only.
--w
vodz
git-svn-id: svn://busybox.net/trunk/busybox@6939 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/getopt_ulflags.c | 145 | ||||
-rw-r--r-- | libbb/inode_hash.c | 2 |
2 files changed, 139 insertions, 8 deletions
diff --git a/libbb/getopt_ulflags.c b/libbb/getopt_ulflags.c index 91de392b6..9bf8c0559 100644 --- a/libbb/getopt_ulflags.c +++ b/libbb/getopt_ulflags.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * getopt_ulflags implementation for busybox | 3 | * universal getopt_ulflags implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> | 5 | * Copyright (C) 2003 Vladimir Oleynik <dzo@simtreas.ru> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -22,20 +22,149 @@ | |||
22 | 22 | ||
23 | #include <getopt.h> | 23 | #include <getopt.h> |
24 | #include <string.h> | 24 | #include <string.h> |
25 | #include <assert.h> | ||
26 | #include <stdlib.h> | ||
25 | #include "libbb.h" | 27 | #include "libbb.h" |
26 | 28 | ||
27 | unsigned long bb_getopt_ulflags(int argc, char **argv, const char *applet_opts) | 29 | /* |
30 | You can set bb_opt_complementaly as string with one or more | ||
31 | complementaly or incongruously options. | ||
32 | If sequential founded option haved from this string | ||
33 | then your incongruously pairs unsets and complementaly make add sets. | ||
34 | Format: | ||
35 | one char - option for check, | ||
36 | chars - complementaly option for add sets. | ||
37 | - chars - option triggered for unsets. | ||
38 | ~ chars - option incongruously. | ||
39 | * - option list, called add_to_list(*ptr_from_usaged, optarg) | ||
40 | : - separator. | ||
41 | Example: du applet can have options "-s" and "-d size" | ||
42 | If getopt found -s then -d option flag unset or if found -d then -s unset. | ||
43 | For this result you must set bb_opt_complementaly = "s-d:d-s". | ||
44 | Result have last option flag only from called arguments. | ||
45 | Warning! You can check returned flag, pointer to "d:" argument seted | ||
46 | to own optarg always. | ||
47 | Example two: cut applet must only one type of list may be specified, | ||
48 | and -b, -c and -f incongruously option, overwited option is error also. | ||
49 | You must set bb_opt_complementaly = "b~bcf:c~bcf:f~bcf". | ||
50 | If called have more one specified, return value have error flag - | ||
51 | high bite set (0x80000000UL). | ||
52 | Example three: grep applet can have one or more "-e pattern" arguments. | ||
53 | You should use bb_getopt_ulflags() as | ||
54 | llist_t *paterns; | ||
55 | bb_opt_complementaly = "e*"; | ||
56 | bb_getopt_ulflags (argc, argv, "e:", &paterns); | ||
57 | */ | ||
58 | |||
59 | const char *bb_opt_complementaly; | ||
60 | |||
61 | typedef struct | ||
62 | { | ||
63 | char opt; | ||
64 | char list_flg; | ||
65 | unsigned long switch_on; | ||
66 | unsigned long switch_off; | ||
67 | unsigned long incongruously; | ||
68 | void **optarg; /* char **optarg or llist_t **optarg */ | ||
69 | } t_complementaly; | ||
70 | |||
71 | /* You can set bb_applet_long_options for parse called long options */ | ||
72 | |||
73 | static const struct option bb_default_long_options[] = { | ||
74 | /* { "help", 0, NULL, '?' }, */ | ||
75 | { 0, 0, 0, 0 } | ||
76 | }; | ||
77 | |||
78 | const struct option *bb_applet_long_options = bb_default_long_options; | ||
79 | |||
80 | |||
81 | unsigned long | ||
82 | bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) | ||
28 | { | 83 | { |
29 | unsigned long flags = 0; | 84 | unsigned long flags = 0; |
85 | int c = 0; | ||
30 | const char *s; | 86 | const char *s; |
31 | int c; | 87 | t_complementaly *complementaly; |
88 | t_complementaly *on_off; | ||
89 | va_list p; | ||
90 | |||
91 | va_start (p, applet_opts); | ||
32 | 92 | ||
33 | while ((c = getopt(argc, argv, applet_opts)) > 0) { | 93 | for (s = applet_opts; *s; s++) { |
34 | if (!(s = strchr(applet_opts, c))) { | 94 | c++; |
35 | bb_show_usage(); | 95 | while (s[1] == ':') { |
96 | /* check GNU extension "o::" - optional arg */ | ||
97 | s++; | ||
98 | } | ||
99 | } | ||
100 | complementaly = xcalloc (c + 1, sizeof (t_complementaly)); | ||
101 | c = 0; | ||
102 | for (s = applet_opts; *s; s++) { | ||
103 | complementaly->opt = *s; | ||
104 | complementaly->switch_on |= (1 << c); | ||
105 | c++; | ||
106 | if (s[1] == ':') { | ||
107 | complementaly->optarg = va_arg (p, void **); | ||
108 | do | ||
109 | s++; | ||
110 | while (s[1] == ':'); | ||
36 | } | 111 | } |
37 | flags |= (1 << (s-applet_opts)); | 112 | complementaly++; |
38 | } | 113 | } |
114 | complementaly->opt = 0; | ||
115 | complementaly -= c; | ||
116 | c = 0; | ||
117 | for (s = bb_opt_complementaly; s && *s; s++) { | ||
118 | t_complementaly *pair; | ||
119 | |||
120 | if (*s == ':') { | ||
121 | c = 0; | ||
122 | continue; | ||
123 | } | ||
124 | if (c) | ||
125 | continue; | ||
126 | for (on_off = complementaly; on_off->opt; on_off++) | ||
127 | if (on_off->opt == *s) | ||
128 | break; | ||
129 | pair = on_off; | ||
130 | for(s++; *s && *s != ':'; s++) { | ||
131 | if (*s == '-' || *s == '~') { | ||
132 | c = *s; | ||
133 | } else if(*s == '*') { | ||
134 | pair->list_flg++; | ||
135 | } else { | ||
136 | unsigned long *pair_switch = &(pair->switch_on); | ||
39 | 137 | ||
138 | if(c) | ||
139 | pair_switch = c == '-' ? &(pair->switch_off) : &(pair->incongruously); | ||
140 | for (on_off = complementaly; on_off->opt; on_off++) | ||
141 | if (on_off->opt == *s) { | ||
142 | *pair_switch |= on_off->switch_on; | ||
143 | break; | ||
144 | } | ||
145 | } | ||
146 | } | ||
147 | s--; | ||
148 | } | ||
149 | |||
150 | while ((c = getopt_long (argc, argv, applet_opts, | ||
151 | bb_applet_long_options, NULL)) > 0) { | ||
152 | |||
153 | for (on_off = complementaly; on_off->opt != c; on_off++) { | ||
154 | if(!on_off->opt) | ||
155 | bb_show_usage (); | ||
156 | } | ||
157 | if(flags & on_off->incongruously) | ||
158 | flags |= 0x80000000UL; | ||
159 | flags &= ~on_off->switch_off; | ||
160 | flags |= on_off->switch_on; | ||
161 | if(on_off->list_flg) { | ||
162 | *(llist_t **)(on_off->optarg) = | ||
163 | llist_add_to(*(llist_t **)(on_off->optarg), optarg); | ||
164 | } else if (on_off->optarg) { | ||
165 | *(char **)(on_off->optarg) = optarg; | ||
166 | } | ||
167 | } | ||
168 | free(complementaly); | ||
40 | return flags; | 169 | return flags; |
41 | } | 170 | } |
diff --git a/libbb/inode_hash.c b/libbb/inode_hash.c index 36484e6ae..4393a5188 100644 --- a/libbb/inode_hash.c +++ b/libbb/inode_hash.c | |||
@@ -83,6 +83,7 @@ void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name) | |||
83 | ino_dev_hashtable[i] = bucket; | 83 | ino_dev_hashtable[i] = bucket; |
84 | } | 84 | } |
85 | 85 | ||
86 | #ifdef CONFIG_FEATURE_CLEAN_UP | ||
86 | /* Clear statbuf hash table */ | 87 | /* Clear statbuf hash table */ |
87 | void reset_ino_dev_hashtable(void) | 88 | void reset_ino_dev_hashtable(void) |
88 | { | 89 | { |
@@ -97,6 +98,7 @@ void reset_ino_dev_hashtable(void) | |||
97 | } | 98 | } |
98 | } | 99 | } |
99 | } | 100 | } |
101 | #endif | ||
100 | 102 | ||
101 | 103 | ||
102 | /* END CODE */ | 104 | /* END CODE */ |