Improved some error messages for command line processing.
[python/dscho.git] / Parser / parsetok.c
blob6453b6afe55a133510a7e6add04cd695b11f66e3
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Parser-tokenizer link implementation */
34 #include "pgenheaders.h"
35 #include "tokenizer.h"
36 #include "node.h"
37 #include "grammar.h"
38 #include "parser.h"
39 #include "parsetok.h"
40 #include "errcode.h"
42 int Py_TabcheckFlag;
45 /* Forward */
46 static node *parsetok Py_PROTO((struct tok_state *, grammar *, int,
47 perrdetail *));
49 /* Parse input coming from a string. Return error code, print some errors. */
51 node *
52 PyParser_ParseString(s, g, start, err_ret)
53 char *s;
54 grammar *g;
55 int start;
56 perrdetail *err_ret;
58 struct tok_state *tok;
60 err_ret->error = E_OK;
61 err_ret->filename = NULL;
62 err_ret->lineno = 0;
63 err_ret->offset = 0;
64 err_ret->text = NULL;
66 if ((tok = PyTokenizer_FromString(s)) == NULL) {
67 err_ret->error = E_NOMEM;
68 return NULL;
71 return parsetok(tok, g, start, err_ret);
75 /* Parse input coming from a file. Return error code, print some errors. */
77 node *
78 PyParser_ParseFile(fp, filename, g, start, ps1, ps2, err_ret)
79 FILE *fp;
80 char *filename;
81 grammar *g;
82 int start;
83 char *ps1, *ps2;
84 perrdetail *err_ret;
86 struct tok_state *tok;
88 err_ret->error = E_OK;
89 err_ret->filename = filename;
90 err_ret->lineno = 0;
91 err_ret->offset = 0;
92 err_ret->text = NULL;
94 if ((tok = PyTokenizer_FromFile(fp, ps1, ps2)) == NULL) {
95 err_ret->error = E_NOMEM;
96 return NULL;
98 if (Py_TabcheckFlag || Py_VerboseFlag) {
99 tok->filename = filename;
100 tok->altwarning = (filename != NULL);
101 if (Py_TabcheckFlag >= 2)
102 tok->alterror++;
105 #ifdef macintosh
107 int tabsize = guesstabsize(filename);
108 if (tabsize > 0)
109 tok->tabsize = tabsize;
111 #endif
113 return parsetok(tok, g, start, err_ret);
116 /* Parse input coming from the given tokenizer structure.
117 Return error code. */
119 static node *
120 parsetok(tok, g, start, err_ret)
121 struct tok_state *tok;
122 grammar *g;
123 int start;
124 perrdetail *err_ret;
126 parser_state *ps;
127 node *n;
128 int started = 0;
130 if ((ps = PyParser_New(g, start)) == NULL) {
131 fprintf(stderr, "no mem for new parser\n");
132 err_ret->error = E_NOMEM;
133 return NULL;
136 for (;;) {
137 char *a, *b;
138 int type;
139 int len;
140 char *str;
142 type = PyTokenizer_Get(tok, &a, &b);
143 if (type == ERRORTOKEN) {
144 err_ret->error = tok->done;
145 break;
147 if (type == ENDMARKER && started) {
148 type = NEWLINE; /* Add an extra newline */
149 started = 0;
151 else
152 started = 1;
153 len = b - a; /* XXX this may compute NULL - NULL */
154 str = PyMem_NEW(char, len + 1);
155 if (str == NULL) {
156 fprintf(stderr, "no mem for next token\n");
157 err_ret->error = E_NOMEM;
158 break;
160 if (len > 0)
161 strncpy(str, a, len);
162 str[len] = '\0';
163 if ((err_ret->error =
164 PyParser_AddToken(ps, (int)type, str,
165 tok->lineno)) != E_OK) {
166 if (err_ret->error != E_DONE)
167 PyMem_DEL(str);
168 break;
172 if (err_ret->error == E_DONE) {
173 n = ps->p_tree;
174 ps->p_tree = NULL;
176 else
177 n = NULL;
179 PyParser_Delete(ps);
181 if (n == NULL) {
182 if (tok->lineno <= 1 && tok->done == E_EOF)
183 err_ret->error = E_EOF;
184 err_ret->lineno = tok->lineno;
185 err_ret->offset = tok->cur - tok->buf;
186 if (tok->buf != NULL) {
187 int len = tok->inp - tok->buf;
188 err_ret->text = malloc(len + 1);
189 if (err_ret->text != NULL) {
190 if (len > 0)
191 strncpy(err_ret->text, tok->buf, len);
192 err_ret->text[len] = '\0';
197 PyTokenizer_Free(tok);
199 return n;