xref: /Universal-ctags/peg/thrift_post.h (revision 243bfd56d3e6ce287995c1fff534e20047e1babc)
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