| Guido van Rossum | f70e43a | 1991-02-19 12:39:46 +0000 | [diff] [blame] | 1 |  | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 2 | /* Parser-tokenizer link implementation */ | 
 | 3 |  | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 4 | #include "pgenheaders.h" | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 5 | #include "tokenizer.h" | 
 | 6 | #include "node.h" | 
 | 7 | #include "grammar.h" | 
 | 8 | #include "parser.h" | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 9 | #include "parsetok.h" | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 10 | #include "errcode.h" | 
| Martin v. Löwis | 00f1e3f | 2002-08-04 17:29:52 +0000 | [diff] [blame] | 11 | #include "graminit.h" | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 12 |  | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 13 |  | 
 | 14 | /* Forward */ | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 15 | static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int *); | 
| Victor Stinner | 14e461d | 2013-08-26 22:28:21 +0200 | [diff] [blame] | 16 | static int initerr(perrdetail *err_ret, PyObject * filename); | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 17 |  | 
 | 18 | /* Parse input coming from a string.  Return error code, print some errors. */ | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 19 | node * | 
| Martin v. Löwis | 95292d6 | 2002-12-11 14:04:59 +0000 | [diff] [blame] | 20 | PyParser_ParseString(const char *s, grammar *g, int start, perrdetail *err_ret) | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 21 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 22 |     return PyParser_ParseStringFlagsFilename(s, NULL, g, start, err_ret, 0); | 
| Tim Peters | fe2127d | 2001-07-16 05:37:24 +0000 | [diff] [blame] | 23 | } | 
 | 24 |  | 
 | 25 | node * | 
| Martin v. Löwis | 95292d6 | 2002-12-11 14:04:59 +0000 | [diff] [blame] | 26 | PyParser_ParseStringFlags(const char *s, grammar *g, int start, | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 27 |                           perrdetail *err_ret, int flags) | 
| Tim Peters | fe2127d | 2001-07-16 05:37:24 +0000 | [diff] [blame] | 28 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 29 |     return PyParser_ParseStringFlagsFilename(s, NULL, | 
 | 30 |                                              g, start, err_ret, flags); | 
| Thomas Heller | 6b17abf | 2002-07-09 09:23:27 +0000 | [diff] [blame] | 31 | } | 
 | 32 |  | 
 | 33 | node * | 
| Martin v. Löwis | 95292d6 | 2002-12-11 14:04:59 +0000 | [diff] [blame] | 34 | PyParser_ParseStringFlagsFilename(const char *s, const char *filename, | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 35 |                           grammar *g, int start, | 
 | 36 |                           perrdetail *err_ret, int flags) | 
| Thomas Heller | 6b17abf | 2002-07-09 09:23:27 +0000 | [diff] [blame] | 37 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 38 |     int iflags = flags; | 
 | 39 |     return PyParser_ParseStringFlagsFilenameEx(s, filename, g, start, | 
 | 40 |                                                err_ret, &iflags); | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 41 | } | 
 | 42 |  | 
 | 43 | node * | 
| Victor Stinner | 14e461d | 2013-08-26 22:28:21 +0200 | [diff] [blame] | 44 | PyParser_ParseStringObject(const char *s, PyObject *filename, | 
 | 45 |                            grammar *g, int start, | 
 | 46 |                            perrdetail *err_ret, int *flags) | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 47 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 48 |     struct tok_state *tok; | 
 | 49 |     int exec_input = start == file_input; | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 50 |  | 
| Victor Stinner | 7f2fee3 | 2011-04-05 00:39:01 +0200 | [diff] [blame] | 51 |     if (initerr(err_ret, filename) < 0) | 
 | 52 |         return NULL; | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 53 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 54 |     if (*flags & PyPARSE_IGNORE_COOKIE) | 
 | 55 |         tok = PyTokenizer_FromUTF8(s, exec_input); | 
 | 56 |     else | 
 | 57 |         tok = PyTokenizer_FromString(s, exec_input); | 
 | 58 |     if (tok == NULL) { | 
 | 59 |         err_ret->error = PyErr_Occurred() ? E_DECODE : E_NOMEM; | 
 | 60 |         return NULL; | 
 | 61 |     } | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 62 |  | 
