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;
}
_______________________________________________
Devel mailing list
Devel@lists.geany.org
https://lists.geany.org/cgi-bin/mailman/listinfo/devel

Reply via email to