diff --git a/src/parser.y b/src/parser.y index 781626b..ad01666 100644 --- a/src/parser.y +++ b/src/parser.y @@ -22,6 +22,8 @@ #include "tac.h" #include "error.h" #include "list.h" +#include "string.h" +#include "switches.h" struct tacnode* spdltac; @@ -65,6 +67,8 @@ List findMacroDefinition(Symbol s) } %token ID +%token TEXT + %token PROTOCOL %token ROLE %token READT @@ -85,9 +89,10 @@ List findMacroDefinition(Symbol s) %token HASHFUNCTION %token KNOWS %token TRUSTED +%token OPTION +%token MACRO %token MATCH %token NOT -%token MACRO %type spdlcomplete %type spdlrep @@ -109,6 +114,7 @@ List findMacroDefinition(Symbol s) %type roleref %type knowsdecl %type macrodecl +%type options %type singular @@ -161,6 +167,18 @@ spdl : UNTRUSTED termlist ';' { $$ = $1; } + | options + { + $$ = $1; + } + ; + +options : OPTION TEXT optclosing + { + // Process 'option' as command-line options. + process_switch_buffer($2); + $$ = NULL; + } ; roles : /* empty */ diff --git a/src/scanner.l b/src/scanner.l index 71ab075..5e77e3c 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -178,6 +178,23 @@ function { return FUNCTION; } hashfunction { return HASHFUNCTION; } knows { return KNOWS; } trusted { return TRUSTED; } +option { return OPTION; } +{text} { + if (strlen(yytext) >= 2) + { + // Make a copy without the surrounding + // double-quotes. + // TODO: Allow to unescape quotes inside string if + // needed later. + yylval.str = strndup(yytext+1,strlen(yytext)-2); + } + else + { + // If only one character, then simply copy + yylval.str = strdup(yytext); + } + return TEXT; + } {id} { yylval.symb = mkstring(yytext); return ID; diff --git a/src/switches.c b/src/switches.c index 0403009..b0b21da 100644 --- a/src/switches.c +++ b/src/switches.c @@ -48,7 +48,7 @@ char *lastfoundprefix = NULL; // Forward declarations void process_environment (void); -void process_switches (int commandline); +int process_switches (int commandline); //! Init switches /** @@ -1556,42 +1556,51 @@ switcher (const int process, int index, int commandline) } // If the option is not recognized, it means a file name. - if (!process) + // But we only consider this for the command line + if (commandline) { - helptext ("FILE", "input file ('-' for stdin)"); - } - else - { - if (!strcmp (this_arg, "-") && commandline) + if (!process) { - // '-' input: Leave input to stdin + helptext ("FILE", "input file ('-' for stdin)"); } else { - // not '-' input: change stdin to come from this file - if (!openFileStdin (this_arg)) + if (!strcmp (this_arg, "-")) { - // The file was not found. We have two options... - if (this_arg[0] == '-') - { - printfstderr ("Unknown switch '%s'.\n", this_arg); - } - else - { - printfstderr ("Could not open input file '%s'.\n", - this_arg); - } - exit (1); + // '-' input: Leave input to stdin + } + else + { + // not '-' input: change stdin to come from this file + if (!openFileStdin (this_arg)) + { + // The file was not found. We have two options... + if (this_arg[0] == '-') + { + printfstderr ("Unknown switch '%s'.\n", this_arg); + } + else + { + printfstderr ("Could not open input file '%s'.\n", + this_arg); + } + exit (1); + } + return index + 1; } - return index + 1; } } + else + { + // Unrecognized option. + error ("Could not parse argument \"%s\".\n", this_arg); + } // Now show the environment variables if (!process) { printf - ("\nThere are two environment variables that influence the behaviour of Scyther.\n"); + ("\nThere are two environment variables that influence the behaviour of the Scyther command-line tool.\n"); printf (" SCYTHERFLAGS Put any default command-line options here, syntax as on the command line.\n"); printf @@ -1603,22 +1612,22 @@ switcher (const int process, int index, int commandline) return 0; } -//! Process environment +//! Process a single buffer as a potential switch +/** + * This is a public function. It is used for the environment variables but also for the in-specification defines. + */ void -process_environment (void) +process_switch_buffer (char *buf) { - char *flags; - - flags = getenv ("SCYTHERFLAGS"); - if (flags != NULL) + if (buf != NULL) { int slen; - slen = strlen (flags); + slen = strlen (buf); if (slen > 0) { /** - * We scan the flags here, but assume a stupid upper limit of 100 pieces, otherwise this all becomes fairly vague. + * We scan the buf here, but assume a stupid upper limit of 100 pieces, otherwise this all becomes fairly vague. */ int max = 100; char *argv[100]; @@ -1629,7 +1638,7 @@ process_environment (void) /* make a safe copy */ args = (char *) malloc (slen + 1); - memcpy (args, flags, slen + 1); + memcpy (args, buf, slen + 1); /* warning */ /* @@ -1678,8 +1687,26 @@ process_environment (void) } } -//! Process switches +//! Process environment void +process_environment (void) +{ + char *flags; + + flags = getenv ("SCYTHERFLAGS"); + process_switch_buffer (flags); +} + +//! Process switches +/** + * The 'commandline' boolean argument is set to true if called with input from the command line. + * If true: + * - Generate help info if empty + * - Accept input file argument + * + * Returns false if an error occurred. + */ +int process_switches (int commandline) { int index; @@ -1695,7 +1722,7 @@ process_switches (int commandline) } else { - return; + return true; } } @@ -1704,4 +1731,10 @@ process_switches (int commandline) { index = switcher (1, index, commandline); } + if (index < 0) + { + // An error occurred: return false. + return false; + } + return true; } diff --git a/src/switches.h b/src/switches.h index fffad75..fb56357 100644 --- a/src/switches.h +++ b/src/switches.h @@ -93,5 +93,6 @@ struct switchdata extern struct switchdata switches; //!< pointer to switchdata structure FILE *openFileSearch (char *filename, FILE * reopener); +void process_switch_buffer (char *buf); //!< Process buffer for switches #endif diff --git a/src/tac.h b/src/tac.h index c6145b9..0cbbaa0 100644 --- a/src/tac.h +++ b/src/tac.h @@ -41,6 +41,7 @@ enum tactypes TAC_FUNC, TAC_STRING, TAC_ROLE, + TAC_PROTOCOL, TAC_KNOWS, TAC_RUN,