Skip to content

Commit 5f8a6e6

Browse files
committed
CPreProcessor: run subparsers for extrating interesting language objects in C comments
1 parent c415954 commit 5f8a6e6

File tree

3 files changed

+141
-8
lines changed

3 files changed

+141
-8
lines changed

main/parse.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4030,7 +4030,8 @@ static unsigned int parserCorkFlags (parserDefinition *parser)
40304030
return r;
40314031
}
40324032

4033-
static void setupLanguageSubparsersInUse (const langType language)
4033+
/* NOTE: Exported only for CPreProcessor */
4034+
extern void setupLanguageSubparsersInUse (const langType language)
40344035
{
40354036
subparser *tmp;
40364037

@@ -4044,7 +4045,8 @@ static void setupLanguageSubparsersInUse (const langType language)
40444045
}
40454046
}
40464047

4047-
static subparser* teardownLanguageSubparsersInUse (const langType language)
4048+
/* NOTE: Exported only for CPreProcessor */
4049+
extern subparser* teardownLanguageSubparsersInUse (const langType language)
40484050
{
40494051
subparser *tmp;
40504052

parsers/cpreprocessor.c

Lines changed: 124 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "general.h" /* must always come first */
1515

1616
#include <string.h>
17+
#include <ctype.h>
1718

1819
#include "debug.h"
1920
#include "entry.h"
@@ -30,6 +31,12 @@
3031

3132
#include "cxx/cxx_debug.h"
3233

34+
/* Ideally these two should be private in "main" part.
35+
* Because the CPreProcessor parser is imperfect as a base parser, the
36+
* parser must call them directly. */
37+
extern subparser* teardownLanguageSubparsersInUse (const langType language);
38+
extern void setupLanguageSubparsersInUse (const langType language);
39+
3340
/*
3441
* MACROS
3542
*/
@@ -296,6 +303,9 @@ static void cppInitCommon(langType clientLang,
296303
t = getNamedLanguage ("CPreProcessor", 0);
297304
initializeParser (t);
298305
}
306+
pushLanguage(Cpp.lang);
307+
setupLanguageSubparsersInUse (Cpp.lang);
308+
popLanguage();
299309

300310
Cpp.clientLang = clientLang;
301311
Cpp.ungetBuffer = NULL;
@@ -439,6 +449,9 @@ extern void cppTerminate (void)
439449
hashTableDelete (Cpp.fileMacroTable);
440450
Cpp.fileMacroTable = NULL;
441451
}
452+
pushLanguage(Cpp.lang);
453+
teardownLanguageSubparsersInUse (Cpp.lang);
454+
popLanguage();
442455
}
443456

444457
extern void cppBeginStatement (void)
@@ -1243,30 +1256,135 @@ static Comment isComment (void)
12431256
return comment;
12441257
}
12451258

