Fix to Mantis #250, support escaped characters in record field values.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user