~ubuntu-branches/ubuntu/lucid/codelite/lucid

« back to all changes in this revision

Viewing changes to sdk/codelite_indexer/libctags/erlang.c

  • Committer: Bazaar Package Importer
  • Author(s): Chow Loong Jin
  • Date: 2009-02-10 02:27:55 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090210022755-m5692nfc1t5uf1w9
Tags: 1.0.2759+dfsg-0ubuntu1
* New upstream release (LP: #327216).
* debian/patches/series, debian/patches/00_fix-ia64-build.patch:
  + Dropped, applied upstream already.
* debian/patches/02_fix-desktop.patch,
  debian/patches/03_fix-sh.patch:
  + Refreshed to patch cleanly.
* debian/rules:
  + Make get-orig-source honour UPSTREAM_VERSION if set.
* debian/ctags-le.1,
  debian/codelite_indexer.1,
  debian/codelite.manpages:
  + Dropped ctags-le manpage, since ctags-le was replaced by
    codelite_indexer.
  + Added codelite_indexer manpage.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
*   $Id: erlang.c,v 1.3 2006/05/30 04:37:12 darren Exp $
 
3
*
 
4
*   Copyright (c) 2003, Brent Fulgham <bfulgham@debian.org>
 
5
*
 
6
*   This source code is released for free distribution under the terms of the
 
7
*   GNU General Public License.
 
8
*
 
9
*   This module contains functions for generating tags for Erlang language
 
10
*   files.  Some of the parsing constructs are based on the Emacs 'etags'
 
11
*   program by Francesco Potori <pot@gnu.org>
 
12
*/
 
13
/*
 
14
*   INCLUDE FILES
 
15
*/
 
16
#include "general.h"  /* must always come first */
 
17
 
 
18
#include <string.h>
 
19
 
 
20
#include "entry.h"
 
21
#include "options.h"
 
22
#include "read.h"
 
23
#include "routines.h"
 
24
#include "vstring.h"
 
25
 
 
26
/*
 
27
*   DATA DEFINITIONS
 
28
*/
 
29
typedef enum {
 
30
        K_MACRO, K_FUNCTION, K_MODULE, K_RECORD
 
31
} erlangKind;
 
32
 
 
33
static kindOption ErlangKinds[] = {
 
34
        {TRUE, 'd', "macro",    "macro definitions"},
 
35
        {TRUE, 'f', "function", "functions"},
 
36
        {TRUE, 'm', "module",   "modules"},
 
37
        {TRUE, 'r', "record",   "record definitions"},
 
38
};
 
39
 
 
40
/*
 
41
*   FUNCTION DEFINITIONS
 
42
*/
 
43
/* tagEntryInfo and vString should be preinitialized/preallocated but not
 
44
 * necessary. If successful you will find class name in vString
 
45
 */
 
46
 
 
47
static boolean isIdentifierFirstCharacter (int c)
 
48
{
 
49
        return (boolean) (isalpha (c));
 
50
}
 
51
 
 
52
static boolean isIdentifierCharacter (int c)
 
53
{
 
54
        return (boolean) (isalnum (c) || c == '_' || c == ':');
 
55
}
 
56
 
 
57
static const unsigned char *skipSpace (const unsigned char *cp)
 
58
{
 
59
        while (isspace ((int) *cp))
 
60
                ++cp;
 
61
        return cp;
 
62
}
 
63
 
 
64
static const unsigned char *parseIdentifier (
 
65
                const unsigned char *cp, vString *const identifier)
 
66
{
 
67
        vStringClear (identifier);
 
68
        while (isIdentifierCharacter ((int) *cp))
 
69
        {
 
70
                vStringPut (identifier, (int) *cp);
 
71
                ++cp;
 
72
        }
 
73
        vStringTerminate (identifier);
 
74
        return cp;
 
75
}
 
76
 
 
77
static void makeMemberTag (
 
78
                vString *const identifier, erlangKind kind, vString *const module)
 
79
{
 
80
        if (ErlangKinds [kind].enabled  &&  vStringLength (identifier) > 0)
 
81
        {
 
82
                tagEntryInfo tag;
 
83
                initTagEntry (&tag, vStringValue (identifier));
 
84
                tag.kindName = ErlangKinds[kind].name;
 
85
                tag.kind = ErlangKinds[kind].letter;
 
86
 
 
87
                if (module != NULL  &&  vStringLength (module) > 0)
 
88
                {
 
89
                        tag.extensionFields.scope [0] = "module";
 
90
                        tag.extensionFields.scope [1] = vStringValue (module);
 
91
                }
 
92
                makeTagEntry (&tag);
 
93
        }
 
94
}
 
95
 
 
96
static void parseModuleTag (const unsigned char *cp, vString *const module)
 
97
{
 
98
        vString *const identifier = vStringNew ();
 
99
        parseIdentifier (cp, identifier);
 
100
        makeSimpleTag (identifier, ErlangKinds, K_MODULE);
 
101
 
 
102
        /* All further entries go in the new module */
 
103
        vStringCopy (module, identifier);
 
104
        vStringDelete (identifier);
 
105
}
 
106
 
 
107
static void parseSimpleTag (const unsigned char *cp, erlangKind kind)
 
108
{
 
109
        vString *const identifier = vStringNew ();
 
110
        parseIdentifier (cp, identifier);
 
111
        makeSimpleTag (identifier, ErlangKinds, kind);
 
112
        vStringDelete (identifier);
 
113
}
 
114
 
 
115
static void parseFunctionTag (const unsigned char *cp, vString *const module)
 
116
{
 
117
        vString *const identifier = vStringNew ();
 
118
        parseIdentifier (cp, identifier);
 
119
        makeMemberTag (identifier, K_FUNCTION, module);
 
120
        vStringDelete (identifier);
 
121
}
 
122
 
 
123
/*
 
124
 * Directives are of the form:
 
125
 * -module(foo)
 
126
 * -define(foo, bar)
 
127
 * -record(graph, {vtab = notable, cyclic = true}).
 
128
 */
 
129
static void parseDirective (const unsigned char *cp, vString *const module)
 
130
{
 
131
        /*
 
132
         * A directive will be either a record definition or a directive.
 
133
         * Record definitions are handled separately
 
134
         */
 
135
        vString *const directive = vStringNew ();
 
136
        const char *const drtv = vStringValue (directive);
 
137
        cp = parseIdentifier (cp, directive);
 
138
        cp = skipSpace (cp);
 
139
        if (*cp == '(')
 
140
                ++cp;
 
141
 
 
142
        if (strcmp (drtv, "record") == 0)
 
143
                parseSimpleTag (cp, K_RECORD);
 
144
        else if (strcmp (drtv, "define") == 0)
 
145
                parseSimpleTag (cp, K_MACRO);
 
146
        else if (strcmp (drtv, "module") == 0)
 
147
                parseModuleTag (cp, module);
 
148
        /* Otherwise, it was an import, export, etc. */
 
149
        
 
150
        vStringDelete (directive);
 
151
}
 
152
 
 
153
static void findErlangTags (void)
 
154
{
 
155
        vString *const module = vStringNew ();
 
156
        const unsigned char *line;
 
157
 
 
158
        while ((line = fileReadLine ()) != NULL)
 
159
        {
 
160
                const unsigned char *cp = line;
 
161
 
 
162
                if (*cp == '%')  /* skip initial comment */
 
163
                        continue;
 
164
                if (*cp == '"')  /* strings sometimes start in column one */
 
165
                        continue;
 
166
 
 
167
                if ( *cp == '-')
 
168
                {
 
169
                        ++cp;  /* Move off of the '-' */
 
170
                        parseDirective(cp, module);
 
171
                }
 
172
                else if (isIdentifierFirstCharacter ((int) *cp))
 
173
                        parseFunctionTag (cp, module);
 
174
        }
 
175
        vStringDelete (module);
 
176
}
 
177
 
 
178
extern parserDefinition *ErlangParser (void)
 
179
{
 
180
        static const char *const extensions[] = { "erl", "ERL", "hrl", "HRL", NULL };
 
181
        parserDefinition *def = parserNew ("Erlang");
 
182
        def->kinds = ErlangKinds;
 
183
        def->kindCount = KIND_COUNT (ErlangKinds);
 
184
        def->extensions = extensions;
 
185
        def->parser = findErlangTags;
 
186
        return def;
 
187
}
 
188
 
 
189
/* vi:set tabstop=4 shiftwidth=4: */