1259+
static cPreProcessorSubparser *notifyLineToSubparsers (cPreProcessorSubparser *sub,
1260+
char firstchar,
1261+
vString *line,
1262+
bool *sentThe1stLine)
1263+
{
1264+
if (sub == NULL && *sentThe1stLine == true)
1265+
return NULL;
1266+
1267+
if (!*sentThe1stLine)
1268+
{
1269+
Assert (sub == NULL);
1270+
1271+
subparser *s;
1272+
1273+
*sentThe1stLine = true;
1274+
1275+
pushLanguage (Cpp.lang);
1276+
foreachSubparser(s, false)
1277+
{
1278+
bool b = false;
1279+
cPreProcessorSubparser *cpp = (cPreProcessorSubparser *)s;
1280+
enterSubparser(s);
1281+
if (cpp->firstLineNotify)
1282+
b = cpp->firstLineNotify (cpp, firstchar, vStringValue(line));
1283+
leaveSubparser();
1284+
1285+
if (b)
1286+
{
1287+
sub = cpp;
1288+
break;
1289+
}
1290+
}
1291+
popLanguage ();
1292+
return sub;
1293+
}
1294+
1295+
enterSubparser(&sub->subparser);
1296+
if (sub->restLineNotify)
1297+
sub->restLineNotify (sub, vStringValue(line));
1298+
leaveSubparser();
1299+
return sub;
1300+
}
1301+
1302+
static void notifyEndOfComment (cPreProcessorSubparser *cpp)
1303+
{
1304+
enterSubparser(&cpp->subparser);
1305+
if (cpp->endOfCommentNotify)
1306+
cpp->endOfCommentNotify(cpp);
1307+
leaveSubparser();
1308+
}
1309+
1310+
static bool isDocCommentStarter(int c)
1311+
{
1312+
return c == '*';
1313+
}
1314+
1315+
static bool isWhitespaceOnly (vString *line)
1316+
{
1317+
const char *c = vStringValue(line);
1318+
1319+
while (*c)
1320+
{
1321+
if (!isspace((unsigned char) *c)
1322+
&& !isDocCommentStarter(*c))
1323+
return false;
1324+
c++;
1325+
}
1326+
return true;
1327+
}
1328+
12461329
/* Skips over a C style comment. According to ANSI specification a comment
12471330
* is treated as white space, so we perform this substitution.
1331+
*
1332+
* As side effects, running subparsers interested in comments.
12481333
*/
12491334
static int cppSkipOverCComment (void)
12501335
{
12511336
int c = cppGetcFromUngetBufferOrFile ();
1337+
int c0 = 0;
1338+
vString *line = NULL;
1339+
bool sentThe1stLine = false;
1340+
cPreProcessorSubparser *sub = NULL;
1341+
1342+
1343+
if (isDocCommentStarter (c))
1344+
{
1345+
c0 = c;
1346+
c = cppGetcFromUngetBufferOrFile ();
1347+
if (c0 == '*' && c == '/')
1348+
return SPACE;
1349+
cppUngetc (c);
1350+
c = c0;
1351+
line = vStringNew ();
1352+
}
12521353

12531354
while (c != EOF)
12541355
{
1255-
if (c != '*')
1256-
c = cppGetcFromUngetBufferOrFile ();
1257-
else
1356+
if (c == '*')
12581357
{
12591358
const int next = cppGetcFromUngetBufferOrFile ();
12601359

1261-
if (next != '/')
1262-
c = next;
1263-
else
1360+
if (next == '/')
12641361
{
12651362
c = SPACE; /* replace comment with space */
12661363
break;
12671364
}
1365+
cppUngetc (next);
12681366
}
1367+
1368+
if (line)
1369+
{
1370+
vStringPut (line, c);
1371+
if (c == '\n')
1372+
{
1373+
if (sub || !isWhitespaceOnly (line))
1374+
sub = notifyLineToSubparsers (sub, c0, line, &sentThe1stLine);
1375+
vStringClear (line);
1376+
}
1377+
}
1378+
c = cppGetcFromUngetBufferOrFile ();
12691379
}
1380+
1381+
if (line && !vStringIsEmpty(line) && (sub || !isWhitespaceOnly (line)))
1382+
sub = notifyLineToSubparsers (sub, c0, line, &sentThe1stLine);
1383+
1384+
if (sub)
1385+
notifyEndOfComment (sub);
1386+
1387+
vStringDelete (line); /* NULL is acceptable */
12701388
return c;
12711389
}
12721390

parsers/cpreprocessor.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include "types.h"
1818
#include "vstring.h"
1919

20+
#include "subparser.h"
21+
2022
/*
2123
* MACROS
2224
*/
@@ -144,4 +146,15 @@ extern void cppBuildMacroReplacementWithPtrArrayAndUngetResult(
144146
cppMacroInfo * macro,
145147
const ptrArray * args);
146148

149+
/* Running a parser inside comments. */
150+
typedef struct sCPreProcessorSubparser cPreProcessorSubparser;
151+
152+
struct sCPreProcessorSubparser {
153+
subparser subparser;
154+
155+
bool (* firstLineNotify) (cPreProcessorSubparser *s, char firstchar, const char *line);
156+
void (* restLineNotify) (cPreProcessorSubparser *s, const char *line);
157+
void (* endOfCommentNotify) (cPreProcessorSubparser *s);
158+
};
159+
147160
#endif /* CTAGS_MAIN_GET_H */

0 commit comments

Comments
 (0)