Corrected handling of verilog backslash-escaped names in the

verilog netlist parser.
This commit is contained in:
Tim Edwards 2019-05-05 10:52:07 -04:00
parent 395f857a82
commit 8e0371e09b
2 changed files with 59 additions and 11 deletions

View File

@ -471,6 +471,23 @@ char *strdtok(char *pstring, char *delim1, char *delim2)
/* "stoken" is now set. Now find the end of the current token */
s = stoken;
/* Special verilog rule: If a name begins with '\', then all characters */
/* are a valid part of the name until a space character is reached. The */
/* space character becomes part of the verilog name. The remainder of the */
/* name is parsed according to the rules of "delim2". */
if (*s == '\\') {
while (*s != '\0') {
if (*s == ' ') {
s++;
break;
}
s++;
}
}
/* Check string from position stoken. If a character in "delim2" is found, */
/* save the character in "lastdelim", null the byte at that position, and */
/* return the token. If a character in "delim1" is found, do the same but */
@ -479,7 +496,7 @@ char *strdtok(char *pstring, char *delim1, char *delim2)
/* as for "delim2" above. If not, then set "lastdelim" to a null byte and */
/* return the token. */
for (s = stoken; *s; s++) {
for (; *s; s++) {
twofer = (delim2 && (*delim2 == 'X')) ? TRUE : FALSE;
for (s2 = ((twofer == TRUE) ? delim2 + 1 : delim2); s2 && *s2; s2++) {
if (*s2 == 'X') {

View File

@ -59,8 +59,9 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
// See netfile.c for explanation of delimiters. 'X'
// separates single-character delimiters from two-character delimiters.
#define VLOG_DELIMITERS "X///**/#((**)X,::(){}[]="
#define VLOG_DELIMITERS "X///**/(**)#(X,;:(){}[]="
#define VLOG_PIN_NAME_DELIMITERS "X///**/(**)X()"
#define VLOG_PIN_CHECK_DELIMITERS "X///**/(**)X(),{}"
// Global storage for verilog parameters
struct hashdict verilogparams;
@ -291,6 +292,8 @@ int GetBusTok(struct bus *wb)
return 1;
}
}
/* Move token forward to bus name */
SkipTokComments(VLOG_DELIMITERS);
}
else {
struct bus *hbus;
@ -312,7 +315,7 @@ int GetBusTok(struct bus *wb)
int GetBus(char *astr, struct bus *wb)
{
char *colonptr, *brackstart, *brackend;
char *colonptr, *brackstart, *brackend, *sstr;
int result, start, end;
if (wb == NULL) return 0;
@ -320,15 +323,21 @@ int GetBus(char *astr, struct bus *wb)
wb->start = -1;
wb->end = -1;
}
brackstart = strchr(astr, '[');
sstr = astr;
// Skip to the end of verilog names bounded by '\' and ' '
if (*sstr == '\\')
while (*sstr && *sstr != ' ') sstr++;
brackstart = strchr(sstr, '[');
if (brackstart != NULL) {
brackend = strchr(astr, ']');
brackend = strchr(sstr, ']');
if (brackend == NULL) {
Printf("Badly formed array notation \"%s\"\n", astr);
return 1;
}
*brackend = '\0';
colonptr = strchr(astr, ':');
colonptr = strchr(sstr, ':');
if (colonptr) *colonptr = '\0';
result = sscanf(brackstart + 1, "%d", &start);
if (colonptr) *colonptr = ':';
@ -1229,12 +1238,12 @@ skip_endmodule:
arraystart = wb.start;
arrayend = wb.end;
}
SkipTokComments(VLOG_DELIMITERS);
}
if (match(nexttok, "(")) {
char savetok = (char)0;
struct portelement *new_port;
char *in_line_net = NULL;
// Read the pin list
while (nexttok != NULL) {
@ -1261,7 +1270,7 @@ skip_endmodule:
Printf("Badly formed subcircuit pin line at \"%s\"\n", nexttok);
SkipNewLine(VLOG_DELIMITERS);
}
SkipTokComments(VLOG_PIN_NAME_DELIMITERS);
SkipTokComments(VLOG_PIN_CHECK_DELIMITERS);
if (match(nexttok, ")")) {
char localnet[100];
// Empty parens, so create a new local node
@ -1270,7 +1279,29 @@ skip_endmodule:
new_port->net = strsave(localnet);
}
else {
new_port->net = strsave(nexttok);
if (!strcmp(nexttok, "{")) {
char *in_line_net = (char *)MALLOC(1);
*in_line_net = '\0';
/* In-line array---Read to "}" */
while (nexttok) {
char *new_in_line_net = (char *)MALLOC(
strlen(in_line_net) +
strlen(nexttok) + 1);
strcpy(new_in_line_net, in_line_net);
strcat(new_in_line_net, nexttok);
FREE(in_line_net);
in_line_net = new_in_line_net;
if (!strcmp(nexttok, "}")) break;
SkipTokComments(VLOG_PIN_CHECK_DELIMITERS);
}
if (!nexttok) {
Printf("Unterminated net in pin %s\n", in_line_net);
}
new_port->net = in_line_net;
}
else
new_port->net = strsave(nexttok);
/* Read array information along with name; will be parsed later */
SkipTokComments(VLOG_DELIMITERS);
if (match(nexttok, "[")) {
@ -1279,8 +1310,8 @@ skip_endmodule:
if (!match(nexttok, ")")) {
char *expnet;
expnet = (char *)MALLOC(strlen(new_port->net)
+ strlen(nexttok) + 2);
sprintf(expnet, "%s[%s", new_port->net, nexttok);
+ strlen(nexttok) + 3);
sprintf(expnet, "%s [%s", new_port->net, nexttok);
FREE(new_port->net);
new_port->net = expnet;
}