root/trunk/src/json.c

Revision 489, 11.0 kB (checked in by walter, 2 years ago)

eliminate more warnings

  • Property svn:eol-style set to native
Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2009 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 // This implements the JSON capability.
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <time.h>
15 #include <ctype.h>
16 #include <assert.h>
17
18 #include "rmem.h"
19 #include "root.h"
20
21 #include "mars.h"
22 #include "dsymbol.h"
23 #include "macro.h"
24 #include "template.h"
25 #include "lexer.h"
26 #include "aggregate.h"
27 #include "declaration.h"
28 #include "enum.h"
29 #include "id.h"
30 #include "module.h"
31 #include "scope.h"
32 #include "hdrgen.h"
33 #include "json.h"
34 #include "mtype.h"
35 #include "attrib.h"
36 #include "cond.h"
37
38 const char Pname[] = "name";
39 const char Pkind[] = "kind";
40 const char Pfile[] = "file";
41 const char Pline[] = "line";
42 const char Ptype[] = "type";
43 const char Pcomment[] = "comment";
44 const char Pmembers[] = "members";
45
46 void JsonRemoveComma(OutBuffer *buf);
47
48 void json_generate(Array *modules)
49 {   OutBuffer buf;
50
51     buf.writestring("[\n");
52     for (int i = 0; i < modules->dim; i++)
53     {   Module *m = (Module *)modules->data[i];
54         if (global.params.verbose)
55             printf("json gen %s\n", m->toChars());
56         m->toJsonBuffer(&buf);
57         buf.writestring(",\n");
58     }
59     JsonRemoveComma(&buf);
60     buf.writestring("]\n");
61
62     // Write buf to file
63     char *arg = global.params.xfilename;
64     if (!arg || !*arg)
65     {   // Generate lib file name from first obj name
66         char *n = (char *)global.params.objfiles->data[0];
67
68         n = FileName::name(n);
69         FileName *fn = FileName::forceExt(n, global.json_ext);
70         arg = fn->toChars();
71     }
72     else if (arg[0] == '-' && arg[1] == 0)
73     {   // Write to stdout; assume it succeeds
74         int n = fwrite(buf.data, 1, buf.offset, stdout);
75         assert(n == buf.offset);        // keep gcc happy about return values
76         return;
77     }
78 //    if (!FileName::absolute(arg))
79 //        arg = FileName::combine(dir, arg);
80     FileName *jsonfilename = FileName::defaultExt(arg, global.json_ext);
81     File *jsonfile = new File(jsonfilename);
82     assert(jsonfile);
83     jsonfile->setbuffer(buf.data, buf.offset);
84     jsonfile->ref = 1;
85     char *pt = FileName::path(jsonfile->toChars());
86     if (*pt)
87         FileName::ensurePathExists(pt);
88     mem.free(pt);
89     jsonfile->writev();
90 }
91
92
93 /*********************************
94  * Encode string into buf, and wrap it in double quotes.
95  */
96 void JsonString(OutBuffer *buf, const char *s)
97 {
98     buf->writeByte('\"');
99     for (; *s; s++)
100     {
101         unsigned char c = (unsigned char) *s;
102         switch (c)
103         {
104             case '\n':
105                 buf->writestring("\\n");
106                 break;
107
108             case '\r':
109                 buf->writestring("\\r");
110                 break;
111
112             case '\t':
113                 buf->writestring("\\t");
114                 break;
115
116             case '\"':
117                 buf->writestring("\\\"");
118                 break;
119
120             case '\\':
121                 buf->writestring("\\\\");
122                 break;
123
124             case '/':
125                 buf->writestring("\\/");
126                 break;
127
128             case '\b':
129                 buf->writestring("\\b");
130                 break;
131
132             case '\f':
133                 buf->writestring("\\f");
134                 break;
135
136             default:
137                 if (c < 0x20)
138                     buf->printf("\\u%04x", c);
139                 else
140                     // Note that UTF-8 chars pass through here just fine
141                     buf->writeByte(c);
142                 break;
143         }
144     }
145     buf->writeByte('\"');
146 }
147
148 void JsonProperty(OutBuffer *buf, const char *name, const char *value)
149 {
150     JsonString(buf, name);
151     buf->writestring(" : ");
152     JsonString(buf, value);
153     buf->writestring(",\n");
154 }
155
156 void JsonProperty(OutBuffer *buf, const char *name, int value)
157 {
158     JsonString(buf, name);
159     buf->writestring(" : ");
160     buf->printf("%d", value);
161     buf->writestring(",\n");
162 }
163
164 void JsonRemoveComma(OutBuffer *buf)
165 {
166     if (buf->offset >= 2 &&
167         buf->data[buf->offset - 2] == ',' &&
168         buf->data[buf->offset - 1] == '\n')
169         buf->offset -= 2;
170 }
171
172 void Dsymbol::toJsonBuffer(OutBuffer *buf)
173 {
174 }
175
176 void Module::toJsonBuffer(OutBuffer *buf)
177 {
178     buf->writestring("{\n");
179
180     if (md)
181         JsonProperty(buf, Pname, md->toChars());
182
183     JsonProperty(buf, Pkind, kind());
184
185     JsonProperty(buf, Pfile, srcfile->toChars());
186
187     if (comment)
188         JsonProperty(buf, Pcomment, (const char *)comment);
189
190     JsonString(buf, Pmembers);
191     buf->writestring(" : [\n");
192
193     size_t offset = buf->offset;
194     for (int i = 0; i < members->dim; i++)
195     {   Dsymbol *s = (Dsymbol *)members->data[i];
196         if (offset != buf->offset)
197         {   buf->writestring(",\n");
198             offset = buf->offset;
199         }
200         s->toJsonBuffer(buf);
201     }
202
203     JsonRemoveComma(buf);
204     buf->writestring("]\n");
205
206     buf->writestring("}\n");
207 }
208
209 void AttribDeclaration::toJsonBuffer(OutBuffer *buf)
210 {
211     //printf("AttribDeclaration::toJsonBuffer()\n");
212
213     Array *d = include(NULL, NULL);
214
215     if (d)
216     {
217         size_t offset = buf->offset;
218         for (unsigned i = 0; i < d->dim; i++)
219         {   Dsymbol *s = (Dsymbol *)d->data[i];
220             //printf("AttribDeclaration::toJsonBuffer %s\n", s->toChars());
221             if (offset != buf->offset)
222             {   buf->writestring(",\n");
223                 offset = buf->offset;
224             }
225             s->toJsonBuffer(buf);
226         }
227         JsonRemoveComma(buf);
228     }
229 }
230
231
232 void ConditionalDeclaration::toJsonBuffer(OutBuffer *buf)
233 {
234     //printf("ConditionalDeclaration::toJsonBuffer()\n");
235     if (condition->inc)
236     {
237         AttribDeclaration::toJsonBuffer(buf);
238     }
239 }
240
241
242 void InvariantDeclaration::toJsonBuffer(OutBuffer *buf)  { }
243 void DtorDeclaration::toJsonBuffer(OutBuffer *buf)       { }
244 void StaticCtorDeclaration::toJsonBuffer(OutBuffer *buf) { }
245 void StaticDtorDeclaration::toJsonBuffer(OutBuffer *buf) { }
246 void ClassInfoDeclaration::toJsonBuffer(OutBuffer *buf)  { }
247 void ModuleInfoDeclaration::toJsonBuffer(OutBuffer *buf) { }
248 void TypeInfoDeclaration::toJsonBuffer(OutBuffer *buf)   { }
249 void UnitTestDeclaration::toJsonBuffer(OutBuffer *buf)   { }
250 #if DMDV2
251 void PostBlitDeclaration::toJsonBuffer(OutBuffer *buf)   { }
252 #endif
253
254 void Declaration::toJsonBuffer(OutBuffer *buf)
255 {
256     //printf("Declaration::toJsonBuffer()\n");
257     buf->writestring("{\n");
258
259     JsonProperty(buf, Pname, toChars());
260     JsonProperty(buf, Pkind, kind());
261     if (type)
262         JsonProperty(buf, Ptype, type->toChars());
263
264     if (comment)
265         JsonProperty(buf, Pcomment, (const char *)comment);
266
267     if (loc.linnum)
268         JsonProperty(buf, Pline, loc.linnum);
269
270     TypedefDeclaration *td = isTypedefDeclaration();
271     if (td)
272     {
273         JsonProperty(buf, "base", td->basetype->toChars());
274     }
275
276     JsonRemoveComma(buf);
277     buf->writestring("}\n");
278 }
279
280 void AggregateDeclaration::toJsonBuffer(OutBuffer *buf)
281 {
282     //printf("AggregateDeclaration::toJsonBuffer()\n");
283     buf->writestring("{\n");
284
285     JsonProperty(buf, Pname, toChars());
286     JsonProperty(buf, Pkind, kind());
287     if (comment)
288         JsonProperty(buf, Pcomment, (const char *)comment);
289     if (loc.linnum)
290         JsonProperty(buf, Pline, loc.linnum);
291
292     ClassDeclaration *cd = isClassDeclaration();
293     if (cd)
294     {
295         if (cd->baseClass)
296         {
297             JsonProperty(buf, "base", cd->baseClass->toChars());
298         }
299         if (cd->interfaces_dim)
300         {
301             JsonString(buf, "interfaces");
302             buf->writestring(" : [\n");
303             size_t offset = buf->offset;
304             for (int i = 0; i < cd->interfaces_dim; i++)
305             {   BaseClass *b = cd->interfaces[i];
306                 if (offset != buf->offset)
307                 {   buf->writestring(",\n");
308                     offset = buf->offset;
309                 }
310                 JsonString(buf, b->base->toChars());
311             }
312             JsonRemoveComma(buf);
313             buf->writestring("],\n");
314         }
315     }
316
317     if (members)
318     {
319         JsonString(buf, Pmembers);
320         buf->writestring(" : [\n");
321         size_t offset = buf->offset;
322         for (int i = 0; i < members->dim; i++)
323         {   Dsymbol *s = (Dsymbol *)members->data[i];
324             if (offset != buf->offset)
325             {   buf->writestring(",\n");
326                 offset = buf->offset;
327             }
328             s->toJsonBuffer(buf);
329         }
330         JsonRemoveComma(buf);
331         buf->writestring("]\n");
332     }
333     JsonRemoveComma(buf);
334
335     buf->writestring("}\n");
336 }
337
338 void TemplateDeclaration::toJsonBuffer(OutBuffer *buf)
339 {
340     //printf("TemplateDeclaration::toJsonBuffer()\n");
341
342     buf->writestring("{\n");
343
344     JsonProperty(buf, Pname, toChars());
345     JsonProperty(buf, Pkind, kind());
346     if (comment)
347         JsonProperty(buf, Pcomment, (const char *)comment);
348
349     if (loc.linnum)
350         JsonProperty(buf, Pline, loc.linnum);
351
352     JsonString(buf, Pmembers);
353     buf->writestring(" : [\n");
354     size_t offset = buf->offset;
355     for (int i = 0; i < members->dim; i++)
356     {   Dsymbol *s = (Dsymbol *)members->data[i];
357         if (offset != buf->offset)
358         {   buf->writestring(",\n");
359             offset = buf->offset;
360         }
361         s->toJsonBuffer(buf);
362     }
363     JsonRemoveComma(buf);
364     buf->writestring("]\n");
365
366     buf->writestring("}\n");
367 }
368
369 void EnumDeclaration::toJsonBuffer(OutBuffer *buf)
370 {
371     //printf("EnumDeclaration::toJsonBuffer()\n");
372     if (isAnonymous())
373     {
374         if (members)
375         {
376             for (int i = 0; i < members->dim; i++)
377             {
378                 Dsymbol *s = (Dsymbol *)members->data[i];
379                 s->toJsonBuffer(buf);
380                 buf->writestring(",\n");
381             }
382             JsonRemoveComma(buf);
383         }
384         return;
385     }
386
387     buf->writestring("{\n");
388
389     JsonProperty(buf, Pname, toChars());
390     JsonProperty(buf, Pkind, kind());
391     if (comment)
392         JsonProperty(buf, Pcomment, (const char *)comment);
393
394     if (loc.linnum)
395         JsonProperty(buf, Pline, loc.linnum);
396
397     if (memtype)
398         JsonProperty(buf, "base", memtype->toChars());
399
400     if (members)
401     {
402         JsonString(buf, Pmembers);
403         buf->writestring(" : [\n");
404         size_t offset = buf->offset;
405         for (int i = 0; i < members->dim; i++)
406         {   Dsymbol *s = (Dsymbol *)members->data[i];
407             if (offset != buf->offset)
408             {   buf->writestring(",\n");
409                 offset = buf->offset;
410             }
411             s->toJsonBuffer(buf);
412         }
413         JsonRemoveComma(buf);
414         buf->writestring("]\n");
415     }
416     JsonRemoveComma(buf);
417
418     buf->writestring("}\n");
419 }
420
421 void EnumMember::toJsonBuffer(OutBuffer *buf)
422 {
423     //printf("EnumMember::toJsonBuffer()\n");
424     buf->writestring("{\n");
425
426     JsonProperty(buf, Pname, toChars());
427     JsonProperty(buf, Pkind, kind());
428
429     if (comment)
430         JsonProperty(buf, Pcomment, (const char *)comment);
431
432     if (loc.linnum)
433         JsonProperty(buf, Pline, loc.linnum);
434
435     JsonRemoveComma(buf);
436     buf->writestring("}\n");
437 }
Note: See TracBrowser for help on using the browser.