13ae02089SMasatake YAMATO
23ae02089SMasatake YAMATO /*
33ae02089SMasatake YAMATO * Copyright (c) 2010, Vincent Berthoux
43ae02089SMasatake YAMATO *
53ae02089SMasatake YAMATO * This source code is released for free distribution under the terms of the
60ce38835Sviccuad * GNU General Public License version 2 or (at your option) any later version.
73ae02089SMasatake YAMATO *
83ae02089SMasatake YAMATO * This module contains functions for generating tags for Objective C
93ae02089SMasatake YAMATO * language files.
103ae02089SMasatake YAMATO */
113ae02089SMasatake YAMATO /*
123ae02089SMasatake YAMATO * INCLUDE FILES
133ae02089SMasatake YAMATO */
143ae02089SMasatake YAMATO #include "general.h" /* must always come first */
153ae02089SMasatake YAMATO
163ae02089SMasatake YAMATO #include <string.h>
173ae02089SMasatake YAMATO
183ae02089SMasatake YAMATO #include "keyword.h"
19a67d9dbeSMasatake YAMATO #include "debug.h"
203ae02089SMasatake YAMATO #include "entry.h"
210d502ef0SMasatake YAMATO #include "parse.h"
223ae02089SMasatake YAMATO #include "read.h"
233ae02089SMasatake YAMATO #include "routines.h"
2467b3f87eSMasatake YAMATO #include "selectors.h"
25d650c941SMasatake YAMATO #include "trashbox.h"
263ae02089SMasatake YAMATO #include "vstring.h"
273ae02089SMasatake YAMATO
283ae02089SMasatake YAMATO typedef enum {
293ae02089SMasatake YAMATO K_INTERFACE,
303ae02089SMasatake YAMATO K_IMPLEMENTATION,
313ae02089SMasatake YAMATO K_PROTOCOL,
323ae02089SMasatake YAMATO K_METHOD,
333ae02089SMasatake YAMATO K_CLASSMETHOD,
343ae02089SMasatake YAMATO K_VAR,
353ae02089SMasatake YAMATO K_FIELD,
363ae02089SMasatake YAMATO K_FUNCTION,
373ae02089SMasatake YAMATO K_PROPERTY,
383ae02089SMasatake YAMATO K_TYPEDEF,
393ae02089SMasatake YAMATO K_STRUCT,
403ae02089SMasatake YAMATO K_ENUM,
419af73c5bSMasatake YAMATO K_MACRO,
429af73c5bSMasatake YAMATO K_CATEGORY,
433ae02089SMasatake YAMATO } objcKind;
443ae02089SMasatake YAMATO
45e112e8abSMasatake YAMATO static kindDefinition ObjcKinds[] = {
46ce990805SThomas Braun {true, 'i', "interface", "class interface"},
47ce990805SThomas Braun {true, 'I', "implementation", "class implementation"},
48ce990805SThomas Braun {true, 'P', "protocol", "Protocol"},
49ce990805SThomas Braun {true, 'm', "method", "Object's method"},
50ce990805SThomas Braun {true, 'c', "class", "Class' method"},
51ce990805SThomas Braun {true, 'v', "var", "Global variable"},
528050d8baSMasatake YAMATO {true, 'E', "field", "Object field"},
53ce990805SThomas Braun {true, 'f', "function", "A function"},
54ce990805SThomas Braun {true, 'p', "property", "A property"},
55ce990805SThomas Braun {true, 't', "typedef", "A type alias"},
56ce990805SThomas Braun {true, 's', "struct", "A type structure"},
57ce990805SThomas Braun {true, 'e', "enum", "An enumeration"},
58ce990805SThomas Braun {true, 'M', "macro", "A preprocessor macro"},
599af73c5bSMasatake YAMATO {true, 'C', "category", "categories"},
603ae02089SMasatake YAMATO };
613ae02089SMasatake YAMATO
623ae02089SMasatake YAMATO typedef enum {
633ae02089SMasatake YAMATO ObjcTYPEDEF,
643ae02089SMasatake YAMATO ObjcSTRUCT,
653ae02089SMasatake YAMATO ObjcENUM,
663ae02089SMasatake YAMATO ObjcIMPLEMENTATION,
673ae02089SMasatake YAMATO ObjcINTERFACE,
683ae02089SMasatake YAMATO ObjcPROTOCOL,
693ae02089SMasatake YAMATO ObjcENCODE,
702b88b85fSMasatake YAMATO ObjcEXTERN,
713ae02089SMasatake YAMATO ObjcSYNCHRONIZED,
723ae02089SMasatake YAMATO ObjcSELECTOR,
733ae02089SMasatake YAMATO ObjcPROPERTY,
743ae02089SMasatake YAMATO ObjcEND,
753ae02089SMasatake YAMATO ObjcDEFS,
763ae02089SMasatake YAMATO ObjcCLASS,
773ae02089SMasatake YAMATO ObjcPRIVATE,
783ae02089SMasatake YAMATO ObjcPACKAGE,
793ae02089SMasatake YAMATO ObjcPUBLIC,
803ae02089SMasatake YAMATO ObjcPROTECTED,
813ae02089SMasatake YAMATO ObjcSYNTHESIZE,
823ae02089SMasatake YAMATO ObjcDYNAMIC,
833ae02089SMasatake YAMATO ObjcOPTIONAL,
843ae02089SMasatake YAMATO ObjcREQUIRED,
853ae02089SMasatake YAMATO ObjcSTRING,
863ae02089SMasatake YAMATO ObjcIDENTIFIER,
873ae02089SMasatake YAMATO
883ae02089SMasatake YAMATO Tok_COMA, /* ',' */
893ae02089SMasatake YAMATO Tok_PLUS, /* '+' */
903ae02089SMasatake YAMATO Tok_MINUS, /* '-' */
913ae02089SMasatake YAMATO Tok_PARL, /* '(' */
923ae02089SMasatake YAMATO Tok_PARR, /* ')' */
933ae02089SMasatake YAMATO Tok_CurlL, /* '{' */
943ae02089SMasatake YAMATO Tok_CurlR, /* '}' */
953ae02089SMasatake YAMATO Tok_SQUAREL, /* '[' */
963ae02089SMasatake YAMATO Tok_SQUARER, /* ']' */
973ae02089SMasatake YAMATO Tok_semi, /* ';' */
983ae02089SMasatake YAMATO Tok_dpoint, /* ':' */
993ae02089SMasatake YAMATO Tok_Sharp, /* '#' */
1003ae02089SMasatake YAMATO Tok_Backslash, /* '\\' */
10180eb4460SMasatake YAMATO Tok_Asterisk, /* '*' */
102d650c941SMasatake YAMATO Tok_ANGLEL, /* '<' */
103d650c941SMasatake YAMATO Tok_ANGLER, /* '>' */
1043ae02089SMasatake YAMATO Tok_EOL, /* '\r''\n' */
1052b88b85fSMasatake YAMATO Tok_CSTRING, /* "..." */
1063ae02089SMasatake YAMATO Tok_any,
1073ae02089SMasatake YAMATO
1083ae02089SMasatake YAMATO Tok_EOF /* END of file */
1093ae02089SMasatake YAMATO } objcKeyword;
1103ae02089SMasatake YAMATO
1113ae02089SMasatake YAMATO typedef objcKeyword objcToken;
1123ae02089SMasatake YAMATO
11382c11d8cSRich Siegel static const keywordTable objcKeywordTable[] = {
1143ae02089SMasatake YAMATO {"typedef", ObjcTYPEDEF},
1153ae02089SMasatake YAMATO {"struct", ObjcSTRUCT},
1163ae02089SMasatake YAMATO {"enum", ObjcENUM},
1172b88b85fSMasatake YAMATO {"extern", ObjcEXTERN},
1183ae02089SMasatake YAMATO {"@implementation", ObjcIMPLEMENTATION},
1193ae02089SMasatake YAMATO {"@interface", ObjcINTERFACE},
1203ae02089SMasatake YAMATO {"@protocol", ObjcPROTOCOL},
1213ae02089SMasatake YAMATO {"@encode", ObjcENCODE},
1223ae02089SMasatake YAMATO {"@property", ObjcPROPERTY},
1233ae02089SMasatake YAMATO {"@synchronized", ObjcSYNCHRONIZED},
1243ae02089SMasatake YAMATO {"@selector", ObjcSELECTOR},
1253ae02089SMasatake YAMATO {"@end", ObjcEND},
1263ae02089SMasatake YAMATO {"@defs", ObjcDEFS},
1273ae02089SMasatake YAMATO {"@class", ObjcCLASS},
1283ae02089SMasatake YAMATO {"@private", ObjcPRIVATE},
1293ae02089SMasatake YAMATO {"@package", ObjcPACKAGE},
1303ae02089SMasatake YAMATO {"@public", ObjcPUBLIC},
1313ae02089SMasatake YAMATO {"@protected", ObjcPROTECTED},
1323ae02089SMasatake YAMATO {"@synthesize", ObjcSYNTHESIZE},
1333ae02089SMasatake YAMATO {"@dynamic", ObjcDYNAMIC},
1343ae02089SMasatake YAMATO {"@optional", ObjcOPTIONAL},
1353ae02089SMasatake YAMATO {"@required", ObjcREQUIRED},
1363ae02089SMasatake YAMATO };
1373ae02089SMasatake YAMATO
1389af73c5bSMasatake YAMATO typedef enum {
1399af73c5bSMasatake YAMATO F_CATEGORY,
140d650c941SMasatake YAMATO F_PROTOCOLS,
1419af73c5bSMasatake YAMATO } objcField;
1429af73c5bSMasatake YAMATO
1439af73c5bSMasatake YAMATO static fieldDefinition ObjcFields [] = {
1449af73c5bSMasatake YAMATO {
1459af73c5bSMasatake YAMATO .name = "category",
1469af73c5bSMasatake YAMATO .description = "category attached to the class",
1479af73c5bSMasatake YAMATO .enabled = true,
1489af73c5bSMasatake YAMATO },
149d650c941SMasatake YAMATO {
150d650c941SMasatake YAMATO .name = "protocols",
151d650c941SMasatake YAMATO .description = "protocols that the class (or category) confirms to",
152d650c941SMasatake YAMATO .enabled = true,
153d650c941SMasatake YAMATO },
1549af73c5bSMasatake YAMATO };
1559af73c5bSMasatake YAMATO
1563ae02089SMasatake YAMATO static langType Lang_ObjectiveC;
1573ae02089SMasatake YAMATO
1583ae02089SMasatake YAMATO /*//////////////////////////////////////////////////////////////////
1593ae02089SMasatake YAMATO //// lexingInit */
1603ae02089SMasatake YAMATO typedef struct _lexingState {
1613ae02089SMasatake YAMATO vString *name; /* current parsed identifier/operator */
1623ae02089SMasatake YAMATO const unsigned char *cp; /* position in stream */
1633ae02089SMasatake YAMATO } lexingState;
1643ae02089SMasatake YAMATO
1653ae02089SMasatake YAMATO /*//////////////////////////////////////////////////////////////////////
1663ae02089SMasatake YAMATO //// Lexing */
isNum(char c)167ce990805SThomas Braun static bool isNum (char c)
1683ae02089SMasatake YAMATO {
1693ae02089SMasatake YAMATO return c >= '0' && c <= '9';
1703ae02089SMasatake YAMATO }
1713ae02089SMasatake YAMATO
isLowerAlpha(char c)172ce990805SThomas Braun static bool isLowerAlpha (char c)
1733ae02089SMasatake YAMATO {
1743ae02089SMasatake YAMATO return c >= 'a' && c <= 'z';
1753ae02089SMasatake YAMATO }
1763ae02089SMasatake YAMATO
isUpperAlpha(char c)177ce990805SThomas Braun static bool isUpperAlpha (char c)
1783ae02089SMasatake YAMATO {
1793ae02089SMasatake YAMATO return c >= 'A' && c <= 'Z';
1803ae02089SMasatake YAMATO }
1813ae02089SMasatake YAMATO
isAlpha(char c)182ce990805SThomas Braun static bool isAlpha (char c)
1833ae02089SMasatake YAMATO {
1843ae02089SMasatake YAMATO return isLowerAlpha (c) || isUpperAlpha (c);
1853ae02089SMasatake YAMATO }
1863ae02089SMasatake YAMATO
isIdent(char c)187ce990805SThomas Braun static bool isIdent (char c)
1883ae02089SMasatake YAMATO {
1893ae02089SMasatake YAMATO return isNum (c) || isAlpha (c) || c == '_';
1903ae02089SMasatake YAMATO }
1913ae02089SMasatake YAMATO
isSpace(char c)192ce990805SThomas Braun static bool isSpace (char c)
1933ae02089SMasatake YAMATO {
1943ae02089SMasatake YAMATO return c == ' ' || c == '\t';
1953ae02089SMasatake YAMATO }
1963ae02089SMasatake YAMATO
1973ae02089SMasatake YAMATO /* return true if it end with an end of line */
eatWhiteSpace(lexingState * st)1983ae02089SMasatake YAMATO static void eatWhiteSpace (lexingState * st)
1993ae02089SMasatake YAMATO {
2003ae02089SMasatake YAMATO const unsigned char *cp = st->cp;
2013ae02089SMasatake YAMATO while (isSpace (*cp))
2023ae02089SMasatake YAMATO cp++;
2033ae02089SMasatake YAMATO
2043ae02089SMasatake YAMATO st->cp = cp;
2053ae02089SMasatake YAMATO }
2063ae02089SMasatake YAMATO
readCString(lexingState * st)2072b88b85fSMasatake YAMATO static void readCString (lexingState * st)
2083ae02089SMasatake YAMATO {
209ce990805SThomas Braun bool lastIsBackSlash = false;
210ce990805SThomas Braun bool unfinished = true;
2113ae02089SMasatake YAMATO const unsigned char *c = st->cp + 1;
2123ae02089SMasatake YAMATO
2132b88b85fSMasatake YAMATO vStringClear (st->name);
2142b88b85fSMasatake YAMATO
2153ae02089SMasatake YAMATO while (unfinished)
2163ae02089SMasatake YAMATO {
2173ae02089SMasatake YAMATO /* end of line should never happen.
2183ae02089SMasatake YAMATO * we tolerate it */
2193ae02089SMasatake YAMATO if (c == NULL || c[0] == '\0')
2203ae02089SMasatake YAMATO break;
2213ae02089SMasatake YAMATO else if (*c == '"' && !lastIsBackSlash)
222ce990805SThomas Braun unfinished = false;
2233ae02089SMasatake YAMATO else
2242b88b85fSMasatake YAMATO {
2253ae02089SMasatake YAMATO lastIsBackSlash = *c == '\\';
2262b88b85fSMasatake YAMATO vStringPut (st->name, (int) *c);
2272b88b85fSMasatake YAMATO }
2283ae02089SMasatake YAMATO
2293ae02089SMasatake YAMATO c++;
2303ae02089SMasatake YAMATO }
2313ae02089SMasatake YAMATO
2323ae02089SMasatake YAMATO st->cp = c;
2333ae02089SMasatake YAMATO }
2343ae02089SMasatake YAMATO
eatComment(lexingState * st)2353ae02089SMasatake YAMATO static void eatComment (lexingState * st)
2363ae02089SMasatake YAMATO {
237ce990805SThomas Braun bool unfinished = true;
238ce990805SThomas Braun bool lastIsStar = false;
2393ae02089SMasatake YAMATO const unsigned char *c = st->cp + 2;
2403ae02089SMasatake YAMATO
2413ae02089SMasatake YAMATO while (unfinished)
2423ae02089SMasatake YAMATO {
2433ae02089SMasatake YAMATO /* we've reached the end of the line..
2443ae02089SMasatake YAMATO * so we have to reload a line... */
2453ae02089SMasatake YAMATO if (c == NULL || *c == '\0')
2463ae02089SMasatake YAMATO {
2471b312fe7SMasatake YAMATO st->cp = readLineFromInputFile ();
2483ae02089SMasatake YAMATO /* WOOPS... no more input...
2493ae02089SMasatake YAMATO * we return, next lexing read
2503ae02089SMasatake YAMATO * will be null and ok */
2513ae02089SMasatake YAMATO if (st->cp == NULL)
2523ae02089SMasatake YAMATO return;
2533ae02089SMasatake YAMATO c = st->cp;
2543ae02089SMasatake YAMATO }
2553ae02089SMasatake YAMATO /* we've reached the end of the comment */
2563ae02089SMasatake YAMATO else if (*c == '/' && lastIsStar)
257ce990805SThomas Braun unfinished = false;
2583ae02089SMasatake YAMATO else
2593ae02089SMasatake YAMATO {
2603ae02089SMasatake YAMATO lastIsStar = '*' == *c;
2613ae02089SMasatake YAMATO c++;
2623ae02089SMasatake YAMATO }
2633ae02089SMasatake YAMATO }
2643ae02089SMasatake YAMATO
2653ae02089SMasatake YAMATO st->cp = c;
2663ae02089SMasatake YAMATO }
2673ae02089SMasatake YAMATO
readIdentifier(lexingState * st)2683ae02089SMasatake YAMATO static void readIdentifier (lexingState * st)
2693ae02089SMasatake YAMATO {
2703ae02089SMasatake YAMATO const unsigned char *p;
2713ae02089SMasatake YAMATO vStringClear (st->name);
2723ae02089SMasatake YAMATO
2733ae02089SMasatake YAMATO /* first char is a simple letter */
2743ae02089SMasatake YAMATO if (isAlpha (*st->cp) || *st->cp == '_')
2753ae02089SMasatake YAMATO vStringPut (st->name, (int) *st->cp);
2763ae02089SMasatake YAMATO
2773ae02089SMasatake YAMATO /* Go till you get identifier chars */
2783ae02089SMasatake YAMATO for (p = st->cp + 1; isIdent (*p); p++)
2793ae02089SMasatake YAMATO vStringPut (st->name, (int) *p);
2803ae02089SMasatake YAMATO
2813ae02089SMasatake YAMATO st->cp = p;
2823ae02089SMasatake YAMATO }
2833ae02089SMasatake YAMATO
2843ae02089SMasatake YAMATO /* read the @something directives */
readIdentifierObjcDirective(lexingState * st)2853ae02089SMasatake YAMATO static void readIdentifierObjcDirective (lexingState * st)
2863ae02089SMasatake YAMATO {
2873ae02089SMasatake YAMATO const unsigned char *p;
2883ae02089SMasatake YAMATO vStringClear (st->name);
2893ae02089SMasatake YAMATO
2903ae02089SMasatake YAMATO /* first char is a simple letter */
2913ae02089SMasatake YAMATO if (*st->cp == '@')
2923ae02089SMasatake YAMATO vStringPut (st->name, (int) *st->cp);
2933ae02089SMasatake YAMATO
2943ae02089SMasatake YAMATO /* Go till you get identifier chars */
2953ae02089SMasatake YAMATO for (p = st->cp + 1; isIdent (*p); p++)
2963ae02089SMasatake YAMATO vStringPut (st->name, (int) *p);
2973ae02089SMasatake YAMATO
2983ae02089SMasatake YAMATO st->cp = p;
2993ae02089SMasatake YAMATO }
3003ae02089SMasatake YAMATO
3013ae02089SMasatake YAMATO /* The lexer is in charge of reading the file.
3023ae02089SMasatake YAMATO * Some of sub-lexer (like eatComment) also read file.
3033ae02089SMasatake YAMATO * lexing is finished when the lexer return Tok_EOF */
lex(lexingState * st)3043ae02089SMasatake YAMATO static objcKeyword lex (lexingState * st)
3053ae02089SMasatake YAMATO {
3063ae02089SMasatake YAMATO int retType;
3073ae02089SMasatake YAMATO
3083ae02089SMasatake YAMATO /* handling data input here */
3093ae02089SMasatake YAMATO while (st->cp == NULL || st->cp[0] == '\0')
3103ae02089SMasatake YAMATO {
3111b312fe7SMasatake YAMATO st->cp = readLineFromInputFile ();
3123ae02089SMasatake YAMATO if (st->cp == NULL)
3133ae02089SMasatake YAMATO return Tok_EOF;
3143ae02089SMasatake YAMATO
3153ae02089SMasatake YAMATO return Tok_EOL;
3163ae02089SMasatake YAMATO }
3173ae02089SMasatake YAMATO
31894653669SRich Siegel if (isAlpha (*st->cp) || (*st->cp == '_'))
3193ae02089SMasatake YAMATO {
3203ae02089SMasatake YAMATO readIdentifier (st);
3213ae02089SMasatake YAMATO retType = lookupKeyword (vStringValue (st->name), Lang_ObjectiveC);
3223ae02089SMasatake YAMATO
3233ae02089SMasatake YAMATO if (retType == -1) /* If it's not a keyword */
3243ae02089SMasatake YAMATO {
3253ae02089SMasatake YAMATO return ObjcIDENTIFIER;
3263ae02089SMasatake YAMATO }
3273ae02089SMasatake YAMATO else
3283ae02089SMasatake YAMATO {
3293ae02089SMasatake YAMATO return retType;
3303ae02089SMasatake YAMATO }
3313ae02089SMasatake YAMATO }
3323ae02089SMasatake YAMATO else if (*st->cp == '@')
3333ae02089SMasatake YAMATO {
3343ae02089SMasatake YAMATO readIdentifierObjcDirective (st);
3353ae02089SMasatake YAMATO retType = lookupKeyword (vStringValue (st->name), Lang_ObjectiveC);
3363ae02089SMasatake YAMATO
3373ae02089SMasatake YAMATO if (retType == -1) /* If it's not a keyword */
3383ae02089SMasatake YAMATO {
3393ae02089SMasatake YAMATO return Tok_any;
3403ae02089SMasatake YAMATO }
3413ae02089SMasatake YAMATO else
3423ae02089SMasatake YAMATO {
3433ae02089SMasatake YAMATO return retType;
3443ae02089SMasatake YAMATO }
3453ae02089SMasatake YAMATO }
3463ae02089SMasatake YAMATO else if (isSpace (*st->cp))
3473ae02089SMasatake YAMATO {
3483ae02089SMasatake YAMATO eatWhiteSpace (st);
3493ae02089SMasatake YAMATO return lex (st);
3503ae02089SMasatake YAMATO }
3513ae02089SMasatake YAMATO else
3523ae02089SMasatake YAMATO switch (*st->cp)
3533ae02089SMasatake YAMATO {
3543ae02089SMasatake YAMATO case '(':
3553ae02089SMasatake YAMATO st->cp++;
3563ae02089SMasatake YAMATO return Tok_PARL;
3573ae02089SMasatake YAMATO
3583ae02089SMasatake YAMATO case '\\':
3593ae02089SMasatake YAMATO st->cp++;
3603ae02089SMasatake YAMATO return Tok_Backslash;
3613ae02089SMasatake YAMATO
3623ae02089SMasatake YAMATO case '#':
3633ae02089SMasatake YAMATO st->cp++;
3643ae02089SMasatake YAMATO return Tok_Sharp;
3653ae02089SMasatake YAMATO
3663ae02089SMasatake YAMATO case '/':
3673ae02089SMasatake YAMATO if (st->cp[1] == '*') /* ergl, a comment */
3683ae02089SMasatake YAMATO {
3693ae02089SMasatake YAMATO eatComment (st);
3703ae02089SMasatake YAMATO return lex (st);
3713ae02089SMasatake YAMATO }
3723ae02089SMasatake YAMATO else if (st->cp[1] == '/')
3733ae02089SMasatake YAMATO {
3743ae02089SMasatake YAMATO st->cp = NULL;
3753ae02089SMasatake YAMATO return lex (st);
3763ae02089SMasatake YAMATO }
3773ae02089SMasatake YAMATO else
3783ae02089SMasatake YAMATO {
3793ae02089SMasatake YAMATO st->cp++;
3803ae02089SMasatake YAMATO return Tok_any;
3813ae02089SMasatake YAMATO }
3823ae02089SMasatake YAMATO break;
3833ae02089SMasatake YAMATO
3843ae02089SMasatake YAMATO case ')':
3853ae02089SMasatake YAMATO st->cp++;
3863ae02089SMasatake YAMATO return Tok_PARR;
3873ae02089SMasatake YAMATO case '{':
3883ae02089SMasatake YAMATO st->cp++;
3893ae02089SMasatake YAMATO return Tok_CurlL;
3903ae02089SMasatake YAMATO case '}':
3913ae02089SMasatake YAMATO st->cp++;
3923ae02089SMasatake YAMATO return Tok_CurlR;
3933ae02089SMasatake YAMATO case '[':
3943ae02089SMasatake YAMATO st->cp++;
3953ae02089SMasatake YAMATO return Tok_SQUAREL;
3963ae02089SMasatake YAMATO case ']':
3973ae02089SMasatake YAMATO st->cp++;
3983ae02089SMasatake YAMATO return Tok_SQUARER;
3993ae02089SMasatake YAMATO case ',':
4003ae02089SMasatake YAMATO st->cp++;
4013ae02089SMasatake YAMATO return Tok_COMA;
4023ae02089SMasatake YAMATO case ';':
4033ae02089SMasatake YAMATO st->cp++;
4043ae02089SMasatake YAMATO return Tok_semi;
4053ae02089SMasatake YAMATO case ':':
4063ae02089SMasatake YAMATO st->cp++;
4073ae02089SMasatake YAMATO return Tok_dpoint;
4083ae02089SMasatake YAMATO case '"':
4092b88b85fSMasatake YAMATO readCString (st);
4102b88b85fSMasatake YAMATO return Tok_CSTRING;
4113ae02089SMasatake YAMATO case '+':
4123ae02089SMasatake YAMATO st->cp++;
4133ae02089SMasatake YAMATO return Tok_PLUS;
4143ae02089SMasatake YAMATO case '-':
4153ae02089SMasatake YAMATO st->cp++;
4163ae02089SMasatake YAMATO return Tok_MINUS;
41780eb4460SMasatake YAMATO case '*':
41880eb4460SMasatake YAMATO st->cp++;
41980eb4460SMasatake YAMATO return Tok_Asterisk;
420d650c941SMasatake YAMATO case '<':
421d650c941SMasatake YAMATO st->cp++;
422d650c941SMasatake YAMATO return Tok_ANGLEL;
423d650c941SMasatake YAMATO case '>':
424d650c941SMasatake YAMATO st->cp++;
425d650c941SMasatake YAMATO return Tok_ANGLER;
4263ae02089SMasatake YAMATO
4273ae02089SMasatake YAMATO default:
4283ae02089SMasatake YAMATO st->cp++;
4293ae02089SMasatake YAMATO break;
4303ae02089SMasatake YAMATO }
4313ae02089SMasatake YAMATO
4323ae02089SMasatake YAMATO /* default return if nothing is recognized,
4333ae02089SMasatake YAMATO * shouldn't happen, but at least, it will
4343ae02089SMasatake YAMATO * be handled without destroying the parsing. */
4353ae02089SMasatake YAMATO return Tok_any;
4363ae02089SMasatake YAMATO }
4373ae02089SMasatake YAMATO
4383ae02089SMasatake YAMATO /*//////////////////////////////////////////////////////////////////////
4393ae02089SMasatake YAMATO //// Parsing */
4403ae02089SMasatake YAMATO typedef void (*parseNext) (vString * const ident, objcToken what);
4413ae02089SMasatake YAMATO
4423ae02089SMasatake YAMATO /********** Helpers */
4433ae02089SMasatake YAMATO /* This variable hold the 'parser' which is going to
4443ae02089SMasatake YAMATO * handle the next token */
4453ae02089SMasatake YAMATO static parseNext toDoNext;
4463ae02089SMasatake YAMATO
4473ae02089SMasatake YAMATO /* Special variable used by parser eater to
4483ae02089SMasatake YAMATO * determine which action to put after their
4493ae02089SMasatake YAMATO * job is finished. */
4503ae02089SMasatake YAMATO static parseNext comeAfter;
4513ae02089SMasatake YAMATO
4523ae02089SMasatake YAMATO /* Used by some parsers detecting certain token
4533ae02089SMasatake YAMATO * to revert to previous parser. */
4543ae02089SMasatake YAMATO static parseNext fallback;
4553ae02089SMasatake YAMATO
4563ae02089SMasatake YAMATO
4573ae02089SMasatake YAMATO /********** Grammar */
4583ae02089SMasatake YAMATO static void globalScope (vString * const ident, objcToken what);
4593ae02089SMasatake YAMATO static void parseMethods (vString * const ident, objcToken what);
4603ae02089SMasatake YAMATO static void parseImplemMethods (vString * const ident, objcToken what);
4613ae02089SMasatake YAMATO static vString *tempName = NULL;
4623ae02089SMasatake YAMATO static vString *parentName = NULL;
4633ae02089SMasatake YAMATO static objcKind parentType = K_INTERFACE;
4643afb5475SMasatake YAMATO static int parentCorkIndex = CORK_NIL;
4653afb5475SMasatake YAMATO static int categoryCorkIndex = CORK_NIL;
4663ae02089SMasatake YAMATO
4673ae02089SMasatake YAMATO /* used to prepare tag for OCaml, just in case their is a need to
4683ae02089SMasatake YAMATO * add additional information to the tag. */
prepareTag(tagEntryInfo * tag,vString const * name,objcKind kind)4693ae02089SMasatake YAMATO static void prepareTag (tagEntryInfo * tag, vString const *name, objcKind kind)
4703ae02089SMasatake YAMATO {
47116a2541cSMasatake YAMATO initTagEntry (tag, vStringValue (name), kind);
4723ae02089SMasatake YAMATO
473c848d905SMasatake YAMATO if (vStringLength (parentName) > 0)
4743ae02089SMasatake YAMATO {
475f92e6bf2SMasatake YAMATO tag->extensionFields.scopeKindIndex = parentType;
476015ab54cSMasatake YAMATO tag->extensionFields.scopeName = vStringValue (parentName);
4773ae02089SMasatake YAMATO }
4783ae02089SMasatake YAMATO }
4793ae02089SMasatake YAMATO
pushEnclosingContext(const vString * parent,objcKind type)4803ae02089SMasatake YAMATO static void pushEnclosingContext (const vString * parent, objcKind type)
4813ae02089SMasatake YAMATO {
4823ae02089SMasatake YAMATO vStringCopy (parentName, parent);
4833ae02089SMasatake YAMATO parentType = type;
4843ae02089SMasatake YAMATO }
4853ae02089SMasatake YAMATO
pushEnclosingContextFull(const vString * parent,objcKind type,int corkIndex)4863afb5475SMasatake YAMATO static void pushEnclosingContextFull (const vString * parent, objcKind type, int corkIndex)
487a67d9dbeSMasatake YAMATO {
488a67d9dbeSMasatake YAMATO pushEnclosingContext (parent, type);
489a67d9dbeSMasatake YAMATO parentCorkIndex = corkIndex;
490a67d9dbeSMasatake YAMATO }
491a67d9dbeSMasatake YAMATO
popEnclosingContext(void)4923ae02089SMasatake YAMATO static void popEnclosingContext (void)
4933ae02089SMasatake YAMATO {
4943ae02089SMasatake YAMATO vStringClear (parentName);
49509152b33SMasatake YAMATO parentCorkIndex = CORK_NIL;
4963ae02089SMasatake YAMATO }
4973ae02089SMasatake YAMATO
pushCategoryContext(int category_index)4983afb5475SMasatake YAMATO static void pushCategoryContext (int category_index)
4999af73c5bSMasatake YAMATO {
5009af73c5bSMasatake YAMATO categoryCorkIndex = category_index;
5019af73c5bSMasatake YAMATO }
5029af73c5bSMasatake YAMATO
popCategoryContext(void)5039af73c5bSMasatake YAMATO static void popCategoryContext (void)
5049af73c5bSMasatake YAMATO {
5059af73c5bSMasatake YAMATO categoryCorkIndex = CORK_NIL;
5069af73c5bSMasatake YAMATO }
5079af73c5bSMasatake YAMATO
5083ae02089SMasatake YAMATO /* Used to centralise tag creation, and be able to add
5093ae02089SMasatake YAMATO * more information to it in the future */
addTag(vString * const ident,int kind)51080eb4460SMasatake YAMATO static int addTag (vString * const ident, int kind)
5113ae02089SMasatake YAMATO {
5123ae02089SMasatake YAMATO tagEntryInfo toCreate;
5134a95e4a5SColomban Wendling
5144a95e4a5SColomban Wendling if (! ObjcKinds[kind].enabled)
51580eb4460SMasatake YAMATO return CORK_NIL;
5164a95e4a5SColomban Wendling
5173ae02089SMasatake YAMATO prepareTag (&toCreate, ident, kind);
51880eb4460SMasatake YAMATO return makeTagEntry (&toCreate);
5193ae02089SMasatake YAMATO }
5203ae02089SMasatake YAMATO
5213ae02089SMasatake YAMATO static objcToken waitedToken, fallBackToken;
5223ae02089SMasatake YAMATO
5233ae02089SMasatake YAMATO /* Ignore everything till waitedToken and jump to comeAfter.
5243ae02089SMasatake YAMATO * If the "end" keyword is encountered break, doesn't remember
5253ae02089SMasatake YAMATO * why though. */
tillToken(vString * const ident CTAGS_ATTR_UNUSED,objcToken what)5268ccb7ee9SJiří Techet static void tillToken (vString * const ident CTAGS_ATTR_UNUSED, objcToken what)
5273ae02089SMasatake YAMATO {
5283ae02089SMasatake YAMATO if (what == waitedToken)
5293ae02089SMasatake YAMATO toDoNext = comeAfter;
5303ae02089SMasatake YAMATO }
5313ae02089SMasatake YAMATO
tillTokenOrFallBack(vString * const ident CTAGS_ATTR_UNUSED,objcToken what)5328ccb7ee9SJiří Techet static void tillTokenOrFallBack (vString * const ident CTAGS_ATTR_UNUSED, objcToken what)
5333ae02089SMasatake YAMATO {
5343ae02089SMasatake YAMATO if (what == waitedToken)
5353ae02089SMasatake YAMATO toDoNext = comeAfter;
5363ae02089SMasatake YAMATO else if (what == fallBackToken)
5373ae02089SMasatake YAMATO {
5383ae02089SMasatake YAMATO toDoNext = fallback;
5393ae02089SMasatake YAMATO }
5403ae02089SMasatake YAMATO }
5413ae02089SMasatake YAMATO
5423ae02089SMasatake YAMATO static int ignoreBalanced_count = 0;
ignoreBalanced(vString * const ident CTAGS_ATTR_UNUSED,objcToken what)5438ccb7ee9SJiří Techet static void ignoreBalanced (vString * const ident CTAGS_ATTR_UNUSED, objcToken what)
5443ae02089SMasatake YAMATO {
5453ae02089SMasatake YAMATO
5463ae02089SMasatake YAMATO switch (what)
5473ae02089SMasatake YAMATO {
5483ae02089SMasatake YAMATO case Tok_PARL:
5493ae02089SMasatake YAMATO case Tok_CurlL:
5503ae02089SMasatake YAMATO case Tok_SQUAREL:
5513ae02089SMasatake YAMATO ignoreBalanced_count++;
5523ae02089SMasatake YAMATO break;
5533ae02089SMasatake YAMATO
5543ae02089SMasatake YAMATO case Tok_PARR:
5553ae02089SMasatake YAMATO case Tok_CurlR:
5563ae02089SMasatake YAMATO case Tok_SQUARER:
5573ae02089SMasatake YAMATO ignoreBalanced_count--;
5583ae02089SMasatake YAMATO break;
5593ae02089SMasatake YAMATO
5603ae02089SMasatake YAMATO default:
5613ae02089SMasatake YAMATO /* don't care */
5623ae02089SMasatake YAMATO break;
5633ae02089SMasatake YAMATO }
5643ae02089SMasatake YAMATO
5653ae02089SMasatake YAMATO if (ignoreBalanced_count == 0)
5663ae02089SMasatake YAMATO toDoNext = comeAfter;
5673ae02089SMasatake YAMATO }
5683ae02089SMasatake YAMATO
parseFields(vString * const ident,objcToken what)5693ae02089SMasatake YAMATO static void parseFields (vString * const ident, objcToken what)
5703ae02089SMasatake YAMATO {
5713ae02089SMasatake YAMATO switch (what)
5723ae02089SMasatake YAMATO {
5733ae02089SMasatake YAMATO case Tok_CurlR:
5743ae02089SMasatake YAMATO toDoNext = &parseMethods;
5753ae02089SMasatake YAMATO break;
5763ae02089SMasatake YAMATO
5773ae02089SMasatake YAMATO case Tok_SQUAREL:
5783ae02089SMasatake YAMATO case Tok_PARL:
5793ae02089SMasatake YAMATO toDoNext = &ignoreBalanced;
5803ae02089SMasatake YAMATO comeAfter = &parseFields;
5813ae02089SMasatake YAMATO break;
5823ae02089SMasatake YAMATO
5833ae02089SMasatake YAMATO /* we got an identifier, keep track of it */
5843ae02089SMasatake YAMATO case ObjcIDENTIFIER:
5853ae02089SMasatake YAMATO vStringCopy (tempName, ident);
5863ae02089SMasatake YAMATO break;
5873ae02089SMasatake YAMATO
5883ae02089SMasatake YAMATO /* our last kept identifier must be our variable name =) */
5893ae02089SMasatake YAMATO case Tok_semi:
5903ae02089SMasatake YAMATO addTag (tempName, K_FIELD);
5913ae02089SMasatake YAMATO vStringClear (tempName);
5923ae02089SMasatake YAMATO break;
5933ae02089SMasatake YAMATO
5943ae02089SMasatake YAMATO default:
5953ae02089SMasatake YAMATO /* NOTHING */
5963ae02089SMasatake YAMATO break;
5973ae02089SMasatake YAMATO }
5983ae02089SMasatake YAMATO }
5993ae02089SMasatake YAMATO
6003ae02089SMasatake YAMATO static objcKind methodKind;
6013ae02089SMasatake YAMATO
6023ae02089SMasatake YAMATO
6033ae02089SMasatake YAMATO static vString *fullMethodName;
6043ae02089SMasatake YAMATO static vString *prevIdent;
60580eb4460SMasatake YAMATO static vString *signature;
60680eb4460SMasatake YAMATO
tillTokenWithCapturingSignature(vString * const ident,objcToken what)60780eb4460SMasatake YAMATO static void tillTokenWithCapturingSignature (vString * const ident, objcToken what)
60880eb4460SMasatake YAMATO {
60980eb4460SMasatake YAMATO tillToken (ident, what);
61080eb4460SMasatake YAMATO
61180eb4460SMasatake YAMATO if (what != waitedToken)
61280eb4460SMasatake YAMATO {
61380eb4460SMasatake YAMATO if (what == Tok_Asterisk)
61480eb4460SMasatake YAMATO vStringPut (signature, '*');
61580eb4460SMasatake YAMATO else if (vStringLength (ident) > 0)
61680eb4460SMasatake YAMATO {
61780eb4460SMasatake YAMATO if (! (vStringLast (signature) == ','
61880eb4460SMasatake YAMATO || vStringLast (signature) == '('
61980eb4460SMasatake YAMATO || vStringLast (signature) == ' '))
62080eb4460SMasatake YAMATO vStringPut (signature, ' ');
62180eb4460SMasatake YAMATO
62280eb4460SMasatake YAMATO vStringCat (signature, ident);
62380eb4460SMasatake YAMATO }
62480eb4460SMasatake YAMATO }
62580eb4460SMasatake YAMATO }
6263ae02089SMasatake YAMATO
parseMethodsNameCommon(vString * const ident,objcToken what,parseNext reEnter,parseNext nextAction)6279f8df264SMasatake YAMATO static void parseMethodsNameCommon (vString * const ident, objcToken what,
6289f8df264SMasatake YAMATO parseNext reEnter,
6299f8df264SMasatake YAMATO parseNext nextAction)
6303ae02089SMasatake YAMATO {
6313afb5475SMasatake YAMATO int index;
63280eb4460SMasatake YAMATO
6333ae02089SMasatake YAMATO switch (what)
6343ae02089SMasatake YAMATO {
6353ae02089SMasatake YAMATO case Tok_PARL:
6363ae02089SMasatake YAMATO toDoNext = &tillToken;
6379f8df264SMasatake YAMATO comeAfter = reEnter;
6383ae02089SMasatake YAMATO waitedToken = Tok_PARR;
63980eb4460SMasatake YAMATO
64080eb4460SMasatake YAMATO if (! (vStringLength(prevIdent) == 0
64180eb4460SMasatake YAMATO && vStringLength(fullMethodName) == 0))
64280eb4460SMasatake YAMATO toDoNext = &tillTokenWithCapturingSignature;
6433ae02089SMasatake YAMATO break;
6443ae02089SMasatake YAMATO
6453ae02089SMasatake YAMATO case Tok_dpoint:
6463ae02089SMasatake YAMATO vStringCat (fullMethodName, prevIdent);
6471da6e7e4SMasatake YAMATO vStringPut (fullMethodName, ':');
6483ae02089SMasatake YAMATO vStringClear (prevIdent);
64980eb4460SMasatake YAMATO
65080eb4460SMasatake YAMATO if (vStringLength (signature) > 1)
65180eb4460SMasatake YAMATO vStringPut (signature, ',');
6523ae02089SMasatake YAMATO break;
6533ae02089SMasatake YAMATO
6543ae02089SMasatake YAMATO case ObjcIDENTIFIER:
65580eb4460SMasatake YAMATO if ((vStringLength (prevIdent) > 0
65680eb4460SMasatake YAMATO /* "- initWithObject: o0 withAnotherObject: o1;"
65780eb4460SMasatake YAMATO Overwriting the last value of prevIdent ("o0");
65880eb4460SMasatake YAMATO a parameter name ("o0") was stored to prevIdent,
65980eb4460SMasatake YAMATO and a part of selector("withAnotherObject")
66080eb4460SMasatake YAMATO overwrites it.
66180eb4460SMasatake YAMATO If type for the parameter specified explicitly,
66280eb4460SMasatake YAMATO the last char of signature should not be ',' nor
66380eb4460SMasatake YAMATO '('. In this case, "id" must be put as the type for
66480eb4460SMasatake YAMATO the parameter. */
66580eb4460SMasatake YAMATO && (vStringLast (signature) == ','
66680eb4460SMasatake YAMATO || vStringLast (signature) == '('))
66780eb4460SMasatake YAMATO || (/* "- initWithObject: object;"
66880eb4460SMasatake YAMATO In this case no overwriting happens.
66980eb4460SMasatake YAMATO However, "id" for "object" is part
67080eb4460SMasatake YAMATO of signature. */
67180eb4460SMasatake YAMATO vStringLength (prevIdent) == 0
67280eb4460SMasatake YAMATO && vStringLength (fullMethodName) > 0
67380eb4460SMasatake YAMATO && vStringLast (signature) == '('))
67480eb4460SMasatake YAMATO vStringCatS (signature, "id");
67580eb4460SMasatake YAMATO
6763ae02089SMasatake YAMATO vStringCopy (prevIdent, ident);
6773ae02089SMasatake YAMATO break;
6783ae02089SMasatake YAMATO
6793ae02089SMasatake YAMATO case Tok_CurlL:
6803ae02089SMasatake YAMATO case Tok_semi:
6813ae02089SMasatake YAMATO /* method name is not simple */
6823ae02089SMasatake YAMATO if (vStringLength (fullMethodName) != '\0')
6833ae02089SMasatake YAMATO {
68480eb4460SMasatake YAMATO index = addTag (fullMethodName, methodKind);
6853ae02089SMasatake YAMATO vStringClear (fullMethodName);
6863ae02089SMasatake YAMATO }
6873ae02089SMasatake YAMATO else
68880eb4460SMasatake YAMATO index = addTag (prevIdent, methodKind);
6893ae02089SMasatake YAMATO
6909f8df264SMasatake YAMATO toDoNext = nextAction;
6913ae02089SMasatake YAMATO parseImplemMethods (ident, what);
6923ae02089SMasatake YAMATO vStringClear (prevIdent);
69380eb4460SMasatake YAMATO
69480eb4460SMasatake YAMATO tagEntryInfo *e = getEntryInCorkQueue (index);
695*3671ad72SMasatake YAMATO if (e)
696*3671ad72SMasatake YAMATO {
69780eb4460SMasatake YAMATO if (vStringLast (signature) == ',')
69880eb4460SMasatake YAMATO vStringCatS (signature, "id");
69980eb4460SMasatake YAMATO vStringPut (signature, ')');
70080eb4460SMasatake YAMATO
701f270909bSMasatake YAMATO e->extensionFields.signature = vStringStrdup (signature);
70280eb4460SMasatake YAMATO
70380eb4460SMasatake YAMATO vStringClear (signature);
70480eb4460SMasatake YAMATO vStringPut (signature, '(');
70566fba980SMasatake YAMATO
706*3671ad72SMasatake YAMATO tagEntryInfo *e_cat = getEntryInCorkQueue (categoryCorkIndex);
707*3671ad72SMasatake YAMATO if (e_cat)
70866fba980SMasatake YAMATO attachParserFieldToCorkEntry (index,
70966fba980SMasatake YAMATO ObjcFields [F_CATEGORY].ftype,
710*3671ad72SMasatake YAMATO e_cat->name);
71180eb4460SMasatake YAMATO }
7123ae02089SMasatake YAMATO break;
7133ae02089SMasatake YAMATO
7143ae02089SMasatake YAMATO default:
7153ae02089SMasatake YAMATO break;
7163ae02089SMasatake YAMATO }
7173ae02089SMasatake YAMATO }
7183ae02089SMasatake YAMATO
parseMethodsName(vString * const ident,objcToken what)7199f8df264SMasatake YAMATO static void parseMethodsName (vString * const ident, objcToken what)
7209f8df264SMasatake YAMATO {
7219f8df264SMasatake YAMATO parseMethodsNameCommon (ident, what, parseMethodsName, parseMethods);
7229f8df264SMasatake YAMATO }
7239f8df264SMasatake YAMATO
parseMethodsImplemName(vString * const ident,objcToken what)7243ae02089SMasatake YAMATO static void parseMethodsImplemName (vString * const ident, objcToken what)
7253ae02089SMasatake YAMATO {
7269f8df264SMasatake YAMATO parseMethodsNameCommon (ident, what, parseMethodsImplemName, parseImplemMethods);
7273ae02089SMasatake YAMATO }
7283ae02089SMasatake YAMATO
parseCategory(vString * const ident,objcToken what)7299af73c5bSMasatake YAMATO static void parseCategory (vString * const ident, objcToken what)
7309af73c5bSMasatake YAMATO {
7319af73c5bSMasatake YAMATO if (what == ObjcIDENTIFIER)
7329af73c5bSMasatake YAMATO {
7339af73c5bSMasatake YAMATO tagEntryInfo *e = getEntryInCorkQueue (parentCorkIndex);
7349af73c5bSMasatake YAMATO if (e)
735*3671ad72SMasatake YAMATO {
7369af73c5bSMasatake YAMATO attachParserFieldToCorkEntry (parentCorkIndex,
7379af73c5bSMasatake YAMATO ObjcFields [F_CATEGORY].ftype,
7389af73c5bSMasatake YAMATO vStringValue (ident));
7399af73c5bSMasatake YAMATO if (e->kindIndex == K_INTERFACE)
7409af73c5bSMasatake YAMATO toDoNext = &parseMethods;
7419af73c5bSMasatake YAMATO else
7429af73c5bSMasatake YAMATO toDoNext = &parseImplemMethods;
743*3671ad72SMasatake YAMATO }
7449af73c5bSMasatake YAMATO
7453afb5475SMasatake YAMATO int index = addTag (ident, K_CATEGORY);
7469af73c5bSMasatake YAMATO pushCategoryContext (index);
7479af73c5bSMasatake YAMATO }
7489af73c5bSMasatake YAMATO }
7499af73c5bSMasatake YAMATO
parseImplemMethods(vString * const ident,objcToken what)7503ae02089SMasatake YAMATO static void parseImplemMethods (vString * const ident, objcToken what)
7513ae02089SMasatake YAMATO {
7523ae02089SMasatake YAMATO switch (what)
7533ae02089SMasatake YAMATO {
7543ae02089SMasatake YAMATO case Tok_PLUS: /* + */
7553ae02089SMasatake YAMATO toDoNext = &parseMethodsImplemName;
7563ae02089SMasatake YAMATO methodKind = K_CLASSMETHOD;
7573ae02089SMasatake YAMATO break;
7583ae02089SMasatake YAMATO
7593ae02089SMasatake YAMATO case Tok_MINUS: /* - */
7603ae02089SMasatake YAMATO toDoNext = &parseMethodsImplemName;
7613ae02089SMasatake YAMATO methodKind = K_METHOD;
7623ae02089SMasatake YAMATO break;
7633ae02089SMasatake YAMATO
7643ae02089SMasatake YAMATO case ObjcEND: /* @end */
7653ae02089SMasatake YAMATO popEnclosingContext ();
7669af73c5bSMasatake YAMATO popCategoryContext ();
7673ae02089SMasatake YAMATO toDoNext = &globalScope;
7683ae02089SMasatake YAMATO break;
7693ae02089SMasatake YAMATO
7703ae02089SMasatake YAMATO case Tok_CurlL: /* { */
7713ae02089SMasatake YAMATO toDoNext = &ignoreBalanced;
7723ae02089SMasatake YAMATO ignoreBalanced (ident, what);
7733ae02089SMasatake YAMATO comeAfter = &parseImplemMethods;
7743ae02089SMasatake YAMATO break;
7753ae02089SMasatake YAMATO
7769af73c5bSMasatake YAMATO case Tok_PARL: /* ( */
7779af73c5bSMasatake YAMATO toDoNext = &parseCategory;
7789af73c5bSMasatake YAMATO break;
7799af73c5bSMasatake YAMATO
7803ae02089SMasatake YAMATO default:
7813ae02089SMasatake YAMATO break;
7823ae02089SMasatake YAMATO }
7833ae02089SMasatake YAMATO }
7843ae02089SMasatake YAMATO
parseProperty(vString * const ident,objcToken what)7853ae02089SMasatake YAMATO static void parseProperty (vString * const ident, objcToken what)
7863ae02089SMasatake YAMATO {
7873ae02089SMasatake YAMATO switch (what)
7883ae02089SMasatake YAMATO {
7893ae02089SMasatake YAMATO case Tok_PARL:
7903ae02089SMasatake YAMATO toDoNext = &tillToken;
7913ae02089SMasatake YAMATO comeAfter = &parseProperty;
7923ae02089SMasatake YAMATO waitedToken = Tok_PARR;
7933ae02089SMasatake YAMATO break;
7943ae02089SMasatake YAMATO
7953ae02089SMasatake YAMATO /* we got an identifier, keep track of it */
7963ae02089SMasatake YAMATO case ObjcIDENTIFIER:
7973ae02089SMasatake YAMATO vStringCopy (tempName, ident);
7983ae02089SMasatake YAMATO break;
7993ae02089SMasatake YAMATO
8003ae02089SMasatake YAMATO /* our last kept identifier must be our variable name =) */
8013ae02089SMasatake YAMATO case Tok_semi:
8023ae02089SMasatake YAMATO addTag (tempName, K_PROPERTY);
8033ae02089SMasatake YAMATO vStringClear (tempName);
80421e74e6aSsolawing toDoNext = &parseMethods;
8053ae02089SMasatake YAMATO break;
8063ae02089SMasatake YAMATO
8073ae02089SMasatake YAMATO default:
8083ae02089SMasatake YAMATO break;
8093ae02089SMasatake YAMATO }
8103ae02089SMasatake YAMATO }
8113ae02089SMasatake YAMATO
parseInterfaceSuperclass(vString * const ident,objcToken what)812a67d9dbeSMasatake YAMATO static void parseInterfaceSuperclass (vString * const ident, objcToken what)
813a67d9dbeSMasatake YAMATO {
814a67d9dbeSMasatake YAMATO tagEntryInfo *e = getEntryInCorkQueue (parentCorkIndex);
815*3671ad72SMasatake YAMATO if (what == ObjcIDENTIFIER && e)
816a67d9dbeSMasatake YAMATO e->extensionFields.inheritance = vStringStrdup (ident);
817a67d9dbeSMasatake YAMATO
818a67d9dbeSMasatake YAMATO toDoNext = &parseMethods;
819a67d9dbeSMasatake YAMATO }
820a67d9dbeSMasatake YAMATO
parseInterfaceProtocolList(vString * const ident,objcToken what)821d650c941SMasatake YAMATO static void parseInterfaceProtocolList (vString * const ident, objcToken what)
822d650c941SMasatake YAMATO {
823d650c941SMasatake YAMATO static vString *protocol_list;
824d650c941SMasatake YAMATO
825d650c941SMasatake YAMATO if (parentCorkIndex == CORK_NIL)
826d650c941SMasatake YAMATO {
827d650c941SMasatake YAMATO toDoNext = &parseMethods;
828d650c941SMasatake YAMATO return;
829d650c941SMasatake YAMATO }
830d650c941SMasatake YAMATO
831d650c941SMasatake YAMATO if (protocol_list == NULL)
832d650c941SMasatake YAMATO {
833d650c941SMasatake YAMATO protocol_list = vStringNew ();
834d650c941SMasatake YAMATO DEFAULT_TRASH_BOX(protocol_list, vStringDelete);
835d650c941SMasatake YAMATO }
836d650c941SMasatake YAMATO
837d650c941SMasatake YAMATO if (what == ObjcIDENTIFIER)
838d650c941SMasatake YAMATO vStringCat(protocol_list, ident);
839d650c941SMasatake YAMATO else if (what == Tok_COMA)
840d650c941SMasatake YAMATO vStringPut (protocol_list, ',');
841d650c941SMasatake YAMATO else if (what == Tok_ANGLER)
842d650c941SMasatake YAMATO {
843d650c941SMasatake YAMATO attachParserFieldToCorkEntry (parentCorkIndex,
844d650c941SMasatake YAMATO ObjcFields [F_PROTOCOLS].ftype,
845d650c941SMasatake YAMATO vStringValue (protocol_list));
846d650c941SMasatake YAMATO if (categoryCorkIndex != CORK_NIL)
847d650c941SMasatake YAMATO attachParserFieldToCorkEntry (categoryCorkIndex,
848d650c941SMasatake YAMATO ObjcFields [F_PROTOCOLS].ftype,
849d650c941SMasatake YAMATO vStringValue (protocol_list));
850d650c941SMasatake YAMATO vStringClear (protocol_list);
851d650c941SMasatake YAMATO toDoNext = &parseMethods;
852d650c941SMasatake YAMATO }
853d650c941SMasatake YAMATO }
854d650c941SMasatake YAMATO
parseMethods(vString * const ident CTAGS_ATTR_UNUSED,objcToken what)8558ccb7ee9SJiří Techet static void parseMethods (vString * const ident CTAGS_ATTR_UNUSED, objcToken what)
8563ae02089SMasatake YAMATO {
8573ae02089SMasatake YAMATO switch (what)
8583ae02089SMasatake YAMATO {
8593ae02089SMasatake YAMATO case Tok_PLUS: /* + */
8603ae02089SMasatake YAMATO toDoNext = &parseMethodsName;
8613ae02089SMasatake YAMATO methodKind = K_CLASSMETHOD;
8623ae02089SMasatake YAMATO break;
8633ae02089SMasatake YAMATO
8643ae02089SMasatake YAMATO case Tok_MINUS: /* - */
8653ae02089SMasatake YAMATO toDoNext = &parseMethodsName;
8663ae02089SMasatake YAMATO methodKind = K_METHOD;
8673ae02089SMasatake YAMATO break;
8683ae02089SMasatake YAMATO
8693ae02089SMasatake YAMATO case ObjcPROPERTY:
8703ae02089SMasatake YAMATO toDoNext = &parseProperty;
8713ae02089SMasatake YAMATO break;
8723ae02089SMasatake YAMATO
8733ae02089SMasatake YAMATO case ObjcEND: /* @end */
8743ae02089SMasatake YAMATO popEnclosingContext ();
8759af73c5bSMasatake YAMATO popCategoryContext ();
8763ae02089SMasatake YAMATO toDoNext = &globalScope;
8773ae02089SMasatake YAMATO break;
8783ae02089SMasatake YAMATO
8793ae02089SMasatake YAMATO case Tok_CurlL: /* { */
8803ae02089SMasatake YAMATO toDoNext = &parseFields;
8813ae02089SMasatake YAMATO break;
8823ae02089SMasatake YAMATO
883a67d9dbeSMasatake YAMATO case Tok_dpoint: /* : */
884a67d9dbeSMasatake YAMATO toDoNext = &parseInterfaceSuperclass;
885a67d9dbeSMasatake YAMATO break;
886a67d9dbeSMasatake YAMATO
8879af73c5bSMasatake YAMATO case Tok_PARL: /* ( */
8889af73c5bSMasatake YAMATO toDoNext = &parseCategory;
8899af73c5bSMasatake YAMATO break;
8909af73c5bSMasatake YAMATO
891d650c941SMasatake YAMATO case Tok_ANGLEL: /* < */
892d650c941SMasatake YAMATO toDoNext = &parseInterfaceProtocolList;
893d650c941SMasatake YAMATO break;
894d650c941SMasatake YAMATO
8953ae02089SMasatake YAMATO default:
8963ae02089SMasatake YAMATO break;
8973ae02089SMasatake YAMATO }
8983ae02089SMasatake YAMATO }
8993ae02089SMasatake YAMATO
9003ae02089SMasatake YAMATO
parseProtocol(vString * const ident,objcToken what)9013ae02089SMasatake YAMATO static void parseProtocol (vString * const ident, objcToken what)
9023ae02089SMasatake YAMATO {
9033ae02089SMasatake YAMATO if (what == ObjcIDENTIFIER)
9043ae02089SMasatake YAMATO {
9053afb5475SMasatake YAMATO int index = addTag (ident, K_PROTOCOL);
906f92402a3SMasatake YAMATO pushEnclosingContextFull (ident, K_PROTOCOL, index);
9073ae02089SMasatake YAMATO }
9083ae02089SMasatake YAMATO toDoNext = &parseMethods;
9093ae02089SMasatake YAMATO }
9103ae02089SMasatake YAMATO
parseImplementation(vString * const ident,objcToken what)9113ae02089SMasatake YAMATO static void parseImplementation (vString * const ident, objcToken what)
9123ae02089SMasatake YAMATO {
9133ae02089SMasatake YAMATO if (what == ObjcIDENTIFIER)
9143ae02089SMasatake YAMATO {
9153afb5475SMasatake YAMATO int index = addTag (ident, K_IMPLEMENTATION);
9169af73c5bSMasatake YAMATO pushEnclosingContextFull (ident, K_IMPLEMENTATION, index);
9173ae02089SMasatake YAMATO }
9183ae02089SMasatake YAMATO toDoNext = &parseImplemMethods;
9193ae02089SMasatake YAMATO }
9203ae02089SMasatake YAMATO
parseInterface(vString * const ident,objcToken what)9213ae02089SMasatake YAMATO static void parseInterface (vString * const ident, objcToken what)
9223ae02089SMasatake YAMATO {
9233ae02089SMasatake YAMATO if (what == ObjcIDENTIFIER)
9243ae02089SMasatake YAMATO {
9253afb5475SMasatake YAMATO int index = addTag (ident, K_INTERFACE);
926a67d9dbeSMasatake YAMATO pushEnclosingContextFull (ident, K_INTERFACE, index);
9273ae02089SMasatake YAMATO }
9283ae02089SMasatake YAMATO
9293ae02089SMasatake YAMATO toDoNext = &parseMethods;
9303ae02089SMasatake YAMATO }
9313ae02089SMasatake YAMATO
parseStructMembers(vString * const ident,objcToken what)9323ae02089SMasatake YAMATO static void parseStructMembers (vString * const ident, objcToken what)
9333ae02089SMasatake YAMATO {
9343ae02089SMasatake YAMATO static parseNext prev = NULL;
9353ae02089SMasatake YAMATO
9363ae02089SMasatake YAMATO if (prev != NULL)
9373ae02089SMasatake YAMATO {
9383ae02089SMasatake YAMATO comeAfter = prev;
9393ae02089SMasatake YAMATO prev = NULL;
9403ae02089SMasatake YAMATO }
9413ae02089SMasatake YAMATO
9423ae02089SMasatake YAMATO switch (what)
9433ae02089SMasatake YAMATO {
9443ae02089SMasatake YAMATO case ObjcIDENTIFIER:
9453ae02089SMasatake YAMATO vStringCopy (tempName, ident);
9463ae02089SMasatake YAMATO break;
9473ae02089SMasatake YAMATO
9483ae02089SMasatake YAMATO case Tok_semi: /* ';' */
9493ae02089SMasatake YAMATO addTag (tempName, K_FIELD);
9503ae02089SMasatake YAMATO vStringClear (tempName);
9513ae02089SMasatake YAMATO break;
9523ae02089SMasatake YAMATO
9533ae02089SMasatake YAMATO /* some types are complex, the only one
9543ae02089SMasatake YAMATO * we will loose is the function type.
9553ae02089SMasatake YAMATO */
9563ae02089SMasatake YAMATO case Tok_CurlL: /* '{' */
9573ae02089SMasatake YAMATO case Tok_PARL: /* '(' */
9583ae02089SMasatake YAMATO case Tok_SQUAREL: /* '[' */
9593ae02089SMasatake YAMATO toDoNext = &ignoreBalanced;
9603ae02089SMasatake YAMATO prev = comeAfter;
9613ae02089SMasatake YAMATO comeAfter = &parseStructMembers;
9623ae02089SMasatake YAMATO ignoreBalanced (ident, what);
9633ae02089SMasatake YAMATO break;
9643ae02089SMasatake YAMATO
9653ae02089SMasatake YAMATO case Tok_CurlR:
9663ae02089SMasatake YAMATO toDoNext = comeAfter;
9673ae02089SMasatake YAMATO break;
9683ae02089SMasatake YAMATO
9693ae02089SMasatake YAMATO default:
9703ae02089SMasatake YAMATO /* don't care */
9713ae02089SMasatake YAMATO break;
9723ae02089SMasatake YAMATO }
9733ae02089SMasatake YAMATO }
9743ae02089SMasatake YAMATO
9753ae02089SMasatake YAMATO /* Called just after the struct keyword */
976ce990805SThomas Braun static bool parseStruct_gotName = false;
parseStruct(vString * const ident,objcToken what)9773ae02089SMasatake YAMATO static void parseStruct (vString * const ident, objcToken what)
9783ae02089SMasatake YAMATO {
9793ae02089SMasatake YAMATO switch (what)
9803ae02089SMasatake YAMATO {
9813ae02089SMasatake YAMATO case ObjcIDENTIFIER:
9823ae02089SMasatake YAMATO if (!parseStruct_gotName)
9833ae02089SMasatake YAMATO {
9843ae02089SMasatake YAMATO addTag (ident, K_STRUCT);
9853ae02089SMasatake YAMATO pushEnclosingContext (ident, K_STRUCT);
986ce990805SThomas Braun parseStruct_gotName = true;
9873ae02089SMasatake YAMATO }
9883ae02089SMasatake YAMATO else
9893ae02089SMasatake YAMATO {
990ce990805SThomas Braun parseStruct_gotName = false;
9913ae02089SMasatake YAMATO popEnclosingContext ();
9923ae02089SMasatake YAMATO toDoNext = comeAfter;
9933ae02089SMasatake YAMATO comeAfter (ident, what);
9943ae02089SMasatake YAMATO }
9953ae02089SMasatake YAMATO break;
9963ae02089SMasatake YAMATO
9973ae02089SMasatake YAMATO case Tok_CurlL:
9983ae02089SMasatake YAMATO toDoNext = &parseStructMembers;
9993ae02089SMasatake YAMATO break;
10003ae02089SMasatake YAMATO
10013ae02089SMasatake YAMATO /* maybe it was just a forward declaration
10023ae02089SMasatake YAMATO * in which case, we pop the context */
10033ae02089SMasatake YAMATO case Tok_semi:
10043ae02089SMasatake YAMATO if (parseStruct_gotName)
10053ae02089SMasatake YAMATO popEnclosingContext ();
10063ae02089SMasatake YAMATO
10073ae02089SMasatake YAMATO toDoNext = comeAfter;
10083ae02089SMasatake YAMATO comeAfter (ident, what);
10093ae02089SMasatake YAMATO break;
10103ae02089SMasatake YAMATO
10113ae02089SMasatake YAMATO default:
10123ae02089SMasatake YAMATO /* we don't care */
10133ae02089SMasatake YAMATO break;
10143ae02089SMasatake YAMATO }
10153ae02089SMasatake YAMATO }
10163ae02089SMasatake YAMATO
10173ae02089SMasatake YAMATO /* Parse enumeration members, ignoring potential initialization */
10183ae02089SMasatake YAMATO static parseNext parseEnumFields_prev = NULL;
parseEnumFields(vString * const ident,objcToken what)10193ae02089SMasatake YAMATO static void parseEnumFields (vString * const ident, objcToken what)
10203ae02089SMasatake YAMATO {
10213ae02089SMasatake YAMATO if (parseEnumFields_prev != NULL)
10223ae02089SMasatake YAMATO {
10233ae02089SMasatake YAMATO comeAfter = parseEnumFields_prev;
10243ae02089SMasatake YAMATO parseEnumFields_prev = NULL;
10253ae02089SMasatake YAMATO }
10263ae02089SMasatake YAMATO
10273ae02089SMasatake YAMATO switch (what)
10283ae02089SMasatake YAMATO {
10293ae02089SMasatake YAMATO case ObjcIDENTIFIER:
10303ae02089SMasatake YAMATO addTag (ident, K_ENUM);
10313ae02089SMasatake YAMATO parseEnumFields_prev = comeAfter;
10323ae02089SMasatake YAMATO waitedToken = Tok_COMA;
10333ae02089SMasatake YAMATO /* last item might not have a coma */
10343ae02089SMasatake YAMATO fallBackToken = Tok_CurlR;
10353ae02089SMasatake YAMATO fallback = comeAfter;
10363ae02089SMasatake YAMATO comeAfter = parseEnumFields;
10373ae02089SMasatake YAMATO toDoNext = &tillTokenOrFallBack;
10383ae02089SMasatake YAMATO break;
10393ae02089SMasatake YAMATO
10403ae02089SMasatake YAMATO case Tok_CurlR:
10413ae02089SMasatake YAMATO toDoNext = comeAfter;
10423ae02089SMasatake YAMATO popEnclosingContext ();
10433ae02089SMasatake YAMATO break;
10443ae02089SMasatake YAMATO
10453ae02089SMasatake YAMATO default:
10463ae02089SMasatake YAMATO /* don't care */
10473ae02089SMasatake YAMATO break;
10483ae02089SMasatake YAMATO }
10493ae02089SMasatake YAMATO }
10503ae02089SMasatake YAMATO
10513ae02089SMasatake YAMATO /* parse enum ... { ... */
1052ce990805SThomas Braun static bool parseEnum_named = false;
parseEnum(vString * const ident,objcToken what)10533ae02089SMasatake YAMATO static void parseEnum (vString * const ident, objcToken what)
10543ae02089SMasatake YAMATO {
10553ae02089SMasatake YAMATO switch (what)
10563ae02089SMasatake YAMATO {
10573ae02089SMasatake YAMATO case ObjcIDENTIFIER:
10583ae02089SMasatake YAMATO if (!parseEnum_named)
10593ae02089SMasatake YAMATO {
10603ae02089SMasatake YAMATO addTag (ident, K_ENUM);
10613ae02089SMasatake YAMATO pushEnclosingContext (ident, K_ENUM);
1062ce990805SThomas Braun parseEnum_named = true;
10633ae02089SMasatake YAMATO }
10643ae02089SMasatake YAMATO else
10653ae02089SMasatake YAMATO {
1066ce990805SThomas Braun parseEnum_named = false;
10673ae02089SMasatake YAMATO popEnclosingContext ();
10683ae02089SMasatake YAMATO toDoNext = comeAfter;
10693ae02089SMasatake YAMATO comeAfter (ident, what);
10703ae02089SMasatake YAMATO }
10713ae02089SMasatake YAMATO break;
10723ae02089SMasatake YAMATO
10733ae02089SMasatake YAMATO case Tok_CurlL: /* '{' */
10743ae02089SMasatake YAMATO toDoNext = &parseEnumFields;
1075ce990805SThomas Braun parseEnum_named = false;
10763ae02089SMasatake YAMATO break;
10773ae02089SMasatake YAMATO
10783ae02089SMasatake YAMATO case Tok_semi: /* ';' */
10793ae02089SMasatake YAMATO if (parseEnum_named)
10803ae02089SMasatake YAMATO popEnclosingContext ();
10813ae02089SMasatake YAMATO toDoNext = comeAfter;
10823ae02089SMasatake YAMATO comeAfter (ident, what);
10833ae02089SMasatake YAMATO break;
10843ae02089SMasatake YAMATO
10853ae02089SMasatake YAMATO default:
10863ae02089SMasatake YAMATO /* don't care */
10873ae02089SMasatake YAMATO break;
10883ae02089SMasatake YAMATO }
10893ae02089SMasatake YAMATO }
10903ae02089SMasatake YAMATO
10913ae02089SMasatake YAMATO /* Parse something like
10923ae02089SMasatake YAMATO * typedef .... ident ;
10933ae02089SMasatake YAMATO * ignoring the defined type but in the case of struct,
10943ae02089SMasatake YAMATO * in which case struct are parsed.
10953ae02089SMasatake YAMATO */
parseTypedef(vString * const ident,objcToken what)10963ae02089SMasatake YAMATO static void parseTypedef (vString * const ident, objcToken what)
10973ae02089SMasatake YAMATO {
10983ae02089SMasatake YAMATO switch (what)
10993ae02089SMasatake YAMATO {
11003ae02089SMasatake YAMATO case ObjcSTRUCT:
11013ae02089SMasatake YAMATO toDoNext = &parseStruct;
11023ae02089SMasatake YAMATO comeAfter = &parseTypedef;
11033ae02089SMasatake YAMATO break;
11043ae02089SMasatake YAMATO
11053ae02089SMasatake YAMATO case ObjcENUM:
11063ae02089SMasatake YAMATO toDoNext = &parseEnum;
11073ae02089SMasatake YAMATO comeAfter = &parseTypedef;
11083ae02089SMasatake YAMATO break;
11093ae02089SMasatake YAMATO
11103ae02089SMasatake YAMATO case ObjcIDENTIFIER:
11113ae02089SMasatake YAMATO vStringCopy (tempName, ident);
11123ae02089SMasatake YAMATO break;
11133ae02089SMasatake YAMATO
11143ae02089SMasatake YAMATO case Tok_semi: /* ';' */
11153ae02089SMasatake YAMATO addTag (tempName, K_TYPEDEF);
11163ae02089SMasatake YAMATO vStringClear (tempName);
11173ae02089SMasatake YAMATO toDoNext = &globalScope;
11183ae02089SMasatake YAMATO break;
11193ae02089SMasatake YAMATO
11203ae02089SMasatake YAMATO default:
11213ae02089SMasatake YAMATO /* we don't care */
11223ae02089SMasatake YAMATO break;
11233ae02089SMasatake YAMATO }
11243ae02089SMasatake YAMATO }
11253ae02089SMasatake YAMATO
1126ce990805SThomas Braun static bool ignorePreprocStuff_escaped = false;
ignorePreprocStuff(vString * const ident CTAGS_ATTR_UNUSED,objcToken what)11278ccb7ee9SJiří Techet static void ignorePreprocStuff (vString * const ident CTAGS_ATTR_UNUSED, objcToken what)
11283ae02089SMasatake YAMATO {
11293ae02089SMasatake YAMATO switch (what)
11303ae02089SMasatake YAMATO {
11313ae02089SMasatake YAMATO case Tok_Backslash:
1132ce990805SThomas Braun ignorePreprocStuff_escaped = true;
11333ae02089SMasatake YAMATO break;
11343ae02089SMasatake YAMATO
11353ae02089SMasatake YAMATO case Tok_EOL:
11363ae02089SMasatake YAMATO if (ignorePreprocStuff_escaped)
11373ae02089SMasatake YAMATO {
1138ce990805SThomas Braun ignorePreprocStuff_escaped = false;
11393ae02089SMasatake YAMATO }
11403ae02089SMasatake YAMATO else
11413ae02089SMasatake YAMATO {
11423ae02089SMasatake YAMATO toDoNext = &globalScope;
11433ae02089SMasatake YAMATO }
11443ae02089SMasatake YAMATO break;
11453ae02089SMasatake YAMATO
11463ae02089SMasatake YAMATO default:
1147ce990805SThomas Braun ignorePreprocStuff_escaped = false;
11483ae02089SMasatake YAMATO break;
11493ae02089SMasatake YAMATO }
11503ae02089SMasatake YAMATO }
11513ae02089SMasatake YAMATO
parseMacroName(vString * const ident,objcToken what)11523ae02089SMasatake YAMATO static void parseMacroName (vString * const ident, objcToken what)
11533ae02089SMasatake YAMATO {
11543ae02089SMasatake YAMATO if (what == ObjcIDENTIFIER)
11553ae02089SMasatake YAMATO addTag (ident, K_MACRO);
11563ae02089SMasatake YAMATO
11573ae02089SMasatake YAMATO toDoNext = &ignorePreprocStuff;
11583ae02089SMasatake YAMATO }
11593ae02089SMasatake YAMATO
parsePreproc(vString * const ident,objcToken what)11603ae02089SMasatake YAMATO static void parsePreproc (vString * const ident, objcToken what)
11613ae02089SMasatake YAMATO {
11623ae02089SMasatake YAMATO switch (what)
11633ae02089SMasatake YAMATO {
11643ae02089SMasatake YAMATO case ObjcIDENTIFIER:
11653ae02089SMasatake YAMATO if (strcmp (vStringValue (ident), "define") == 0)
11663ae02089SMasatake YAMATO toDoNext = &parseMacroName;
11673ae02089SMasatake YAMATO else
11683ae02089SMasatake YAMATO toDoNext = &ignorePreprocStuff;
11693ae02089SMasatake YAMATO break;
11703ae02089SMasatake YAMATO
11713ae02089SMasatake YAMATO default:
11723ae02089SMasatake YAMATO toDoNext = &ignorePreprocStuff;
11733ae02089SMasatake YAMATO break;
11743ae02089SMasatake YAMATO }
11753ae02089SMasatake YAMATO }
11763ae02089SMasatake YAMATO
skipCurlL(vString * const ident,objcToken what)11772b88b85fSMasatake YAMATO static void skipCurlL (vString * const ident, objcToken what)
11782b88b85fSMasatake YAMATO {
11792b88b85fSMasatake YAMATO if (what == Tok_CurlL)
11802b88b85fSMasatake YAMATO toDoNext = comeAfter;
11812b88b85fSMasatake YAMATO }
11822b88b85fSMasatake YAMATO
parseCPlusPlusCLinkage(vString * const ident,objcToken what)11832b88b85fSMasatake YAMATO static void parseCPlusPlusCLinkage (vString * const ident, objcToken what)
11842b88b85fSMasatake YAMATO {
11852b88b85fSMasatake YAMATO toDoNext = comeAfter;
11862b88b85fSMasatake YAMATO
11872b88b85fSMasatake YAMATO /* Linkage specification like "C" */
11882b88b85fSMasatake YAMATO if (what == Tok_CSTRING)
11892b88b85fSMasatake YAMATO toDoNext = skipCurlL;
11902b88b85fSMasatake YAMATO else
11912b88b85fSMasatake YAMATO /* Force handle this ident in globalScope */
11922b88b85fSMasatake YAMATO globalScope (ident, what);
11932b88b85fSMasatake YAMATO }
11942b88b85fSMasatake YAMATO
11953ae02089SMasatake YAMATO /* Handle the "strong" top levels, all 'big' declarations
11963ae02089SMasatake YAMATO * happen here */
globalScope(vString * const ident,objcToken what)11973ae02089SMasatake YAMATO static void globalScope (vString * const ident, objcToken what)
11983ae02089SMasatake YAMATO {
11993ae02089SMasatake YAMATO switch (what)
12003ae02089SMasatake YAMATO {
12013ae02089SMasatake YAMATO case Tok_Sharp:
12023ae02089SMasatake YAMATO toDoNext = &parsePreproc;
12033ae02089SMasatake YAMATO break;
12043ae02089SMasatake YAMATO
12053ae02089SMasatake YAMATO case ObjcSTRUCT:
12063ae02089SMasatake YAMATO toDoNext = &parseStruct;
12073ae02089SMasatake YAMATO comeAfter = &globalScope;
12083ae02089SMasatake YAMATO break;
12093ae02089SMasatake YAMATO
12103ae02089SMasatake YAMATO case ObjcIDENTIFIER:
12113ae02089SMasatake YAMATO /* we keep track of the identifier if we
12123ae02089SMasatake YAMATO * come across a function. */
12133ae02089SMasatake YAMATO vStringCopy (tempName, ident);
12143ae02089SMasatake YAMATO break;
12153ae02089SMasatake YAMATO
12163ae02089SMasatake YAMATO case Tok_PARL:
12173ae02089SMasatake YAMATO /* if we find an opening parenthesis it means we
12183ae02089SMasatake YAMATO * found a function (or a macro...) */
12193ae02089SMasatake YAMATO addTag (tempName, K_FUNCTION);
12203ae02089SMasatake YAMATO vStringClear (tempName);
12213ae02089SMasatake YAMATO comeAfter = &globalScope;
12223ae02089SMasatake YAMATO toDoNext = &ignoreBalanced;
12233ae02089SMasatake YAMATO ignoreBalanced (ident, what);
12243ae02089SMasatake YAMATO break;
12253ae02089SMasatake YAMATO
12263ae02089SMasatake YAMATO case ObjcINTERFACE:
12273ae02089SMasatake YAMATO toDoNext = &parseInterface;
12283ae02089SMasatake YAMATO break;
12293ae02089SMasatake YAMATO
12303ae02089SMasatake YAMATO case ObjcIMPLEMENTATION:
12313ae02089SMasatake YAMATO toDoNext = &parseImplementation;
12323ae02089SMasatake YAMATO break;
12333ae02089SMasatake YAMATO
12343ae02089SMasatake YAMATO case ObjcPROTOCOL:
12353ae02089SMasatake YAMATO toDoNext = &parseProtocol;
12363ae02089SMasatake YAMATO break;
12373ae02089SMasatake YAMATO
12383ae02089SMasatake YAMATO case ObjcTYPEDEF:
12393ae02089SMasatake YAMATO toDoNext = parseTypedef;
12403ae02089SMasatake YAMATO comeAfter = &globalScope;
12413ae02089SMasatake YAMATO break;
12423ae02089SMasatake YAMATO
12433ae02089SMasatake YAMATO case Tok_CurlL:
12443ae02089SMasatake YAMATO comeAfter = &globalScope;
12453ae02089SMasatake YAMATO toDoNext = &ignoreBalanced;
12463ae02089SMasatake YAMATO ignoreBalanced (ident, what);
12473ae02089SMasatake YAMATO break;
12483ae02089SMasatake YAMATO
12492b88b85fSMasatake YAMATO case ObjcEXTERN:
12502b88b85fSMasatake YAMATO comeAfter = &globalScope;
12512b88b85fSMasatake YAMATO toDoNext = &parseCPlusPlusCLinkage;
12522b88b85fSMasatake YAMATO break;
12532b88b85fSMasatake YAMATO
12543ae02089SMasatake YAMATO case ObjcEND:
12553ae02089SMasatake YAMATO case ObjcPUBLIC:
12563ae02089SMasatake YAMATO case ObjcPROTECTED:
12573ae02089SMasatake YAMATO case ObjcPRIVATE:
12583ae02089SMasatake YAMATO
12593ae02089SMasatake YAMATO default:
12603ae02089SMasatake YAMATO /* we don't care */
12613ae02089SMasatake YAMATO break;
12623ae02089SMasatake YAMATO }
12633ae02089SMasatake YAMATO }
12643ae02089SMasatake YAMATO
12653ae02089SMasatake YAMATO /*////////////////////////////////////////////////////////////////
12663ae02089SMasatake YAMATO //// Deal with the system */
12673ae02089SMasatake YAMATO
findObjcTags(void)12683ae02089SMasatake YAMATO static void findObjcTags (void)
12693ae02089SMasatake YAMATO {
12703ae02089SMasatake YAMATO vString *name = vStringNew ();
12713ae02089SMasatake YAMATO lexingState st;
12723ae02089SMasatake YAMATO objcToken tok;
12733ae02089SMasatake YAMATO
12743ae02089SMasatake YAMATO parentName = vStringNew ();
12753ae02089SMasatake YAMATO tempName = vStringNew ();
12763ae02089SMasatake YAMATO fullMethodName = vStringNew ();
12773ae02089SMasatake YAMATO prevIdent = vStringNew ();
127880eb4460SMasatake YAMATO signature = vStringNewInit ("(");
12793ae02089SMasatake YAMATO
12803ae02089SMasatake YAMATO /* (Re-)initialize state variables, this might be a second file */
12813ae02089SMasatake YAMATO comeAfter = NULL;
12823ae02089SMasatake YAMATO fallback = NULL;
12833ae02089SMasatake YAMATO parentType = K_INTERFACE;
12843ae02089SMasatake YAMATO ignoreBalanced_count = 0;
12853ae02089SMasatake YAMATO methodKind = 0;
1286ce990805SThomas Braun parseStruct_gotName = false;
12873ae02089SMasatake YAMATO parseEnumFields_prev = NULL;
1288ce990805SThomas Braun parseEnum_named = false;
1289ce990805SThomas Braun ignorePreprocStuff_escaped = false;
12903ae02089SMasatake YAMATO
12913ae02089SMasatake YAMATO st.name = vStringNew ();
12921b312fe7SMasatake YAMATO st.cp = readLineFromInputFile ();
12933ae02089SMasatake YAMATO toDoNext = &globalScope;
12943ae02089SMasatake YAMATO tok = lex (&st);
12953ae02089SMasatake YAMATO while (tok != Tok_EOF)
12963ae02089SMasatake YAMATO {
12973ae02089SMasatake YAMATO (*toDoNext) (st.name, tok);
12983ae02089SMasatake YAMATO tok = lex (&st);
12993ae02089SMasatake YAMATO }
13003ae02089SMasatake YAMATO vStringDelete(st.name);
13013ae02089SMasatake YAMATO
13023ae02089SMasatake YAMATO vStringDelete (name);
13033ae02089SMasatake YAMATO vStringDelete (parentName);
13043ae02089SMasatake YAMATO vStringDelete (tempName);
13053ae02089SMasatake YAMATO vStringDelete (fullMethodName);
13063ae02089SMasatake YAMATO vStringDelete (prevIdent);
130780eb4460SMasatake YAMATO vStringDelete (signature);
130880eb4460SMasatake YAMATO signature = NULL;
13093ae02089SMasatake YAMATO parentName = NULL;
13103ae02089SMasatake YAMATO tempName = NULL;
13113ae02089SMasatake YAMATO prevIdent = NULL;
13123ae02089SMasatake YAMATO fullMethodName = NULL;
13139af73c5bSMasatake YAMATO categoryCorkIndex = CORK_NIL;
131409152b33SMasatake YAMATO parentCorkIndex = CORK_NIL;
13153ae02089SMasatake YAMATO }
13163ae02089SMasatake YAMATO
objcInitialize(const langType language)13173ae02089SMasatake YAMATO static void objcInitialize (const langType language)
13183ae02089SMasatake YAMATO {
13193ae02089SMasatake YAMATO Lang_ObjectiveC = language;
13203ae02089SMasatake YAMATO }
13213ae02089SMasatake YAMATO
ObjcParser(void)13223ae02089SMasatake YAMATO extern parserDefinition *ObjcParser (void)
13233ae02089SMasatake YAMATO {
13243ae02089SMasatake YAMATO static const char *const extensions[] = { "mm", "m", "h",
13253ae02089SMasatake YAMATO NULL };
13263ae02089SMasatake YAMATO static const char *const aliases[] = { "objc", "objective-c",
13273ae02089SMasatake YAMATO NULL };
13285a38b5ceSMasatake YAMATO static selectLanguage selectors[] = { selectByObjectiveCAndMatLabKeywords,
13298e1e6125SMasatake YAMATO selectByObjectiveCKeywords,
13305a38b5ceSMasatake YAMATO NULL };
1331b29ae60fSMasatake YAMATO parserDefinition *def = parserNew ("ObjectiveC");
133209ae690fSMasatake YAMATO def->kindTable = ObjcKinds;
13333db72c21SMasatake YAMATO def->kindCount = ARRAY_SIZE (ObjcKinds);
13343ae02089SMasatake YAMATO def->extensions = extensions;
13359af73c5bSMasatake YAMATO def->fieldTable = ObjcFields;
13369af73c5bSMasatake YAMATO def->fieldCount = ARRAY_SIZE (ObjcFields);
13373ae02089SMasatake YAMATO def->aliases = aliases;
13383ae02089SMasatake YAMATO def->parser = findObjcTags;
13393ae02089SMasatake YAMATO def->initialize = objcInitialize;
13405a38b5ceSMasatake YAMATO def->selectLanguage = selectors;
1341c379c5d2SMasatake YAMATO def->keywordTable = objcKeywordTable;
13423db72c21SMasatake YAMATO def->keywordCount = ARRAY_SIZE (objcKeywordTable);
13436b1a862eSMasatake YAMATO def->useCork = CORK_QUEUE;
13443ae02089SMasatake YAMATO return def;
13453ae02089SMasatake YAMATO }
1346