1 /*
2 * Copyright (c) 2021 Masatake YAMATO
3 *
4 * This source code is released for free distribution under the terms of the
5 * GNU General Public License version 2 or (at your option) any later version.
6 *
7 * This module contains macros, data decls and prototypes to generate tags for Thrift IDL.
8 * Reference: https://thrift.apache.org/docs/idl
9 */
10
11 /*
12 * INCLUDE FILES
13 */
14 #include "options.h"
15 #include "parse.h"
16 #include "routines.h"
17 #include "dependency.h"
18
makeThriftTagFull(struct parserCtx * auxil,const char * name,long offset,int kind,int role,bool pushScope)19 static int makeThriftTagFull (struct parserCtx *auxil, const char *name, long offset, int kind, int role,
20 bool pushScope)
21 {
22 tagEntryInfo e;
23 int k = (kind == USE_KIND_STACK? PEEK_KIND (auxil): kind);
24 if (role == ROLE_DEFINITION_INDEX)
25 initTagEntry(&e, name, k);
26 else
27 initRefTagEntry(&e, name, k, role);
28 e.lineNumber = getInputLineNumberForFileOffset (offset);
29 e.filePosition = getInputFilePositionForLine (e.lineNumber);
30 e.extensionFields.scopeIndex = BASE_SCOPE (auxil);
31 int scope_index = makeTagEntry (&e);
32 if (pushScope)
33 SET_SCOPE(auxil, scope_index);
34 return scope_index;
35 }
36
makeThriftTag(struct parserCtx * auxil,const char * name,long offset,int kind,bool pushScope)37 static int makeThriftTag (struct parserCtx *auxil, const char *name, long offset, int kind, bool pushScope)
38 {
39 return makeThriftTagFull (auxil, name, offset, kind, ROLE_DEFINITION_INDEX, pushScope);
40 }
41
unliteral(const char * literal)42 static vString* unliteral(const char *literal)
43 {
44 vString *vstr = vStringNew ();
45
46 const char *c = literal;
47 if (*c == '"' || *c == '\'')
48 c++;
49
50 for (; *c != '\0'; c++)
51 {
52 if (*c == '\\')
53 {
54 c++;
55 if (*c == '\0')
56 break;
57
58 /* ???
59 * How the backslash is handled is not wel explained in the document. */
60 if (! (*c == '"' || *c == '\'' || *c == '\\'))
61 vStringPut (vstr, '\\');
62 }
63 vStringPut (vstr, *c);
64 }
65
66 if (vStringLength (vstr) > 0 &&
67 (vStringLast (vstr) == '"' ||
68 vStringLast (vstr) == '\''))
69 vStringTruncate(vstr, vStringLength(vstr) - 1);
70
71 return vstr;
72 }
73
ctxInit(struct parserCtx * auxil)74 static void ctxInit (struct parserCtx *auxil)
75 {
76 BASE_INIT(auxil, K_STRUCT);
77 }
78
ctxFini(struct parserCtx * auxil)79 static void ctxFini (struct parserCtx *auxil)
80 {
81 BASE_FINI(auxil);
82 }
83
findThriftTags(void)84 static void findThriftTags (void)
85 {
86 struct parserCtx auxil;
87
88 ctxInit (&auxil);
89 // BASE_DEBUG_RULE(&auxil, "Const");
90
91 pthrift_context_t *pctx = pthrift_create(&auxil);
92
93 while ( pthrift_parse(pctx, NULL) && (!BASE_ERROR(&auxil)) );
94
95 pthrift_destroy(pctx);
96 ctxFini (&auxil);
97 }
98
ThriftParser(void)99 extern parserDefinition* ThriftParser (void)
100 {
101 static const char *const extensions [] = { "thrift", NULL };
102 parserDefinition* def = parserNew ("Thrift");
103
104 static parserDependency dependencies [] = {
105 [0] = { DEPTYPE_FOREIGNER, "C++", NULL },
106 };
107
108 def->kindTable = ThriftKinds;
109 def->kindCount = ARRAY_SIZE (ThriftKinds);
110 def->fieldTable = ThriftFields;
111 def->fieldCount = ARRAY_SIZE (ThriftFields);
112 def->extensions = extensions;
113 def->dependencies = dependencies;
114 def->dependencyCount = ARRAY_SIZE (dependencies);
115 def->parser = findThriftTags;
116 def->useCork = true;
117 def->enabled = true;
118 def->defaultScopeSeparator = ".";
119 return def;
120 }
121