| Victor Stinner | 7f2fee3 | 2011-04-05 00:39:01 +0200 | [diff] [blame] | 63 | #ifndef PGEN | 
 | 64 |     Py_INCREF(err_ret->filename); | 
 | 65 |     tok->filename = err_ret->filename; | 
 | 66 | #endif | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 67 |     return parsetok(tok, g, start, err_ret, flags); | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 68 | } | 
 | 69 |  | 
| Victor Stinner | 14e461d | 2013-08-26 22:28:21 +0200 | [diff] [blame] | 70 | node * | 
 | 71 | PyParser_ParseStringFlagsFilenameEx(const char *s, const char *filename_str, | 
 | 72 |                           grammar *g, int start, | 
 | 73 |                           perrdetail *err_ret, int *flags) | 
 | 74 | { | 
 | 75 |     node *n; | 
 | 76 |     PyObject *filename = NULL; | 
 | 77 | #ifndef PGEN | 
 | 78 |     if (filename_str != NULL) { | 
 | 79 |         filename = PyUnicode_DecodeFSDefault(filename_str); | 
 | 80 |         if (filename == NULL) { | 
 | 81 |             err_ret->error = E_ERROR; | 
 | 82 |             return NULL; | 
 | 83 |         } | 
 | 84 |     } | 
 | 85 | #endif | 
 | 86 |     n = PyParser_ParseStringObject(s, filename, g, start, err_ret, flags); | 
 | 87 | #ifndef PGEN | 
 | 88 |     Py_XDECREF(filename); | 
 | 89 | #endif | 
 | 90 |     return n; | 
 | 91 | } | 
 | 92 |  | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 93 | /* Parse input coming from a file.  Return error code, print some errors. */ | 
 | 94 |  | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 95 | node * | 
| Martin v. Löwis | 95292d6 | 2002-12-11 14:04:59 +0000 | [diff] [blame] | 96 | PyParser_ParseFile(FILE *fp, const char *filename, grammar *g, int start, | 
| Serhiy Storchaka | c679227 | 2013-10-19 21:03:34 +0300 | [diff] [blame] | 97 |                    const char *ps1, const char *ps2, | 
 | 98 |                    perrdetail *err_ret) | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 99 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 100 |     return PyParser_ParseFileFlags(fp, filename, NULL, | 
 | 101 |                                    g, start, ps1, ps2, err_ret, 0); | 
| Tim Peters | fe2127d | 2001-07-16 05:37:24 +0000 | [diff] [blame] | 102 | } | 
 | 103 |  | 
 | 104 | node * | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 105 | PyParser_ParseFileFlags(FILE *fp, const char *filename, const char *enc, | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 106 |                         grammar *g, int start, | 
| Serhiy Storchaka | c679227 | 2013-10-19 21:03:34 +0300 | [diff] [blame] | 107 |                         const char *ps1, const char *ps2, | 
 | 108 |                         perrdetail *err_ret, int flags) | 
| Tim Peters | fe2127d | 2001-07-16 05:37:24 +0000 | [diff] [blame] | 109 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 110 |     int iflags = flags; | 
 | 111 |     return PyParser_ParseFileFlagsEx(fp, filename, enc, g, start, ps1, | 
 | 112 |                                      ps2, err_ret, &iflags); | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 113 | } | 
 | 114 |  | 
 | 115 | node * | 
| Victor Stinner | 14e461d | 2013-08-26 22:28:21 +0200 | [diff] [blame] | 116 | PyParser_ParseFileObject(FILE *fp, PyObject *filename, | 
 | 117 |                          const char *enc, grammar *g, int start, | 
| Serhiy Storchaka | c679227 | 2013-10-19 21:03:34 +0300 | [diff] [blame] | 118 |                          const char *ps1, const char *ps2, | 
 | 119 |                          perrdetail *err_ret, int *flags) | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 120 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 121 |     struct tok_state *tok; | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 122 |  | 
| Victor Stinner | 7f2fee3 | 2011-04-05 00:39:01 +0200 | [diff] [blame] | 123 |     if (initerr(err_ret, filename) < 0) | 
 | 124 |         return NULL; | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 125 |  | 
