On 09/24/2013 04:18 PM, Tory Gaurnier wrote:
On 09/24/2013 01:10 PM, Tory Gaurnier wrote:
Well, I've pretty much got it working, the highlighting is working, and the Javascript functions show up in the symbol list, it's just not showing the QML Objects, so once I get that fixed it'll be finished, at least the first version, I'm sure I'll want to improve it in the future.
Ok, so now I really am at a loss, my qml.c file works fine in Ctags, but in Geany it only adds the Javascript functions to the symbol list, I really can't figure it out. I've looked over everything, I've compared the differences from Ctags in Geany to the original Ctags, the only real change that makes a difference that I can see is the fact that the type for filePosition was changed to MIOPos. I'm pretty sure I've edited the different config files correctly, everythings working except for the QML Objects. Now when I'm running Geany I'm running in terminal and there are 0 errors being printed.
Here's my qml.c file:
#include "general.h" /* always include first */ #include "entry.h" #include "parse.h" /* always include */ #include "read.h" /* to define file fileReadLine() */
#include <string.h> /* to declare strxxx() functions */
typedef struct { vString *id; vString *kind; vString *name; unsigned long line_num; MIOPos file_pos; // THIS IS THE ONLY THING I'VE CHANGED FROM THE CTAGS VERSION char *kind_name; char kind_letter; } QMLObject;
typedef enum { QML_OBJECT, JS_FUNCTION, KIND_COUNT } QMLKind;
static kindOption QMLKinds[KIND_COUNT] = { { TRUE, 'o', "object", "objects" }, { TRUE, 'f', "function", "functions" } };
const unsigned char* skipMultilineComment(const unsigned char *line) { boolean found = FALSE;
while(*line != '\0') { if(strncmp(line, "*/", 2) == 0) { line += 2; found = TRUE; break; } line++; } if(found) line = NULL; return line;
}
void createQMLObjectTag(QMLObject *qml_obj, boolean *is_qml_object) { tagEntryInfo entry;
// Added this line here to test, and it's printing fine, all
values are there printf("%s - %d - %s - %c\n", qml_obj->name->buffer, (int)qml_obj->line_num, qml_obj->kind_name, qml_obj->kind_letter);
initTagEntry(&entry, qml_obj->name->buffer); entry.lineNumber = qml_obj->line_num; entry.filePosition = qml_obj->file_pos; entry.kindName = qml_obj->kind_name; entry.kind = qml_obj->kind_letter; makeTagEntry(&entry); // WHY YOU NO MAKE TAG IN SYMBOL LIST!!!! >_< vStringClear(qml_obj->name); vStringDelete(qml_obj->name); *is_qml_object = FALSE;
}
vString* getName(const unsigned char **str_ptr) { vString *name = vStringNew(); const unsigned char *str = *str_ptr;
while(isalnum(*str) || *str == '_') { vStringPut(name, *str); str++; } *str_ptr = str; vStringTerminate(name); return name;
}
vString *getId(const unsigned char *str, vString *name) { vString *id = vStringNew();
while(strstr(str, "id:") != NULL) { if(strncmp(str, "id:", 3) == 0) { str += 3; while(isspace(*str)) str++; id = getName(&str); vStringCatS(name, " "); vStringCat(name, id); } else str++; } vStringClear(id); vStringDelete(id); return name;
}
static void findQMLTags(void) { vString *js_name; QMLObject *qml_obj = malloc(sizeof(QMLObject)); const unsigned char *line; boolean is_multiline_comment = FALSE; boolean is_qml_object = FALSE;
while((line = fileReadLine()) != NULL) { // If in middle of multiline comment, skip through till end if(is_multiline_comment) { if((line = skipMultilineComment(line)) == NULL) continue; else is_multiline_comment = FALSE; } // Skip whitespace and comments while(isspace(*line)) line++; if(strncmp(line, "//", 2) == 0) continue; if(strncmp(line, "/*", 2) == 0) { is_multiline_comment = TRUE; if((line = skipMultilineComment(line)) == NULL) continue; else is_multiline_comment = FALSE; } // If in middle of QML Object { } check for ID and '}' if(is_qml_object && (strstr(line, "id:") != NULL ||
strchr(line, '}') != NULL)) { if(strstr(line, "id:") != NULL) qml_obj->name = getId(line, qml_obj->name);
else createQMLObjectTag(qml_obj, &is_qml_object); } // If '{' in line, but '(' not in line, then there might be a
QML Object if(strchr(line, '{') != NULL && strchr(line, '(') == NULL) { int i = 0; while(isspace(*line)) line++; // Increment ptr past any whitespace before 'Object {' // Search past whole word of 'Object' while(!isspace(line[i])) { if(line[i] == '{' || line[i] == ':') break; i++; }
while(isspace(line[i])) i++; // Search past any space
between 'Object' and '{'
// If '{' is after potential Object name and any
whitespace, prepare tag to be added if(line[i] == '{') { qml_obj->name = getName(&line); qml_obj->line_num = File.lineNumber; qml_obj->file_pos = File.filePosition; qml_obj->kind_name = (char*)QMLKinds[QML_OBJECT].name; qml_obj->kind_letter = QMLKinds[QML_OBJECT].letter; qml_obj->kind = QML_OBJECT; is_qml_object = TRUE;
// If ID is on same line if(strstr(line, "id:") != NULL) { while(strncmp(line, "id:", 3) != 0) line++; qml_obj->name = getId(line, qml_obj->name); } // If single line Object if(strchr(line, '}') != NULL) createQMLObjectTag(qml_obj, &is_qml_object); } } // If line contains a function // Using while to prepare for unlikely event that "function"
appears more than once in line while(strstr(line, "function") != NULL) { while(strncmp(line, "function", 8) != 0) line++;
// If whitespace is after "function" if(isspace(line[8])) { line += 8; // Skip past "function" while(isspace(*line)) line++; vString *name = getName(&line); while(isspace(*line)) line++; // If '(' is after "function" and whitespace, then add
tag as JS_FUNCTION if(*line == '(') makeSimpleTag(name, QMLKinds, JS_FUNCTION); vStringClear(name); vStringDelete(name);
break; } else line++; } }
}
extern parserDefinition *QMLParser(void) { parserDefinition* def = parserNew("QML"); static const char *const extensions [] = { "qml", NULL };
def->kinds = QMLKinds; def->kindCount = KIND_COUNT(QMLKinds); def->extensions = extensions; def->parser = findQMLTags; def->regex = FALSE; return def;
}
Still can't figure it out, to test I even put printf("MAKING TAG: %s - %d - %s - %c\n", tag->name, (int)tag->lineNumber, tag->kindName, tag->kind); in entry.c's makeTagEntry function, and it prints just as you'd expect, it prints the info for QML objects and JS functions, but only the JS functions show in the symbol list, I've tried tracing it back further but can't even figure it out. But, I mean, if makeTagEntry is getting all the data, it should be adding to symbol list right???
This is getting very frustrating, I've looked over my code a million times and I can't find anything that would be keeping this from working, it works fine in CTags, but not in Geany, makeSimpleTag works fine, but when I try to manually use makeTagEntry, nothing happens, even though makeSimpleTag is doing the exact same thing...