X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=userv.git;a=blobdiff_plain;f=lexer.l.m4;h=7be0be0d079322467b0cd9176c5439f132c4ed48;hp=2f360606017eb44ba2695832c90e79015f3d2f3e;hb=f53cd40f20431be077e96cb70e6dae9692276356;hpb=464d71c37246e556de9ec05f7b97af834a5224ee diff --git a/lexer.l.m4 b/lexer.l.m4 index 2f36060..7be0be0 100644 --- a/lexer.l.m4 +++ b/lexer.l.m4 @@ -1,7 +1,7 @@ dnl userv - lexer.l.m4 dnl lexer, passed through m4 with defs from langauge.i4 /* - * Copyright (C)1996-1997 Ian Jackson + * Copyright (C)1996-1997,1999 Ian Jackson * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by @@ -33,13 +33,16 @@ include(language.i4) #include #include #include +#include #include #include +#include #include "config.h" #include "common.h" #include "daemon.h" #include "lib.h" +#include "both.h" #include "tokens.h" #define HYPHEN '-' @@ -48,7 +51,7 @@ typedef int directive_fnt(int dtoken); static directive_fnt df_reject, df_execute, df_executefrompath; static directive_fnt df_executefromdirectory, df_executebuiltin; static directive_fnt df_errorstostderr, df_errorstosyslog, df_errorstofile; -static directive_fnt dfg_fdwant, dfg_setflag; +static directive_fnt dfg_fdwant, dfg_setflag, dfg_lookupquotemode; static directive_fnt df_reset, df_cd, df_userrcfile, df_include; static directive_fnt df_includelookup, df_includedirectory; static directive_fnt df_message, df_error, df_quit, df_eof; @@ -57,14 +60,17 @@ static directive_fnt dfi_includeuserrcfile, dfi_includeclientconfig; /* directive functions return: * 0 for success having scanned up to and including end of line but not beyond, * or tokv_error or tokv_quit. + * They expect to parse the whitespace before their parameters (if any). */ -typedef int parmcondition_fnt(int ctoken, char **parmvalues, int *rtrue); +typedef int parmcondition_fnt(int ctoken, char *const *parmvalues, int *rtrue); static parmcondition_fnt pcf_glob, pcf_range, pcf_grep; /* all conditional functions return tokv_error for failure or 0 for success * at parsing and testing, in which case *rtrue is set to 0 or 1. * On success they have scanned up to and including the condition's - * terminating newline. + * terminating newline; the pcf_... functions expect to parse the whitespace + * between the parameter name and the condition's arguments. + * Otherwise they return tokv_error. * The parameter-based conditionals take a list of parameter values * as obtained from the parameter functions and pa_parameter, * and do _not_ free it. @@ -108,6 +114,7 @@ static int lr_fdwant_readwrite; /* -1=never, 0=opt, 1=always */ struct parser_state { int lineno, reportlineno, notedreferer, isinternal; const char *filename; + struct stat filestab; YY_BUFFER_STATE ybuf; struct parser_state *upstate; }; @@ -116,7 +123,8 @@ static struct parser_state *cstate; struct error_handling { int handling; /* One of the error handling modes tokt_ehandlemode */ - int logfacility, loglevel, filekeep; + int logfacility, loglevel; + int filekeep; /* File is in use by higher-level errors-push, leave it open */ FILE *file; char *filename; }; @@ -124,9 +132,15 @@ struct error_handling { static struct error_handling eh = { tokv_word_errorstostderr, 0,0,0,0,0 }; static int dequote(char *inplace); +static void countnewlines(void); + +#define YY_NO_INPUT %} + %option noyywrap +%option nounput + %% dnl simple words @@ -141,47 +155,47 @@ changequote({*,*}) } [0-9]{1,8}-[0-9]{1,8} { char *ep; - lr_min=(int)strtoul(yytext,&ep,10); + lr_min= (int)strtoul(yytext,&ep,10); assert(*ep == HYPHEN); - assert(*++ep); - lr_max=(int)strtoul(ep,&ep,10); + ep++; assert(*ep); + lr_max= (int)strtoul(ep,&ep,10); assert(!*ep); - if (lr_max < lr_min) { - parseerrprint("fd range has min > max"); - return tokv_error; - } + if (lr_max < lr_min) + return parseerrprint("fd range has min > max"); return tokv_fdrange; } [0-9]{1,8}- { char *ep; lr_min= (int)strtoul(yytext,&ep,10); assert(*ep == HYPHEN); - assert(!*++ep); + ep++; assert(!*ep); lr_max=-1; return tokv_fdstoend; } -[\ \t]+ return tokv_lwsp; +([\ \t]*\\[\ \t]*\n[\ \t]*)+ countnewlines(); return tokv_lwsp; +[\ \t]+ return tokv_lwsp; [\ \t]*\n cstate->lineno++; return tokv_newline; [\ \t]*\#[^\n]*\n cstate->lineno++; return tokv_newline; -[\ \t]*\#[^\n]* { - parseerrprint("missing newline at eof after comment"); - return tokv_error; - } -[^\ \t\n]+ return tokv_barestring; -\"([^\\\"\n]|\\[a-z]|\\[0-9]{3}|\\x[0-9A-Fa-f]{2}|\\[:punct:]|\\[ \t]*\n)*\" { +[\ \t]*\#[^\n]* return parseerrprint("missing newline at eof after comment"); +\"([^\\\"\n]|\\[a-z]|\\[0-9]{3}|\\x[0-9A-Fa-f]{2}|\\[[:punct:]]|\\[ \t]*\n)*\" { + countnewlines(); return dequote(yytext); } -\".* { - parseerrprint("misquoted or unterminated string"); - return tokv_error; - } -<> return tokv_eof; +[^\ \t\n\\\"]+ return tokv_barestring; +<> return tokv_eof; +\" return parseerrprint("misquoted or unterminated string"); +\\ return parseerrprint("unexpected backslash"); +. abort(); /* expect lex warning "rule cannot be matched" */ *} changequote(`,') %% + +const char *const builtinservicehelpstrings[]= { +undivert(5)dnl + 0 +}; ` #include "parser.c" ' divert(-1) undivert -