| Serhiy Storchaka | c679227 | 2013-10-19 21:03:34 +0300 | [diff] [blame] | 126 |     if ((tok = PyTokenizer_FromFile(fp, enc, ps1, ps2)) == NULL) { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 127 |         err_ret->error = E_NOMEM; | 
 | 128 |         return NULL; | 
 | 129 |     } | 
| Victor Stinner | 7f2fee3 | 2011-04-05 00:39:01 +0200 | [diff] [blame] | 130 | #ifndef PGEN | 
 | 131 |     Py_INCREF(err_ret->filename); | 
 | 132 |     tok->filename = err_ret->filename; | 
 | 133 | #endif | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 134 |     return parsetok(tok, g, start, err_ret, flags); | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 135 | } | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 136 |  | 
| Victor Stinner | 14e461d | 2013-08-26 22:28:21 +0200 | [diff] [blame] | 137 | node * | 
 | 138 | PyParser_ParseFileFlagsEx(FILE *fp, const char *filename, | 
 | 139 |                           const char *enc, grammar *g, int start, | 
| Serhiy Storchaka | c679227 | 2013-10-19 21:03:34 +0300 | [diff] [blame] | 140 |                           const char *ps1, const char *ps2, | 
 | 141 |                           perrdetail *err_ret, int *flags) | 
| Victor Stinner | 14e461d | 2013-08-26 22:28:21 +0200 | [diff] [blame] | 142 | { | 
 | 143 |     node *n; | 
 | 144 |     PyObject *fileobj = NULL; | 
 | 145 | #ifndef PGEN | 
 | 146 |     if (filename != NULL) { | 
 | 147 |         fileobj = PyUnicode_DecodeFSDefault(filename); | 
 | 148 |         if (fileobj == NULL) { | 
 | 149 |             err_ret->error = E_ERROR; | 
 | 150 |             return NULL; | 
 | 151 |         } | 
 | 152 |     } | 
 | 153 | #endif | 
 | 154 |     n = PyParser_ParseFileObject(fp, fileobj, enc, g, | 
 | 155 |                                  start, ps1, ps2, err_ret, flags); | 
 | 156 | #ifndef PGEN | 
 | 157 |     Py_XDECREF(fileobj); | 
 | 158 | #endif | 
 | 159 |     return n; | 
 | 160 | } | 
 | 161 |  | 
| Neal Norwitz | e4993c7 | 2006-03-16 06:01:25 +0000 | [diff] [blame] | 162 | #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD | 
| Brett Cannon | e3944a5 | 2009-04-01 05:08:41 +0000 | [diff] [blame] | 163 | #if 0 | 
| Thomas Wouters | 34aa7ba | 2006-02-28 19:02:24 +0000 | [diff] [blame] | 164 | static char with_msg[] = | 
 | 165 | "%s:%d: Warning: 'with' will become a reserved keyword in Python 2.6\n"; | 
 | 166 |  | 
 | 167 | static char as_msg[] = | 
 | 168 | "%s:%d: Warning: 'as' will become a reserved keyword in Python 2.6\n"; | 
 | 169 |  | 
 | 170 | static void | 
 | 171 | warn(const char *msg, const char *filename, int lineno) | 
 | 172 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 173 |     if (filename == NULL) | 
 | 174 |         filename = "<string>"; | 
 | 175 |     PySys_WriteStderr(msg, filename, lineno); | 
| Thomas Wouters | 34aa7ba | 2006-02-28 19:02:24 +0000 | [diff] [blame] | 176 | } | 
| Neal Norwitz | fc85c92 | 2006-03-17 05:44:46 +0000 | [diff] [blame] | 177 | #endif | 
| Brett Cannon | e3944a5 | 2009-04-01 05:08:41 +0000 | [diff] [blame] | 178 | #endif | 
| Guido van Rossum | da62ecc | 2001-07-17 16:53:11 +0000 | [diff] [blame] | 179 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 180 | /* Parse input coming from the given tokenizer structure. | 
 | 181 |    Return error code. */ | 
 | 182 |  | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 183 | static node * | 
