Some sync of lcpp.c/h

Sync things which are possible to sync from lcpp.c/h. This file is heavily
dependent on c.c and since our c.c differs quite significantly, it's
not possible to use the universal-ctags implementation right now.
This commit is contained in:
Jiří Techet 2016-10-09 11:04:51 +02:00
parent 1a43ee2afa
commit e685d956d6
4 changed files with 82 additions and 34 deletions

View File

@ -26,6 +26,7 @@
#define WHOLE_FILE -1L
#define NO_PARSER_FIELD -1
#define CORK_NIL 0
/*
* DATA DECLARATIONS

View File

@ -22,7 +22,7 @@
#include "options.h"
#include "read.h"
#include "vstring.h"
#include "routines.h"
#include "parse.h"
#include "xtag.h"
/*
@ -135,10 +135,7 @@ extern void cppInit (const bool state, const bool hasAtLiteralStrings,
Cpp.directive.ifdef [0].branchChosen = false;
Cpp.directive.ifdef [0].ignoring = false;
if (Cpp.directive.name == NULL)
Cpp.directive.name = vStringNew ();
else
vStringClear (Cpp.directive.name);
Cpp.directive.name = vStringNewOrClear (Cpp.directive.name);
}
extern void cppTerminate (void)
@ -305,35 +302,40 @@ static bool popConditional (void)
return isIgnore ();
}
static void makeDefineTag (const char *const name, bool parameterized)
static int makeDefineTag (const char *const name, bool parameterized, bool undef)
{
const bool isFileScope = (bool) (! isInputHeaderFile ());
if (includingDefineTags () &&
(! isFileScope || isXtagEnabled(XTAG_FILE_SCOPE)))
if (!Cpp.defineMacroKind)
return CORK_NIL;
if (isFileScope && !isXtagEnabled(XTAG_FILE_SCOPE))
return CORK_NIL;
if ( /* condition for definition tag */
((!undef) && Cpp.defineMacroKind->enabled)
|| /* condition for reference tag */
(undef && isXtagEnabled(XTAG_REFERENCE_TAGS)))
{
tagEntryInfo e;
initTagEntry (&e, name, Cpp.defineMacroKind);
e.lineNumberEntry = (bool) (Option.locate != EX_PATTERN);
e.lineNumberEntry = (bool) (Option.locate == EX_LINENUM);
e.isFileScope = isFileScope;
e.truncateLine = true;
if (parameterized)
{
e.extensionFields.signature = cppGetArglistFromFilePos(getInputFilePosition()
, e.name);
}
e.extensionFields.signature = cppGetArglistFromFilePos(getInputFilePosition(), e.name);
makeTagEntry (&e);
if (parameterized)
eFree((char *) e.extensionFields.signature);
}
return CORK_NIL;
}
static void directiveDefine (const int c)
static int directiveDefine (const int c, bool undef)
{
bool parameterized;
int nc;
int r = CORK_NIL;
if (cppIsident1 (c))
{
@ -342,9 +344,22 @@ static void directiveDefine (const int c)
ungetcToInputFile (nc);
parameterized = (bool) (nc == '(');
if (! isIgnore ())
makeDefineTag (vStringValue (Cpp.directive.name), parameterized);
makeDefineTag (vStringValue (Cpp.directive.name), parameterized, undef);
}
Cpp.directive.state = DRCTV_NONE;
return r;
}
static void directiveUndef (const int c)
{
if (isXtagEnabled (XTAG_REFERENCE_TAGS))
{
directiveDefine (c, true);
}
else
{
Cpp.directive.state = DRCTV_NONE;
}
}
static void directivePragma (int c)
@ -362,7 +377,7 @@ static void directivePragma (int c)
if (cppIsident1 (c))
{
readIdentifier (c, Cpp.directive.name);
makeDefineTag (vStringValue (Cpp.directive.name), false);
makeDefineTag (vStringValue (Cpp.directive.name), NULL, false);
}
}
}
@ -417,18 +432,20 @@ static bool directiveHash (const int c)
/* Handles a pre-processor directive whose first character is given by "c".
*/
static bool handleDirective (const int c)
static bool handleDirective (const int c, int *macroCorkIndex)
{
bool ignore = isIgnore ();
switch (Cpp.directive.state)
{
case DRCTV_NONE: ignore = isIgnore (); break;
case DRCTV_DEFINE: directiveDefine (c); break;
case DRCTV_DEFINE:
*macroCorkIndex = directiveDefine (c, false);
break;
case DRCTV_HASH: ignore = directiveHash (c); break;
case DRCTV_IF: ignore = directiveIf (c); break;
case DRCTV_PRAGMA: directivePragma (c); break;
case DRCTV_UNDEF: directiveDefine (c); break;
case DRCTV_UNDEF: directiveUndef (c); break;
}
return ignore;
}
@ -612,13 +629,6 @@ static int skipToEndOfChar (void)
ungetcToInputFile (c);
break;
}
else if (count == 1 && strchr ("DHOB", toupper (c)) != NULL)
veraBase = c;
else if (veraBase != '\0' && ! isalnum (c))
{
ungetcToInputFile (c);
break;
}
}
return CHAR_SYMBOL; /* symbolic representation of character */
}
@ -633,6 +643,7 @@ extern int cppGetc (void)
bool directive = false;
bool ignore = false;
int c;
int macroCorkIndex = CORK_NIL;
if (Cpp.ungetch != '\0')
{
@ -643,6 +654,7 @@ extern int cppGetc (void)
}
else do
{
start_loop:
c = getcFromInputFile ();
process:
switch (c)
@ -650,6 +662,7 @@ process:
case EOF:
ignore = false;
directive = false;
macroCorkIndex = CORK_NIL;
break;
case TAB:
@ -658,7 +671,10 @@ process:
case NEWLINE:
if (directive && ! ignore)
{
macroCorkIndex = CORK_NIL;
directive = false;
}
Cpp.directive.accept = true;
break;
@ -705,7 +721,7 @@ process:
int next = getcFromInputFile ();
if (next == NEWLINE)
continue;
goto start_loop;
else
ungetcToInputFile (next);
break;
@ -828,7 +844,7 @@ process:
enter:
Cpp.directive.accept = false;
if (directive)
ignore = handleDirective (c);
ignore = handleDirective (c, &macroCorkIndex);
break;
}
} while (directive || ignore);

