00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "system.h"
00023 #include "intl.h"
00024 #include "coretypes.h"
00025 #include "opts.h"
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 size_t
00052 find_opt (const char *input, int lang_mask)
00053 {
00054 size_t mn, mx, md, opt_len;
00055 size_t match_wrong_lang;
00056 int comp;
00057
00058 mn = 0;
00059 mx = cl_options_count;
00060
00061
00062
00063 while (mx - mn > 1)
00064 {
00065 md = (mn + mx) / 2;
00066 opt_len = cl_options[md].opt_len;
00067 comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);
00068
00069 if (comp < 0)
00070 mx = md;
00071 else
00072 mn = md;
00073 }
00074
00075
00076
00077 match_wrong_lang = cl_options_count;
00078
00079
00080
00081
00082 do
00083 {
00084 const struct cl_option *opt = &cl_options[mn];
00085
00086
00087
00088 if (!strncmp (input, opt->opt_text + 1, opt->opt_len)
00089 && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
00090 {
00091
00092 if (opt->flags & lang_mask)
00093 return mn;
00094
00095
00096
00097 if (match_wrong_lang == cl_options_count)
00098 match_wrong_lang = mn;
00099 }
00100
00101
00102
00103 mn = opt->back_chain;
00104 }
00105 while (mn != cl_options_count);
00106
00107
00108 return match_wrong_lang;
00109 }
00110
00111
00112
00113
00114 static bool
00115 cancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx)
00116 {
00117
00118
00119 if (cl_options [next_opt_idx].neg_index == opt_idx)
00120 return true;
00121
00122 if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx)
00123 return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index,
00124 orig_next_opt_idx);
00125
00126 return false;
00127 }
00128
00129
00130
00131 void
00132 prune_options (int *argcp, char ***argvp)
00133 {
00134 int argc = *argcp;
00135 int *options = xmalloc (argc * sizeof (*options));
00136 char **argv = xmalloc (argc * sizeof (char *));
00137 int i, arg_count, need_prune = 0;
00138 const struct cl_option *option;
00139 size_t opt_index;
00140
00141
00142 for (i = 1; i < argc; i++)
00143 {
00144 int value = 1;
00145 const char *opt = (*argvp) [i];
00146
00147 opt_index = find_opt (opt + 1, -1);
00148 if (opt_index == cl_options_count
00149 && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm')
00150 && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
00151 {
00152 char *dup;
00153
00154
00155 size_t len = strlen (opt) - 3;
00156
00157 dup = XNEWVEC (char, len + 1);
00158 dup[0] = '-';
00159 dup[1] = opt[1];
00160 memcpy (dup + 2, opt + 5, len - 2 + 1);
00161 opt = dup;
00162 value = 0;
00163 opt_index = find_opt (opt + 1, -1);
00164 free (dup);
00165 }
00166
00167 if (opt_index == cl_options_count)
00168 {
00169 cont:
00170 options [i] = 0;
00171 continue;
00172 }
00173
00174 option = &cl_options[opt_index];
00175 if (option->neg_index < 0)
00176 goto cont;
00177
00178
00179 if ((option->flags & CL_JOINED))
00180 goto cont;
00181
00182
00183
00184 if (!value && (option->flags & CL_REJECT_NEGATIVE))
00185 goto cont;
00186
00187 options [i] = (int) opt_index;
00188 need_prune |= options [i];
00189 }
00190
00191 if (!need_prune)
00192 goto done;
00193
00194
00195 argv [0] = (*argvp) [0];
00196 arg_count = 1;
00197 for (i = 1; i < argc; i++)
00198 {
00199 int j, opt_idx;
00200
00201 opt_idx = options [i];
00202 if (opt_idx)
00203 {
00204 int next_opt_idx;
00205 for (j = i + 1; j < argc; j++)
00206 {
00207 next_opt_idx = options [j];
00208 if (next_opt_idx
00209 && cancel_option (opt_idx, next_opt_idx,
00210 next_opt_idx))
00211 break;
00212 }
00213 }
00214 else
00215 goto keep;
00216
00217 if (j == argc)
00218 {
00219 keep:
00220 argv [arg_count] = (*argvp) [i];
00221 arg_count++;
00222 }
00223 }
00224
00225 if (arg_count != argc)
00226 {
00227 *argcp = arg_count;
00228 *argvp = argv;
00229 }
00230 else
00231 {
00232 done:
00233 free (argv);
00234 }
00235
00236 free (options);
00237 }