| Tim Peters | fe2127d | 2001-07-16 05:37:24 +0000 | [diff] [blame] | 184 | parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 185 |          int *flags) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 186 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 187 |     parser_state *ps; | 
 | 188 |     node *n; | 
| Brett Cannon | b94767f | 2011-02-22 20:15:44 +0000 | [diff] [blame] | 189 |     int started = 0; | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 190 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 191 |     if ((ps = PyParser_New(g, start)) == NULL) { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 192 |         err_ret->error = E_NOMEM; | 
 | 193 |         PyTokenizer_Free(tok); | 
 | 194 |         return NULL; | 
 | 195 |     } | 
| Thomas Wouters | 34aa7ba | 2006-02-28 19:02:24 +0000 | [diff] [blame] | 196 | #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 197 |     if (*flags & PyPARSE_BARRY_AS_BDFL) | 
 | 198 |         ps->p_flags |= CO_FUTURE_BARRY_AS_BDFL; | 
| Neil Schemenauer | c24ea08 | 2002-03-22 23:53:36 +0000 | [diff] [blame] | 199 | #endif | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 200 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 201 |     for (;;) { | 
 | 202 |         char *a, *b; | 
 | 203 |         int type; | 
 | 204 |         size_t len; | 
 | 205 |         char *str; | 
 | 206 |         int col_offset; | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 207 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 208 |         type = PyTokenizer_Get(tok, &a, &b); | 
 | 209 |         if (type == ERRORTOKEN) { | 
 | 210 |             err_ret->error = tok->done; | 
 | 211 |             break; | 
 | 212 |         } | 
 | 213 |         if (type == ENDMARKER && started) { | 
 | 214 |             type = NEWLINE; /* Add an extra newline */ | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 215 |             started = 0; | 
 | 216 |             /* Add the right number of dedent tokens, | 
 | 217 |                except if a certain flag is given -- | 
 | 218 |                codeop.py uses this. */ | 
 | 219 |             if (tok->indent && | 
 | 220 |                 !(*flags & PyPARSE_DONT_IMPLY_DEDENT)) | 
 | 221 |             { | 
 | 222 |                 tok->pendin = -tok->indent; | 
 | 223 |                 tok->indent = 0; | 
 | 224 |             } | 
 | 225 |         } | 
 | 226 |         else | 
 | 227 |             started = 1; | 
 | 228 |         len = b - a; /* XXX this may compute NULL - NULL */ | 
 | 229 |         str = (char *) PyObject_MALLOC(len + 1); | 
 | 230 |         if (str == NULL) { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 231 |             err_ret->error = E_NOMEM; | 
 | 232 |             break; | 
 | 233 |         } | 
 | 234 |         if (len > 0) | 
 | 235 |             strncpy(str, a, len); | 
 | 236 |         str[len] = '\0'; | 
| Guido van Rossum | da62ecc | 2001-07-17 16:53:11 +0000 | [diff] [blame] | 237 |  | 
| Thomas Wouters | 34aa7ba | 2006-02-28 19:02:24 +0000 | [diff] [blame] | 238 | #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 239 |         if (type == NOTEQUAL) { | 
 | 240 |             if (!(ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) && | 
 | 241 |                             strcmp(str, "!=")) { | 
| Antoine Pitrou | 9ec2593 | 2011-11-13 01:01:23 +0100 | [diff] [blame] | 242 |                 PyObject_FREE(str); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 243 |                 err_ret->error = E_SYNTAX; | 
 | 244 |                 break; | 
 | 245 |             } | 
 | 246 |             else if ((ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) && | 
 | 247 |                             strcmp(str, "<>")) { | 
| Antoine Pitrou | 9ec2593 | 2011-11-13 01:01:23 +0100 | [diff] [blame] | 248 |                 PyObject_FREE(str); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 249 |                 err_ret->text = "with Barry as BDFL, use '<>' " | 
 | 250 |                                 "instead of '!='"; | 
 | 251 |                 err_ret->error = E_SYNTAX; | 
 | 252 |                 break; | 
 | 253 |             } | 
 | 254 |         } | 
