1 /*
2  *  gretl -- Gnu Regression, Econometrics and Time-series Library
3  *  Copyright (C) 2001 Allin Cottrell and Riccardo "Jack" Lucchetti
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 #include "libgretl.h"
21 #include "uservar.h"
22 #include "gretl_func.h"
23 
24 #include <errno.h>
25 
26 #define OPTDEBUG 0
27 
28 /* commands for which --vcv (= OPT_O) is applicable */
29 
30 #define vcv_opt_ok(c) (MODEL_COMMAND(c) || c == ADD || c == OMIT)
31 
32 #define window_opt_ok(c) (MODEL_COMMAND(c) || c == VAR || c == VECM)
33 
34 /* commands for which --quiet (= OPT_Q) is applicable */
35 
36 #define yields_result(c) (c == CORR || c == FREQ || c == SUMMARY)
37 
38 #define quiet_opt_ok(c) (MODEL_COMMAND(c) ||    \
39                          yields_result(c) ||    \
40                          c == ADD ||            \
41                          c == ADF ||            \
42                          c == ANOVA ||          \
43                          c == APPEND ||         \
44 			 c == BDS ||		\
45                          c == BKW ||            \
46                          c == COEFFSUM ||       \
47                          c == CHOW ||           \
48                          c == COINT2 ||         \
49                          c == CORRGM ||         \
50                          c == CUSUM ||          \
51                          c == DATA ||           \
52                          c == DIFFTEST ||       \
53                          c == ESTIMATE ||       \
54                          c == FCAST ||          \
55                          c == FOREIGN ||        \
56                          c == FRACTINT ||       \
57                          c == FREQ ||           \
58                          c == KPSS ||           \
59                          c == MAKEPKG ||        \
60                          c == MODTEST ||        \
61                          c == LEVERAGE ||       \
62                          c == LEVINLIN ||       \
63                          c == LOOP ||           \
64                          c == MAHAL ||          \
65                          c == NORMTEST ||       \
66                          c == OLS ||            \
67                          c == OMIT ||           \
68                          c == OPEN ||           \
69 			 c == PANSPEC ||	\
70                          c == PKG ||            \
71                          c == QLRTEST ||        \
72                          c == RENAME ||         \
73                          c == RESET ||          \
74                          c == RESTRICT ||       \
75                          c == RMPLOT ||         \
76                          c == SMPL ||           \
77                          c == SYSTEM ||         \
78                          c == VAR ||            \
79                          c == VECM ||           \
80                          c == VIF ||            \
81                          c == XCORRGM ||        \
82                          c == XTAB)
83 
84 struct gretl_option {
85     int ci;              /* command index (gives context) */
86     gretlopt o;          /* index of integer type */
87     const char *longopt; /* "--"-style string representation of option */
88     char parminfo;       /* 0 = option can never take a parameter,
89                             1 = option may take a parameter,
90                             2 = option requires a parameter
91                          */
92 };
93 
94 struct flag_match {
95     gretlopt o;
96     unsigned char c;
97 };
98 
99 /* Below: This is used as a one-way mapping from the long form
100    to the index (e.g. OPT_Q), so a given index can have more than
101    one long-form counterpart, depending on context.  The last field
102    flags whether the given option accepts (1), or requires (2), an
103    accompanying parameter value.
104 */
105 
106 struct gretl_option gretl_opts[] = {
107     { ADD,      OPT_B, "both", 0 },
108     { ADD,      OPT_I, "silent", 0 },
109     { ADD,      OPT_L, "lm", 0 },
110     { ADF,      OPT_N, "nc", 0 },
111     { ADF,      OPT_C, "c", 0 },
112     { ADF,      OPT_D, "seasonals", 0 },
113     { ADF,      OPT_R, "ctt", 0 },
114     { ADF,      OPT_T, "ct", 0 },
115     { ADF,      OPT_V, "verbose", 1 },
116     { ADF,      OPT_F, "difference", 0 },
117     { ADF,      OPT_E, "test-down", 1 },
118     { ADF,      OPT_G, "gls", 0 },
119     { ADF,      OPT_U, "perron-qu", 0 },
120     { AR1,      OPT_B, "no-corc", 0 },
121     { AR1,      OPT_H, "hilu", 0 },
122     { AR1,      OPT_P, "pwe", 0 },
123     { AR1,      OPT_L, "loose", 0 },
124     { APPEND,   OPT_A, "all-cols", 0 },
125     { APPEND,   OPT_T, "time-series", 0 },
126     { APPEND,   OPT_R, "rowoffset", 2 },
127     { APPEND,   OPT_C, "coloffset", 2 },
128     { APPEND,   OPT_F, "fixed-cols", 2 },
129     { APPEND,   OPT_M, "rowmask", 2 },
130     { APPEND,   OPT_L, "cols", 2 },
131     { APPEND,   OPT_S, "sheet", 2 },
132     { APPEND,   OPT_V, "verbose", 0 },
133     { APPEND,   OPT_U, "update-overlap", 0 },
134     { APPEND,   OPT_X, "fixed-sample", 0 },
135     { ARMA,     OPT_A, "as154", 0 },
136     { ARMA,     OPT_K, "kalman", 0 },
137     { ARMA,     OPT_C, "conditional", 0 },
138     { ARMA,     OPT_E, "save-ehat", 0 },
139     { ARMA,     OPT_G, "opg", 0 },
140     { ARMA,     OPT_H, "hessian", 0 },
141     { ARMA,     OPT_L, "lbfgs", 0 },
142     { ARMA,     OPT_N, "nc", 0 },
143     { ARMA,     OPT_V, "verbose", 0 },
144     { ARMA,     OPT_X, "x-12-arima", 0 },
145     { ARMA,     OPT_Y, "y-diff-only", 0 },
146     { ARMA,     OPT_R, "robust", 0 },
147     { ARMA,     OPT_S, "stdx", 0 },
148     { BDS,      OPT_B, "boot", 2 },
149     { BDS,      OPT_C, "corr1", 2 },
150     { BDS,      OPT_S, "sdcrit", 2 },
151     { BDS,      OPT_X, "matrix", 2 },
152     { BIPROBIT, OPT_G, "opg", 0 },
153     { BIPROBIT, OPT_R, "robust", 0 },
154     { BIPROBIT, OPT_V, "verbose", 0 },
155     { BIPROBIT, OPT_C, "cluster", 2 },
156     { BIPROBIT, OPT_X, "save-xbeta", 0 },
157     { BXPLOT,   OPT_O, "notches", 0 },
158     { BXPLOT,   OPT_K, "tweaks", 2 },
159     { BXPLOT,   OPT_L, "outliers", 2 },
160     { BXPLOT,   OPT_P, "panel", 0 },
161     { BXPLOT,   OPT_U, "output", 2 },
162     { BXPLOT,   OPT_X, "matrix", 2 },
163     { BXPLOT,   OPT_Z, "factorized", 0 },
164     { BXPLOT,   OPT_B, "whiskerbars", 0 },
165     { CHOW,     OPT_D, "dummy", 0 },
166     { CHOW,     OPT_L, "limit-to", 2 },
167     { CLEAR,    OPT_D, "dataset", 0 },
168     { CLEAR,    OPT_F, "functions", 0 },
169     { COINT,    OPT_D, "seasonals", 0 },
170     { COINT,    OPT_E, "test-down", 1 },
171     { COINT,    OPT_N, "nc", 0 },
172     { COINT,    OPT_R, "ctt", 0 },
173     { COINT,    OPT_S, "skip-df", 0 },
174     { COINT,    OPT_T, "ct", 0 },
175     { COINT,    OPT_V, "verbose", 0 },
176     { COINT,    OPT_I, "silent", 0 },
177     { COINT2,   OPT_A, "crt", 0 },
178     { COINT2,   OPT_D, "seasonals", 0 },
179     { COINT2,   OPT_N, "nc", 0 },
180     { COINT2,   OPT_R, "rc", 0 },
181     { COINT2,   OPT_C, "uc", 0 },
182     { COINT2,   OPT_T, "ct", 0 },
183     { COINT2,   OPT_S, "silent", 0 },
184     { COINT2,   OPT_V, "verbose", 0 },
185     { COINT2,   OPT_Y, "asy", 0 },
186     { CORR,     OPT_K, "kendall", 0 },
187     { CORR,     OPT_S, "spearman", 0 },
188     { CORR,     OPT_N, "uniform", 0 },
189     { CORR,     OPT_V, "verbose", 0 },
190     { CORR,     OPT_U, "plot", 2 },
191     { CORR,     OPT_X, "matrix", 2 },
192     { CORR,     OPT_T, "triangle", 0 },
193     { CORRGM,   OPT_B, "bartlett", 0 },
194     { CORRGM,   OPT_U, "plot", 2 },
195     { CUSUM,    OPT_R, "squares", 0 },
196     { CUSUM,    OPT_U, "plot", 2 },
197     { DATA,     OPT_C, "compact", 2 },
198     { DATA,     OPT_O, "odbc", 0 },
199     { DATA,     OPT_N, "name", 2 },
200     { DATA,     OPT_V, "verbose", 0 },
201     { DATA,     OPT_F, "no-align", 0 },
202     { DATAMOD,  OPT_P, "preserve", 0 },
203     { DATAMOD,  OPT_T, "panel-time", 0 },
204     { DELEET,   OPT_D, "db", 0 },
205     { DELEET,   OPT_F, "force", 0 },
206     { DELEET,   OPT_L, "list", 0 },
207     { DELEET,   OPT_T, "type", 2 },
208     { DIFFTEST, OPT_G, "sign", 0 },
209     { DIFFTEST, OPT_R, "rank-sum", 0 },
210     { DIFFTEST, OPT_I, "signed-rank", 0 },
211     { DIFFTEST, OPT_V, "verbose", 0 },
212     { DISCRETE, OPT_R, "reverse", 0 },
213     { DPANEL,   OPT_A, "asymptotic", 0 },
214     { DPANEL,   OPT_D, "time-dummies", 1 },
215     { DPANEL,   OPT_K, "keep-extra", 0 },
216     { DPANEL,   OPT_L, "system", 0 },
217     { DPANEL,   OPT_T, "two-step", 0 },
218     { DPANEL,   OPT_V, "verbose", 0 },
219     { DPANEL,   OPT_X, "dpdstyle", 0 },
220     { DUMMIFY,  OPT_F, "drop-first", 0 },
221     { DUMMIFY,  OPT_L, "drop-last", 0 },
222     { DURATION, OPT_B, "weibull", 0 },
223     { DURATION, OPT_E, "exponential", 0 },
224     { DURATION, OPT_L, "loglogistic", 0 },
225     { DURATION, OPT_Z, "lognormal", 0 },
226     { DURATION, OPT_M, "medians", 0 },
227     { DURATION, OPT_G, "opg", 0 },
228     { DURATION, OPT_R, "robust", 0 },
229     { DURATION, OPT_C, "cluster", 2 },
230     { DURATION, OPT_V, "verbose", 0 },
231     { EQNPRINT, OPT_O, "complete", 0 },
232     { EQNPRINT, OPT_T, "t-ratios", 0 },
233     { EQNPRINT, OPT_U, "output", 2 },
234     { TABPRINT, OPT_O, "complete", 0 },
235     { TABPRINT, OPT_C, "csv", 0 },
236     { TABPRINT, OPT_R, "rtf", 0 },
237     { TABPRINT, OPT_T, "format", 2 },
238     { TABPRINT, OPT_U, "output", 2 },
239     { EQUATION, OPT_M, "multi", 0 },
240     { ESTIMATE, OPT_I, "iterate", 0 },
241     { ESTIMATE, OPT_M, "geomean", 0 },
242     { ESTIMATE, OPT_N, "no-df-corr", 0 },
243     { ESTIMATE, OPT_U, "unrestrict-init", 0 },
244     { ESTIMATE, OPT_V, "verbose", 0 },
245     { ESTIMATE, OPT_W, "window", 0 },
246     { FCAST,    OPT_D, "dynamic", 0 },
247     { FCAST,    OPT_M, "mean-y", 0 },
248     { FCAST,    OPT_N, "no-stats", 0 },
249     { FCAST,    OPT_T, "stats-only", 0 },
250     { FCAST,    OPT_S, "static", 0 },
251     { FCAST,    OPT_R, "recursive", 0 },
252     { FCAST,    OPT_R, "rolling", 0 }, /* legacy alias */
253     { FCAST,    OPT_O, "out-of-sample", 0 },
254     { FCAST,    OPT_I, "integrate", 0 },
255     { FCAST,    OPT_U, "plot", 2 },
256     { FOREIGN,  OPT_D, "send-data", 1 },
257     { FOREIGN,  OPT_V, "verbose", 0 },
258     { FOREIGN,  OPT_F, "frame", 0 },
259     { FOREIGN,  OPT_N, "no-compile", 0 },
260     { FOREIGN,  OPT_I, "io-funcs", 2 },
261     { FRACTINT, OPT_G, "gph", 0 },
262     { FRACTINT, OPT_A, "all", 0 },
263     { FREQ,     OPT_G, "show-plot", 0 }, /* legacy */
264     { FREQ,     OPT_O, "gamma", 0 },
265     { FREQ,     OPT_S, "silent", 0 },
266     { FREQ,     OPT_Z, "normal", 0 },
267     { FREQ,     OPT_N, "nbins", 2 },
268     { FREQ,     OPT_M, "min", 2 },
269     { FREQ,     OPT_W, "binwidth", 2 },
270     { FREQ,     OPT_X, "matrix", 2 },
271     { FREQ,     OPT_U, "plot", 2 },
272     { FREQ,     OPT_K, "tweaks", 2 },
273     { FUNDEBUG, OPT_C, "continue", 0 },
274     { FUNDEBUG, OPT_N, "next", 0 },
275     { FUNDEBUG, OPT_Q, "quit", 0 },
276     { GARCH,    OPT_A, "arma-init", 0 },
277     { GARCH,    OPT_F, "fcp", 0 },
278     { GARCH,    OPT_N, "nc", 0 },
279     { GARCH,    OPT_R, "robust", 0 },
280     { GARCH,    OPT_V, "verbose", 0 },
281     { GARCH,    OPT_Z, "stdresid", 0 },
282     { GMM,      OPT_I, "iterate", 0 },
283     { GMM,      OPT_L, "lbfgs", 0 },
284     { GMM,      OPT_T, "two-step", 0 },
285     { GMM,      OPT_V, "verbose", 0 },
286     { GNUPLOT,  OPT_I, "input", 2 },
287     { GNUPLOT,  OPT_O, "with-lines", 1 },
288     { GNUPLOT,  OPT_F, "fit", 2 },
289     { GNUPLOT,  OPT_K, "tweaks", 2 },
290     { GNUPLOT,  OPT_M, "with-impulses", 1 },
291     { GNUPLOT,  OPT_P, "with-lp", 1 },
292     { GNUPLOT,  OPT_B, "with-boxes", 1 },
293     { GNUPLOT,  OPT_Q, "with-steps", 1 },
294     { GNUPLOT,  OPT_T, "time-series", 0 },
295     { GNUPLOT,  OPT_Z, "dummy", 0 },
296     { GNUPLOT,  OPT_C, "control", 0 },
297     { GNUPLOT,  OPT_U, "output", 2 },
298     { GNUPLOT,  OPT_Y, "single-yaxis", 0 },
299     { GNUPLOT,  OPT_X, "matrix", 2 },
300     { GNUPLOT,  OPT_N, "band", 2 },
301     { GNUPLOT,  OPT_J, "band-style", 2 },
302     { GNUPLOT,  OPT_W, "font", 2 },
303     { GNUPLOT,  OPT_L, "ylogscale", 1 },
304     { GRAPHPG,  OPT_M, "monochrome", 0 },
305     { GRAPHPG,  OPT_O, "output", 2 },
306     { HECKIT,   OPT_M, "ml", 0 },
307     { HECKIT,   OPT_G, "opg", 0 },
308     { HECKIT,   OPT_R, "robust", 0 },
309     { HECKIT,   OPT_C, "cluster", 2 },
310     { HECKIT,   OPT_T, "two-step", 0 },
311     { HECKIT,   OPT_V, "verbose", 0 },
312     { HELP,     OPT_F, "func", 0 },
313     { HFPLOT,   OPT_O, "with-lines", 0 },
314     { HFPLOT,   OPT_T, "time-series", 0 },
315     { HFPLOT,   OPT_U, "output", 2 },
316     { HSK,      OPT_N, "no-squares", 0 },
317     { HURST,    OPT_U, "plot", 2 },
318     { INCLUDE,  OPT_F, "force", 0 },
319     { INTREG,   OPT_G, "opg", 0 },
320     { INTREG,   OPT_R, "robust", 0 },
321     { INTREG,   OPT_C, "cluster", 2 },
322     { INTREG,   OPT_V, "verbose", 0 },
323     { IVREG,    OPT_G, "gmm", 0 },
324     { IVREG,    OPT_I, "iterate", 0 },
325     { IVREG,    OPT_L, "liml", 0 },
326     { IVREG,    OPT_N, "no-df-corr", 0 },
327     { IVREG,    OPT_R, "robust", 0 },
328     { IVREG,    OPT_S, "save", 0 },
329     { IVREG,    OPT_T, "two-step", 0 },
330     { IVREG,    OPT_H, "weights", 2 },
331     { IVREG,    OPT_X, "no-tests", 0 },
332     { IVREG,    OPT_C, "cluster", 2 },
333     { JOIN,     OPT_I, "ikey", 2 },
334     { JOIN,     OPT_O, "okey", 2 },
335     { JOIN,     OPT_F, "filter", 2 },
336     { JOIN,     OPT_A, "aggr", 2 },
337     { JOIN,     OPT_D, "data", 2 },
338     { JOIN,     OPT_T, "tconv-fmt", 2 },
339     { JOIN,     OPT_K, "tkey", 2 },
340     { JOIN,     OPT_X, "tconvert", 2 },
341     { JOIN,     OPT_H, "no-header", 0 },
342     { JOIN,     OPT_V, "verbose", 0 },
343     { JOIN,     OPT_P, "pd", 2 }, /* undocumented: is it wanted? */
344     { KPSS,     OPT_T, "trend", 0 },
345     { KPSS,     OPT_D, "seasonals", 0 },
346     { KPSS,     OPT_V, "verbose", 0 },
347     { KPSS,     OPT_F, "difference", 0 },
348     { LAGS,     OPT_L, "bylag", 0 },
349     { LEVERAGE, OPT_S, "save", 0 },
350     { LEVERAGE, OPT_U, "plot", 2 },
351     { LEVERAGE, OPT_O, "overwrite", 0 },
352     { LEVINLIN, OPT_N, "nc", 0 },
353     { LEVINLIN, OPT_T, "ct", 0 },
354     { LEVINLIN, OPT_V, "verbose", 0 },
355     { MAKEPKG,  OPT_D, "dtd", 2 },
356     { MAKEPKG,  OPT_I, "index", 0 },
357     { MAKEPKG,  OPT_T, "translations", 0 },
358     { MARKERS,  OPT_D, "delete", 0 },
359     { MARKERS,  OPT_F, "from-file", 2 },
360     { MARKERS,  OPT_T, "to-file", 2 },
361     { MARKERS,  OPT_A, "to-array", 2 },
362     { MODTEST,  OPT_A, "autocorr", 0 },
363     { MODTEST,  OPT_B, "breusch-pagan", 0 },
364     { MODTEST,  OPT_C, "comfac", 0 },
365     { MODTEST,  OPT_D, "xdepend", 0 },
366     { MODTEST,  OPT_H, "arch", 0 },
367     { MODTEST,  OPT_L, "logs", 0 },
368     { MODTEST,  OPT_N, "normality", 0 },
369     { MODTEST,  OPT_S, "squares", 0 },
370     { MODTEST,  OPT_P, "panel", 0 },
371     { MODTEST,  OPT_R, "robust", 0 },
372     { MODTEST,  OPT_W, "white", 0 },
373     { MODTEST,  OPT_X, "white-nocross", 0 },
374     { MODTEST,  OPT_I, "silent", 0 },
375     { MODTEST,  OPT_U, "univariate", 0 },
376     { MPI,      OPT_D, "send-data", 1 },
377     { MPI,      OPT_F, "send-functions", 0 },
378     { MPI,      OPT_L, "local", 0 },
379     { MPI,      OPT_N, "np", 2 },
380     { MPI,      OPT_T, "omp-threads", 2 },
381     { MPI,      OPT_Q, "quiet", 0},
382     { MPI,      OPT_V, "verbose", 1 },
383     { MPI,      OPT_S, "single-rng", 0},
384     { LABELS,   OPT_D, "delete", 0 },
385     { LABELS,   OPT_F, "from-file", 2 },
386     { LABELS,   OPT_T, "to-file", 2 },
387     { LABELS,   OPT_A, "from-array", 2 },
388     { LABELS,   OPT_R, "to-array", 2 },
389     { LAD,      OPT_N, "no-vcv", 0 },
390     { LOGISTIC, OPT_M, "ymax", 2 },
391     { LOGISTIC, OPT_R, "robust", 0 },
392     { LOGISTIC, OPT_C, "cluster", 2 },
393     { LOGISTIC, OPT_F, "fixed-effects", 0 },
394     { LOGIT,    OPT_M, "multinomial", 0 },
395     { LOGIT,    OPT_P, "p-values", 0 },
396     { LOGIT,    OPT_R, "robust", 0 },
397     { LOGIT,    OPT_C, "cluster", 2 },
398     { LOGIT,    OPT_V, "verbose", 0 },
399     { LOGIT,    OPT_S, "estrella", 0 },
400     { LOOP,     OPT_P, "progressive", 0 },
401     { LOOP,     OPT_V, "verbose", 0 },
402     { MAHAL,    OPT_S, "save", 0 },
403     { MAHAL,    OPT_V, "vcv", 0 },
404     { MEANTEST, OPT_O, "unequal-vars", 0 },
405     { MIDASREG, OPT_R, "robust", 0 },
406     { MIDASREG, OPT_V, "verbose", 0 },
407     { MIDASREG, OPT_L, "levenberg", 0 },
408     { MIDASREG, OPT_P, "print-spec", 0 },
409     { MIDASREG, OPT_B, "breaktest", 0 },
410     { MIDASREG, OPT_C, "clamp-beta", 0 }, /* legacy */
411     { MLE,      OPT_A, "auxiliary", 0 },
412     { MLE,      OPT_G, "opg", 0 },
413     { MLE,      OPT_H, "hessian", 0 },
414     { MLE,      OPT_S, "no-gradient-check", 0 },
415     { MLE,      OPT_L, "lbfgs", 0 },
416     { MLE,      OPT_N, "numerical", 0 },
417     { MLE,      OPT_R, "robust", 1 },
418     { MLE,      OPT_C, "cluster", 2 },
419     { MLE,      OPT_V, "verbose", 0 },
420     { MODPRINT, OPT_A, "addstats", 2 },
421     { MODPRINT, OPT_O, "output", 2 },
422     { MODPRINT, OPT_C, "complete", 0 },
423     { MODELTAB, OPT_O, "output", 2 },
424     { MODELTAB, OPT_C, "complete", 0 },
425     { MPOLS,    OPT_S, "simple-print", 0 },
426     { NEGBIN,   OPT_G, "opg", 0 },
427     { NEGBIN,   OPT_M, "model1", 0 },
428     { NEGBIN,   OPT_R, "robust", 0 },
429     { NEGBIN,   OPT_C, "cluster", 2 },
430     { NEGBIN,   OPT_V, "verbose", 0 },
431     { NLS,      OPT_N, "numerical", 0 },
432     { NLS,      OPT_R, "robust", 0 },
433     { NLS,      OPT_V, "verbose", 0 },
434     { NLS,      OPT_S, "no-gradient-check", 0 },
435     { NORMTEST, OPT_A, "all", 0 },
436     { NORMTEST, OPT_D, "dhansen", 0 },
437     { NORMTEST, OPT_W, "swilk", 0 },
438     { NORMTEST, OPT_J, "jbera", 0 },
439     { NORMTEST, OPT_L, "lillie", 0 },
440     { NULLDATA, OPT_N, "no-index", 0 },
441     { NULLDATA, OPT_P, "preserve", 0 },
442     { OLS,      OPT_F, "print-final", 0 },
443     { OLS,      OPT_J, "jackknife", 0 },
444     { OLS,      OPT_N, "no-df-corr", 0 },
445     { OLS,      OPT_O, "vcv", 0 },
446     { OLS,      OPT_R, "robust", 0 },
447     { OLS,      OPT_Q, "quiet", 0 }, /* note: for the sake of documentation */
448     { OLS,      OPT_S, "simple-print", 0 },
449     { OLS,      OPT_V, "anova", 0 },
450     { OLS,      OPT_C, "cluster", 2 },
451     { OLS,      OPT_W, "window", 0 },
452     { OMIT,     OPT_A, "auto", 1 },
453     { OMIT,     OPT_B, "both", 0 },
454     { OMIT,     OPT_X, "chi-square", 0 },
455     { OMIT,     OPT_I, "silent", 0 },
456     { OMIT,     OPT_W, "test-only", 0 },
457     { OMIT,     OPT_T, "trend", 0 },      /* omit auto-trend: VAR only */
458     { OMIT,     OPT_E, "seasonals", 0 },  /* omit auto-seasonals: VAR only */
459     { OPEN,     OPT_A, "all-cols", 0 },
460     { OPEN,     OPT_B, "progress-bar", 0 },
461     { OPEN,     OPT_D, "drop-empty", 0 },
462     { OPEN,     OPT_E, "select", 2 },
463     { OPEN,     OPT_F, "fixed-cols", 2 },
464     { OPEN,     OPT_O, "odbc", 0 },
465     { OPEN,     OPT_P, "preserve", 0 },
466     { OPEN,     OPT_R, "rowoffset", 2 },
467     { OPEN,     OPT_C, "coloffset", 2 },
468     { OPEN,     OPT_S, "sheet", 2 },
469     { OPEN,     OPT_W, "www", 0 },
470     { OPEN,     OPT_L, "cols", 2 },
471     { OPEN,     OPT_M, "rowmask", 2 },
472     { OPEN,     OPT_V, "verbose", 0 },
473     { OPEN,     OPT_K, "frompkg", 2 },
474     { OPEN,     OPT_H, "no-header", 0 },
475     { OPEN,     OPT_I, "ignore-quotes", 0 },
476     { OUTFILE,  OPT_A, "append", 0 },
477     { OUTFILE,  OPT_C, "close", 0 },
478     { OUTFILE,  OPT_W, "write", 0 },
479     { OUTFILE,  OPT_Q, "quiet", 0 },
480     { OUTFILE,  OPT_B, "buffer", 1 },
481     { OUTFILE,  OPT_T, "tempfile", 1 },
482     { PANEL,    OPT_B, "between", 0 },
483     { PANEL,    OPT_D, "time-dummies", 1 },
484     { PANEL,    OPT_F, "fixed-effects", 0 },
485     { PANEL,    OPT_I, "iterate", 0 },
486     { PANEL,    OPT_M, "matrix-diff", 0 },
487     { PANEL,    OPT_N, "nerlove", 0 },
488     { PANEL,    OPT_P, "pooled", 0 },
489     { PANEL,    OPT_R, "robust", 0 },
490     { PANEL,    OPT_U, "random-effects", 0 },
491     { PANEL,    OPT_V, "verbose", 0 },
492     { PANEL,    OPT_H, "unit-weights", 0 },
493     { PANEL,    OPT_X, "unbalanced", 1 },
494     { PANPLOT,  OPT_M, "means", 0 },
495     { PANPLOT,  OPT_V, "overlay", 0 },
496     { PANPLOT,  OPT_S, "sequence", 0 },
497     { PANPLOT,  OPT_D, "grid", 0 },
498     { PANPLOT,  OPT_A, "stack", 0 },
499     { PANPLOT,  OPT_B, "boxplots", 0 },
500     { PANPLOT,  OPT_C, "boxplot", 0 },
501     { PANPLOT,  OPT_U, "output", 2},
502     { PANSPEC,  OPT_M, "matrix-diff", 0 },
503     { PANSPEC,  OPT_N, "nerlove", 0 },
504     { POISSON,  OPT_R, "robust", 0 },
505     { POISSON,  OPT_C, "cluster", 2 },
506     { POISSON,  OPT_V, "verbose", 0 },
507     { PCA,      OPT_C, "covariance", 0 },
508     { PCA,      OPT_A, "save-all", 0 },
509     { PCA,      OPT_O, "save", 1 },
510     { PCA,      OPT_Q, "quiet", 0 },
511     { PERGM,    OPT_O, "bartlett", 0 },
512     { PERGM,    OPT_L, "log", 0 },
513     { PERGM,    OPT_R, "radians", 0 },
514     { PERGM,    OPT_D, "degrees", 0 },
515     { PERGM,    OPT_U, "plot", 2 },
516     { PKG,      OPT_L, "local", 0 },
517     { PKG,      OPT_V, "verbose", 0 },
518     { PLOT,     OPT_C, "control", 0 },
519     { PLOT,     OPT_O, "with-lines", 1 },
520     { PLOT,     OPT_F, "fit", 2 },
521     { PLOT,     OPT_B, "with-boxes", 1 },
522     { PLOT,     OPT_Q, "with-steps", 1 },
523     { PLOT,     OPT_M, "with-impulses", 1 },
524     { PLOT,     OPT_P, "with-lp", 1 },
525     { PLOT,     OPT_T, "time-series", 0 },
526     { PLOT,     OPT_U, "output", 2 },
527     { PLOT,     OPT_Y, "single-yaxis", 0 },
528     { PLOT,     OPT_Z, "dummy", 0 },
529     { PLOT,     OPT_N, "band", 2 },
530     { PLOT,     OPT_J, "band-style", 2 },
531     { PLOT,     OPT_W, "font", 2 },
532     { PLOT,     OPT_L, "ylogscale", 1 },
533     { PRINT,    OPT_O, "byobs", 0 },
534     { PRINT,    OPT_L, "list", 0 },
535     { PRINT,    OPT_D, "no-dates", 0 },
536     { PRINT,    OPT_U, "numeric", 0 },
537     { PRINT,    OPT_M, "midas", 0 },
538     { PRINT,    OPT_C, "complex", 0 },
539     { PRINT,    OPT_T, "tree", 0 },
540     { PRINT,    OPT_R, "range", 2 },
541     { PRINT,    OPT_X, "data-only", 0 },
542     { PROBIT,   OPT_P, "p-values", 0 },
543     { PROBIT,   OPT_R, "robust", 0 },
544     { PROBIT,   OPT_C, "cluster", 2 },
545     { PROBIT,   OPT_V, "verbose", 0 },
546     { PROBIT,   OPT_E, "random-effects", 0 },
547     { PROBIT,   OPT_G, "quadpoints", 2 },
548     { PROBIT,   OPT_B, "bootstrap", 1 },
549     { PROBIT,   OPT_S, "estrella", 0 },
550     { QLRTEST,  OPT_L, "limit-to", 2 },
551     { QLRTEST,  OPT_U, "plot", 2 },
552     { QQPLOT,   OPT_R, "raw", 0 },
553     { QQPLOT,   OPT_Z, "z-scores", 0 },
554     { QQPLOT,   OPT_U, "output", 2 },
555     { QUANTREG, OPT_I, "intervals", 1 },
556     { QUANTREG, OPT_N, "no-df-corr", 0 },
557     { QUANTREG, OPT_R, "robust", 0 },
558     { QUIT,     OPT_X, "exit", 0 },
559     { RESET,    OPT_C, "cubes-only", 0 },
560     { RESET,    OPT_R, "squares-only", 0 },
561     { RESET,    OPT_I, "silent", 0 },
562     { RESTRICT, OPT_B, "bootstrap", 1 },
563     { RESTRICT, OPT_F, "full", 0 },
564     { RESTRICT, OPT_J, "jitter", 0 },
565     { RESTRICT, OPT_V, "verbose", 0 },
566     { RESTRICT, OPT_L, "lbfgs", 0 },
567     { RESTRICT, OPT_N, "no-scaling", 0 },
568     { RESTRICT, OPT_S, "silent", 0 },
569     { RESTRICT, OPT_W, "wald", 0 },
570     { RMPLOT,   OPT_T, "trim", 0 },
571     { RMPLOT,   OPT_U, "output", 2 },
572     { RUNS,     OPT_D, "difference", 0 },
573     { RUNS,     OPT_E, "equal", 0 },
574     { SCATTERS, OPT_O, "with-lines", 0 },
575     { SCATTERS, OPT_T, "time-series", 0 },
576     { SCATTERS, OPT_U, "output", 2 },
577     { SCATTERS, OPT_X, "matrix", 2 },
578     { SCATTERS, OPT_K, "tweaks", 2 },
579     { SET,      OPT_F, "from-file", 2 },
580     { SET,      OPT_T, "to-file", 2 },
581     { SETINFO,  OPT_C, "continuous", 0 },
582     { SETINFO,  OPT_D, "discrete", 0 },
583     { SETINFO,  OPT_I, "description", 2 },
584     { SETINFO,  OPT_G, "graph-name", 2 },
585     { SETINFO,  OPT_M, "midas", 0 },
586     { SETINFO,  OPT_F, "coded", 0 },
587     { SETINFO,  OPT_N, "numeric", 0 },
588     { SETOBS,   OPT_C, "stacked-cross-section", 0 },
589     { SETOBS,   OPT_P, "panel-vars", 0 },
590     { SETOBS,   OPT_R, "restructure", 0 },
591     { SETOBS,   OPT_S, "stacked-time-series", 0 },
592     { SETOBS,   OPT_T, "time-series", 0 },
593     { SETOBS,   OPT_X, "cross-section", 0 },
594     { SETOBS,   OPT_N, "special-time-series", 0 },
595     { SETOBS,   OPT_G, "panel-groups", 0 },
596     { SETOBS,   OPT_I, "panel-time", 0 },
597     { SMPL,     OPT_A, "no-all-missing", 0 },
598     { SMPL,     OPT_B, "balanced", 0 },
599     { SMPL,     OPT_C, "contiguous", 0 },
600     { SMPL,     OPT_F, "full", 0 },
601     { SMPL,     OPT_O, "dummy", 0 },
602     { SMPL,     OPT_M, "no-missing", 0 },
603     { SMPL,     OPT_N, "random", 0 },
604     { SMPL,     OPT_P, "replace", 0 },
605     { SMPL,     OPT_R, "restrict", 0 },
606     { SMPL,     OPT_T, "permanent", 0 },
607     { SMPL,     OPT_U, "unit", 0 },
608     { SPEARMAN, OPT_V, "verbose", 0 },
609     { SQUARE,   OPT_O, "cross", 0 },
610     { STDIZE,   OPT_C, "center-only", 0 },
611     { STDIZE,   OPT_N, "no-df-corr", 0 },
612     { STORE,    OPT_A, "matrix", 2 },
613     { STORE,    OPT_C, "compat", 1 },
614     { STORE,    OPT_D, "database", 0 },
615     { STORE,    OPT_E, "comment", 2 },
616     { STORE,    OPT_F, "overwrite", 0 },
617     { STORE,    OPT_G, "dat", 0 },
618     { STORE,    OPT_I, "decimal-comma", 0 },
619     { STORE,    OPT_J, "jmulti", 0 },
620     { STORE,    OPT_L, "lcnames", 0 },
621     { STORE,    OPT_M, "gnu-octave", 0 },
622     { STORE,    OPT_N, "no-header", 0 },
623     { STORE,    OPT_P, "preserve-strvals", 0 },
624     { STORE,    OPT_R, "gnu-R", 0 },
625     { STORE,    OPT_X, "omit-obs", 0 },
626     { STORE,    OPT_Z, "gzipped", 1 },
627     { SUMMARY,  OPT_B, "by", 2 },
628     { SUMMARY,  OPT_S, "simple", 0 },
629     { SUMMARY,  OPT_W, "weights", 2 },
630     { SUMMARY,  OPT_X, "matrix", 2 },
631     { SYSTEM,   OPT_I, "iterate", 0 },
632     { SYSTEM,   OPT_V, "verbose", 0 },
633     { SYSTEM,   OPT_R, "robust", 0 },
634     { SYSTEM,   OPT_N, "no-df-corr", 0 },
635     { TEXTPLOT, OPT_O, "one-scale", 0 },
636     { TEXTPLOT, OPT_S, "time-series", 0 },
637     { TEXTPLOT, OPT_T, "tall", 0 },
638     { TOBIT,    OPT_L, "llimit", 2 },
639     { TOBIT,    OPT_M, "rlimit", 2 },
640     { TOBIT,    OPT_G, "opg", 0 },
641     { TOBIT,    OPT_R, "robust", 0 },
642     { TOBIT,    OPT_C, "cluster", 2 },
643     { TOBIT,    OPT_V, "verbose", 0 },
644     { VAR,      OPT_D, "seasonals", 0 },
645     { VAR,      OPT_F, "variance-decomp", 0 },
646     { VAR,      OPT_H, "robust-hac", 0 },
647     { VAR,      OPT_I, "impulse-responses", 0 },
648     { VAR,      OPT_L, "lagselect", 0 },
649     { VAR,      OPT_N, "nc", 0 },
650     { VAR,      OPT_R, "robust", 0 },
651     { VAR,      OPT_T, "trend", 0 },
652     { VAR,      OPT_S, "silent", 0 },
653     { VAR,      OPT_M, "minlag", 2 },
654     { VARLIST,  OPT_A, "accessors", 0 },
655     { VARLIST,  OPT_S, "scalars", 0 },
656     { VARLIST,  OPT_T, "type", 2 },
657     { VARLIST,  OPT_D, "debug" },
658     { VECM,     OPT_A, "crt", 0 },
659     { VECM,     OPT_D, "seasonals", 0 },
660     { VECM,     OPT_F, "variance-decomp", 0 },
661     { VECM,     OPT_I, "impulse-responses", 1 },
662     { VECM,     OPT_N, "nc", 0 },
663     { VECM,     OPT_R, "rc", 0 },
664     { VECM,     OPT_C, "uc", 0 },
665     { VECM,     OPT_T, "ct", 0 },
666     { VECM,     OPT_V, "verbose", 0 },
667     { VECM,     OPT_S, "silent", 0 },
668     { WLS,      OPT_R, "robust", 0 },
669     { WLS,      OPT_C, "cluster", 2 },
670     { WLS,      OPT_Z, "allow-zeros", 0 },
671     { XCORRGM,  OPT_U, "plot", 2 },
672     { XTAB,     OPT_C, "column", 0 },
673     { XTAB,     OPT_X, "matrix", 2 },
674     { XTAB,     OPT_R, "row", 0 },
675     { XTAB,     OPT_Z, "zeros", 0 },
676     { XTAB,     OPT_T, "tex", 1 },
677     { XTAB,     OPT_N, "no-totals", 0 },
678     { XTAB,     OPT_E, "equal", 0 },
679     { 0,        0L,    NULL, 0 }
680 };
681 
get_longopt(int ci,gretlopt opt)682 static const char *get_longopt (int ci, gretlopt opt)
683 {
684     int i, got_ci = 0;
685 
686     for (i=0; gretl_opts[i].ci; i++) {
687         if (gretl_opts[i].ci == ci) {
688             if (gretl_opts[i].o == opt) {
689                 return gretl_opts[i].longopt;
690             }
691             got_ci = 1;
692         } else if (got_ci) {
693             break;
694         }
695     }
696 
697     return "??";
698 }
699 
cluster_option_ok(int ci)700 int cluster_option_ok (int ci)
701 {
702     int i, got_ci = 0;
703 
704     for (i=0; gretl_opts[i].ci; i++) {
705         if (gretl_opts[i].ci == ci) {
706             if (gretl_opts[i].o == OPT_C &&
707                 !strcmp(gretl_opts[i].longopt, "cluster")) {
708                 return 1;
709             }
710             got_ci = 1;
711         } else if (got_ci) {
712             break;
713         }
714     }
715 
716     return 0;
717 }
718 
719 /* used in tokenize.c: detects the case where a command
720    has an option of the form --matrix=foo, indicating that
721    the columns of a named matrix replace the dataset
722    series that the comand would otherwise require as
723    arguments
724 */
725 
matrix_data_option(int ci,gretlopt opt)726 int matrix_data_option (int ci, gretlopt opt)
727 {
728     if (opt & OPT_X) {
729         int i, got_ci = 0;
730 
731         for (i=0; gretl_opts[i].ci; i++) {
732             if (gretl_opts[i].ci == ci) {
733                 if (gretl_opts[i].o == OPT_X &&
734                     !strcmp(gretl_opts[i].longopt, "matrix")) {
735                     return 1;
736                 }
737                 got_ci = 1;
738             } else if (got_ci) {
739                 break;
740             }
741         }
742     }
743 
744     return 0;
745 }
746 
747 /* this function is used in compiling the gretl reference
748    manual */
749 
get_all_option_strings(int * pn)750 char **get_all_option_strings (int *pn)
751 {
752     char **optstrs;
753     int i, n = 0;
754 
755     for (i=0; gretl_opts[i].ci != 0; i++) {
756         n++;
757     }
758 
759     optstrs = strings_array_new(n);
760 
761     if (optstrs != NULL) {
762         for (i=0; i<n; i++) {
763             optstrs[i] = gretl_strdup(gretl_opts[i].longopt);
764             if (optstrs[i] == NULL) {
765                 strings_array_free(optstrs, n);
766                 optstrs = NULL;
767                 break;
768             }
769         }
770     }
771 
772     if (optstrs != NULL) {
773         strings_array_sort(&optstrs, &n, OPT_U);
774         *pn = n;
775     }
776 
777     return optstrs;
778 }
779 
780 /* used in checking command documentation */
781 
get_opts_for_command(int ci,int * nopt)782 const char **get_opts_for_command (int ci, int *nopt)
783 {
784     int i, j, got_ci, n = 0;
785     const char **ret = NULL;
786 
787     if (ci != OLS) {
788         /* widely applicable options which are "attached" to OLS */
789         n += vcv_opt_ok(ci);
790         n += quiet_opt_ok(ci);
791         n += window_opt_ok(ci);
792     }
793 
794     for (i=0; gretl_opts[i].ci != 0; i++) {
795         n += (gretl_opts[i].ci == ci);
796     }
797 
798     if (n == 0) {
799         *nopt = 0;
800         return NULL;
801     }
802 
803     ret = malloc(n * sizeof *ret);
804     if (ret == NULL) return NULL;
805 
806     j = got_ci = 0;
807     for (i=0; gretl_opts[i].ci != 0; i++) {
808         if (gretl_opts[i].ci == ci) {
809             ret[j++] = gretl_opts[i].longopt;
810             got_ci = 1;
811         } else if (got_ci) {
812             break;
813         }
814     }
815 
816     if (ci != OLS) {
817         if (vcv_opt_ok(ci)) {
818             ret[j++] = "vcv";
819         }
820         if (quiet_opt_ok(ci)) {
821             ret[j++] = "quiet";
822         }
823         if (window_opt_ok(ci)) {
824             ret[j++] = "window";
825         }
826     }
827 
828     *nopt = n;
829 
830     return ret;
831 }
832 
833 struct flag_match flag_matches[] = {
834     { OPT_A, 'a' },
835     { OPT_B, 'b' },
836     { OPT_C, 'c' },
837     { OPT_D, 'd' },
838     { OPT_E, 'e' },
839     { OPT_F, 'f' },
840     { OPT_G, 'g' },
841     { OPT_H, 'h' },
842     { OPT_I, 'i' },
843     { OPT_J, 'j' },
844     { OPT_K, 'k' },
845     { OPT_L, 'l' },
846     { OPT_M, 'm' },
847     { OPT_N, 'n' },
848     { OPT_O, 'o' },
849     { OPT_P, 'p' },
850     { OPT_Q, 'q' },
851     { OPT_R, 'r' },
852     { OPT_S, 's' },
853     { OPT_T, 't' },
854     { OPT_U, 'u' },
855     { OPT_V, 'v' },
856     { OPT_W, 'w' },
857     { OPT_X, 'x' },
858     { OPT_Y, 'y' },
859     { OPT_Z, 'z' },
860     { 0L,   '\0' }
861 };
862 
863 /**
864  * opt_from_flag:
865  *
866  * Returns: the gretl option value associated with a given
867  * single-character flag.  Gives 0 if there is no associated
868  * option.
869  */
870 
opt_from_flag(unsigned char c)871 gretlopt opt_from_flag (unsigned char c)
872 {
873     int i;
874 
875     for (i=0; flag_matches[i].c != '\0'; i++) {
876         if (c == flag_matches[i].c) {
877             return flag_matches[i].o;
878         }
879     }
880 
881     return OPT_NONE;
882 }
883 
opt_is_valid(gretlopt opt,int ci,char c)884 static int opt_is_valid (gretlopt opt, int ci, char c)
885 {
886     int i, got_ci = 0;
887 
888     if (opt == OPT_O && vcv_opt_ok(ci)) {
889         return 1;
890     } else if (opt == OPT_Q && quiet_opt_ok(ci)) {
891         return 1;
892     } else if (opt == OPT_W && window_opt_ok(ci)) {
893         return 1;
894     }
895 
896     for (i=0; gretl_opts[i].ci != 0; i++) {
897         if (ci == gretl_opts[i].ci) {
898             if (opt == gretl_opts[i].o) {
899                 return 1;
900             }
901             got_ci = 1;
902         } else if (got_ci) {
903             break;
904         }
905     }
906 
907     if (c != 0) {
908         gretl_errmsg_sprintf("Invalid option '-%c'", c);
909     }
910 
911     return 0;
912 }
913 
914 enum {
915     OPT_SETOPT  = 1 << 0,
916     OPT_PERSIST = 1 << 1
917 };
918 
919 /* The following apparatus is used for
920 
921    (a) setting and retrieving parameters associated with
922        command options, as in --opt=val, and
923 
924    (b) storing options for a specified command via the
925        "setopt" command (with or without parameters).
926 */
927 
928 typedef struct stored_opt_ stored_opt;
929 
930 struct stored_opt_ {
931     int ci;       /* index of the associated command */
932     gretlopt opt; /* option flag */
933     char *val;    /* option parameter value, or NULL */
934     int flags;    /* may include OPT_SETOPT, OPT_PERSIST */
935     int fd;       /* "function depth" at which registered */
936 };
937 
938 static stored_opt *optinfo;
939 static int n_stored_opts;
940 
clear_one_option(stored_opt * so)941 static void clear_one_option (stored_opt *so)
942 {
943     free(so->val);
944     so->val = NULL;
945     so->ci = 0;
946     so->opt = 0;
947     so->flags = 0;
948 }
949 
950 /**
951  * clear_stored_options_for_command:
952  * @ci: target command index.
953  *
954  * Clears any (non-persistent) option information currently
955  * associated with the given command, identified by its
956  * index.
957  */
958 
clear_stored_options_for_command(int ci)959 void clear_stored_options_for_command (int ci)
960 {
961     int i, fd = gretl_function_depth();
962 
963 #if OPTDEBUG > 1
964     fprintf(stderr, "clearing stored options for %s\n",
965             gretl_command_word(ci));
966 #endif
967 
968     for (i=0; i<n_stored_opts; i++) {
969         if (optinfo[i].fd == fd && optinfo[i].ci == ci &&
970             !(optinfo[i].flags & OPT_PERSIST)) {
971             clear_one_option(&optinfo[i]);
972         }
973     }
974 }
975 
976 /* called on exiting a user-defined function */
977 
destroy_option_params_at_level(int level)978 void destroy_option_params_at_level (int level)
979 {
980     int i, n = n_stored_opts;
981 
982 #if OPTDEBUG
983     fprintf(stderr, "destroy_option_params_at_level: %d\n", level);
984 #endif
985 
986     for (i=0; i<n_stored_opts; i++) {
987         if (optinfo[i].fd == level) {
988             clear_one_option(&optinfo[i]);
989             n--;
990         }
991     }
992 
993     if (n == 0) {
994         free(optinfo);
995         optinfo = NULL;
996     }
997 
998     n_stored_opts = n;
999 }
1000 
1001 /* unconditionally clean up the entire optinfo stack */
1002 
stored_options_cleanup(void)1003 void stored_options_cleanup (void)
1004 {
1005     int i;
1006 
1007 #if OPTDEBUG
1008     fprintf(stderr, "stored_options_cleanup\n");
1009 #endif
1010 
1011     for (i=0; i<n_stored_opts; i++) {
1012         free(optinfo[i].val);
1013     }
1014 
1015     free(optinfo);
1016     optinfo = NULL;
1017     n_stored_opts = 0;
1018 }
1019 
1020 /* scrub just those options set via "setopt" */
1021 
setopt_cleanup(void)1022 void setopt_cleanup (void)
1023 {
1024     int i, n = n_stored_opts;
1025 
1026 #if OPTDEBUG
1027     fprintf(stderr, "setopt_cleanup\n");
1028 #endif
1029 
1030     for (i=0; i<n_stored_opts; i++) {
1031         if (optinfo[i].flags & OPT_SETOPT) {
1032             clear_one_option(&optinfo[i]);
1033             n--;
1034         }
1035     }
1036 
1037     if (n == 0) {
1038         free(optinfo);
1039         optinfo = NULL;
1040     }
1041 
1042     n_stored_opts = n;
1043 }
1044 
matching_stored_opt(int ci,gretlopt opt)1045 static stored_opt *matching_stored_opt (int ci, gretlopt opt)
1046 {
1047     int i, fd = gretl_function_depth();
1048 
1049 #if OPTDEBUG
1050     fprintf(stderr, "matching_stored_opt? ci=%d, fd=%d, opt=%d, n_stored=%d\n",
1051             ci, fd, opt, n_stored_opts);
1052 #endif
1053 
1054     for (i=0; i<n_stored_opts; i++) {
1055 	stored_opt *so = &optinfo[i];
1056 
1057         if (so->ci == ci && so->opt == opt && so->fd == fd) {
1058             return so;
1059         }
1060     }
1061 
1062     return NULL;
1063 }
1064 
empty_stored_opt_slot(void)1065 static stored_opt *empty_stored_opt_slot (void)
1066 {
1067     int i;
1068 
1069     for (i=0; i<n_stored_opts; i++) {
1070         if (optinfo[i].ci == 0) {
1071             return &optinfo[i];
1072         }
1073     }
1074 
1075     return NULL;
1076 }
1077 
1078 /* for a given (@ci, @opt) pair, determine its status with regard
1079    to a parameter value: 0 = not allowed, 1 = optional, 2 = required
1080 */
1081 
option_parm_status(int ci,gretlopt opt)1082 static int option_parm_status (int ci, gretlopt opt)
1083 {
1084     int i, got_ci = 0;
1085 
1086     for (i=0; gretl_opts[i].ci != 0; i++) {
1087 
1088         if (gretl_opts[i].ci == ci) {
1089             if (gretl_opts[i].o == opt) {
1090                 return gretl_opts[i].parminfo;
1091             }
1092             got_ci = 1;
1093         } else if (got_ci) {
1094             break;
1095         }
1096     }
1097 
1098     return 0;
1099 }
1100 
1101 /* Handle the case where we got input on the pattern
1102 
1103    --option-with-param=eval(foo)
1104 
1105    where "foo" is the name of a string variable and the
1106    option parameter should be set to the value of that
1107    variable.
1108 */
1109 
maybe_evaluate_optval(stored_opt * so)1110 static int maybe_evaluate_optval (stored_opt *so)
1111 {
1112     char *s = so->val;
1113     int n = strlen(s);
1114     int err = 0;
1115 
1116     if (!strncmp(s, "eval(", 5) && s[n-1] == ')') {
1117         char *sname = gretl_strndup(s + 5, n - 6);
1118 
1119         if (sname != NULL) {
1120             char *tmp = generate_string(sname, NULL, &err);
1121 
1122             if (tmp != NULL) {
1123                 free(so->val);
1124                 so->val = tmp;
1125             }
1126             free(sname);
1127         }
1128     }
1129 
1130     return err;
1131 }
1132 
real_push_option(int ci,gretlopt opt,char * val,int checked,int flags)1133 static int real_push_option (int ci, gretlopt opt, char *val,
1134                              int checked, int flags)
1135 {
1136     int fd = gretl_function_depth();
1137     int n, err = 0;
1138     int val_set = 0;
1139     stored_opt *so;
1140 
1141     if (!checked && ci > 0 && option_parm_status(ci, opt) == OPT_NO_PARM)  {
1142         return E_DATA;
1143     }
1144 
1145 #if OPTDEBUG
1146     fprintf(stderr, "push_option_param: ci=%d (%s), fd=%d, opt=%d,"
1147             " val='%s', SETOPT %d\n", ci, gretl_command_word(ci),
1148 	    fd, opt, val, flags & OPT_SETOPT ? 1 : 0);
1149 #endif
1150 
1151     so = matching_stored_opt(ci, opt);
1152 
1153     if (so != NULL) {
1154         /* got a match for the (ci, opt) pair already */
1155 #if OPTDEBUG
1156         fprintf(stderr, " push_option_param: replacing\n");
1157 #endif
1158         if (!(flags & OPT_SETOPT)) {
1159             free(so->val);
1160             so->val = val;
1161             val_set = 1;
1162         }
1163         so->flags = flags;
1164         goto finish;
1165     }
1166 
1167     so = empty_stored_opt_slot();
1168 
1169     if (so != NULL) {
1170         /* re-use a vacant slot */
1171 #if OPTDEBUG
1172         fprintf(stderr, " push_option_param: reusing empty\n");
1173 #endif
1174         so->ci = ci;
1175         so->opt = opt;
1176         so->val = val;
1177         val_set = 1;
1178         so->flags = flags;
1179         so->fd = fd;
1180         goto finish;
1181     }
1182 
1183     /* so we have to extend the array */
1184     n = n_stored_opts + 1;
1185     so = realloc(optinfo, n * sizeof *so);
1186 
1187     if (so == NULL) {
1188         err = E_ALLOC;
1189     } else {
1190 #if OPTDEBUG
1191         fprintf(stderr, " push_option_param: appending\n");
1192 #endif
1193         optinfo = so;
1194         so = &optinfo[n-1];
1195         so->ci = ci;
1196         so->opt = opt;
1197         so->val = val;
1198         val_set = 1;
1199         so->flags = flags;
1200         so->fd = fd;
1201         n_stored_opts = n;
1202     }
1203 
1204  finish:
1205 
1206     if (val_set && so->val != NULL) {
1207         maybe_evaluate_optval(so);
1208     }
1209 
1210     return err;
1211 }
1212 
1213 /**
1214  * push_option_param:
1215  * @ci: gretl command index.
1216  * @opt: gretl option flag.
1217  * @val: parameter value as string.
1218  *
1219  * Pushes onto an internal stack a record of the @val
1220  * to be associated with @opt for the current @ci. Note
1221  * that the command option apparatus takes ownership of
1222  * @val, so the value passed in should be copied if need
1223  * be.
1224  *
1225  * Returns: 0 on success, non-zero on failure.
1226  */
1227 
push_option_param(int ci,gretlopt opt,char * val)1228 int push_option_param (int ci, gretlopt opt, char *val)
1229 {
1230     return real_push_option(ci, opt, val, 0, 0);
1231 }
1232 
1233 /**
1234  * get_optval_string:
1235  * @ci: gretl command index.
1236  * @opt: gretl option value.
1237  *
1238  * Returns: the ancillary string value currently
1239  * associated with option @opt for command @ci, if any,
1240  * otherwise %NULL.
1241  */
1242 
get_optval_string(int ci,gretlopt opt)1243 const char *get_optval_string (int ci, gretlopt opt)
1244 {
1245     stored_opt *so = matching_stored_opt(ci, opt);
1246 
1247     return (so != NULL)? so->val : NULL;
1248 }
1249 
1250 /**
1251  * get_optval_double:
1252  * @ci: gretl command index.
1253  * @opt: gretl option value.
1254  * @err: location to receive error code.
1255  *
1256  * Returns: the double-precision ancillary value currently
1257  * associated with option @opt for command @ci, if any,
1258  * otherwise #NADBL. If @opt is an active option for
1259  * @ci but the parameter for this option cannot be
1260  * interpreted as a numerical value, E_INVARG is written
1261  * into @err.
1262  */
1263 
get_optval_double(int ci,gretlopt opt,int * err)1264 double get_optval_double (int ci, gretlopt opt, int *err)
1265 {
1266     stored_opt *so = matching_stored_opt(ci, opt);
1267     double ret = NADBL;
1268 
1269     if (so != NULL && so->val != NULL) {
1270         ret = gretl_double_from_string(so->val, err);
1271         if (err) {
1272             ret = generate_scalar(so->val, NULL, err);
1273         }
1274         if (*err) {
1275             gretl_errmsg_sprintf(_("%s: invalid option argument"), so->val);
1276             *err = E_INVARG;
1277         }
1278     }
1279 
1280     return ret;
1281 }
1282 
1283 /**
1284  * get_optval_int:
1285  * @ci: gretl command index.
1286  * @opt: gretl option value.
1287  * @err: location to receive error code.
1288  *
1289  * Returns: the integer ancillary value currently
1290  * associated with option @opt for command @ci, if any,
1291  * otherwise 0. A non-zero value written to @err if
1292  * such a value is required for the option in question
1293  * but is not present.
1294  */
1295 
get_optval_int(int ci,gretlopt opt,int * err)1296 int get_optval_int (int ci, gretlopt opt, int *err)
1297 {
1298     stored_opt *so = matching_stored_opt(ci, opt);
1299     int status = option_parm_status(ci, opt);
1300     int ret = 0;
1301 
1302     if (so != NULL && so->val != NULL) {
1303         ret = gretl_int_from_string(so->val, err);
1304         if (*err) {
1305             ret = generate_int(so->val, NULL, err);
1306         }
1307         if (*err) {
1308             gretl_errmsg_sprintf(_("%s: invalid option argument"), so->val);
1309             *err = E_INVARG;
1310         }
1311     } else if (status == 2 && err != NULL) {
1312         const char *longopt = get_longopt(ci, opt);
1313 
1314         gretl_errmsg_sprintf(_("The option '--%s' requires a parameter"),
1315                              longopt);
1316         *err = E_DATA;
1317     }
1318 
1319     return ret;
1320 }
1321 
clear_options_for_command(int ci)1322 static void clear_options_for_command (int ci)
1323 {
1324     int i, fd = gretl_function_depth();
1325 
1326     for (i=0; i<n_stored_opts; i++) {
1327         if (optinfo[i].fd == fd && optinfo[i].ci == ci) {
1328             clear_one_option(&optinfo[i]);
1329         }
1330     }
1331 }
1332 
set_stored_options(int ci,gretlopt opt,int flags)1333 static void set_stored_options (int ci, gretlopt opt, int flags)
1334 {
1335     int i, got_ci = 0;
1336 
1337 #if OPTDEBUG
1338     fprintf(stderr, "setting stored options for %s (%d): ",
1339             gretl_command_word(ci), ci);
1340     debug_print_option_flags(NULL, opt);
1341 #endif
1342 
1343     if (vcv_opt_ok(ci) && (opt & OPT_O)) {
1344         real_push_option(ci, OPT_O, NULL, 1, flags);
1345         opt &= ~OPT_O; /* handled */
1346     }
1347 
1348     if (quiet_opt_ok(ci) && (opt & OPT_Q)) {
1349         real_push_option(ci, OPT_Q, NULL, 1, flags);
1350         opt &= ~OPT_Q; /* handled */
1351     }
1352 
1353     if (window_opt_ok(ci) && (opt & OPT_W)) {
1354         real_push_option(ci, OPT_W, NULL, 1, flags);
1355         opt &= ~OPT_W; /* handled */
1356     }
1357 
1358     if (opt == 0) {
1359         return;
1360     }
1361 
1362     for (i=0; gretl_opts[i].o != 0; i++) {
1363 	struct gretl_option *gopt = &gretl_opts[i];
1364 
1365         if (ci == gopt->ci) {
1366             if (opt & gopt->o) {
1367 		real_push_option(ci, gopt->o, NULL, 1, flags);
1368             }
1369             got_ci = ci;
1370         } else if (got_ci > 0 && ci != got_ci) {
1371             break;
1372         }
1373     }
1374 }
1375 
1376 /* Apparatus for pre-selecting options for a specified command,
1377    using the "setopt" command.
1378 */
1379 
set_options_for_command(const char * cmdword,const char * param,gretlopt opt)1380 int set_options_for_command (const char *cmdword,
1381                              const char *param,
1382                              gretlopt opt)
1383 {
1384     int target_ci = gretl_command_number(cmdword);
1385     int flags = OPT_SETOPT;
1386     int clear = 0;
1387     int err = 0;
1388 
1389     if (target_ci == 0 || target_ci == SETOPT) {
1390         gretl_errmsg_sprintf(_("field '%s' in command is invalid"),
1391                              cmdword);
1392         return E_DATA;
1393     }
1394 
1395     if (param != NULL && *param != '\0') {
1396         if (!strcmp(param, "persist")) {
1397             flags |= OPT_PERSIST;
1398         } else if (!strcmp(param, "clear")) {
1399             clear = 1;
1400         } else {
1401             gretl_errmsg_sprintf(_("field '%s' in command is invalid"),
1402                                  param);
1403             return E_DATA;
1404         }
1405     }
1406 
1407     if (clear) {
1408         clear_options_for_command(target_ci);
1409     } else if (opt == 0) {
1410         err = E_ARGS;
1411     } else {
1412         set_stored_options(target_ci, opt, flags);
1413     }
1414 
1415     return err;
1416 }
1417 
1418 #if OPTDEBUG
1419 
option_flag_char(gretlopt opt)1420 static char option_flag_char (gretlopt opt)
1421 {
1422     char c = 'A';
1423     int i;
1424 
1425     for (i=OPT_A; i<=OPT_Y; i*=2) {
1426         if (opt == i) {
1427             return c;
1428         }
1429         c++;
1430     }
1431 
1432     return '?';
1433 }
1434 
1435 #endif
1436 
maybe_get_stored_options(int ci,gretlopt * popt)1437 void maybe_get_stored_options (int ci, gretlopt *popt)
1438 {
1439     int i, fd = gretl_function_depth();
1440 
1441     for (i=0; i<n_stored_opts; i++) {
1442         if (optinfo[i].fd == fd && optinfo[i].ci == ci &&
1443             (optinfo[i].flags & OPT_SETOPT)) {
1444 #if OPTDEBUG
1445             fprintf(stderr, "ci %d: got stored OPT_%c\n",
1446                     ci, option_flag_char(optinfo[i].opt));
1447 #endif
1448             *popt |= optinfo[i].opt;
1449         }
1450     }
1451 }
1452 
1453 /* When writing data as gdt this is called conditionally on OPT_Z
1454    being given, but when writing gdtb it is called unconditionally
1455    (since the format of the latter is a zipfile in all cases).
1456    The effects are then:
1457 
1458    gdt: no compression applied by default; if --gzipped given
1459    with no parameter, zlib level 1 used; if --gzipped given
1460    with parameter, param value respected within range 0 to 9.
1461 
1462    gdtb: zlib level 1 used by default, levels 0 to 9 can be
1463    specified via --gzipped + param.
1464 */
1465 
get_compression_option(int ci)1466 int get_compression_option (int ci)
1467 {
1468     stored_opt *so = matching_stored_opt(ci, OPT_Z);
1469     int level = 0;
1470 
1471     if (so == NULL || so->val == NULL) {
1472         /* use zlib level 1 by default */
1473         level = 1;
1474     } else {
1475         level = atoi(so->val);
1476         if (level < 0) {
1477             level = 0;
1478         } else if (level > 9) {
1479             level = 9;
1480         }
1481     }
1482 
1483     return level;
1484 }
1485 
1486 /* below: called via GUI */
1487 
1488 /**
1489  * set_optval_double:
1490  * @ci: gretl command index.
1491  * @opt: gretl option value.
1492  * @x: value to set.
1493  *
1494  * Sets a double-precision ancillary value to be associated
1495  * with option @opt for command @ci.
1496  *
1497  * Returns: 0 on success, non-zero on failure.
1498  */
1499 
set_optval_double(int ci,gretlopt opt,double x)1500 int set_optval_double (int ci, gretlopt opt, double x)
1501 {
1502     char s[32];
1503 
1504     gretl_push_c_numeric_locale();
1505     sprintf(s, "%g", x);
1506     gretl_pop_c_numeric_locale();
1507 
1508     return real_push_option(ci, opt, gretl_strdup(s), 1, 0);
1509 }
1510 
1511 /**
1512  * set_optval_int:
1513  * @ci: gretl command index.
1514  * @opt: gretl option value.
1515  * @k: value to set.
1516  *
1517  * Sets a integer ancillary value to be associated
1518  * with option @opt for command @ci.
1519  *
1520  * Returns: 0 on success, non-zero on failure.
1521  */
1522 
set_optval_int(int ci,gretlopt opt,int k)1523 int set_optval_int (int ci, gretlopt opt, int k)
1524 {
1525     char *s = gretl_strdup_printf("%d", k);
1526 
1527     return real_push_option(ci, opt, s, 1, 0);
1528 }
1529 
1530 /**
1531  * set_optval_string:
1532  * @ci: gretl command index.
1533  * @opt: gretl option value.
1534  * @s: value to set.
1535  *
1536  * Sets a ancillary string value to be associated
1537  * with option @opt for command @ci.
1538  *
1539  * Returns: 0 on success, non-zero on failure.
1540  */
1541 
set_optval_string(int ci,gretlopt opt,const char * s)1542 int set_optval_string (int ci, gretlopt opt, const char *s)
1543 {
1544     char *scpy = gretl_strdup(s);
1545 
1546     if (scpy == NULL) {
1547         return E_ALLOC;
1548     } else {
1549         return real_push_option(ci, opt, scpy, 1, 0);
1550     }
1551 }
1552 
1553 /* valid_long_opt: this is (semi-) public because we have need of
1554    it in the new command tokenizer
1555 */
1556 
valid_long_opt(int ci,const char * s,OptStatus * status)1557 gretlopt valid_long_opt (int ci, const char *s, OptStatus *status)
1558 {
1559     gretlopt opt = OPT_NONE;
1560     int i, got_ci = 0;
1561 
1562     *status = 0;
1563 
1564     if (*s == '\0') {
1565         return 0;
1566     }
1567 
1568     if (vcv_opt_ok(ci) && !strcmp(s, "vcv")) {
1569         return OPT_O;
1570     }
1571 
1572     if (quiet_opt_ok(ci) && !strcmp(s, "quiet")) {
1573         return OPT_Q;
1574     }
1575 
1576     if (window_opt_ok(ci) && !strcmp(s, "window")) {
1577         return OPT_W;
1578     }
1579 
1580     /* start by looking for an exact match */
1581     for (i=0; gretl_opts[i].o != 0; i++) {
1582         if (ci == gretl_opts[i].ci) {
1583             if (!strcmp(s, gretl_opts[i].longopt)) {
1584                 opt = gretl_opts[i].o;
1585                 *status = gretl_opts[i].parminfo;
1586                 break;
1587             }
1588             got_ci = 1;
1589         } else if (got_ci) {
1590             break;
1591         }
1592     }
1593 
1594     /* if this failed, try for a unique abbreviation */
1595     if (opt == OPT_NONE) {
1596         int optlen, slen = strlen(s);
1597         int nmatch = 0;
1598 
1599         got_ci = 0;
1600         for (i=0; gretl_opts[i].o != 0; i++) {
1601             if (ci == gretl_opts[i].ci) {
1602                 optlen = strlen(gretl_opts[i].longopt);
1603                 if (optlen > slen && !strncmp(s, gretl_opts[i].longopt, slen)) {
1604                     opt = gretl_opts[i].o;
1605                     *status = gretl_opts[i].parminfo;
1606                     nmatch++;
1607                 }
1608                 got_ci = 1;
1609             } else if (got_ci) {
1610                 break;
1611             }
1612         }
1613         if (nmatch > 1) {
1614             if (ci == SETOBS && !strcmp(s, "panel")) {
1615                 /* backward compatibility: --panel-vars was there first */
1616                 return OPT_P;
1617             }
1618             *status = OPT_AMBIGUOUS;
1619             return OPT_NONE;
1620         }
1621     }
1622 
1623     /* backward compatibility */
1624     if (opt == OPT_NONE && !strcmp(s, "wald")) {
1625         opt = OPT_W;
1626         *status = 0;
1627     }
1628 
1629     return opt;
1630 }
1631 
1632 /* see valid_long_opt() above */
1633 
valid_short_opt(int ci,char c)1634 gretlopt valid_short_opt (int ci, char c)
1635 {
1636     gretlopt opt = 0;
1637     int i, ok;
1638 
1639     for (i=0; flag_matches[i].c != '\0'; i++) {
1640         if (c == flag_matches[i].c) {
1641             opt = flag_matches[i].o;
1642             break;
1643         }
1644     }
1645 
1646     if (opt) {
1647         ok = opt_is_valid(opt, ci, c);
1648         if (!ok) {
1649             opt = 0;
1650         }
1651     }
1652 
1653     return opt;
1654 }
1655 
print_option_param(const char * s,PRN * prn)1656 static void print_option_param (const char *s, PRN *prn)
1657 {
1658     const char *qchars = "=%, ";
1659     const char *p = s;
1660     int wrap = 0;
1661     int escape = 0;
1662 
1663     while (*p) {
1664         if (strspn(p, qchars)) {
1665             wrap = 1;
1666         } else if (*p == '"') {
1667             escape = 1;
1668         }
1669         p++;
1670     }
1671 
1672     if (wrap) {
1673         if (escape) {
1674             pputs(prn, "=\"");
1675             while (*s) {
1676                 if (*s == '"') {
1677                     pputs(prn, "\\\"");
1678                 } else {
1679                     pputc(prn, *s);
1680                 }
1681                 s++;
1682             }
1683             pputs(prn, "\"\n");
1684         } else {
1685             pprintf(prn, "=\"%s\"", s);
1686         }
1687     } else {
1688         pprintf(prn, "=%s", s);
1689     }
1690 }
1691 
1692 static PRN *flagprn;
1693 
1694 /**
1695  * print_flags:
1696  * @oflags: options.
1697  * @ci: command index, for context.
1698  *
1699  * Returns: a string representation of the options in @oflags,
1700  * or an empty string if no options are found.  The returned
1701  * value should not be modified in any way.
1702  */
1703 
print_flags(gretlopt oflags,int ci)1704 const char *print_flags (gretlopt oflags, int ci)
1705 {
1706     const char *parm;
1707     gretlopt opt;
1708     int i, got_ci;
1709 
1710     if (ci == FUNDEBUG) {
1711         /* options are for internal use only */
1712         return "";
1713     }
1714 
1715     if (flagprn == NULL) {
1716         int err = 0;
1717 
1718         flagprn = gretl_print_new(GRETL_PRINT_BUFFER, &err);
1719         if (err) {
1720             return "";
1721         }
1722     } else {
1723         gretl_print_reset_buffer(flagprn);
1724     }
1725 
1726     if (oflags == OPT_NONE || ci == QUIT || ci == GENR) {
1727         /* no options, or only hidden ones */
1728         return "";
1729     }
1730 
1731     /* special: -o (--vcv) can be used with several model
1732        commands */
1733     if ((oflags & OPT_O) && vcv_opt_ok(ci)) {
1734         pputs(flagprn, " --vcv");
1735         oflags &= ~OPT_O; /* handled */
1736     }
1737 
1738     if ((oflags & OPT_Q) && quiet_opt_ok(ci)) {
1739         pputs(flagprn, " --quiet");
1740         oflags &= ~OPT_Q; /* handled */
1741     }
1742 
1743     if ((oflags & OPT_W) && window_opt_ok(ci)) {
1744         pputs(flagprn, " --window");
1745         oflags &= ~OPT_W; /* handled */
1746     }
1747 
1748     got_ci = 0;
1749     for (i=0; gretl_opts[i].ci != 0; i++) {
1750         if (ci == gretl_opts[i].ci) {
1751             opt = gretl_opts[i].o;
1752             if (oflags & opt) {
1753                 pprintf(flagprn, " --%s", gretl_opts[i].longopt);
1754                 if (gretl_opts[i].parminfo) {
1755                     parm = get_optval_string(ci, opt);
1756                     if (parm != NULL && *parm != '\0') {
1757                         print_option_param(parm, flagprn);
1758                     }
1759                 }
1760             }
1761             got_ci = 1;
1762         } else if (got_ci) {
1763             break;
1764         }
1765     }
1766 
1767     return gretl_print_get_buffer(flagprn);
1768 }
1769 
option_printing_cleanup(void)1770 void option_printing_cleanup (void)
1771 {
1772     gretl_print_destroy(flagprn);
1773     flagprn = NULL;
1774 }
1775 
1776 /**
1777  * check_for_loop_only_options:
1778  * @ci: gretl command index.
1779  * @opt: option flag to be tested.
1780  * @prn: gretl printing struct.
1781  *
1782  * Returns: 1 if option @opt is applicable for command @ci only
1783  * in the context of a command loop (in which case a warning is
1784  * printed to @prn), otherwise 0.
1785  */
1786 
check_for_loop_only_options(int ci,gretlopt opt,PRN * prn)1787 int check_for_loop_only_options (int ci, gretlopt opt, PRN *prn)
1788 {
1789     int ret = 0;
1790 
1791     if (ci == OLS && (opt & OPT_P)) {
1792         const char *flagstr = print_flags(OPT_P, OLS);
1793 
1794         pprintf(prn, _("Warning: option%s ignored outside of loop"),
1795                 flagstr);
1796         pputc(prn, '\n');
1797         ret = 1;
1798     }
1799 
1800     return ret;
1801 }
1802 
1803 /**
1804  * transcribe_options:
1805  * @targ: pointer to target option flags.
1806  * @src: source option flags.
1807  * @test: bitwise OR of flags that are of interest in context.
1808  *
1809  * If the intersection of the flags in @src and @test is non-
1810  * empty, set the corresponding flags in @targ.
1811  *
1812  * Returns: the (possibly modified) @targ.
1813  */
1814 
transcribe_option_flags(gretlopt * targ,gretlopt src,gretlopt test)1815 gretlopt transcribe_option_flags (gretlopt *targ, gretlopt src,
1816                                   gretlopt test)
1817 {
1818     *targ |= (src & test);
1819 
1820     return *targ;
1821 }
1822 
1823 /**
1824  * delete_option_flags:
1825  * @targ: pointer to target option flags.
1826  * @test: bitwise OR of flags that to be deleted.
1827  *
1828  * If the intersection of the flags in @targ and @test is non-
1829  * empty, unset the corresponding flags in @targ.
1830  *
1831  * Returns: the (possibly modified) @targ.
1832  */
1833 
delete_option_flags(gretlopt * targ,gretlopt test)1834 gretlopt delete_option_flags (gretlopt *targ, gretlopt test)
1835 {
1836     *targ &= ~(*targ & test);
1837 
1838     return *targ;
1839 }
1840 
1841 /**
1842  * incompatible_options:
1843  * @opt: option flags to be tested.
1844  * @test: bitwise OR of flags that are incompatible in context.
1845  *
1846  * Returns: %E_BADOPT if @opt contains more than one of the flags
1847  * in @test, otherwise 0.
1848  */
1849 
incompatible_options(gretlopt opt,gretlopt test)1850 int incompatible_options (gretlopt opt, gretlopt test)
1851 {
1852     int optcount = 0;
1853     gretlopt o;
1854 
1855     for (o=OPT_A; o<=OPT_Z; o=o<<1) {
1856         if ((opt & o) && (test & o)) {
1857             optcount++;
1858             if (optcount > 1) {
1859                 return E_BADOPT;
1860             }
1861         }
1862     }
1863 
1864     return 0;
1865 }
1866 
1867 /**
1868  * options_incompatible_with:
1869  * @opt: option flags to be tested.
1870  * @base: "base" option.
1871  * @test: bitwise OR of flags that are incompatible with @base.
1872  *
1873  * Returns: %E_BADOPT if @opt contains both @base and one or more of
1874  * the flags in @test, otherwise 0.
1875  */
1876 
options_incompatible_with(gretlopt opt,gretlopt base,gretlopt test)1877 int options_incompatible_with (gretlopt opt, gretlopt base,
1878                                gretlopt test)
1879 {
1880     if (opt & base) {
1881         if (opt & test) {
1882             return E_BADOPT;
1883         }
1884     }
1885 
1886     return 0;
1887 }
1888 
1889 /**
1890  * option_prereq_missing:
1891  * @opt: option flags to be tested.
1892  * @test: bitwise OR of flags that have a definite prequisite.
1893  * @prereq: bitwise OR of prerequisite flags.
1894  *
1895  * Returns: %E_BADOPT if @opt contains at least one element of
1896  * @test but no elements of @prereq, otherwise 0.
1897  */
1898 
option_prereq_missing(gretlopt opt,gretlopt test,gretlopt prereq)1899 int option_prereq_missing (gretlopt opt, gretlopt test,
1900                            gretlopt prereq)
1901 {
1902     if (opt & test) {
1903         if (!(opt & prereq)) {
1904             return E_BADOPT;
1905         }
1906     }
1907 
1908     return 0;
1909 }
1910 
1911 /**
1912  * inapplicable_option_error:
1913  * @ci: command index.
1914  * @opt: bad option flag.
1915  *
1916  * Flags an error: to be used when @opt is not applicable
1917  * for command @ci, in context.
1918  *
1919  * Returns: %E_BADOPT.
1920  */
1921 
inapplicable_option_error(int ci,gretlopt opt)1922 int inapplicable_option_error (int ci, gretlopt opt)
1923 {
1924     const char *s = print_flags(opt, ci);
1925 
1926     gretl_errmsg_sprintf(_("%s: inapplicable option"), s);
1927     return E_BADOPT;
1928 }
1929 
debug_print_option_flags(const char * msg,gretlopt opt)1930 void debug_print_option_flags (const char *msg, gretlopt opt)
1931 {
1932     if (msg != NULL && *msg != '\0') {
1933         fprintf(stderr, "%s: ", msg);
1934     }
1935 
1936     if (opt == 0) {
1937         fprintf(stderr, "opt=0\n");
1938     } else {
1939         char c = 'A';
1940         int i, started = 0;
1941 
1942         fprintf(stderr, "opt=%d (", opt);
1943 
1944         for (i=OPT_A; i<=OPT_Y; i*=2) {
1945             if (opt & i) {
1946                 if (started) {
1947                     fputc('|', stderr);
1948                 }
1949                 fprintf(stderr, "OPT_%c", c);
1950                 started = 1;
1951             }
1952             c++;
1953         }
1954 
1955         fputs(")\n", stderr);
1956     }
1957 }
1958