Made checking for single-character words faster. The testing now also uses less memory and works for 8-bit characters, which would have previously caused buffer overruns. It is also more modular and has additional documentation.
This commit is contained in:
parent
2ab6f03de1
commit
eddd2827ec
|
|
@ -12,10 +12,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
#include "variable.h"
|
||||
|
||||
|
||||
char cp_chars[128]; /* used in fcn cp_lexer() from lexical.c */
|
||||
|
||||
static char *singlec = "<>;&";
|
||||
|
||||
void
|
||||
cp_init(void)
|
||||
/* called from ft_cpinit() in cpitf.c.
|
||||
|
|
@ -25,13 +21,6 @@ cp_init(void)
|
|||
cp_curin, cp_curout, cp_curerr (defined in streams.c)
|
||||
*/
|
||||
{
|
||||
char *s;
|
||||
|
||||
memset(cp_chars, 0, 128);
|
||||
for (s = singlec; *s; s++)
|
||||
/* break word to right or left of characters <>;&*/
|
||||
cp_chars[(int) *s] = (CPC_BRR | CPC_BRL);
|
||||
|
||||
cp_vset("history", CP_NUM, &cp_maxhistlength);
|
||||
|
||||
cp_curin = stdin;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
* Initial lexer.
|
||||
*/
|
||||
|
||||
#include "ngspice/defines.h"
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/cpdefs.h"
|
||||
|
||||
|
|
@ -44,6 +45,23 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
#include "ngspice/fteinput.h"
|
||||
#include "lexical.h"
|
||||
|
||||
/** Constants related to characters that form their own words.
|
||||
** These expressions will be resolved at compile time */
|
||||
#define ID_SOLO_CHAR 1 /* Identifier for special chars */
|
||||
|
||||
/* Largest of the special chars */
|
||||
#define MAX_SOLO_CHAR1 ('<' > '>' ? '<' : '>')
|
||||
#define MAX_SOLO_CHAR2 (MAX_SOLO_CHAR1 > ';' ? MAX_SOLO_CHAR1 : ';')
|
||||
#define MAX_SOLO_CHAR (MAX_SOLO_CHAR2 > '&' ? MAX_SOLO_CHAR2 : '&')
|
||||
|
||||
/* Smallest of the special chars */
|
||||
#define MIN_SOLO_CHAR1 ('<' < '>' ? '<' : '>')
|
||||
#define MIN_SOLO_CHAR2 (MIN_SOLO_CHAR1 < ';' ? MIN_SOLO_CHAR1 : ';')
|
||||
#define MIN_SOLO_CHAR (MIN_SOLO_CHAR2 < '&' ? MIN_SOLO_CHAR2 : '&')
|
||||
|
||||
/* Largest index of solo char array */
|
||||
#define MAX_INDEX_SOLO_CHAR (MAX_SOLO_CHAR - MIN_SOLO_CHAR)
|
||||
|
||||
static void prompt(void);
|
||||
|
||||
extern bool cp_echo; /* For CDHW patches: defined in variable.c */
|
||||
|
|
@ -370,19 +388,48 @@ nloop:
|
|||
goto ldefault;
|
||||
|
||||
default:
|
||||
/* We have to remember the special case $<
|
||||
* here
|
||||
*/
|
||||
ldefault:
|
||||
if ((cp_chars[c] & CPC_BRL) && (buf.i > 0))
|
||||
if ((c != '<') || (buf.s[buf.i - 1] != '$'))
|
||||
newword;
|
||||
push(&buf, c);
|
||||
if (cp_chars[c] & CPC_BRR)
|
||||
if ((c != '<') || (buf.i < 2) || (buf.s[buf.i - 2] != '$'))
|
||||
newword;
|
||||
}
|
||||
}
|
||||
/* $< is a special case where the '<' is not treated
|
||||
* as a character forming its own word */
|
||||
ldefault: {
|
||||
/* Lookup table for "solo" chars forming their own word */
|
||||
static const char id_solo_chars[MAX_INDEX_SOLO_CHAR + 1] = {
|
||||
['<' - MIN_SOLO_CHAR] = ID_SOLO_CHAR,
|
||||
['>' - MIN_SOLO_CHAR] = ID_SOLO_CHAR,
|
||||
[';' - MIN_SOLO_CHAR] = ID_SOLO_CHAR,
|
||||
['&' - MIN_SOLO_CHAR] = ID_SOLO_CHAR
|
||||
};
|
||||
|
||||
/* Find index into solo chars table */
|
||||
const unsigned int index_char =
|
||||
(unsigned int) c - (unsigned int) MIN_SOLO_CHAR;
|
||||
|
||||
/* Flag that the current character c is a solo character */
|
||||
const bool f_solo_char = index_char <= MAX_INDEX_SOLO_CHAR &&
|
||||
id_solo_chars[index_char];
|
||||
bool f_is_dollar_lt = FALSE;
|
||||
|
||||
if (f_solo_char && buf.i > 0) {
|
||||
/* The current char is a character forming its own word,
|
||||
* unless it is "$<" */
|
||||
if (c == '<' && buf.s[buf.i - 1] == '$') { /* is "$<" */
|
||||
f_is_dollar_lt = TRUE; /* set flag that "$<" found */
|
||||
}
|
||||
else {
|
||||
/* not "$<", so terminate current word and start
|
||||
* another one */
|
||||
newword;
|
||||
}
|
||||
}
|
||||
|
||||
push(&buf, c); /* Add the current char to the current word */
|
||||
|
||||
if (f_solo_char && !f_is_dollar_lt) {
|
||||
/* Split into a new word if this char forms its own word */
|
||||
newword;
|
||||
}
|
||||
} /* end of ldefault block */
|
||||
} /* end of switch over character value */
|
||||
} /* end of loop over characters */
|
||||
|
||||
done:
|
||||
if (wlist->wl_word)
|
||||
|
|
|
|||
|
|
@ -84,11 +84,6 @@ struct alias {
|
|||
struct alias *al_prev;
|
||||
} ;
|
||||
|
||||
/* The current record of what characters are special. */
|
||||
|
||||
#define CPC_BRR 004 /* Break word to right of character. */
|
||||
#define CPC_BRL 010 /* Break word to left of character. */
|
||||
|
||||
|
||||
#define CT_ALIASES 1
|
||||
#define CT_LABEL 15
|
||||
|
|
|
|||
Loading…
Reference in New Issue