removal due to another working script
[trueprint.git] / src / options.c
blobab82a3b3a87fb35500c6aa694d9f3db409459b7f
1 /*
2 * Source file:
3 * options.c
4 */
6 #include "config.h"
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #ifdef HAVE_GETOPT_H
12 #include <getopt.h>
13 #else
14 #include "getopt.h"
15 #endif
17 extern int optind; /* undocumented variable used to reset getopt() */
19 #include "trueprint.h" /* needed for boolean type */
20 #include "utils.h" /* needed for strdup */
21 #include "debug.h" /* needed for dm macro */
23 #include "options.h"
25 /******************************************************************************
26 * Macros
29 /* If there are more than MAX_OPTIONS options then this must be increased */
30 #define MAX_OPTIONS 256
32 /* This must specify a bit outside the range of MAX_OPTIONS */
33 #define OPT_FLAG 0x1000
35 #define SHORT_OPTION(opt) (short_options[('A'<=opt&&opt<='Z')?(opt-'A')*2:\
36 ('a'<=opt&&opt<='z')?(opt-'a')*2+1:\
37 ('0'<=opt&&opt<='9')?opt-'0'+52:\
38 62])
40 #define PRINTUSAGE printf(gettext(" Usage: trueprint <options> <filename>\n Use -H for details\n"))
42 /******************************************************************************
43 * Typedefs
46 typedef enum {
47 NOPARM,
48 OPTIONAL,
49 BOOLEAN,
50 CHAR,
51 CHOICE,
52 SHORT,
53 INT,
54 STRING,
55 FLAG_STRING
56 } option_types;
58 typedef struct option_type{
59 char letter;
60 option_types type;
61 boolean set;
62 char need_string;
63 option_class class;
64 union {
65 struct {
66 char *string;
67 boolean default_opt;
68 void (*handler)(const char *p, const char *s);
69 void (*set_default)(void);
70 char *help_string;
71 } onoparm;
72 struct {
73 char *string;
74 void (*handler)(const char *p, const char *s, char *value);
75 char *help_string;
76 } ooptional;
77 struct {
78 char *true_string;
79 char *false_string;
80 boolean *var;
81 boolean default_value;
82 void (*handler)(const char *p, const char *s, boolean value);
83 void (*set_default)(boolean value);
84 char *true_help_string;
85 char *false_help_string;
86 } obool;
87 struct {
88 char *string;
89 char *var;
90 char default_value;
91 char *valid_set;
92 void (*handler)(const char *p, const char *s, char value, char *valid_set);
93 void (*set_default)(char value);
94 char *help_string;
95 } ochar;
96 struct {
97 char *var;
98 char *choice1_string;
99 char *choice2_string;
100 char choice1; /* Also default */
101 char choice2;
102 void (*handler)(const char *p, const char *s, char value);
103 void (*set_default)(char value);
104 char *choice1_help_string;
105 char *choice2_help_string;
106 } ochoice;
107 struct {
108 char *string;
109 short *var;
110 short default_value;
111 char *special_string;
112 short special_value;
113 short min;
114 short max;
115 void (*handler)(const char *p, const char *s, short value, short min, short max);
116 void (*set_default)(short value);
117 char *help_string;
118 char *special_help_string;
119 } oshrt;
120 struct {
121 char *string;
122 int *var;
123 int default_value;
124 char *special_string;
125 short special_value;
126 int min;
127 int max;
128 void (*handler)(const char *p, const char *s, int value, int min, int max);
129 void (*set_default)(int value);
130 char *help_string;
131 char *special_help_string;
132 } oint;
133 struct {
134 char *string;
135 char **var;
136 char *default_value;
137 void (*handler)(const char *p, const char *s, char *value);
138 void (*set_default)(char *value);
139 char *help_string;
140 } ostrng;
141 struct {
142 char *set_string;
143 char *not_set_string;
144 boolean flag_var;
145 char **var;
146 boolean default_value;
147 char *true_value;
148 char *false_value;
149 void (*handler)(const char *p, const char *s, boolean value, char *true_value, char *false_value);
150 void (*set_default)(boolean value, char *string_value);
151 char *set_help_string;
152 char *not_set_help_string;
153 } oflg;
154 } t;
155 } option_type;
157 /******************************************************************************
158 * Private functions
160 static void set_option(int option, char *prefix, const char *option_name, char *value);
161 static void set_option_default(int option);
163 /******************************************************************************
164 * Constant variables and data structures
167 static int short_options[62];
169 static struct option_type option_list[MAX_OPTIONS+1];
170 static struct option long_options[MAX_OPTIONS+1];
171 static int next_option;
172 static int next_long_option;
173 static int this_option;
175 /******************************************************************************
176 * Function:
177 * setup_options
179 void
180 setup_options(void)
182 next_option = 0;
183 next_long_option = 0;
186 /******************************************************************************
187 * Function:
188 * handle_string_options
190 * This function takes options as a single string, parses them into
191 * a char[][], and calls handle_options.
193 void
194 handle_string_options(char *options)
197 int opt_argc = -1;
198 char arguments[100][100];
199 char *opt_argv[100];
200 int options_index = -1;
201 int argv_index = 0;
202 boolean quoted = FALSE;
203 boolean ended = FALSE;
205 if (options == (char *)0) return;
206 if (strlen(options) == 0) return;
208 while (ended == FALSE)
210 switch (options[++options_index])
212 case ' ':
213 case ' ':
214 if (quoted)
216 if (argv_index == 0) opt_argc += 1;
217 arguments[opt_argc][argv_index++] = options[options_index];
218 continue;
220 if (argv_index > 0)
222 arguments[opt_argc][argv_index] = '\0';
223 argv_index = 0;
225 break;
227 case '\0':
228 if (argv_index > 0)
230 arguments[opt_argc][argv_index] = '\0';
231 argv_index = 0;
233 ended = TRUE;
234 break;
236 case '"':
237 if (quoted) quoted = FALSE;
238 else
239 quoted = TRUE;
240 break;
242 default:
243 if (argv_index == 0) opt_argc += 1;
244 arguments[opt_argc][argv_index++] = options[options_index];
245 break;
248 opt_argc += 1;
250 for (argv_index=0; argv_index < opt_argc; argv_index++)
251 opt_argv[argv_index+1] = arguments[argv_index];
253 opt_argv[0] = opt_argv[1];
254 opt_argc += 1;
256 handle_options(opt_argc, opt_argv);
257 return;
260 /******************************************************************************
261 * Function:
262 * handle_options
264 * This function handles the options passed to the program, and also
265 * the defaults for each language. Since the options passed to the
266 * program gake priority and are also found first, this function
267 * will only assign a value to a flag if the flag has not previously
268 * been set.
270 unsigned int
271 handle_options(int argc, char **argv)
274 int option;
275 int option_index;
276 int short_option_index = 0;
277 int long_option_index;
278 char short_option_list[125]; /* 125 = (26+26+10)*2 + 1 */
281 * Since this function will be called twice, we need to initialise
282 * getopt_long() variables to make sure that it behaves properly during
283 * the second call.
285 optind = 1;
288 * Set up the string of single-letter options and set the last long_option
289 * to all zeros - this will be done multiple times each time trueprint
290 * is invoked, but it's quick so it shouldn't hurt.
292 for (option_index = 0; option_index < next_long_option; option_index++)
294 if (option_list[option_index].letter)
296 short_option_list[short_option_index++] = option_list[option_index].letter;
297 if (option_list[option_index].need_string)
298 short_option_list[short_option_index++] = ':';
302 long_options[next_long_option].name = 0;
303 long_options[next_long_option].has_arg = 0;
304 long_options[next_long_option].flag = 0;
305 long_options[next_long_option].val = 0;
308 * Loop through the options. This call will set this_option
309 * to the option number if it is looking at a long option.
311 while ((option =
312 getopt_long((unsigned int)argc, argv,
313 short_option_list, long_options, &long_option_index)
314 ) != EOF)
316 if (option == '?')
318 fprintf(stderr, gettext(CMD_NAME ": failed to parse options\n"));
319 exit(1);
321 else if (option != 0)
323 char *option_name;
324 option_name = xmalloc(2);
325 option_name[0] = option;
326 option_name[1] = '\0';
327 option_index = SHORT_OPTION(option);
328 set_option(option_index,"-",option_name,optarg);
330 else
332 set_option(this_option, "--", long_options[long_option_index].name,optarg);
335 return(optind);
338 /******************************************************************************
339 * Option declaration functions
342 /******************************************************************************
343 * noparm_option
344 * -c
345 * --s
346 * Calls handler if used.
347 * Uses either single-letter option or string long option or both
349 void noparm_option(char *c, char *s,
350 boolean default_opt,
351 void (*handler)(const char *p, const char *s),
352 void (*set_default)(void),
353 option_class class,
354 char *help_string)
356 int option_index = next_option++;
358 if (s)
360 int long_option_index = next_long_option++;
361 long_options[long_option_index].name = s;
362 long_options[long_option_index].has_arg = 0;
363 long_options[long_option_index].flag = &this_option;
364 long_options[long_option_index].val = option_index;
368 * This checks for an internal error, so it is OK to
369 * risk an out-of-bounds access
370 * before checking for the bounds limit.
372 if ((next_option > MAX_OPTIONS) || (next_long_option > MAX_OPTIONS))
373 abort();
375 if (handler == NULL)
376 abort();
378 if (default_opt && set_default == NULL)
379 abort();
381 if (c)
383 option_list[option_index].letter = *c;
384 SHORT_OPTION(*c) = option_index;
386 else
387 option_list[option_index].letter = 0;
389 option_list[option_index].type = NOPARM;
390 option_list[option_index].class = class;
391 option_list[option_index].need_string = FALSE;
392 option_list[option_index].set = FALSE;
393 option_list[option_index].t.onoparm.string = s;
394 option_list[option_index].t.onoparm.default_opt = default_opt;
395 option_list[option_index].t.onoparm.handler = handler;
396 option_list[option_index].t.onoparm.set_default = set_default;
397 option_list[option_index].t.onoparm.help_string = help_string;
400 /******************************************************************************
401 * optional_string_option
402 * -c
403 * --s
404 * --s=[string]
405 * Note that only the long option has the optional string.
406 * Calls handler if used.
407 * Uses either single-letter option or string long option or both
409 void optional_string_option(char *c, char *s,
410 void (*handler)(const char *p, const char *s, char *value),
411 option_class class,
412 char *help_string)
414 int option_index = next_option++;
416 if (s)
418 int long_option_index = next_long_option++;
419 long_options[long_option_index].name = s;
420 long_options[long_option_index].has_arg = 2;
421 long_options[long_option_index].flag = &this_option;
422 long_options[long_option_index].val = option_index;
426 * This checks for an internal error, so it is OK to
427 * risk an out-of-bounds access
428 * before checking for the bounds limit.
430 if ((next_option > MAX_OPTIONS) || (next_long_option > MAX_OPTIONS))
431 abort();
433 if (handler == NULL)
434 abort();
436 if (c)
438 option_list[option_index].letter = *c;
439 SHORT_OPTION(*c) = option_index;
441 else
442 option_list[option_index].letter = 0;
444 option_list[option_index].type = OPTIONAL;
445 option_list[option_index].class = class;
446 option_list[option_index].need_string = FALSE;
447 option_list[option_index].set = FALSE;
448 option_list[option_index].t.ooptional.string = s;
449 option_list[option_index].t.ooptional.handler = handler;
450 option_list[option_index].t.ooptional.help_string = help_string;
453 /******************************************************************************
454 * boolean_option
455 * -c = set option to TRUE
456 * --c = set option to FALSE
457 * --s1 = set option to TRUE
458 * --s2 = set option to FALSE
460 void boolean_option(char *c, char *s1, char *s2,
461 boolean default_value,
462 boolean *var,
463 void (*handler)(const char *p, const char *s, boolean value),
464 void (*set_default)(boolean value),
465 option_class class,
466 char *true_help_string,
467 char *false_help_string)
469 int option_index = next_option++;
471 if (c)
473 int long_option_index = next_long_option++;
474 option_list[option_index].letter = *c;
475 SHORT_OPTION(*c) = option_index;
476 long_options[long_option_index].name = c;
477 long_options[long_option_index].has_arg = 0;
478 long_options[long_option_index].flag = &this_option;
479 long_options[long_option_index].val = option_index | OPT_FLAG;
481 else
482 option_list[option_index].letter = 0;
484 if (s1)
486 int long_option_index = next_long_option++;
487 long_options[long_option_index].name = s1;
488 long_options[long_option_index].has_arg = 0;
489 long_options[long_option_index].flag = &this_option;
490 long_options[long_option_index].val = option_index;
492 if (s2)
494 int long_option_index = next_long_option++;
495 long_options[long_option_index].name = s2;
496 long_options[long_option_index].has_arg = 0;
497 long_options[long_option_index].flag = &this_option;
498 long_options[long_option_index].val = option_index | OPT_FLAG;
501 if ((next_option > MAX_OPTIONS) || (next_long_option > MAX_OPTIONS))
502 abort();
503 if ((var == NULL) && (handler == NULL))
504 abort();
505 if ((var != NULL) && (handler != NULL))
506 abort();
507 if ((handler == NULL) != (set_default == NULL))
508 abort();
510 option_list[option_index].type = BOOLEAN;
511 option_list[option_index].class = class;
512 option_list[option_index].need_string = FALSE;
513 option_list[option_index].set = FALSE;
514 option_list[option_index].t.obool.true_string = s1;
515 option_list[option_index].t.obool.false_string = s2;
516 option_list[option_index].t.obool.var = var;
517 option_list[option_index].t.obool.default_value = default_value;
518 option_list[option_index].t.obool.handler = handler;
519 option_list[option_index].t.obool.set_default = set_default;
520 option_list[option_index].t.obool.true_help_string = true_help_string;
521 option_list[option_index].t.obool.false_help_string = false_help_string;
524 /******************************************************************************
525 * choice_option
526 * -c <letter>
527 * --s1
528 * --s2
530 void choice_option(char *c, char *s1, char *s2,
531 char choice1, char choice2,
532 char *var,
533 void (*handler)(const char *p, const char *s, char value),
534 void (*set_default)(char value),
535 option_class class,
536 char *choice1_help_string,
537 char *choice2_help_string)
539 int option_index = next_option++;
541 if (c)
543 option_list[option_index].letter = *c;
544 SHORT_OPTION(*c) = option_index;
546 else
547 option_list[option_index].letter = 0;
549 if (s1)
551 int long_option_index = next_long_option++;
552 long_options[long_option_index].name = s1;
553 long_options[long_option_index].has_arg = 0;
554 long_options[long_option_index].flag = &this_option;
555 long_options[long_option_index].val = option_index;
558 if (s2)
560 int long_option_index = next_long_option++;
561 long_options[long_option_index].name = s2;
562 long_options[long_option_index].has_arg = 0;
563 long_options[long_option_index].flag = &this_option;
564 long_options[long_option_index].val = option_index | OPT_FLAG;
567 if ((next_option > MAX_OPTIONS) || (next_long_option > MAX_OPTIONS))
568 abort();
569 if ((var == NULL) && (handler == NULL))
570 abort();
571 if ((var != NULL) && (handler != NULL))
572 abort();
573 if ((handler == NULL) != (set_default == NULL))
574 abort();
576 option_list[option_index].type = CHOICE;
577 option_list[option_index].class = class;
578 option_list[option_index].need_string = TRUE;
579 option_list[option_index].set = FALSE;
580 option_list[option_index].t.ochoice.var = var;
581 option_list[option_index].t.ochoice.choice1_string = s1;
582 option_list[option_index].t.ochoice.choice2_string = s2;
583 option_list[option_index].t.ochoice.choice1 = choice1;
584 option_list[option_index].t.ochoice.choice2 = choice2;
585 option_list[option_index].t.ochoice.handler = handler;
586 option_list[option_index].t.ochoice.set_default = set_default;
587 option_list[option_index].t.ochoice.choice1_help_string = choice1_help_string;
588 option_list[option_index].t.ochoice.choice2_help_string = choice2_help_string;
591 /******************************************************************************
592 * char_option
593 * -c <letter>
594 * --s <letter>
596 void char_option(char *c, char *s,
597 char default_value,
598 char *valid_set,
599 char *var,
600 void (*handler)(const char *p, const char *s, char value, char *var),
601 void (*set_default)(char value),
602 option_class class,
603 char *help_string)
605 int option_index = next_option++;
607 if (c)
609 option_list[option_index].letter = *c;
610 SHORT_OPTION(*c) = option_index;
612 else
613 option_list[option_index].letter = 0;
615 if (s)
617 int long_option_index = next_long_option++;
618 long_options[long_option_index].name = s;
619 long_options[long_option_index].has_arg = 1;
620 long_options[long_option_index].flag = &this_option;
621 long_options[long_option_index].val = option_index;
624 if ((next_option > MAX_OPTIONS) || (next_long_option > MAX_OPTIONS))
625 abort();
626 if ((var == NULL) && (handler == NULL))
627 abort();
628 if ((var != NULL) && (handler != NULL))
629 abort();
630 if ((handler == NULL) != (set_default == NULL))
631 abort();
633 option_list[option_index].type = CHAR;
634 option_list[option_index].class = class;
635 option_list[option_index].need_string = TRUE;
636 option_list[option_index].set = FALSE;
637 option_list[option_index].t.ochar.string = s;
638 option_list[option_index].t.ochar.var = var;
639 option_list[option_index].t.ochar.default_value = default_value;
640 option_list[option_index].t.ochar.valid_set = valid_set;
641 option_list[option_index].t.ochar.handler = handler;
642 option_list[option_index].t.ochar.set_default = set_default;
643 option_list[option_index].t.ochar.help_string = help_string;
646 /******************************************************************************
647 * short_option
648 * -c <short>
649 * --s <short>
651 void short_option(char *c, char *s, short default_value,
652 char *special_string, short special_value,
653 short min, short max,
654 short *var,
655 void (*handler)(const char *p, const char *s, short value, short min, short max),
656 void (*set_default)(short value),
657 option_class class,
658 char *help_string,
659 char *special_help_string)
661 int option_index = next_option++;
663 if (c)
665 option_list[option_index].letter = *c;
666 SHORT_OPTION(*c) = option_index;
668 else
669 option_list[option_index].letter = 0;
671 if (s)
673 int long_option_index = next_long_option++;
674 long_options[long_option_index].name = s;
675 long_options[long_option_index].has_arg = 1;
676 long_options[long_option_index].flag = &this_option;
677 long_options[long_option_index].val = option_index;
680 if (special_string)
682 int long_option_index = next_long_option++;
683 long_options[long_option_index].name = special_string;
684 long_options[long_option_index].has_arg = 0;
685 long_options[long_option_index].flag = &this_option;
686 long_options[long_option_index].val = option_index | OPT_FLAG;
689 if ((next_option > MAX_OPTIONS) || (next_long_option > MAX_OPTIONS))
690 abort();
691 if ((var == NULL) && (handler == NULL))
692 abort();
693 if ((var != NULL) && (handler != NULL))
694 abort();
695 if ((handler == NULL) != (set_default == NULL))
696 abort();
698 option_list[option_index].type = SHORT;
699 option_list[option_index].class = class;
700 option_list[option_index].need_string = TRUE;
701 option_list[option_index].set = FALSE;
702 option_list[option_index].t.oshrt.string = s;
703 option_list[option_index].t.oshrt.var = var;
704 option_list[option_index].t.oshrt.min = min;
705 option_list[option_index].t.oshrt.max = max;
706 option_list[option_index].t.oshrt.default_value = default_value;
707 option_list[option_index].t.oshrt.handler = handler;
708 option_list[option_index].t.oshrt.set_default = set_default;
709 option_list[option_index].t.oshrt.help_string = help_string;
710 option_list[option_index].t.oshrt.special_string = special_string;
711 option_list[option_index].t.oshrt.special_value = special_value;
712 option_list[option_index].t.oshrt.special_help_string = special_help_string;
715 /******************************************************************************
716 * int_option
717 * -c <short>
718 * --s <short>
721 void int_option(char *c, char *s, int default_value,
722 char *special_string, int special_value,
723 int min, int max,
724 int *var,
725 void (*handler)(const char *p, const char *s, int value, int min, int max),
726 void (*set_default)(int value),
727 option_class class,
728 char *help_string,
729 char *special_help_string)
731 int option_index = next_option++;
733 if (c)
735 option_list[option_index].letter = *c;
736 SHORT_OPTION(*c) = option_index;
738 else
739 option_list[option_index].letter = 0;
741 if (s)
743 int long_option_index = next_long_option++;
744 long_options[long_option_index].name = s;
745 long_options[long_option_index].has_arg = 1;
746 long_options[long_option_index].flag = &this_option;
747 long_options[long_option_index].val = option_index;
750 if (special_string)
752 int long_option_index = next_long_option++;
753 long_options[long_option_index].name = special_string;
754 long_options[long_option_index].has_arg = 0;
755 long_options[long_option_index].flag = &this_option;
756 long_options[long_option_index].val = option_index | OPT_FLAG;
759 if ((next_option > MAX_OPTIONS) || (next_long_option > MAX_OPTIONS))
760 abort();
761 if ((var == NULL) && (handler == NULL))
762 abort();
763 if ((var != NULL) && (handler != NULL))
764 abort();
765 if ((handler == NULL) != (set_default == NULL))
766 abort();
768 option_list[option_index].type = INT;
769 option_list[option_index].class = class;
770 option_list[option_index].need_string = TRUE;
771 option_list[option_index].set = FALSE;
772 option_list[option_index].t.oint.string = s;
773 option_list[option_index].t.oint.var = var;
774 option_list[option_index].t.oint.min = min;
775 option_list[option_index].t.oint.max = max;
776 option_list[option_index].t.oint.default_value = default_value;
777 option_list[option_index].t.oint.handler = handler;
778 option_list[option_index].t.oint.set_default = set_default;
779 option_list[option_index].t.oint.help_string = help_string;
780 option_list[option_index].t.oint.special_string = special_string;
781 option_list[option_index].t.oint.special_value = special_value;
782 option_list[option_index].t.oint.special_help_string = special_help_string;
785 /******************************************************************************
786 * string_option
787 * -c <string>
788 * --s <string>
790 void string_option(char *c, char *s,
791 char *default_value,
792 char **var,
793 void (*handler)(const char *p, const char *s, char *value),
794 void (*set_default)(char *value),
795 option_class class,
796 char *help_string)
798 int option_index = next_option++;
800 if (c)
802 option_list[option_index].letter = *c;
803 SHORT_OPTION(*c) = option_index;
805 else
806 option_list[option_index].letter = 0;
808 if (s)
810 int long_option_index = next_long_option++;
811 long_options[long_option_index].name = s;
812 long_options[long_option_index].has_arg = 1;
813 long_options[long_option_index].flag = &this_option;
814 long_options[long_option_index].val = option_index;
817 if ((var == NULL) && (handler == NULL))
818 abort();
819 if ((var != NULL) && (handler != NULL))
820 abort();
821 if ((handler == NULL) != (set_default == NULL))
822 abort();
824 option_list[option_index].type = STRING;
825 option_list[option_index].class = class;
826 option_list[option_index].need_string = TRUE;
827 option_list[option_index].set = FALSE;
828 option_list[option_index].t.ostrng.string = s;
829 option_list[option_index].t.ostrng.var = var;
830 option_list[option_index].t.ostrng.default_value = default_value;
831 option_list[option_index].t.ostrng.handler = handler;
832 option_list[option_index].t.ostrng.set_default = set_default;
833 option_list[option_index].t.ostrng.help_string = help_string;
836 /******************************************************************************
837 * flag_string_option
838 * -c <string>
839 * --c
840 * -s1 <string>
841 * --s2
843 void flag_string_option(char *c, char *s1, char *s2,
844 boolean default_value,
845 char *true_value, char *false_value,
846 char **var,
847 void (*handler)(const char *p, const char *s, boolean value, char *true_value, char *false_value),
848 void (*set_default)(boolean value, char *string_value),
849 option_class class,
850 char *set_help_string,
851 char *not_set_help_string)
853 int option_index = next_option++;
855 if (c)
857 option_list[option_index].letter = *c;
858 SHORT_OPTION(*c) = option_index;
860 else
861 option_list[option_index].letter = 0;
863 if (s1)
865 int long_option_index = next_long_option++;
866 long_options[long_option_index].name = s1;
867 long_options[long_option_index].has_arg = 1;
868 long_options[long_option_index].flag = &this_option;
869 long_options[long_option_index].val = option_index;
872 if (s2)
874 int long_option_index = next_long_option++;
875 long_options[long_option_index].name = s2;
876 long_options[long_option_index].has_arg = 0;
877 long_options[long_option_index].flag = &this_option;
878 long_options[long_option_index].val = option_index | OPT_FLAG;
881 if ((next_option > MAX_OPTIONS) || (next_long_option > MAX_OPTIONS))
882 abort();
883 if ((var == NULL) && (handler == NULL))
884 abort();
885 if ((var != NULL) && (handler != NULL))
886 abort();
887 if ((handler == NULL) != (set_default == NULL))
888 abort();
890 option_list[option_index].type = FLAG_STRING;
891 option_list[option_index].class = class;
892 option_list[option_index].need_string = FALSE;
893 option_list[option_index].set = FALSE;
894 option_list[option_index].t.oflg.var = var;
895 option_list[option_index].t.oflg.set_string = s1;
896 option_list[option_index].t.oflg.not_set_string = s2;
897 option_list[option_index].t.oflg.default_value = default_value;
898 option_list[option_index].t.oflg.true_value = true_value;
899 option_list[option_index].t.oflg.false_value = false_value;
900 option_list[option_index].t.oflg.handler = handler;
901 option_list[option_index].t.oflg.set_default = set_default;
902 option_list[option_index].t.oflg.set_help_string = set_help_string;
903 option_list[option_index].t.oflg.not_set_help_string = not_set_help_string;
906 /******************************************************************************
907 * set_option - sets the option
910 void set_option(int index, char *prefix, const char *option_name, char *value) {
911 boolean flag_set = ((index & OPT_FLAG) != 0);
912 struct option_type *op;
914 if (flag_set)
915 op = &option_list[index-OPT_FLAG];
916 else
917 op = &option_list[index];
919 if (value)
920 dm('o',3,"Trying to set option %s%s to %s\n", prefix, option_name, value);
921 else
922 dm('o',3,"Trying to set option %s%s\n", prefix, option_name);
924 if (op->set)
926 dm('o',3,"Option %s%s already set\n", prefix, option_name);
927 return;
930 switch (op->type)
933 case NOPARM:
934 (*(op->t.onoparm.handler))(prefix, option_name);
935 break;
937 case OPTIONAL:
938 (*(op->t.ooptional.handler))(prefix, option_name, value);
939 break;
941 case BOOLEAN:
942 if (op->t.obool.var)
944 *(op->t.obool.var) = (!flag_set);
946 else
948 (*(op->t.obool.handler))(prefix, option_name, !flag_set);
950 break;
952 case CHAR:
953 if (strlen(value) != 1)
955 fprintf(stderr, gettext(CMD_NAME ": must have one character parameter for %s%s flag, but got '%s'\n"),prefix,option_name,value);
956 exit(1);
958 /* TODO: Need to check that c is in valid_set */
959 if (op->t.ochar.var)
961 *(op->t.ochar.var) = *value;
963 else
965 (*(op->t.ochar.handler))(prefix, option_name, *value, op->t.ochar.valid_set);
967 break;
969 case CHOICE:
970 if (strlen(prefix) == 1)
972 /* This is a short option */
973 if (strlen(value) != 1)
975 fprintf(stderr, gettext(CMD_NAME ": must have one character parameter for %s%s flag, but got '%s'\n"),prefix,option_name,value);
976 exit(1);
979 if ((*value != op->t.ochoice.choice1) && (*value != op->t.ochoice.choice2))
981 fprintf(stderr, gettext(CMD_NAME ": option %s%s can only take %c or %c, not %c\n"),prefix,option_name,op->t.ochoice.choice1,op->t.ochoice.choice2,*value);
982 exit(1);
985 if (op->t.ochoice.var)
987 *(op->t.ochoice.var) = *value;
989 else
991 (*(op->t.ochoice.handler))(prefix, option_name, *value);
994 else
996 /* This is a long option */
997 char chosen_value;
998 if (strcmp(option_name,op->t.ochoice.choice1_string) == 0)
1000 /* First option selected */
1001 chosen_value = op->t.ochoice.choice1;
1003 else
1005 /* Second option selected */
1006 chosen_value = op->t.ochoice.choice2;
1009 if (op->t.ochoice.var)
1011 *(op->t.ochoice.var) = chosen_value;
1013 else
1015 (*(op->t.ochoice.handler))(prefix, option_name, chosen_value);
1019 break;
1021 case SHORT:
1022 if (flag_set)
1024 if (op->t.oshrt.var)
1026 *(op->t.oshrt.var) = op->t.oshrt.special_value;
1028 else
1030 (*(op->t.oshrt.handler))(prefix, option_name, op->t.oshrt.special_value, op->t.oshrt.min, op->t.oshrt.max);
1033 else
1035 int intvalue = atoi(value);
1036 if ((intvalue > op->t.oshrt.max) || (intvalue < op->t.oshrt.min))
1038 fprintf(stderr, gettext(CMD_NAME ": option %s%s not between %d and %d\n"),prefix,option_name,op->t.oshrt.min,op->t.oshrt.max);
1039 exit(1);
1042 if (op->t.oshrt.var)
1044 *(op->t.oshrt.var) = (short)intvalue;
1046 else
1048 (*(op->t.oshrt.handler))(prefix, option_name, (short)intvalue, op->t.oshrt.min, op->t.oshrt.max);
1051 break;
1053 case INT:
1054 if (flag_set)
1056 if (op->t.oint.var)
1058 *(op->t.oint.var) = op->t.oint.special_value;
1060 else
1062 (*(op->t.oint.handler))(prefix, option_name, op->t.oint.special_value, op->t.oint.min, op->t.oint.max);
1065 else
1067 int intvalue = atoi(value);
1068 if ((intvalue > op->t.oint.max) || (intvalue < op->t.oint.min))
1070 fprintf(stderr, gettext(CMD_NAME ": option %s%s not between %d and %d\n"),prefix,option_name,op->t.oint.min,op->t.oint.max);
1071 exit(1);
1073 if (op->t.oint.var)
1075 *(op->t.oint.var) = intvalue;
1077 else
1079 (*(op->t.oint.handler))(prefix, option_name, intvalue, op->t.oint.min, op->t.oint.max);
1082 break;
1084 case STRING:
1085 if (op->t.ostrng.var)
1087 *(op->t.ostrng.var) = strdup(value);
1089 else
1091 (*(op->t.ostrng.handler))(prefix, option_name, value);
1093 break;
1095 case FLAG_STRING:
1096 if (op->t.oflg.var)
1098 if (flag_set)
1100 if (op->t.oflg.true_value)
1102 *(op->t.oflg.var) = strdup(op->t.oflg.true_value);
1104 else
1106 *(op->t.oflg.var) = NULL;
1109 else
1111 if (op->t.oflg.false_value)
1113 *(op->t.oflg.var) = strdup(op->t.oflg.false_value);
1115 else
1117 *(op->t.oflg.var) = NULL;
1121 else
1123 (*(op->t.oflg.handler))(prefix, option_name, !flag_set, op->t.oflg.true_value, op->t.oflg.false_value);
1125 break;
1127 default:
1128 abort();
1131 op->set = TRUE;
1133 dm('o',3,"Succeeded - %s%s has not been set before\n",prefix,option_name);
1136 /******************************************************************************
1137 * Function:
1138 * set_option_default
1140 void set_option_default(int index)
1142 option_type *op = &option_list[index];
1144 dm('o',3,"Trying to set option %d to default value\n", index);
1146 if (op->set)
1148 dm('o',3,"Option %d already set\n", index);
1149 return;
1152 switch (op->type)
1155 case NOPARM:
1156 if (op->t.onoparm.default_opt)
1157 (*(op->t.onoparm.set_default))();
1158 break;
1160 case OPTIONAL:
1161 break;
1163 case BOOLEAN:
1164 if (op->t.obool.var)
1166 *(op->t.obool.var) = op->t.obool.default_value;
1168 else
1170 (*(op->t.obool.set_default))(op->t.obool.default_value);
1172 break;
1174 case CHAR:
1175 if (op->t.ochar.var)
1177 *(op->t.ochar.var) = op->t.ochar.default_value;
1179 else
1181 (*(op->t.ochar.set_default))(op->t.ochar.default_value);
1183 break;
1185 case CHOICE:
1186 if (op->t.ochoice.var)
1188 *(op->t.ochoice.var) = op->t.ochoice.choice1;
1190 else
1192 (*(op->t.ochoice.set_default))(op->t.ochoice.choice1);
1194 break;
1196 case SHORT:
1197 if (op->t.oshrt.var)
1199 *(op->t.oshrt.var) = op->t.oshrt.default_value;
1201 else
1203 (*(op->t.oshrt.set_default))(op->t.oshrt.default_value);
1205 break;
1207 case INT:
1208 if (op->t.oint.var)
1210 *(op->t.oint.var) = op->t.oint.default_value;
1212 else
1214 (*(op->t.oint.set_default))(op->t.oint.default_value);
1216 break;
1218 case STRING:
1219 if (op->t.ostrng.var)
1221 if (op->t.ostrng.default_value)
1223 *(op->t.ostrng.var) = strdup(op->t.ostrng.default_value);
1225 else
1227 *(op->t.ostrng.var) = NULL;
1230 else
1232 if (op->t.ostrng.default_value)
1234 (*(op->t.ostrng.set_default))(strdup(op->t.ostrng.default_value));
1236 else
1238 (*(op->t.ostrng.set_default))(NULL);
1241 break;
1243 case FLAG_STRING:
1244 if (op->t.oflg.var)
1246 if (op->t.oflg.default_value)
1248 if (op->t.oflg.true_value)
1250 *(op->t.oflg.var) = strdup(op->t.oflg.true_value);
1252 else
1254 *(op->t.oflg.var) = NULL;
1257 else
1259 if (op->t.oflg.false_value)
1261 *(op->t.oflg.var) = strdup(op->t.oflg.false_value);
1263 else
1265 *(op->t.oflg.var) = NULL;
1269 else
1271 if (op->t.oflg.default_value)
1273 if (op->t.oflg.true_value)
1275 (*(op->t.oflg.set_default))(1, strdup(op->t.oflg.true_value));
1277 else
1279 (*(op->t.oflg.set_default))(1, NULL);
1282 else
1284 if (op->t.oflg.false_value)
1286 (*(op->t.oflg.set_default))(0, strdup(op->t.oflg.false_value));
1288 else
1290 (*(op->t.oflg.set_default))(0, NULL);
1294 break;
1296 default:
1297 abort();
1300 dm('o',3,"Succeeded - option %d has not been set before\n",index);
1303 /******************************************************************************
1304 * Function:
1305 * print_usage_msgs
1307 void print_usage_msgs(option_class class)
1309 int option_index;
1311 switch (class){
1312 case OPT_MISC:
1313 printf(gettext("Miscellaneous options:\n"));
1314 break;
1315 case OPT_PAGE_FURNITURE:
1316 printf(gettext("Page furniture options:\n"));
1317 break;
1318 case OPT_TEXT_FORMAT:
1319 printf(gettext("Text formatting options:\n"));
1320 break;
1321 case OPT_PRINT:
1322 printf(gettext("Print selection options:\n"));
1323 break;
1324 case OPT_PAGE_FORMAT:
1325 printf(gettext("Page format options:\n"));
1326 break;
1327 case OPT_OUTPUT:
1328 printf(gettext("Output options:\n"));
1329 break;
1332 for (option_index=0; option_index < next_option; option_index++)
1334 option_type *op = &option_list[option_index];
1335 if (class == op->class)
1337 switch (op->type)
1339 case NOPARM:
1340 if (op->letter)
1341 printf("-%c ",op->letter);
1342 if (op->t.onoparm.string)
1343 printf("--%s",op->t.onoparm.string);
1344 printf("\n %s\n",gettext(op->t.onoparm.help_string));
1345 break;
1347 case OPTIONAL:
1348 if (op->letter)
1349 printf("-%c ",op->letter);
1350 if (op->t.ooptional.string)
1351 printf("--%s[=<string>]",op->t.ooptional.string);
1352 printf("\n %s\n",gettext(op->t.ooptional.help_string));
1353 break;
1355 case BOOLEAN:
1356 if (op->letter)
1357 printf("-%c ",op->letter);
1358 if (op->t.obool.true_string)
1359 printf("--%s",op->t.obool.true_string);
1360 printf("\n %s\n",gettext(op->t.obool.true_help_string));
1361 if (op->letter)
1362 printf("--%c ",op->letter);
1363 if (op->t.obool.false_string)
1364 printf("--%s",op->t.obool.false_string);
1365 printf("\n %s\n",gettext(op->t.obool.false_help_string));
1366 break;
1368 case CHAR:
1369 if (op->letter)
1370 printf("-%c <char> ",op->letter);
1371 if (op->t.ochar.string)
1372 printf("--%s <char>",op->t.ochar.string);
1373 printf("\n %s\n",gettext(op->t.ochar.help_string));
1374 break;
1376 case CHOICE:
1377 if (op->letter)
1378 printf("-%c %c ",op->letter,op->t.ochoice.choice1);
1379 if (op->t.ochoice.choice1_string)
1380 printf("--%s",op->t.ochoice.choice1_string);
1381 printf("\n %s\n",gettext(op->t.ochoice.choice1_help_string));
1382 if (op->letter)
1383 printf("-%c %c ",op->letter,op->t.ochoice.choice2);
1384 if (op->t.ochoice.choice2_string)
1385 printf("--%s",op->t.ochoice.choice2_string);
1386 printf("\n %s\n",gettext(op->t.ochoice.choice2_help_string));
1387 break;
1389 case SHORT:
1390 if (op->letter)
1391 printf("-%c <number> ",op->letter);
1392 if (op->t.oshrt.string)
1393 printf("--%s=<number>",op->t.oshrt.string);
1394 printf("\n %s\n",gettext(op->t.oshrt.help_string));
1395 if (op->t.oshrt.special_string)
1396 printf("--%s\n %s\n", op->t.oshrt.special_string, gettext(op->t.oshrt.special_help_string));
1397 break;
1399 case INT:
1400 if (op->letter)
1401 printf("-%c <number> ",op->letter);
1402 if (op->t.oint.string)
1403 printf("--%s=<number>",op->t.oint.string);
1404 printf("\n %s\n",gettext(op->t.oint.help_string));
1405 if (op->t.oint.special_string)
1406 printf("--%s\n %s\n", op->t.oint.special_string, gettext(op->t.oint.special_help_string));
1407 break;
1409 case STRING:
1410 if (op->letter)
1411 printf("-%c <string> ",op->letter);
1412 if (op->t.ostrng.string)
1413 printf("--%s=<string>",op->t.ostrng.string);
1414 printf("\n %s\n",gettext(op->t.ostrng.help_string));
1415 break;
1417 case FLAG_STRING:
1418 if (op->letter)
1419 printf("-%c <string> ",op->letter);
1420 if (op->t.oflg.set_string)
1421 printf("--%s=<string>",op->t.oflg.set_string);
1422 printf("\n %s\n",gettext(op->t.oflg.set_help_string));
1423 if (op->letter)
1424 printf("--%c ",op->letter);
1425 if (op->t.oflg.set_string)
1426 printf("--%s",op->t.oflg.not_set_string);
1427 printf("\n %s\n",gettext(op->t.oflg.not_set_help_string));
1433 /******************************************************************************
1434 * Function:
1435 * set_option_defaults
1437 void set_option_defaults(void)
1439 int option_index;
1441 for (option_index=0; option_index < next_option; option_index++)
1443 set_option_default(option_index);