diff --git a/src/dbStatic/dbLex.l b/src/dbStatic/dbLex.l index d7e530dd0..da252e57f 100644 --- a/src/dbStatic/dbLex.l +++ b/src/dbStatic/dbLex.l @@ -1,16 +1,20 @@ /*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found +* EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ -name [a-zA-Z0-9_\-:\.\[\]<>;] -notquote [^\"] -escapequote \\\" -string {notquote}|{escapequote} +newline "\n" +backslash "\\" +doublequote "\"" +comment "#" +whitespace [ \t\r\n] +escape {backslash}. +stringchar [^\"\n\\] +bareword [a-zA-Z0-9_\-+:.\[\]<>;] + %{ #undef YY_INPUT #define YY_INPUT(b,r,ms) (r=(*db_yyinput)((char *)b,ms)) @@ -42,23 +46,12 @@ static int yyreset(void) "function" return(tokenFUNCTION); "variable" return(tokenVARIABLE); -[0-9]+ { /*integer number*/ +{bareword}+ { /* unquoted string or number */ yylval.Str = dbmfStrdup(yytext); return(tokenSTRING); } --?(([0-9]+)|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) { /*real number*/ - yylval.Str = dbmfStrdup(yytext); - return(tokenSTRING); -} - - -{name}+ { /*unquoted string*/ - yylval.Str = dbmfStrdup(yytext); - return(tokenSTRING); -} - -\"{string}*\" { /*quoted string*/ +{doublequote}({stringchar}|{escape})*{doublequote} { /* quoted string */ yylval.Str = dbmfStrdup(yytext+1); yylval.Str[strlen(yylval.Str)-1] = '\0'; return(tokenSTRING); @@ -74,15 +67,18 @@ static int yyreset(void) "(" return(yytext[0]); ")" return(yytext[0]); "," return(yytext[0]); -\#.* ; -[ \t\r] ; -\n ; +{comment}.* ; +{whitespace} ; -. { - char message[20]; +{doublequote}({stringchar}|{escape})*{newline} { /* bad string */ + yyerror("Newline in string, closing quote missing"); +} + +. { + char message[40]; YY_BUFFER_STATE *dummy=0; - sprintf(message,"invalid character '%c'",yytext[0]); + sprintf(message,"Invalid character '%c'",yytext[0]); yyerror(message); /*The following suppresses compiler warning messages*/ if(FALSE) yyunput('c',(unsigned char *) message); diff --git a/src/dbStatic/dbLexRoutines.c b/src/dbStatic/dbLexRoutines.c index f2800aeb7..4b89c9056 100644 --- a/src/dbStatic/dbLexRoutines.c +++ b/src/dbStatic/dbLexRoutines.c @@ -347,22 +347,18 @@ static void dbIncludePrint(FILE *fp) { inputFile *pinputFile = pinputFileNow; - fprintf(fp,"input line: %s",my_buffer); - while(pinputFile) { - if(pinputFile->filename) { - fprintf(fp," in:"); - if(pinputFile->path) - fprintf(fp," path \"%s\" ",pinputFile->path); - fprintf(fp," file %s",pinputFile->filename); + while (pinputFile) { + fprintf(fp, " in"); + if (pinputFile->path) + fprintf(fp, " path \"%s\" ",pinputFile->path); + if (pinputFile->filename) { + fprintf(fp, " file %s",pinputFile->filename); } else { - fprintf(fp,"stdin:"); - if(pinputFile->path) - fprintf(fp," path \"%s\" ",pinputFile->path); + fprintf(fp, " standard input"); } - fprintf(fp," line %d\n",pinputFile->line_num); + fprintf(fp, " line %d\n",pinputFile->line_num); pinputFile = (inputFile *)ellPrevious(&pinputFile->node); } - fprintf(fp,"\n"); return; } @@ -950,6 +946,7 @@ static void dbRecordField(char *name,char *value) yyerror(NULL); return; } + dbTranslateEscape(value, value); /* yuck: in-place, but safe */ status = dbPutString(pdbentry,value); if(status) { errMessage(status,"dbPutString"); diff --git a/src/dbStatic/dbStaticLib.c b/src/dbStatic/dbStaticLib.c index 28c4cabcc..3d4166698 100644 --- a/src/dbStatic/dbStaticLib.c +++ b/src/dbStatic/dbStaticLib.c @@ -31,6 +31,7 @@ #include "postfix.h" #include "osiFileName.h" #include "epicsStdlib.h" +#include "epicsString.h" #include "epicsStdioRedirect.h" #define epicsExportSharedSymbols @@ -925,15 +926,17 @@ long epicsShareAPI dbWriteRecordFP( dbGetRecordTypeName(pdbentry),dbGetRecordName(pdbentry)); status = dbFirstField(pdbentry,dctonly); while(!status) { - if(!dbIsDefaultValue(pdbentry) || level>0) { + if (!dbIsDefaultValue(pdbentry) || level>0) { char *pvalstring = dbGetString(pdbentry); - if(!pvalstring) { + if (!pvalstring) { fprintf(fp,"\tfield(%s,\"\")\n", dbGetFieldName(pdbentry)); } else { - fprintf(fp,"\tfield(%s,\"%s\")\n", - dbGetFieldName(pdbentry),dbGetString(pdbentry)); + fprintf(fp,"\tfield(%s,\"", + dbGetFieldName(pdbentry)); + epicsStrPrintEscaped(fp,pvalstring,strlen(pvalstring)); + fprintf(fp,"\")\n"); } } else if(level>0) { /*generate 0 length string*/ fprintf(fp,"\tfield(%s,\"\")\n",dbGetFieldName(pdbentry)); diff --git a/src/dbStatic/dbYacc.y b/src/dbStatic/dbYacc.y index fe882ae48..9ed514237 100644 --- a/src/dbStatic/dbYacc.y +++ b/src/dbStatic/dbYacc.y @@ -247,9 +247,11 @@ record_field: tokenFIELD '(' tokenSTRING ',' tokenSTRING ')' static int yyerror(char *str) { - fprintf(stderr,"Error "); - if(str) fprintf(stderr,"\"%s\"",str); - fprintf(stderr," Last token \"%s\"\n",yytext); + if (str) + fprintf(stderr, "Error: %s\n", str); + else + fprintf(stderr,"Error.\n"); + fprintf(stderr,"Parsing '%s'\n", yytext); dbIncludePrint(stderr); yyFailed = TRUE; return(0);