View File

@ -28,7 +28,32 @@
* VMS allows '$' in identifiers.
* Vala allows '@' in identifiers.
*/
#define cppIsident1(c) (isalpha(c) || (c) == '_' || (c) == '~' || (c) == '$' || (c) == '@')
#define cppIsident1(c) ( ((c >= 0) && (c < 0x80) && isalpha(c)) \
|| (c) == '_' || (c) == '~' || (c) == '$' || (c) == '@')
/* NOTE about isident1 profitability
Doing the same as isascii before passing value to isalpha
----------------------------------------------------------
cppGetc() can return the value out of range of char.
cppGetc calls skipToEndOfString and skipToEndOfString can
return STRING_SYMBOL(== 338).
Depending on the platform, isalpha(338) returns different value .
As far as Fedora22, it returns 0. On Windows 2010, it returns 1.
man page on Fedora 22 says:
These functions check whether c, which must have the value of an
unsigned char or EOF, falls into a certain character class
according to the specified locale.
isascii is for suitable to verify the range of input. However, it
is not portable enough. */
#define RoleTemplateUndef { true, "undef", "undefined" }
#define RoleTemplateSystem { true, "system", "system header" }
#define RoleTemplateLocal { true, "local", "local header" }
/*
* FUNCTION PROTOTYPES
@ -36,7 +61,8 @@
extern bool cppIsBraceFormat (void);
extern unsigned int cppGetDirectiveNestLevel (void);
extern void cppInit (const bool state, const bool hasAtLiteralStrings,
extern void cppInit (const bool state,
const bool hasAtLiteralStrings,
const bool hasCxxRawLiteralStrings,
const kindOption *defineMacroKind);
extern void cppTerminate (void);

View File

@ -3138,11 +3138,16 @@ static bool findCTags (const unsigned int passCount)
{
exception_t exception;
bool retry;
kindOption *kind_for_define = NULL;
contextual_fake_count = 0;
Assert (passCount < 3);
cppInit ((bool) (passCount > 1), isInputLanguage (Lang_csharp), isInputLanguage (Lang_cpp), &(CKinds [CK_DEFINE]));
kind_for_define = CKinds+CK_DEFINE;
cppInit ((bool) (passCount > 1), isInputLanguage (Lang_csharp), isInputLanguage(Lang_cpp),
kind_for_define);
exception = (exception_t) setjmp (Exception);
retry = false;