2 Copyright (C) 1994-2007 Frans Slothouber, Jacco van Weert, Petteri Kettunen,
3 Bernd Koesling, Thomas Aglassinger, Anthon Pang, Stefan Kost, David Druffner,
4 Sasha Vasko, Kai Hofmann, Thierry Pierron, Friedrich Haase, and Gergely Budai.
6 This file is part of ROBODoc
8 ROBODoc is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 /* $Id: optioncheck.c,v 1.19 2007/07/10 19:13:52 gumpu Exp $*/
30 #include "optioncheck.h"
31 #include "roboconfig.h"
37 " robodoc --src <directory> --doc <directory> --multidoc [type] [options]\n"
38 " robodoc --src <directory> --doc <file> --singledoc [type] [options]\n"
39 " robodoc --src <file> --doc <file> --singlefile [type] [options]\n"
40 "\n" "Use robodoc --help for more information\n";
46 fprintf( stdout, "%s\n", short_use );
49 /****t* UserInterface/Option_Test_Kind
51 * Enumeration for the kind of tests that are carried out on the
52 * options that the user specifies.
58 TEST_MUTUAL_EXCLUDE = 1,
59 TEST_SHOULD_EXISTS, /* TODO Create this kind of test */
60 TEST_NO_EFFECT, /* TODO Create this kind of test */
61 TEST_COUNT, /* TODO Create this kind of test */
62 TEST_SPELLING /* TODO Create this kind of test */
71 } Option_Error_Severity;
73 /****s* UserInterface/RB_Option_Name
75 * Element in a list of option names.
76 * Used in a RB_Option_Test to specify to what
77 * options a test applies.
83 /* linked list administration */
84 struct RB_Option_Name *next;
85 /* name of the option */
87 /* use by the Count test */
93 /****s* UserInterface/RB_Option_Test
95 * A test specification for options. This
96 * stores information about the kind of test and
97 * the options it applies to, and the message that
98 * is given to the user.
102 struct RB_Option_Test
104 /* tests are stored in a linked list */
105 struct RB_Option_Test *next;
106 /* the group of options the test applies to. */
107 struct RB_Option_Name *option_group;
108 /* the kind of test */
109 Option_Test_Kind kind;
110 /* More information for the user */
111 char *more_information; /* TODO Fill and use */
113 Option_Error_Severity severity;
118 /****v* UserInterface/ok_options
120 * An list of all allowed command-line options. If you add any
121 * options add its name here too. This list is used to verify
122 * the options specified by the user.
126 static char *ok_options[] = {
137 "--doctype_location",
141 "--one_file_per_header",
142 "--module_index_menu",
144 "--first_section_level",
148 "--ignore_case_when_linking",
155 "--test", /* Special output mode for testing */
159 "--no_subdirectories",
174 "--verbal", /*FS TODO */
175 "--ms_errors", /* TODO is this documented?? */
181 "--syntaxcolors_enable",
194 /****v* UserInterface/option_tests
196 * A linked lists of tests that check the options specified
200 static struct RB_Option_Test *option_tests = NULL;
205 /****f* UserInterface/Add_Option_Test
207 * Add a test to the linked list of options tests.
210 static void Add_Option_Test(
211 struct RB_Option_Test *option_test )
214 * option_test -- the test to be added.
218 option_test->next = option_tests;
219 option_tests = option_test;
224 /****f* UserInterface/Add_Option_Name
226 * Add the name of an option to the group of option names an option
230 static void Add_Option_Name(
231 struct RB_Option_Test *option_test,
235 * option_test -- the option test
236 * name -- the name of the option
240 struct RB_Option_Name *new_option_name =
241 malloc( sizeof( struct RB_Option_Name ) );
242 new_option_name->name = RB_StrDup( name );
243 new_option_name->next = option_test->option_group;
244 new_option_name->count = 0;
245 option_test->option_group = new_option_name;
250 /****f* UserInterface/Create_New_Option_Test
252 * Allocate and initialize a new option test.
255 static struct RB_Option_Test *Create_New_Option_Test(
256 Option_Test_Kind kind,
257 Option_Error_Severity severity )
260 * kind -- the kind of test that has to be created.
264 struct RB_Option_Test *new_option_test =
265 malloc( sizeof( struct RB_Option_Test ) );
266 new_option_test->next = NULL;
267 new_option_test->option_group = NULL;
268 new_option_test->kind = kind;
269 new_option_test->severity = severity;
270 return new_option_test;
275 /****f* UserInterface/Create_Test_Data
277 * Create a linked list of tests.
280 static void Create_Test_Data(
284 * Generate this code automatically from a set
285 * of high-level specifications.
289 struct RB_Option_Test *cur_option_test = NULL;
293 Create_New_Option_Test( TEST_MUTUAL_EXCLUDE, OPTION_FATAL );
294 Add_Option_Name( cur_option_test, "--singledoc" );
295 Add_Option_Name( cur_option_test, "--multidoc" );
296 Add_Option_Name( cur_option_test, "--singlefile" );
297 Add_Option_Test( cur_option_test );
300 Create_New_Option_Test( TEST_MUTUAL_EXCLUDE, OPTION_FATAL );
301 Add_Option_Name( cur_option_test, "--html" );
302 Add_Option_Name( cur_option_test, "--rtf" );
303 Add_Option_Name( cur_option_test, "--ascii" );
304 Add_Option_Name( cur_option_test, "--dbxml" );
305 Add_Option_Name( cur_option_test, "--troff" );
306 Add_Option_Name( cur_option_test, "--latex" );
307 Add_Option_Name( cur_option_test, "--test" );
308 Add_Option_Test( cur_option_test );
310 /* Order is important here */
311 cur_option_test = Create_New_Option_Test( TEST_COUNT, OPTION_FATAL );
312 for ( i = 0; ok_options[i]; i++ )
314 Add_Option_Name( cur_option_test, ok_options[i] );
316 Add_Option_Test( cur_option_test );
322 static int Do_Count_Test(
323 struct RB_Option_Test *cur_option_test )
325 unsigned int parameter_nr = 0;
326 int result = EXIT_SUCCESS;
327 struct RB_Option_Name *option_name;
329 assert( cur_option_test );
331 for ( parameter_nr = 0;
332 parameter_nr < configuration.options.number; parameter_nr++ )
334 for ( option_name = cur_option_test->option_group;
335 option_name; option_name = option_name->next )
338 ( configuration.options.names[parameter_nr],
339 option_name->name ) == 0 )
341 ( option_name->count )++;
346 for ( option_name = cur_option_test->option_group;
347 option_name; option_name = option_name->next )
349 if ( option_name->count > 1 )
351 fprintf( stderr, "The option %s is used more than once.\n",
353 result = EXIT_FAILURE;
361 /****f* UserInterface/Do_Mutual_Exlcude_Test
363 * Check all the options to see if combinations of options
364 * are used that mutually exclude each other, such as
365 * --singledoc and --multidoc.
368 static int Do_Mutual_Exlcude_Test(
369 struct RB_Option_Test *cur_option_test )
372 * * cur_option_test -- the test to be carried out.
377 unsigned int parameter_nr = 0;
378 int result = EXIT_SUCCESS;
380 assert( cur_option_test );
382 for ( parameter_nr = 0;
383 parameter_nr < configuration.options.number; parameter_nr++ )
385 struct RB_Option_Name *option_name = cur_option_test->option_group;
387 for ( ; option_name; option_name = option_name->next )
390 ( configuration.options.names[parameter_nr],
391 option_name->name ) == 0 )
398 /* Only one of the options in the group may be used */
401 fprintf( stderr, "The options: " );
402 for ( parameter_nr = 0;
403 parameter_nr < configuration.options.number; parameter_nr++ )
405 struct RB_Option_Name *option_name =
406 cur_option_test->option_group;
407 for ( ; option_name; option_name = option_name->next )
410 ( configuration.options.names[parameter_nr],
411 option_name->name ) == 0 )
414 fprintf( stderr, "%s ",
415 configuration.options.names[parameter_nr] );
419 fprintf( stderr, "cannot be used together.\n" );
420 result = EXIT_FAILURE;
429 /****f* UserInterface/Do_Option_Tests
431 * Run a series of tests on the options that the user
432 * specified. These tests are specified in
436 static int Do_Option_Tests(
440 * * EXIT_FAILURE -- one of the tests failed.
441 * * EXIT_SUCCESS -- all test completed successfully
445 struct RB_Option_Test *cur_option_test = NULL;
446 int result = EXIT_SUCCESS;
447 int final_result = EXIT_SUCCESS;
449 RB_Say( "Checking the option semantics.\n", SAY_INFO );
451 cur_option_test = option_tests;
453 assert( cur_option_test );
455 for ( ; cur_option_test; cur_option_test = cur_option_test->next )
457 switch ( cur_option_test->kind )
459 case TEST_MUTUAL_EXCLUDE:
460 RB_Say( "Checking for mutual excluding options.\n", SAY_INFO );
461 result = Do_Mutual_Exlcude_Test( cur_option_test );
463 case TEST_COUNT: /* TODO Create */
464 RB_Say( "Checking for duplicate options.\n", SAY_INFO );
465 result = Do_Count_Test( cur_option_test );
467 case TEST_SHOULD_EXISTS: /* TODO Create */
468 case TEST_NO_EFFECT: /* TODO Create */
469 case TEST_SPELLING: /* TODO Create */
473 /* If one of the tests fails the final result is a fail. */
474 if ( result == EXIT_FAILURE )
476 final_result = EXIT_FAILURE;
477 if ( cur_option_test->severity == OPTION_FATAL )
489 /****f* UserInterface/Check_Option_Spelling
491 * Check for misspelled options specified by the user.
495 int Check_Option_Spelling(
499 * * EXIT_SUCCESS -- all options are correctly spelled.
500 * * EXIT_FAILURE -- one of more options are misspelled.
507 unsigned int parameter_nr;
509 RB_Say( "Checking the option syntax.\n", SAY_INFO );
510 for ( parameter_nr = 0;
511 parameter_nr < configuration.options.number; parameter_nr++ )
513 arg = configuration.options.names[parameter_nr];
514 if ( ( arg[0] == '-' ) && ( arg[1] == '-' ) )
516 /* this arg is an option */
521 if ( strcmp( arg, *opts ) == 0 )
530 fprintf( stderr, "Invalid argument: %s\n", arg );
532 "This might also be in your robodoc.rc file\n" );
543 static int Check_Item_Names(
544 struct Parameters *arg_parameters,
547 unsigned int parameter_nr_1;
548 unsigned int parameter_nr_2;
549 int name_is_ok = TRUE;
551 RB_Say( "Checking the item names for %s block.\n", SAY_INFO, block_name );
552 for ( parameter_nr_1 = 0;
553 parameter_nr_1 < arg_parameters->number; parameter_nr_1++ )
556 for ( parameter_nr_2 = 0;
557 parameter_nr_2 < configuration.items.number; parameter_nr_2++ )
559 if ( strcmp( configuration.items.names[parameter_nr_2],
560 arg_parameters->names[parameter_nr_1] ) == 0 )
567 RB_Say( "!! block.\n", SAY_INFO );
568 fprintf( stderr, "Unknown item %s found in the\n",
569 arg_parameters->names[parameter_nr_1] );
570 fprintf( stderr, " %s block\nof your configuration file.\n",
576 RB_Say( "Is %d block.\n", SAY_INFO, name_is_ok );
580 /****f* UserInterface/Check_Item_Options
582 * Check the validity of the item options. Users can specify their
583 * own items, item order, and items that ar to be ignored. This all
584 * should be consistent.
587 static int Check_Item_Options(
591 * * EXIT_SUCCESS -- all options are correct.
592 * * EXIT_FAILURE -- one of more options incorrect.
599 RB_Say( "Checking the item names.\n", SAY_INFO );
601 && Check_Item_Names( &( configuration.ignore_items ),
603 item_OK = item_OK && result;
605 Check_Item_Names( &( configuration.source_items ), "source items:" );
606 item_OK = item_OK && result;
608 Check_Item_Names( &( configuration.preformatted_items ),
609 "preformatted items:" );
610 item_OK = item_OK && result;
612 Check_Item_Names( &( configuration.format_items ), "format items:" );
613 item_OK = item_OK && result;
614 result = Check_Item_Names( &( configuration.item_order ), "item order:" );
615 item_OK = item_OK && result;
629 /****f* UserInterface/Check_Options
631 * Check the validity of all the options in configuration.options[].
632 * This runs a number of checks.
640 * * EXIT_SUCCESS -- all options are correct.
641 * * EXIT_FAILURE -- one of more options incorrect.
647 RB_Say( "Checking the options.\n", SAY_INFO );
648 status = Check_Option_Spelling( );
649 if ( status == EXIT_SUCCESS )
651 status = Do_Option_Tests( );
652 if ( status == EXIT_SUCCESS )
654 status = Check_Item_Options( );
666 /* TODO free option_tests */