Merge pull request #482 from philippwiesemann/fix-typos-po-de
[geany-mirror.git] / tagmanager / ctags / r.c
blob914eb4d6a0f807fd2815ce2ce5f3f7a90ae79af2
1 /*
2 * Copyright (c) 2003-2004, Ascher Stefan <stievie@utanet.at>
4 * This source code is released for free distribution under the terms of the
5 * GNU General Public License.
7 * This module contains functions for generating tags for R language files.
8 * R is a programming language for statistical computing.
9 * R is GPL Software, get it from http://www.r-project.org/
13 * INCLUDE FILES
15 #include "general.h" /* must always come first */
17 #include <string.h>
18 #include <ctype.h> /* to define isalpha(), isalnum(), isspace() */
20 #include "entry.h"
21 #include "read.h"
22 #include "vstring.h"
24 /*#define R_REGEX*/
26 #define SKIPSPACE(ch) while (isspace((int)*ch)) \
27 ch++
29 #ifndef R_REGEX
30 typedef enum {
31 K_FUNCTION,
32 K_LIBRARY,
33 K_SOURCE,
34 KIND_COUNT
35 } rKind;
37 static kindOption RKinds [KIND_COUNT] = {
38 { TRUE, 'f', "function", "functions" },
39 { TRUE, 's', "other", "libraries" },
40 { TRUE, 's', "other", "sources" },
42 #endif
44 #ifdef R_REGEX
45 static void installRRegex (const langType language)
47 /* This is a function, looks as follows:
48 * itent <- function(arg1, arg2) {
49 * do_something;
50 * }
52 addTagRegex (language,
53 "^[ \t]*([.a-zA-Z0-9_]+)([ \t]*)<-([ \t]*)function", "\\1", "f,function", NULL);
54 /* This loads someting, e.g. a library, simply: library(libname) */
55 addTagRegex (language,
56 "^[ \t]*(library|source|load|data)[\\(]([a-zA-Z0-9_]+)[\\)]", "\\2", "s,other", NULL);
58 #else
59 static void makeRTag(const vString* const name, rKind kind)
61 tagEntryInfo e;
62 initTagEntry(&e, vStringValue(name));
64 Assert(kind < KIND_COUNT);
66 e.kindName = RKinds[kind].name;
67 e.kind = RKinds[kind].letter;
69 makeTagEntry(&e);
72 static void createRTags(void)
74 vString *vLine = vStringNew();
75 vString *name = vStringNew();
76 int ikind;
77 const unsigned char *line;
79 while ((line = fileReadLine()) != NULL)
81 const unsigned char *cp = (const unsigned char*)line;
83 vStringClear(name);
84 while ((*cp != '\0') && (*cp != '#')) {
85 /* iterate to the end of line or to a comment */
86 ikind = -1;
87 switch (*cp) {
88 case 'l':
89 case 's':
90 if (strncasecmp((const char*)cp, "library", (size_t)7) == 0) {
91 /* load a library: library(tools) */
92 cp += 7;
93 SKIPSPACE(cp);
94 if (*cp == '(')
95 ikind = K_LIBRARY;
96 else
97 cp -= 7;
98 } else if (strncasecmp((const char*)cp, "source", (size_t)6) == 0) {
99 /* load a source file: source("myfile.r") */
100 cp += 6;
101 SKIPSPACE(cp);
102 if (*cp == '(')
103 ikind = K_SOURCE;
104 else
105 cp -= 6;
107 if (ikind != -1) {
108 cp++;
110 vStringClear(name);
111 while ((!isspace((int)*cp)) && *cp != '\0' && *cp != ')') {
112 vStringPut(name, (int)*cp);
113 cp++;
115 vStringTerminate(name);
117 /* if the string really exists, make a tag of it */
118 if (vStringLength(name) > 0)
119 makeRTag(name, ikind);
121 /* prepare for the next iteration */
122 vStringClear(name);
123 } else {
124 vStringPut(name, (int)*cp);
125 cp++;
127 break;
128 case '<':
129 cp++;
130 if (*cp == '-') {
131 /* assignment: ident <- someval */
132 cp++;
133 SKIPSPACE(cp);
135 if (*cp == '\0') {
136 /* not in this line, read next */
137 /* sometimes functions are declared this way:
138 ident <-
139 function(...)
143 I don't know if there is a reason to write the function keyword
144 in a new line
146 if ((line = fileReadLine()) != NULL) {
147 cp = (const unsigned char*)line;
148 SKIPSPACE(cp);
152 if (strncasecmp((const char*)cp, "function", (size_t)8) == 0) {
153 /* it's a function: ident <- function(args) */
154 cp += 8;
155 vStringTerminate(name);
156 /* if the string really exists, make a tag of it */
157 if (vStringLength(name) > 0)
158 makeRTag(name, K_FUNCTION);
160 /* prepare for the next iteration */
161 vStringClear(name);
162 break;
165 case ' ':
166 case '\x009':
167 /* skip whitespace */
168 cp++;
169 break;
170 default:
171 /* collect all characters that could be a part of an identifier */
172 vStringPut(name, (int)*cp);
173 cp++;
174 break;
179 vStringDelete(name);
180 vStringDelete(vLine);
182 #endif
184 extern parserDefinition* RParser (void)
186 /* *.r: R files
187 * *.s;*.q: S files
189 static const char *const extensions [] = { "r", "s", "q", NULL };
190 parserDefinition* const def = parserNew ("R");
191 #ifndef R_REGEX
192 def->kinds = RKinds;
193 def->kindCount = 4;
194 #endif
195 def->extensions = extensions;
196 #ifndef R_REGEX
197 def->parser = createRTags;
198 #else
199 def->initialize = installRRegex;
200 def->regex = TRUE;
201 #endif
202 return def;
205 /* vi:set tabstop=8 shiftwidth=4: */