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 version 2 or (at your option) any later version.
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/
15 #include "general.h" /* must always come first */
18 #include <ctype.h> /* to define isalpha(), isalnum(), isspace() */
27 #define SKIPSPACE(ch) while (isspace((int)*ch)) \
38 static kindOption RKinds
[KIND_COUNT
] = {
39 { TRUE
, 'f', "function", "functions" },
40 { TRUE
, 'l', "library", "libraries" },
41 { TRUE
, 's', "source", "sources" },
46 static void installRRegex (const langType language
)
48 /* This is a function, looks as follows:
49 * itent <- function(arg1, arg2) {
53 addTagRegex (language
,
54 "^[ \t]*([.a-zA-Z0-9_]+)([ \t]*)<-([ \t]*)function", "\\1", "f,function", NULL
);
55 /* This loads someting, e.g. a library, simply: library(libname) */
56 addTagRegex (language
,
57 "^[ \t]*(library|source|load|data)[\\(]([a-zA-Z0-9_]+)[\\)]", "\\2", "s,other", NULL
);
60 static void makeRTag(const vString
* const name
, rKind kind
)
63 initTagEntry(&e
, vStringValue(name
));
65 Assert(kind
< KIND_COUNT
);
67 e
.kindName
= RKinds
[kind
].name
;
68 e
.kind
= RKinds
[kind
].letter
;
73 static void createRTags(void)
75 vString
*vLine
= vStringNew();
76 vString
*name
= vStringNew();
78 const unsigned char *line
;
80 while ((line
= fileReadLine()) != NULL
)
82 const unsigned char *cp
= (const unsigned char*)line
;
85 while ((*cp
!= '\0') && (*cp
!= '#')) {
86 /* iterate to the end of line or to a comment */
91 if (strncasecmp((const char*)cp
, "library", (size_t)7) == 0) {
92 /* load a library: library(tools) */
99 } else if (strncasecmp((const char*)cp
, "source", (size_t)6) == 0) {
100 /* load a source file: source("myfile.r") */
112 while ((!isspace((int)*cp
)) && *cp
!= '\0' && *cp
!= ')') {
113 vStringPut(name
, (int)*cp
);
116 vStringTerminate(name
);
118 /* if the string really exists, make a tag of it */
119 if (vStringLength(name
) > 0)
120 makeRTag(name
, ikind
);
122 /* prepare for the next iteration */
125 vStringPut(name
, (int)*cp
);
132 /* assignment: ident <- someval */
137 /* not in this line, read next */
138 /* sometimes functions are declared this way:
144 I don't know if there is a reason to write the function keyword
147 if ((line
= fileReadLine()) != NULL
) {
148 cp
= (const unsigned char*)line
;
153 if (strncasecmp((const char*)cp
, "function", (size_t)8) == 0) {
154 /* it's a function: ident <- function(args) */
156 vStringTerminate(name
);
157 /* if the string really exists, make a tag of it */
158 if (vStringLength(name
) > 0)
159 makeRTag(name
, K_FUNCTION
);
161 /* prepare for the next iteration */
168 /* skip whitespace */
172 /* collect all characters that could be a part of an identifier */
173 vStringPut(name
, (int)*cp
);
181 vStringDelete(vLine
);
185 extern parserDefinition
* RParser (void)
190 static const char *const extensions
[] = { "r", "s", "q", NULL
};
191 parserDefinition
* const def
= parserNew ("R");
194 def
->kindCount
= KIND_COUNT (RKinds
);
196 def
->extensions
= extensions
;
198 def
->parser
= createRTags
;
200 def
->initialize
= installRRegex
;
206 /* vi:set tabstop=8 shiftwidth=4: */