Updated for 2.1a3
[python/dscho.git] / Python / future.c
blobf67abc978f8777b2a2f53af743fe35e3924ea2c7
1 #include "Python.h"
2 #include "node.h"
3 #include "token.h"
4 #include "graminit.h"
5 #include "compile.h"
6 #include "symtable.h"
8 #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
10 static int
11 future_check_features(PyFutureFeatures *ff, node *n)
13 int i;
14 char *feature;
16 REQ(n, import_stmt); /* must by from __future__ import ... */
18 for (i = 3; i < NCH(n); ++i) {
19 feature = STR(CHILD(CHILD(n, i), 0));
20 if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
21 ff->ff_nested_scopes = 1;
22 } else {
23 PyErr_Format(PyExc_SyntaxError,
24 UNDEFINED_FUTURE_FEATURE, feature);
25 return -1;
28 return 0;
31 /* Relevant portions of the grammar:
33 single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
34 file_input: (NEWLINE | stmt)* ENDMARKER
35 stmt: simple_stmt | compound_stmt
36 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
37 small_stmt: expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | exec_stmt | assert_stmt
38 import_stmt: 'import' dotted_as_name (',' dotted_as_name)* | 'from' dotted_name 'import' ('*' | import_as_name (',' import_as_name)*)
39 import_as_name: NAME [NAME NAME]
40 dotted_as_name: dotted_name [NAME NAME]
41 dotted_name: NAME ('.' NAME)*
44 /* future_parse() return values:
45 -1 indicates an error occurred, e.g. unknown feature name
46 0 indicates no feature was found
47 1 indicates a feature was found
50 static int
51 future_parse(PyFutureFeatures *ff, node *n)
53 int i, r, found;
54 loop:
56 /* fprintf(stderr, "future_parse(%d, %d, %s)\n",
57 TYPE(n), NCH(n), (n == NULL) ? "NULL" : STR(n));
59 switch (TYPE(n)) {
61 case file_input:
62 for (i = 0; i < NCH(n); i++) {
63 node *ch = CHILD(n, i);
64 if (TYPE(ch) == stmt) {
65 n = ch;
66 goto loop;
69 return 0;
71 case simple_stmt:
72 if (NCH(n) == 1) {
73 REQ(CHILD(n, 0), small_stmt);
74 n = CHILD(n, 0);
75 goto loop;
77 found = 0;
78 for (i = 0; i < NCH(n); ++i)
79 if (TYPE(CHILD(n, i)) == small_stmt) {
80 r = future_parse(ff, CHILD(n, i));
81 if (r < 1) {
82 ff->ff_last_lineno = n->n_lineno;
83 ff->ff_n_simple_stmt = i;
84 return r;
85 } else
86 found++;
88 if (found)
89 return 1;
90 else
91 return 0;
93 case stmt:
94 if (TYPE(CHILD(n, 0)) == simple_stmt) {
95 n = CHILD(n, 0);
96 goto loop;
97 } else {
98 REQ(CHILD(n, 0), compound_stmt);
99 ff->ff_last_lineno = n->n_lineno;
100 return 0;
103 case small_stmt:
104 n = CHILD(n, 0);
105 goto loop;
107 case import_stmt: {
108 node *name;
110 if (STR(CHILD(n, 0))[0] != 'f') { /* from */
111 ff->ff_last_lineno = n->n_lineno;
112 return 0;
114 name = CHILD(n, 1);
115 if (strcmp(STR(CHILD(name, 0)), "__future__") != 0)
116 return 0;
117 if (future_check_features(ff, n) < 0)
118 return -1;
119 return 1;
122 default:
123 ff->ff_last_lineno = n->n_lineno;
124 return 0;
128 PyFutureFeatures *
129 PyNode_Future(node *n, char *filename)
131 PyFutureFeatures *ff;
133 ff = (PyFutureFeatures *)PyMem_Malloc(sizeof(PyFutureFeatures));
134 if (ff == NULL)
135 return NULL;
136 ff->ff_last_lineno = 0;
137 ff->ff_n_simple_stmt = -1;
138 ff->ff_nested_scopes = 0;
140 if (future_parse(ff, n) < 0) {
141 PyMem_Free((void *)ff);
142 return NULL;
144 return ff;