Location | Tool | Test ID | Function | Issue |
---|---|---|---|---|
/builddir/build/BUILD/Python-2.7.3/Parser/pgenmain.c:152:20 | clang-analyzer | Potential leak of memory pointed to by 'p' |
1 /* Parser generator main program */
2
3 /* This expects a filename containing the grammar as argv[1] (UNIX)
4 or asks the console for such a file name (THINK C).
5 It writes its output on two files in the current directory:
6 - "graminit.c" gets the grammar as a bunch of initialized data
7 - "graminit.h" gets the grammar's non-terminals as #defines.
8 Error messages and status info during the generation process are
9 written to stdout, or sometimes to stderr. */
10
11 /* XXX TO DO:
12 - check for duplicate definitions of names (instead of fatal err)
13 */
14
15 #include "Python.h"
16 #include "pgenheaders.h"
17 #include "grammar.h"
18 #include "node.h"
19 #include "parsetok.h"
20 #include "pgen.h"
21
22 int Py_DebugFlag;
23 int Py_VerboseFlag;
24 int Py_IgnoreEnvironmentFlag;
25
26 /* Forward */
27 grammar *getgrammar(char *filename);
28
29 void
30 Py_Exit(int sts)
31 {
32 exit(sts);
33 }
34
35 int
36 main(int argc, char **argv)
37 {
38 grammar *g;
39 FILE *fp;
40 char *filename, *graminit_h, *graminit_c;
41
42 if (argc != 4) {
43 fprintf(stderr,
44 "usage: %s grammar graminit.h graminit.c\n", argv[0]);
45 Py_Exit(2);
46 }
47 filename = argv[1];
48 graminit_h = argv[2];
49 graminit_c = argv[3];
50 g = getgrammar(filename);
51 fp = fopen(graminit_c, "w");
52 if (fp == NULL) {
53 perror(graminit_c);
54 Py_Exit(1);
55 }
56 if (Py_DebugFlag)
57 printf("Writing %s ...\n", graminit_c);
58 printgrammar(g, fp);
59 fclose(fp);
60 fp = fopen(graminit_h, "w");
61 if (fp == NULL) {
62 perror(graminit_h);
63 Py_Exit(1);
64 }
65 if (Py_DebugFlag)
66 printf("Writing %s ...\n", graminit_h);
67 printnonterminals(g, fp);
68 fclose(fp);
69 Py_Exit(0);
70 return 0; /* Make gcc -Wall happy */
71 }
72
73 grammar *
74 getgrammar(char *filename)
75 {
76 FILE *fp;
77 node *n;
78 grammar *g0, *g;
79 perrdetail err;
80
81 fp = fopen(filename, "r");
82 if (fp == NULL) {
83 perror(filename);
84 Py_Exit(1);
85 }
86 g0 = meta_grammar();
87 n = PyParser_ParseFile(fp, filename, g0, g0->g_start,
88 (char *)NULL, (char *)NULL, &err);
89 fclose(fp);
90 if (n == NULL) {
91 fprintf(stderr, "Parsing error %d, line %d.\n",
92 err.error, err.lineno);
93 if (err.text != NULL) {
94 size_t i;
95 fprintf(stderr, "%s", err.text);
96 i = strlen(err.text);
97 if (i == 0 || err.text[i-1] != '\n')
98 fprintf(stderr, "\n");
99 for (i = 0; i < err.offset; i++) {
100 if (err.text[i] == '\t')
101 putc('\t', stderr);
102 else
103 putc(' ', stderr);
104 }
105 fprintf(stderr, "^\n");
106 PyObject_FREE(err.text);
107 }
108 Py_Exit(1);
109 }
110 g = pgen(n);
111 if (g == NULL) {
112 printf("Bad grammar.\n");
113 Py_Exit(1);
114 }
115 return g;
116 }
117
118 /* Can't happen in pgen */
119 PyObject*
120 PyErr_Occurred()
121 {
122 return 0;
123 }
124
125 void
126 Py_FatalError(const char *msg)
127 {
128 fprintf(stderr, "pgen: FATAL ERROR: %s\n", msg);
129 Py_Exit(1);
130 }
131
132 /* No-nonsense my_readline() for tokenizer.c */
133
134 char *
135 PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
136 {
137 size_t n = 1000;
138 char *p = (char *)PyMem_MALLOC(n);
139 char *q;
140 if (p == NULL)
141 return NULL;
142 fprintf(stderr, "%s", prompt);
143 q = fgets(p, n, sys_stdin);
144 if (q == NULL) {
145 *p = '\0';
146 return p;
147 }
148 n = strlen(p);
149 if (n > 0 && p[n-1] != '\n')
150 p[n-1] = '\n';
151 return (char *)PyMem_REALLOC(p, n+1);
152 }
(emitted by clang-analyzer)TODO: a detailed trace is available in the data model (not yet rendered in this report)
153
154 /* No-nonsense fgets */
155 char *
156 Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
157 {
158 return fgets(buf, n, stream);
159 }
160
161
162 #include <stdarg.h>
163
164 void
165 PySys_WriteStderr(const char *format, ...)
166 {
167 va_list va;
168
169 va_start(va, format);
170 vfprintf(stderr, format, va);
171 va_end(va);
172 }