| Neil Schemenauer | c24ea08 | 2002-03-22 23:53:36 +0000 | [diff] [blame] | 255 | #endif | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 256 |         if (a >= tok->line_start) | 
| Victor Stinner | cad876d | 2013-11-18 01:09:51 +0100 | [diff] [blame] | 257 |             col_offset = Py_SAFE_DOWNCAST(a - tok->line_start, | 
 | 258 |                                           Py_intptr_t, int); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 259 |         else | 
 | 260 |             col_offset = -1; | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 261 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 262 |         if ((err_ret->error = | 
 | 263 |              PyParser_AddToken(ps, (int)type, str, | 
 | 264 |                                tok->lineno, col_offset, | 
 | 265 |                                &(err_ret->expected))) != E_OK) { | 
 | 266 |             if (err_ret->error != E_DONE) { | 
 | 267 |                 PyObject_FREE(str); | 
 | 268 |                 err_ret->token = type; | 
 | 269 |             } | 
 | 270 |             break; | 
 | 271 |         } | 
 | 272 |     } | 
 | 273 |  | 
 | 274 |     if (err_ret->error == E_DONE) { | 
 | 275 |         n = ps->p_tree; | 
 | 276 |         ps->p_tree = NULL; | 
| Meador Inge | fa21bf0 | 2012-01-19 01:08:41 -0600 | [diff] [blame] | 277 |  | 
| Benjamin Peterson | 79c1f96 | 2012-01-19 08:48:11 -0500 | [diff] [blame] | 278 | #ifndef PGEN | 
| Meador Inge | fa21bf0 | 2012-01-19 01:08:41 -0600 | [diff] [blame] | 279 |         /* Check that the source for a single input statement really | 
 | 280 |            is a single statement by looking at what is left in the | 
 | 281 |            buffer after parsing.  Trailing whitespace and comments | 
 | 282 |            are OK.  */ | 
 | 283 |         if (start == single_input) { | 
 | 284 |             char *cur = tok->cur; | 
 | 285 |             char c = *tok->cur; | 
 | 286 |  | 
| Benjamin Peterson | cff9237 | 2012-01-19 17:46:13 -0500 | [diff] [blame] | 287 |             for (;;) { | 
 | 288 |                 while (c == ' ' || c == '\t' || c == '\n' || c == '\014') | 
 | 289 |                     c = *++cur; | 
| Meador Inge | fa21bf0 | 2012-01-19 01:08:41 -0600 | [diff] [blame] | 290 |  | 
| Benjamin Peterson | cff9237 | 2012-01-19 17:46:13 -0500 | [diff] [blame] | 291 |                 if (!c) | 
 | 292 |                     break; | 
 | 293 |  | 
 | 294 |                 if (c != '#') { | 
 | 295 |                     err_ret->error = E_BADSINGLE; | 
 | 296 |                     PyNode_Free(n); | 
 | 297 |                     n = NULL; | 
 | 298 |                     break; | 
 | 299 |                 } | 
 | 300 |  | 
 | 301 |                 /* Suck up comment. */ | 
 | 302 |                 while (c && c != '\n') | 
 | 303 |                     c = *++cur; | 
| Meador Inge | fa21bf0 | 2012-01-19 01:08:41 -0600 | [diff] [blame] | 304 |             } | 
 | 305 |         } | 
| Benjamin Peterson | 79c1f96 | 2012-01-19 08:48:11 -0500 | [diff] [blame] | 306 | #endif | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 307 |     } | 
 | 308 |     else | 
 | 309 |         n = NULL; | 
| Christian Heimes | b1b3efc | 2008-03-26 23:24:27 +0000 | [diff] [blame] | 310 |  | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 311 | #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 312 |     *flags = ps->p_flags; | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 313 | #endif | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 314 |     PyParser_Delete(ps); | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 315 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 316 |     if (n == NULL) { | 
| Benjamin Peterson | 758888d | 2011-05-30 11:12:38 -0500 | [diff] [blame] | 317 |         if (tok->done == E_EOF) | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 318 |             err_ret->error = E_EOF; | 
 | 319 |         err_ret->lineno = tok->lineno; | 
 | 320 |         if (tok->buf != NULL) { | 
 | 321 |             size_t len; | 
 | 322 |             assert(tok->cur - tok->buf < INT_MAX); | 
 | 323 |             err_ret->offset = (int)(tok->cur - tok->buf); | 
 | 324 |             len = tok->inp - tok->buf; | 
 | 325 |             err_ret->text = (char *) PyObject_MALLOC(len + 1); | 
 | 326 |             if (err_ret->text != NULL) { | 
 | 327 |                 if (len > 0) | 
 | 328 |                     strncpy(err_ret->text, tok->buf, len); | 
 | 329 |                 err_ret->text[len] = '\0'; | 
 | 330 |             } | 
 | 331 |         } | 
 | 332 |     } else if (tok->encoding != NULL) { | 
 | 333 |         /* 'nodes->n_str' uses PyObject_*, while 'tok->encoding' was | 
 | 334 |          * allocated using PyMem_ | 
 | 335 |          */ | 
 | 336 |         node* r = PyNode_New(encoding_decl); | 
 | 337 |         if (r) | 
 | 338 |             r->n_str = PyObject_MALLOC(strlen(tok->encoding)+1); | 
 | 339 |         if (!r || !r->n_str) { | 
 | 340 |             err_ret->error = E_NOMEM; | 
 | 341 |             if (r) | 
 | 342 |                 PyObject_FREE(r); | 
 | 343 |             n = NULL; | 
 | 344 |             goto done; | 
 | 345 |         } | 
 | 346 |         strcpy(r->n_str, tok->encoding); | 
 | 347 |         PyMem_FREE(tok->encoding); | 
 | 348 |         tok->encoding = NULL; | 
 | 349 |         r->n_nchildren = 1; | 
 | 350 |         r->n_child = n; | 
 | 351 |         n = r; | 
 | 352 |     } | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 353 |  | 
