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 "--first_section_level",
146 "--ignore_case_when_linking",
153 "--test", /* Special output mode for testing */
157 "--no_subdirectories",
172 "--verbal", /*FS TODO */
173 "--ms_errors", /* TODO is this documented?? */
179 "--syntaxcolors_enable",
190 /****v* UserInterface/option_tests
192 * A linked lists of tests that check the options specified
196 static struct RB_Option_Test *option_tests = NULL;
201 /****f* UserInterface/Add_Option_Test
203 * Add a test to the linked list of options tests.
206 static void Add_Option_Test(
207 struct RB_Option_Test *option_test )
210 * option_test -- the test to be added.
214 option_test->next = option_tests;
215 option_tests = option_test;
220 /****f* UserInterface/Add_Option_Name
222 * Add the name of an option to the group of option names an option
226 static void Add_Option_Name(
227 struct RB_Option_Test *option_test,
231 * option_test -- the option test
232 * name -- the name of the option
236 struct RB_Option_Name *new_option_name =
237 malloc( sizeof( struct RB_Option_Name ) );
238 new_option_name->name = RB_StrDup( name );
239 new_option_name->next = option_test->option_group;
240 new_option_name->count = 0;
241 option_test->option_group = new_option_name;
246 /****f* UserInterface/Create_New_Option_Test
248 * Allocate and initialize a new option test.
251 static struct RB_Option_Test *Create_New_Option_Test(
252 Option_Test_Kind kind,
253 Option_Error_Severity severity )
256 * kind -- the kind of test that has to be created.
260 struct RB_Option_Test *new_option_test =
261 malloc( sizeof( struct RB_Option_Test ) );
262 new_option_test->next = NULL;
263 new_option_test->option_group = NULL;
264 new_option_test->kind = kind;
265 new_option_test->severity = severity;
266 return new_option_test;
271 /****f* UserInterface/Create_Test_Data
273 * Create a linked list of tests.
276 static void Create_Test_Data(
280 * Generate this code automatically from a set
281 * of high-level specifications.
285 struct RB_Option_Test *cur_option_test = NULL;
289 Create_New_Option_Test( TEST_MUTUAL_EXCLUDE, OPTION_FATAL );
290 Add_Option_Name( cur_option_test, "--singledoc" );
291 Add_Option_Name( cur_option_test, "--multidoc" );
292 Add_Option_Name( cur_option_test, "--singlefile" );
293 Add_Option_Test( cur_option_test );
296 Create_New_Option_Test( TEST_MUTUAL_EXCLUDE, OPTION_FATAL );
297 Add_Option_Name( cur_option_test, "--html" );
298 Add_Option_Name( cur_option_test, "--rtf" );
299 Add_Option_Name( cur_option_test, "--ascii" );
300 Add_Option_Name( cur_option_test, "--dbxml" );
301 Add_Option_Name( cur_option_test, "--troff" );
302 Add_Option_Name( cur_option_test, "--latex" );
303 Add_Option_Name( cur_option_test, "--test" );
304 Add_Option_Test( cur_option_test );
306 /* Order is important here */
307 cur_option_test = Create_New_Option_Test( TEST_COUNT, OPTION_FATAL );
308 for ( i = 0; ok_options[i]; i++ )
310 Add_Option_Name( cur_option_test, ok_options[i] );
312 Add_Option_Test( cur_option_test );
318 static int Do_Count_Test(
319 struct RB_Option_Test *cur_option_test )
321 unsigned int parameter_nr = 0;
322 int result = EXIT_SUCCESS;
323 struct RB_Option_Name *option_name;
325 assert( cur_option_test );
327 for ( parameter_nr = 0;
328 parameter_nr < configuration.options.number; parameter_nr++ )
330 for ( option_name = cur_option_test->option_group;
331 option_name; option_name = option_name->next )
334 ( configuration.options.names[parameter_nr],
335 option_name->name ) == 0 )
337 ( option_name->count )++;
342 for ( option_name = cur_option_test->option_group;
343 option_name; option_name = option_name->next )
345 if ( option_name->count > 1 )
347 fprintf( stderr, "The option %s is used more than once.\n",
349 result = EXIT_FAILURE;
357 /****f* UserInterface/Do_Mutual_Exlcude_Test
359 * Check all the options to see if combinations of options
360 * are used that mutually exclude each other, such as
361 * --singledoc and --multidoc.
364 static int Do_Mutual_Exlcude_Test(
365 struct RB_Option_Test *cur_option_test )
368 * * cur_option_test -- the test to be carried out.
373 unsigned int parameter_nr = 0;
374 int result = EXIT_SUCCESS;
376 assert( cur_option_test );
378 for ( parameter_nr = 0;
379 parameter_nr < configuration.options.number; parameter_nr++ )
381 struct RB_Option_Name *option_name = cur_option_test->option_group;
383 for ( ; option_name; option_name = option_name->next )
386 ( configuration.options.names[parameter_nr],
387 option_name->name ) == 0 )
394 /* Only one of the options in the group may be used */
397 fprintf( stderr, "The options: " );
398 for ( parameter_nr = 0;
399 parameter_nr < configuration.options.number; parameter_nr++ )
401 struct RB_Option_Name *option_name =
402 cur_option_test->option_group;
403 for ( ; option_name; option_name = option_name->next )
406 ( configuration.options.names[parameter_nr],
407 option_name->name ) == 0 )
410 fprintf( stderr, "%s ",
411 configuration.options.names[parameter_nr] );
415 fprintf( stderr, "cannot be used together.\n" );
416 result = EXIT_FAILURE;
425 /****f* UserInterface/Do_Option_Tests
427 * Run a series of tests on the options that the user
428 * specified. These tests are specified in
432 static int Do_Option_Tests(
436 * * EXIT_FAILURE -- one of the tests failed.
437 * * EXIT_SUCCESS -- all test completed successfully
441 struct RB_Option_Test *cur_option_test = NULL;
442 int result = EXIT_SUCCESS;
443 int final_result = EXIT_SUCCESS;
445 RB_Say( "Checking the option semantics.\n", SAY_INFO );
447 cur_option_test = option_tests;
449 assert( cur_option_test );
451 for ( ; cur_option_test; cur_option_test = cur_option_test->next )
453 switch ( cur_option_test->kind )
455 case TEST_MUTUAL_EXCLUDE:
456 RB_Say( "Checking for mutual excluding options.\n", SAY_INFO );
457 result = Do_Mutual_Exlcude_Test( cur_option_test );
459 case TEST_COUNT: /* TODO Create */
460 RB_Say( "Checking for duplicate options.\n", SAY_INFO );
461 result = Do_Count_Test( cur_option_test );
463 case TEST_SHOULD_EXISTS: /* TODO Create */
464 case TEST_NO_EFFECT: /* TODO Create */
465 case TEST_SPELLING: /* TODO Create */
469 /* If one of the tests fails the final result is a fail. */
470 if ( result == EXIT_FAILURE )
472 final_result = EXIT_FAILURE;
473 if ( cur_option_test->severity == OPTION_FATAL )
485 /****f* UserInterface/Check_Option_Spelling
487 * Check for misspelled options specified by the user.
491 int Check_Option_Spelling(
495 * * EXIT_SUCCESS -- all options are correctly spelled.
496 * * EXIT_FAILURE -- one of more options are misspelled.
503 unsigned int parameter_nr;
505 RB_Say( "Checking the option syntax.\n", SAY_INFO );
506 for ( parameter_nr = 0;
507 parameter_nr < configuration.options.number; parameter_nr++ )
509 arg = configuration.options.names[parameter_nr];
510 if ( ( arg[0] == '-' ) && ( arg[1] == '-' ) )
512 /* this arg is an option */
517 if ( strcmp( arg, *opts ) == 0 )
526 fprintf( stderr, "Invalid argument: %s\n", arg );
528 "This might also be in your robodoc.rc file\n" );
539 static int Check_Item_Names(
540 struct Parameters *arg_parameters,
543 unsigned int parameter_nr_1;
544 unsigned int parameter_nr_2;
545 int name_is_ok = TRUE;
547 RB_Say( "Checking the item names for %s block.\n", SAY_INFO, block_name );
548 for ( parameter_nr_1 = 0;
549 parameter_nr_1 < arg_parameters->number; parameter_nr_1++ )
552 for ( parameter_nr_2 = 0;
553 parameter_nr_2 < configuration.items.number; parameter_nr_2++ )
555 if ( strcmp( configuration.items.names[parameter_nr_2],
556 arg_parameters->names[parameter_nr_1] ) == 0 )
563 RB_Say( "!! block.\n", SAY_INFO );
564 fprintf( stderr, "Unknown item %s found in the\n",
565 arg_parameters->names[parameter_nr_1] );
566 fprintf( stderr, " %s block\nof your configuration file.\n",
572 RB_Say( "Is %d block.\n", SAY_INFO, name_is_ok );
576 /****f* UserInterface/Check_Item_Options
578 * Check the validity of the item options. Users can specify their
579 * own items, item order, and items that ar to be ignored. This all
580 * should be consistent.
583 static int Check_Item_Options(
587 * * EXIT_SUCCESS -- all options are correct.
588 * * EXIT_FAILURE -- one of more options incorrect.
595 RB_Say( "Checking the item names.\n", SAY_INFO );
597 && Check_Item_Names( &( configuration.ignore_items ),
599 item_OK = item_OK && result;
601 Check_Item_Names( &( configuration.source_items ), "source items:" );
602 item_OK = item_OK && result;
604 Check_Item_Names( &( configuration.preformatted_items ),
605 "preformatted items:" );
606 item_OK = item_OK && result;
608 Check_Item_Names( &( configuration.format_items ), "format items:" );
609 item_OK = item_OK && result;
610 result = Check_Item_Names( &( configuration.item_order ), "item order:" );
611 item_OK = item_OK && result;
625 /****f* UserInterface/Check_Options
627 * Check the validity of all the options in configuration.options[].
628 * This runs a number of checks.
636 * * EXIT_SUCCESS -- all options are correct.
637 * * EXIT_FAILURE -- one of more options incorrect.
643 RB_Say( "Checking the options.\n", SAY_INFO );
644 status = Check_Option_Spelling( );
645 if ( status == EXIT_SUCCESS )
647 status = Do_Option_Tests( );
648 if ( status == EXIT_SUCCESS )
650 status = Check_Item_Options( );
662 /* TODO free option_tests */