From 510027aa2cbe8d348af97a193bdd631bd3efab3b Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 14 Apr 2010 15:16:36 -0500 Subject: [PATCH] Reject field names that are reserved words. The list of reserved words is combined from C++ and the DB/DBD file parser. This also requires a small change in the rules for generating the C name from the DBD field name, since the aSub record has a field NOT; now if we find the lower-case version is reserved, we use the original instead. Since the aSubRecord.c file doesn't use prec->not this is back-compatible. --- src/dbHost/DBD/Base.pm | 24 +++++++++++++++++++++--- src/dbHost/DBD/Recfield.pm | 12 +++++++++++- src/dbHost/dbdToRecordtypeH.pl | 15 ++++++++------- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/dbHost/DBD/Base.pm b/src/dbHost/DBD/Base.pm index e58d9bc26..b6ac2d724 100644 --- a/src/dbHost/DBD/Base.pm +++ b/src/dbHost/DBD/Base.pm @@ -6,9 +6,9 @@ use Carp; require Exporter; @ISA = qw(Exporter); -@EXPORT = qw(&pushContext &popContext &dieContext &warnContext &identifier - &unquote &escapeCcomment &escapeCstring $RXident $RXname $RXuint $RXint - $RXhex $RXoct $RXuintx $RXintx $RXnum $RXdqs $RXsqs $RXstr); +@EXPORT = qw(&pushContext &popContext &dieContext &warnContext &is_reserved + &identifier &unquote &escapeCcomment &escapeCstring $RXident $RXname + $RXuint $RXint $RXhex $RXoct $RXuintx $RXintx $RXnum $RXdqs $RXsqs $RXstr); our $RXident = qr/ [a-zA-Z] [a-zA-Z0-9_]* /x; @@ -61,6 +61,21 @@ sub unquote (\$) { return $$s; } +# Reserved words from C++ and the DB/DBD file parser +my %reserved = map { $_ => undef } qw(and and_eq asm auto bitand bitor bool + break case catch char class compl const const_cast continue default delete + do double dynamic_cast else enum explicit export extern false float for + friend goto if inline int long mutable namespace new not not_eq operator or + or_eq private protected public register reinterpret_cast return short signed + sizeof static static_cast struct switch template this throw true try typedef + typeid typename union unsigned using virtual void volatile wchar_t while xor + xor_eq addpath alias breaktable choice device driver field function grecord + include info menu path record recordtype registrar variable); +sub is_reserved { + my $id = shift; + return exists $reserved{$id}; +} + sub identifier { my ($id, $what) = @_; unquote $id; @@ -68,6 +83,9 @@ sub identifier { $id =~ m/^$RXident$/o or dieContext("Illegal $what '$id'", "Identifiers are used in C code so must start with a letter, followed", "by letters, digits and/or underscore characters only."); + dieContext("Illegal $what '$id'", + "Identifier is a C++ reserved word.") + if is_reserved($id); return $id; } diff --git a/src/dbHost/DBD/Recfield.pm b/src/dbHost/DBD/Recfield.pm index 2b3e38089..259af0eb6 100644 --- a/src/dbHost/DBD/Recfield.pm +++ b/src/dbHost/DBD/Recfield.pm @@ -99,9 +99,19 @@ sub check_valid { if (defined($default) and !$this->legal_value($default)); } +# The C structure member name is usually the field name converted to +# lower-case. However if that is a reserved word, use the original. +sub C_name { + my ($this) = @_; + my $name = lc $this->name; + $name = $this->name + if is_reserved($name); + return $name; +} + sub toDeclaration { my ($this, $ctype) = @_; - my $name = lc $this->name; + my $name = $this->C_name; my $result = sprintf " %-19s %-12s", $ctype, "$name;"; my $prompt = $this->attribute('prompt'); $result .= "/* $prompt */" if defined $prompt; diff --git a/src/dbHost/dbdToRecordtypeH.pl b/src/dbHost/dbdToRecordtypeH.pl index 763f51b44..06d1dd0cc 100755 --- a/src/dbHost/dbdToRecordtypeH.pl +++ b/src/dbHost/dbdToRecordtypeH.pl @@ -122,13 +122,13 @@ sub oldtables { "{\n" . " ${rn}Record *prec = 0;\n" . join("\n", map { - " prt->papFldDes[${rn}Record$_]->size = " . - "sizeof(prec->" . lc($_) . ");" - } $rtyp->field_names) . "\n" . + " prt->papFldDes[${rn}Record" . $_->name . "]->size = " . + "sizeof(prec->" . $_->C_name . ");" + } $rtyp->fields) . "\n" . join("\n", map { - " prt->papFldDes[${rn}Record$_]->offset = " . - "(char *)&prec->" . lc($_) . " - (char *)prec;" - } $rtyp->field_names) . "\n" . + " prt->papFldDes[${rn}Record" . $_->name . "]->offset = " . + "(char *)&prec->" . $_->C_name . " - (char *)prec;" + } $rtyp->fields) . "\n" . " prt->rec_size = sizeof(*prec);\n" . " return 0;\n" . "}\n" . @@ -154,6 +154,7 @@ sub newtables { "static dbFldDes ${rn}FieldMetaData[] = {\n", join(",\n", map { my $fn = $_->name; + my $cn = $_->C_name; " { ${rn}FieldName${fn}," . $_->dbf_type . ',"' . $_->attribute('initial') . '",' . @@ -162,7 +163,7 @@ sub newtables { ($_->attribute('interest') || '0') . ',' . ($_->attribute('asl') || 'ASL0') . ',' . $n++ . ",\n\t\&${rn}RecordMetaData," . - "GEOMETRY_DATA(${rn}Record," . lc($fn) . ') }'; + "GEOMETRY_DATA(${rn}Record,$cn) }"; } $rtyp->fields), "\n};\n\n"; print OUTFILE "static const ${rn}FieldIndex ${rn}RecordLinkFieldIndices[] = {\n",