| Thomas Wouters | 00ee7ba | 2006-08-21 19:07:27 +0000 | [diff] [blame] | 354 | done: | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 355 |     PyTokenizer_Free(tok); | 
| Guido van Rossum | bd0389d | 1994-08-29 12:25:45 +0000 | [diff] [blame] | 356 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 357 |     return n; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 358 | } | 
| Guido van Rossum | 0c156a5 | 2001-10-20 14:27:56 +0000 | [diff] [blame] | 359 |  | 
| Victor Stinner | 7f2fee3 | 2011-04-05 00:39:01 +0200 | [diff] [blame] | 360 | static int | 
| Victor Stinner | 14e461d | 2013-08-26 22:28:21 +0200 | [diff] [blame] | 361 | initerr(perrdetail *err_ret, PyObject *filename) | 
| Guido van Rossum | 0c156a5 | 2001-10-20 14:27:56 +0000 | [diff] [blame] | 362 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 363 |     err_ret->error = E_OK; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 364 |     err_ret->lineno = 0; | 
 | 365 |     err_ret->offset = 0; | 
 | 366 |     err_ret->text = NULL; | 
 | 367 |     err_ret->token = -1; | 
 | 368 |     err_ret->expected = -1; | 
| Victor Stinner | 7f2fee3 | 2011-04-05 00:39:01 +0200 | [diff] [blame] | 369 | #ifndef PGEN | 
| Victor Stinner | 14e461d | 2013-08-26 22:28:21 +0200 | [diff] [blame] | 370 |     if (filename) { | 
 | 371 |         Py_INCREF(filename); | 
 | 372 |         err_ret->filename = filename; | 
 | 373 |     } | 
 | 374 |     else { | 
| Victor Stinner | 7f2fee3 | 2011-04-05 00:39:01 +0200 | [diff] [blame] | 375 |         err_ret->filename = PyUnicode_FromString("<string>"); | 
| Victor Stinner | 14e461d | 2013-08-26 22:28:21 +0200 | [diff] [blame] | 376 |         if (err_ret->filename == NULL) { | 
 | 377 |             err_ret->error = E_ERROR; | 
 | 378 |             return -1; | 
 | 379 |         } | 
| Victor Stinner | 7f2fee3 | 2011-04-05 00:39:01 +0200 | [diff] [blame] | 380 |     } | 
 | 381 | #endif | 
 | 382 |     return 0; | 
| Guido van Rossum | 0c156a5 | 2001-10-20 14:27:56 +0000 | [diff] [blame] | 383 | } |