/** * interfaces in Obj-C look like: * * @interface Class1 [ : SuperClass | (CategoryName) ] [ <Protocols> ] * [ { * ... * } * ] * methods * @end */ static void interfaceHandler(const char *keyword) { char *ident; char *proto = NULL; char *superclass = NULL; char *inheritance; int z; z = skipToNonWhite(); ident = readToNonIdentifier(0); if (ident && *ident) { ident = eStrdup(ident); } else { return; } recordPosition(); z = skipToNonWhite(); if (z == '(') { char *category; char *newIdent; category = readCategoryTag(); if (category) { newIdent = eMalloc(strlen(category) + strlen(ident) + 1); strcpy(newIdent, ident); strcat(newIdent, category); eFree(ident); ident = newIdent; } } else if (z == ':') { cppGetc(); skipToNonWhite(); superclass = readToNonIdentifier(0); } if (superclass && *superclass) { superclass = eStrdup(superclass); } else{ superclass = eStrdup(""); } proto = readProtocolTag(); if (proto && *proto) { proto = eStrdup(proto); } else { proto = eStrdup("<>"); } inheritance = eMalloc(strlen(proto) + strlen(superclass) + 1); strcpy(inheritance, superclass); strcat(inheritance, proto); emitObjCTag(ident, K_INTERFACE, 0, inheritance, TRUE); readObjCMethods(K_INTMETHOD, ident, inheritance); eFree(ident); eFree(proto); eFree(superclass); eFree(inheritance); }
/** * We need to handle two forms here: * @protocol ProtocolName; // Do Nothing * @protocol ProtocolName | <OtherProtocols> | * ... * @end // Handle this protocol */ static void protocolHandler(const char *keyword) { char *ident; char *proto = NULL; int z; z = skipToNonWhite(); ident = readToNonIdentifier(0); if (ident && *ident) ident = eStrdup(ident); else return; recordPosition(); z = skipToNonWhite(); if (z == ';') { eFree(ident); return; } proto = readProtocolTag(); if (proto && *proto) proto = eStrdup(proto); else proto = eStrdup("<>"); emitObjCTag(ident, K_PROTOCOL, 0, proto, TRUE); readObjCMethods(K_PMETHOD, ident, proto); eFree(ident); eFree(proto); }
/** * Generate tags for all Obj-C methods until an @end. scope and inheritance are * the class/protocol the method belongs to and the inheritance chain for that class */ static void readObjCMethods(objcKind mType, const char *scope, const char *inheritance) { int z; const char *temp; vString *method = vStringNew(); while (1) { z = skipToNonWhite(); if (z == EOF) break; z = skipToMethod(); switch(z) { case '@': cppGetc(); temp = readToNonAlpha(0); if (temp && !strcmp(temp, "end")){ return; } break; case '[': case '{': readToMatchingBrace(0); break; case '-': case '+': recordPosition(); getSingleObjCMethod(method); emitObjCTag(vStringValue(method), mType, scope, inheritance, TRUE); break; default: break; } } vStringDelete(method); }
/** * Find a @ that isn't in a string */ static int skipToObjCKeyword (void) { int z; while ((z = skipToNonWhite()) != EOF) { cppGetc(); if (z == '"') readToMatchingBrace(0); if (z == '@') { break; } } return z; }
/** * implementations in Obj-C look like: * * @implementation Class1 [ (CategoryName) ] * [ { * ... * } * ] * methods * @end */ static void implementationHandler(const char *keyword) { char *ident; int z; z = skipToNonWhite(); ident = readToNonIdentifier(0); if (ident && *ident) { ident = eStrdup(ident); } else { return; } recordPosition(); z = skipToNonWhite(); if (z == '(') { char *category; char *newIdent; category = readCategoryTag(); if (category) { newIdent = eMalloc(strlen(category) + strlen(ident) + 1); strcpy(newIdent, ident); strcat(newIdent, category); eFree(ident); ident = newIdent; } } emitObjCTag(ident, K_IMPLEMENTATION, 0, 0, TRUE); readObjCMethods(K_IMPMETHOD, ident, 0); eFree(ident); }
/** * Reads from 'start' to 'end' and eliminates all spaces * inbetween. */ static char *readBetweenDelimitersWhileTrimmingSpaces(char start, char end) { static vString *wordBuffer = 0; int z; if (!wordBuffer) wordBuffer = vStringNew(); else vStringClear(wordBuffer); z = skipToNonWhite(); if (z != start) return NULL; while ((z = cppGetc()) != EOF && z != end) { if (isspace(z)) continue; vStringPut(wordBuffer, z); } if (z == EOF) return NULL; vStringPut(wordBuffer, z); vStringPut(wordBuffer, 0); return vStringValue(wordBuffer); }
static void findMakeTags (void) { stringList *identifiers = stringListNew (); boolean newline = TRUE; boolean in_define = FALSE; boolean in_rule = FALSE; boolean variable_possible = TRUE; int c; while ((c = nextChar ()) != EOF) { if (newline) { if (in_rule) { if (c == '\t' || (c = skipToNonWhite (c)) == '#') { skipLine (); /* skip rule or comment */ c = nextChar (); } else if (c != '\n') in_rule = FALSE; } stringListClear (identifiers); variable_possible = (boolean)(!in_rule); newline = FALSE; } if (c == '\n') newline = TRUE; else if (isspace (c)) continue; else if (c == '#') skipLine (); else if (variable_possible && c == '?') { c = nextChar (); ungetcToInputFile (c); variable_possible = (c == '='); } else if (variable_possible && c == ':' && stringListCount (identifiers) > 0) { c = nextChar (); ungetcToInputFile (c); if (c != '=') { unsigned int i; for (i = 0; i < stringListCount (identifiers); i++) newTarget (stringListItem (identifiers, i)); stringListClear (identifiers); in_rule = TRUE; } } else if (variable_possible && c == '=' && stringListCount (identifiers) == 1) { newMacro (stringListItem (identifiers, 0)); skipLine (); in_rule = FALSE; } else if (variable_possible && isIdentifier (c)) { vString *name = vStringNew (); readIdentifier (c, name); stringListAdd (identifiers, name); if (stringListCount (identifiers) == 1) { if (in_define && ! strcmp (vStringValue (name), "endef")) in_define = FALSE; else if (in_define) skipLine (); else if (! strcmp (vStringValue (name), "define")) { in_define = TRUE; c = skipToNonWhite (nextChar ()); vStringClear (name); /* all remaining characters on the line are the name -- even spaces */ while (c != EOF && c != '\n') { vStringPut (name, c); c = nextChar (); } if (c == '\n') ungetcToInputFile (c); vStringTerminate (name); vStringStripTrailing (name); newMacro (name); } else if (! strcmp (vStringValue (name), "export")) stringListClear (identifiers); else if (! strcmp (vStringValue (name), "include") || ! strcmp (vStringValue (name), "sinclude") || ! strcmp (vStringValue (name), "-include")) { boolean optional = (vStringValue (name)[0] == 'i')? FALSE: TRUE; while (1) { c = skipToNonWhite (nextChar ()); readIdentifier (c, name); vStringStripTrailing (name); if (isAcceptableAsInclude(name)) newInclude (name, optional); /* non-space characters after readIdentifier() may * be rejected by the function: * e.g. * include $* * * Here, remove such characters from input stream. */ do c = nextChar (); while (c != EOF && c != '\n' && (!isspace (c))); if (c == '\n') ungetcToInputFile (c); if (c == EOF || c == '\n') break; } } } } else variable_possible = FALSE; } stringListDelete (identifiers); }
static void findMakeTags (void) { stringList *identifiers = stringListNew (); boolean newline = TRUE; boolean in_define = FALSE; boolean in_rule = FALSE; boolean variable_possible = TRUE; int c; while ((c = nextChar ()) != EOF) { if (newline) { if (in_rule) { if (c == '\t' || (c = skipToNonWhite (c)) == '#') { skipLine (); /* skip rule or comment */ c = nextChar (); } else if (c != '\n') in_rule = FALSE; } stringListClear (identifiers); variable_possible = (boolean)(!in_rule); newline = FALSE; } if (c == '\n') newline = TRUE; else if (isspace (c)) continue; else if (c == '#') skipLine (); else if (variable_possible && c == '?') { c = nextChar (); fileUngetc (c); variable_possible = (c == '='); } else if (variable_possible && c == ':' && stringListCount (identifiers) > 0) { c = nextChar (); fileUngetc (c); if (c != '=') { unsigned int i; for (i = 0; i < stringListCount (identifiers); i++) newTarget (stringListItem (identifiers, i)); stringListClear (identifiers); in_rule = TRUE; } } else if (variable_possible && c == '=' && stringListCount (identifiers) == 1) { newMacro (stringListItem (identifiers, 0)); skipLine (); in_rule = FALSE; } else if (variable_possible && isIdentifier (c)) { vString *name = vStringNew (); readIdentifier (c, name); stringListAdd (identifiers, name); if (stringListCount (identifiers) == 1) { if (in_define && ! strcmp (vStringValue (name), "endef")) in_define = FALSE; else if (in_define) skipLine (); else if (! strcmp (vStringValue (name), "define")) { in_define = TRUE; c = skipToNonWhite (nextChar ()); vStringClear (name); /* all remaining characters on the line are the name -- even spaces */ while (c != EOF && c != '\n') { vStringPut (name, c); c = nextChar (); } if (c == '\n') fileUngetc (c); vStringTerminate (name); vStringStripTrailing (name); newMacro (name); } else if (! strcmp (vStringValue (name), "export")) stringListClear (identifiers); } } else variable_possible = FALSE; } stringListDelete (identifiers); }
static void findMakeTags (void) { vString *name = vStringNew (); boolean newline = TRUE; boolean in_define = FALSE; boolean in_rule = FALSE; boolean variable_possible = TRUE; int c; while ((c = nextChar ()) != EOF) { if (newline) { if (in_rule) { if (c == '\t') { skipLine (); /* skip rule */ continue; } else in_rule = FALSE; } variable_possible = (boolean)(!in_rule); newline = FALSE; } if (c == '\n') newline = TRUE; else if (isspace (c)) continue; else if (c == '#') skipLine (); else if (c == '(') skipToMatch ("()"); else if (c == '{') skipToMatch ("{}"); else if (c == ':') { variable_possible = TRUE; in_rule = TRUE; } else if (variable_possible && isIdentifier (c)) { readIdentifier (c, name); if (strcmp (vStringValue (name), "endef") == 0) in_define = FALSE; else if (in_define) skipLine (); else if (strcmp (vStringValue (name), "define") == 0 && isIdentifier (c)) { in_define = TRUE; c = skipToNonWhite (); readIdentifier (c, name); makeSimpleTag (name, MakeKinds, K_MACRO); skipLine (); } else { c = skipToNonWhite (); if (strchr (":?+", c) != NULL) { boolean append = (boolean)(c == '+'); if (c == ':') in_rule = TRUE; c = nextChar (); if (c != '=') fileUngetc (c); else if (append) { skipLine (); continue; } } if (c == '=') { makeSimpleTag (name, MakeKinds, K_MACRO); in_rule = FALSE; skipLine (); } } } else variable_possible = FALSE; } vStringDelete (name); }