Commit bd0389d5 authored by Guido van Rossum's avatar Guido van Rossum

don't call strncpy(str, NULL, 0)

parent 4ca6c9db
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
...@@ -34,56 +34,59 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ...@@ -34,56 +34,59 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* Forward */ /* Forward */
static int parsetok PROTO((struct tok_state *, grammar *, int, node **)); static node *parsetok PROTO((struct tok_state *, grammar *, int,
perrdetail *));
/* Parse input coming from a string. Return error code, print some errors. */ /* Parse input coming from a string. Return error code, print some errors. */
int node *
parsestring(s, g, start, n_ret) parsestring(s, g, start, err_ret)
char *s; char *s;
grammar *g; grammar *g;
int start; int start;
node **n_ret; perrdetail *err_ret;
{ {
struct tok_state *tok = tok_setups(s); struct tok_state *tok;
int ret;
if (tok == NULL) { err_ret->error = E_OK;
fprintf(stderr, "no mem for tok_setups\n"); err_ret->filename = NULL;
return E_NOMEM; err_ret->lineno = 0;
} err_ret->offset = 0;
ret = parsetok(tok, g, start, n_ret); err_ret->text = NULL;
/*
XXX Need a more sophisticated way to report the line number. if ((tok = tok_setups(s)) == NULL) {
if (ret == E_TOKEN || ret == E_SYNTAX) { err_ret->error = E_NOMEM;
fprintf(stderr, "String parsing error at line %d\n", return NULL;
tok->lineno);
} }
*/
tok_free(tok); return parsetok(tok, g, start, err_ret);
return ret;
} }
/* Parse input coming from a file. Return error code, print some errors. */ /* Parse input coming from a file. Return error code, print some errors. */
int node *
parsefile(fp, filename, g, start, ps1, ps2, n_ret) parsefile(fp, filename, g, start, ps1, ps2, err_ret)
FILE *fp; FILE *fp;
char *filename; char *filename;
grammar *g; grammar *g;
int start; int start;
char *ps1, *ps2; char *ps1, *ps2;
node **n_ret; perrdetail *err_ret;
{ {
struct tok_state *tok = tok_setupf(fp, ps1, ps2); struct tok_state *tok;
int ret;
if (tok == NULL) { err_ret->error = E_OK;
fprintf(stderr, "no mem for tok_setupf\n"); err_ret->filename = filename;
return E_NOMEM; err_ret->lineno = 0;
err_ret->offset = 0;
err_ret->text = NULL;
if ((tok = tok_setupf(fp, ps1, ps2)) == NULL) {
err_ret->error = E_NOMEM;
return NULL;
} }
#ifdef macintosh #ifdef macintosh
{ {
int tabsize = guesstabsize(filename); int tabsize = guesstabsize(filename);
...@@ -91,49 +94,28 @@ parsefile(fp, filename, g, start, ps1, ps2, n_ret) ...@@ -91,49 +94,28 @@ parsefile(fp, filename, g, start, ps1, ps2, n_ret)
tok->tabsize = tabsize; tok->tabsize = tabsize;
} }
#endif #endif
ret = parsetok(tok, g, start, n_ret);
if (ret == E_TOKEN || ret == E_SYNTAX) {
char *p;
fprintf(stderr, "Parsing error: file %s, line %d:\n",
filename, tok->lineno);
if (tok->buf == NULL)
fprintf(stderr, "(EOF)\n");
else {
*tok->inp = '\0';
if (tok->inp > tok->buf && tok->inp[-1] == '\n')
tok->inp[-1] = '\0';
fprintf(stderr, "%s\n", tok->buf);
for (p = tok->buf; p < tok->cur; p++) {
if (*p == '\t')
putc('\t', stderr);
else
putc(' ', stderr);
}
fprintf(stderr, "^\n");
}
}
tok_free(tok);
return ret;
}
return parsetok(tok, g, start, err_ret);
}
/* Parse input coming from the given tokenizer structure. /* Parse input coming from the given tokenizer structure.
Return error code. */ Return error code. */
static int static node *
parsetok(tok, g, start, n_ret) parsetok(tok, g, start, err_ret)
struct tok_state *tok; struct tok_state *tok;
grammar *g; grammar *g;
int start; int start;
node **n_ret; perrdetail *err_ret;
{ {
parser_state *ps; parser_state *ps;
int ret; node *n;
int started = 0; int started = 0;
if ((ps = newparser(g, start)) == NULL) { if ((ps = newparser(g, start)) == NULL) {
fprintf(stderr, "no mem for new parser\n"); fprintf(stderr, "no mem for new parser\n");
return E_NOMEM; err_ret->error = E_NOMEM;
return NULL;
} }
for (;;) { for (;;) {
...@@ -144,7 +126,7 @@ parsetok(tok, g, start, n_ret) ...@@ -144,7 +126,7 @@ parsetok(tok, g, start, n_ret)
type = tok_get(tok, &a, &b); type = tok_get(tok, &a, &b);
if (type == ERRORTOKEN) { if (type == ERRORTOKEN) {
ret = tok->done; err_ret->error = tok->done;
break; break;
} }
if (type == ENDMARKER && started) { if (type == ENDMARKER && started) {
...@@ -153,30 +135,46 @@ parsetok(tok, g, start, n_ret) ...@@ -153,30 +135,46 @@ parsetok(tok, g, start, n_ret)
} }
else else
started = 1; started = 1;
len = b - a; len = b - a; /* XXX this may compute NULL - NULL */
str = NEW(char, len + 1); str = NEW(char, len + 1);
if (str == NULL) { if (str == NULL) {
fprintf(stderr, "no mem for next token\n"); fprintf(stderr, "no mem for next token\n");
ret = E_NOMEM; err_ret->error = E_NOMEM;
break; break;
} }
if (len > 0)
strncpy(str, a, len); strncpy(str, a, len);
str[len] = '\0'; str[len] = '\0';
ret = addtoken(ps, (int)type, str, tok->lineno); if ((err_ret->error =
if (ret != E_OK) { addtoken(ps, (int)type, str, tok->lineno)) != E_OK)
if (ret == E_DONE) { break;
*n_ret = ps->p_tree; }
if (err_ret->error == E_DONE) {
n = ps->p_tree;
ps->p_tree = NULL; ps->p_tree = NULL;
} }
else { else
*n_ret = NULL; n = NULL;
delparser(ps);
if (n == NULL) {
if (tok->lineno <= 1 && tok->done == E_EOF) if (tok->lineno <= 1 && tok->done == E_EOF)
ret = E_EOF; err_ret->error = E_EOF;
err_ret->lineno = tok->lineno;
err_ret->offset = tok->cur - tok->buf;
if (tok->buf != NULL) {
int len = tok->inp - tok->buf;
err_ret->text = malloc(len + 1);
if (err_ret->text != NULL) {
strncpy(err_ret->text, tok->buf, len+1);
err_ret->text[len] = '\0';
} }
break;
} }
} }
delparser(ps); tok_free(tok);
return ret;
return n;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment