geany  1.38
About: Geany is a text editor (using GTK2) with basic features of an integrated development environment (syntax highlighting, code folding, symbol name auto-completion, ...). F: office T: editor programming GTK+ IDE
  Fossies Dox: geany-1.38.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

geany_go.c
Go to the documentation of this file.
1/*
2* This source code is released for free distribution under the terms of the
3* GNU General Public License version 2 or (at your option) any later version.
4*
5* INCLUDE FILES
6*/
7#include "general.h" /* must always come first */
8
9#include "debug.h"
10#include "entry.h"
11#include "keyword.h"
12#include "read.h"
13#include "parse.h"
14#include "routines.h"
15#include "vstring.h"
16#include "options.h"
17#include "xtag.h"
18
19/*
20 * MACROS
21 */
22#define MAX_SIGNATURE_LENGTH 512
23#define isType(token,t) (bool) ((token)->type == (t))
24#define isKeyword(token,k) (bool) ((token)->keyword == (k))
25
26/*
27 * DATA DECLARATIONS
28 */
29
41};
42typedef int keywordId; /* to allow KEYWORD_NONE */
43
44typedef enum eTokenType {
46 // Token not important for top-level Go parsing
64
65typedef struct sTokenInfo {
68 vString *string; /* the name of the token */
69 unsigned long lineNumber; /* line number of tag */
70 MIOPos filePosition; /* file position of line containing name */
72
73/*
74* DATA DEFINITIONS
75*/
76
77static int Lang_go;
78static vString *scope;
80
81typedef enum {
92
94 {true, 'p', "package", "packages"},
95 {true, 'f', "func", "functions"},
96 {true, 'c', "const", "constants"},
97 {true, 't', "type", "types"},
98 {true, 'v', "var", "variables"},
99 {true, 's', "struct", "structs"},
100 {true, 'i', "interface", "interfaces"},
101 {true, 'm', "member", "struct members"}
102};
103
104static const keywordTable GoKeywordTable[] = {
105 {"package", KEYWORD_package},
106 {"import", KEYWORD_import},
107 {"const", KEYWORD_const},
108 {"type", KEYWORD_type},
109 {"var", KEYWORD_var},
110 {"func", KEYWORD_func},
111 {"struct", KEYWORD_struct},
112 {"interface", KEYWORD_interface},
113 {"map", KEYWORD_map},
114 {"chan", KEYWORD_chan}
115};
116
117/*
118* FUNCTION DEFINITIONS
119*/
120
121// XXX UTF-8
122static bool isStartIdentChar (const int c)
123{
124 return (bool)
125 (isalpha (c) || c == '_' || c > 128);
126}
127
128static bool isIdentChar (const int c)
129{
130 return (bool)
131 (isStartIdentChar (c) || isdigit (c));
132}
133
134static void initialize (const langType language)
135{
136 Lang_go = language;
137}
138
139static tokenInfo *newToken (void)
140{
141 tokenInfo *const token = xMalloc (1, tokenInfo);
142 token->type = TOKEN_NONE;
143 token->keyword = KEYWORD_NONE;
144 token->string = vStringNew ();
145 token->lineNumber = getInputLineNumber ();
147 return token;
148}
149
151{
152 tokenInfo *const token = xMalloc (1, tokenInfo);
153 token->type = other->type;
154 token->keyword = other->keyword;
155 token->string = vStringNewCopy (other->string);
156 token->lineNumber = other->lineNumber;
157 token->filePosition = other->filePosition;
158 return token;
159}
160
161static void deleteToken (tokenInfo * const token)
162{
163 if (token != NULL)
164 {
165 vStringDelete (token->string);
166 eFree (token);
167 }
168}
169
170/*
171 * Parsing functions
172 */
173
174static void parseString (vString *const string, const int delimiter)
175{
176 bool end = false;
177 while (!end)
178 {
179 int c = getcFromInputFile ();
180 if (c == EOF)
181 end = true;
182 else if (c == '\\' && delimiter != '`')
183 {
184 c = getcFromInputFile ();
185 if (c != '\'' && c != '\"')
186 vStringPut (string, '\\');
187 vStringPut (string, c);
188 }
189 else if (c == delimiter)
190 end = true;
191 else
192 vStringPut (string, c);
193 }
194}
195
196static void parseIdentifier (vString *const string, const int firstChar)
197{
198 int c = firstChar;
199 do
200 {
201 vStringPut (string, c);
202 c = getcFromInputFile ();
203 } while (isIdentChar (c));
204 ungetcToInputFile (c); /* always unget, LF might add a semicolon */
205}
206
207static void readToken (tokenInfo *const token)
208{
209 int c;
210 static tokenType lastTokenType = TOKEN_NONE;
211 bool firstWhitespace = true;
212 bool whitespace;
213
214 token->type = TOKEN_NONE;
215 token->keyword = KEYWORD_NONE;
216 vStringClear (token->string);
217
218getNextChar:
219 do
220 {
221 c = getcFromInputFile ();
222 token->lineNumber = getInputLineNumber ();
224 if (c == '\n' && (lastTokenType == TOKEN_IDENTIFIER ||
225 lastTokenType == TOKEN_STRING ||
226 lastTokenType == TOKEN_OTHER ||
227 lastTokenType == TOKEN_CLOSE_PAREN ||
228 lastTokenType == TOKEN_CLOSE_CURLY ||
229 lastTokenType == TOKEN_CLOSE_SQUARE))
230 {
231 c = ';'; // semicolon injection
232 }
233 whitespace = c == '\t' || c == ' ' || c == '\r' || c == '\n';
234 if (signature && whitespace && firstWhitespace && vStringLength (signature) < MAX_SIGNATURE_LENGTH)
235 {
236 firstWhitespace = false;
237 vStringPut(signature, ' ');
238 }
239 }
240 while (whitespace);
241
242 switch (c)
243 {
244 case EOF:
245 token->type = TOKEN_EOF;
246 break;
247
248 case ';':
249 token->type = TOKEN_SEMICOLON;
250 break;
251
252 case '/':
253 {
254 bool hasNewline = false;
255 int d = getcFromInputFile ();
256 switch (d)
257 {
258 case '/':
260 /* Line comments start with the
261 * character sequence // and
262 * continue through the next
263 * newline. A line comment acts
264 * like a newline. */
265 ungetcToInputFile ('\n');
266 goto getNextChar;
267 case '*':
268 do
269 {
270 do
271 {
272 d = getcFromInputFile ();
273 if (d == '\n')
274 {
275 hasNewline = true;
276 }
277 } while (d != EOF && d != '*');
278
279 c = getcFromInputFile ();
280 if (c == '/')
281 break;
282 else
284 } while (c != EOF && c != '\0');
285
286 ungetcToInputFile (hasNewline ? '\n' : ' ');
287 goto getNextChar;
288 default:
289 token->type = TOKEN_OTHER;
291 break;
292 }
293 }
294 break;
295
296 case '"':
297 case '\'':
298 case '`':
299 token->type = TOKEN_STRING;
300 parseString (token->string, c);
301 token->lineNumber = getInputLineNumber ();
303 break;
304
305 case '<':
306 {
307 int d = getcFromInputFile ();
308 if (d == '-')
309 token->type = TOKEN_LEFT_ARROW;
310 else
311 {
313 token->type = TOKEN_OTHER;
314 }
315 }
316 break;
317
318 case '(':
319 token->type = TOKEN_OPEN_PAREN;
320 break;
321
322 case ')':
323 token->type = TOKEN_CLOSE_PAREN;
324 break;
325
326 case '{':
327 token->type = TOKEN_OPEN_CURLY;
328 break;
329
330 case '}':
331 token->type = TOKEN_CLOSE_CURLY;
332 break;
333
334 case '[':
335 token->type = TOKEN_OPEN_SQUARE;
336 break;
337
338 case ']':
339 token->type = TOKEN_CLOSE_SQUARE;
340 break;
341
342 case '*':
343 token->type = TOKEN_STAR;
344 break;
345
346 case '.':
347 token->type = TOKEN_DOT;
348 break;
349
350 case ',':
351 token->type = TOKEN_COMMA;
352 break;
353
354 default:
355 if (isStartIdentChar (c))
356 {
357 parseIdentifier (token->string, c);
358 token->lineNumber = getInputLineNumber ();
360 token->keyword = lookupKeyword (vStringValue (token->string), Lang_go);
361 if (isKeyword (token, KEYWORD_NONE))
362 token->type = TOKEN_IDENTIFIER;
363 else
364 token->type = TOKEN_KEYWORD;
365 }
366 else
367 token->type = TOKEN_OTHER;
368 break;
369 }
370
372 {
373 if (token->type == TOKEN_LEFT_ARROW)
374 vStringCatS(signature, "<-");
375 else if (token->type == TOKEN_STRING)
376 {
377 // only struct member annotations can appear in function prototypes
378 // so only `` type strings are possible
379 vStringPut(signature, '`');
380 vStringCat(signature, token->string);
381 vStringPut(signature, '`');
382 }
383 else if (token->type == TOKEN_IDENTIFIER || token->type == TOKEN_KEYWORD)
384 vStringCat(signature, token->string);
385 else if (c != EOF)
387 }
388
389 lastTokenType = token->type;
390}
391
392static bool skipToMatchedNoRead (tokenInfo *const token)
393{
394 int nest_level = 0;
395 tokenType open_token = token->type;
396 tokenType close_token;
397
398 switch (open_token)
399 {
400 case TOKEN_OPEN_PAREN:
401 close_token = TOKEN_CLOSE_PAREN;
402 break;
403 case TOKEN_OPEN_CURLY:
404 close_token = TOKEN_CLOSE_CURLY;
405 break;
407 close_token = TOKEN_CLOSE_SQUARE;
408 break;
409 default:
410 return false;
411 }
412
413 /*
414 * This routine will skip to a matching closing token.
415 * It will also handle nested tokens.
416 */
417 nest_level++;
418 while (nest_level > 0 && !isType (token, TOKEN_EOF))
419 {
420 readToken (token);
421 if (isType (token, open_token))
422 nest_level++;
423 else if (isType (token, close_token))
424 nest_level--;
425 }
426
427 return true;
428}
429
430static void skipToMatched (tokenInfo *const token)
431{
432 if (skipToMatchedNoRead (token))
433 readToken (token);
434}
435
436static bool skipType (tokenInfo *const token)
437{
438 // Type = TypeName | TypeLit | "(" Type ")" .
439 // Skips also function multiple return values "(" Type {"," Type} ")"
440 if (isType (token, TOKEN_OPEN_PAREN))
441 {
442 skipToMatched (token);
443 return true;
444 }
445
446 // TypeName = QualifiedIdent.
447 // QualifiedIdent = [ PackageName "." ] identifier .
448 // PackageName = identifier .
449 if (isType (token, TOKEN_IDENTIFIER))
450 {
451 readToken (token);
452 if (isType (token, TOKEN_DOT))
453 {
454 readToken (token);
455 if (isType (token, TOKEN_IDENTIFIER))
456 readToken (token);
457 }
458 return true;
459 }
460
461 // StructType = "struct" "{" { FieldDecl ";" } "}"
462 // InterfaceType = "interface" "{" { MethodSpec ";" } "}" .
463 if (isKeyword (token, KEYWORD_struct) || isKeyword (token, KEYWORD_interface))
464 {
465 readToken (token);
466 // skip over "{}"
467 skipToMatched (token);
468 return true;
469 }
470
471 // ArrayType = "[" ArrayLength "]" ElementType .
472 // SliceType = "[" "]" ElementType .
473 // ElementType = Type .
474 if (isType (token, TOKEN_OPEN_SQUARE))
475 {
476 skipToMatched (token);
477 return skipType (token);
478 }
479
480 // PointerType = "*" BaseType .
481 // BaseType = Type .
482 // ChannelType = ( "chan" [ "<-" ] | "<-" "chan" ) ElementType .
483 if (isType (token, TOKEN_STAR) || isKeyword (token, KEYWORD_chan) || isType (token, TOKEN_LEFT_ARROW))
484 {
485 readToken (token);
486 return skipType (token);
487 }
488
489 // MapType = "map" "[" KeyType "]" ElementType .
490 // KeyType = Type .
491 if (isKeyword (token, KEYWORD_map))
492 {
493 readToken (token);
494 // skip over "[]"
495 skipToMatched (token);
496 return skipType (token);
497 }
498
499 // FunctionType = "func" Signature .
500 // Signature = Parameters [ Result ] .
501 // Result = Parameters | Type .
502 // Parameters = "(" [ ParameterList [ "," ] ] ")" .
503 if (isKeyword (token, KEYWORD_func))
504 {
505 readToken (token);
506 // Parameters, skip over "()"
507 skipToMatched (token);
508 // Result is parameters or type or nothing. skipType treats anything
509 // surrounded by parentheses as a type, and does nothing if what
510 // follows is not a type.
511 return skipType (token);
512 }
513
514 return false;
515}
516
517static void makeTag (tokenInfo *const token, const goKind kind,
518 tokenInfo *const parent_token, const goKind parent_kind,
519 const char *argList, const char *varType)
520{
521 const char *const name = vStringValue (token->string);
522
523 tagEntryInfo e;
524 initTagEntry (&e, name, kind);
525
526 if (!GoKinds [kind].enabled)
527 return;
528
529 e.lineNumber = token->lineNumber;
530 e.filePosition = token->filePosition;
531 if (argList)
532 e.extensionFields.signature = argList;
533 if (varType)
534 e.extensionFields.typeRef[1] = varType;
535
536 if (parent_kind != GOTAG_UNDEFINED && parent_token != NULL)
537 {
538 e.extensionFields.scopeKindIndex = parent_kind;
539 e.extensionFields.scopeName = vStringValue (parent_token->string);
540 }
541 makeTagEntry (&e);
542
544 {
545 vString *qualifiedName = vStringNew ();
546 vStringCopy (qualifiedName, scope);
547 vStringCatS (qualifiedName, ".");
548 vStringCat (qualifiedName, token->string);
549 e.name = vStringValue (qualifiedName);
550 makeTagEntry (&e);
551 vStringDelete (qualifiedName);
552 }
553}
554
555static void parsePackage (tokenInfo *const token)
556{
557 readToken (token);
558 if (isType (token, TOKEN_IDENTIFIER))
559 {
562 {
563 scope = vStringNew ();
564 vStringCopy (scope, token->string);
565 }
566 }
567}
568
569static void parseFunctionOrMethod (tokenInfo *const token)
570{
571 // FunctionDecl = "func" identifier Signature [ Body ] .
572 // Body = Block.
573 //
574 // MethodDecl = "func" Receiver MethodName Signature [ Body ] .
575 // Receiver = "(" [ identifier ] [ "*" ] BaseTypeName ")" .
576 // BaseTypeName = identifier .
577
578 // Skip over receiver.
579 readToken (token);
580 if (isType (token, TOKEN_OPEN_PAREN))
581 skipToMatched (token);
582
583 if (isType (token, TOKEN_IDENTIFIER))
584 {
585 vString *argList;
586 tokenInfo *functionToken = copyToken (token);
587
588 // Start recording signature
590
591 // Skip over parameters.
592 readToken (token);
593 skipToMatchedNoRead (token);
594
597 argList = signature;
599
600 readToken (token);
601
602 // Skip over result.
603 skipType (token);
604
605 // Remove the extra { we have just read
608
611 makeTag (functionToken, GOTAG_FUNCTION, NULL, GOTAG_UNDEFINED, argList->buffer, signature->buffer);
612 deleteToken (functionToken);
614 vStringDelete(argList);
615
616 // Stop recording signature
617 signature = NULL;
618
619 // Skip over function body.
620 if (isType (token, TOKEN_OPEN_CURLY))
621 skipToMatched (token);
622 }
623}
624
625static void parseStructMembers (tokenInfo *const token, tokenInfo *const parent_token)
626{
627 // StructType = "struct" "{" { FieldDecl ";" } "}" .
628 // FieldDecl = (IdentifierList Type | AnonymousField) [ Tag ] .
629 // AnonymousField = [ "*" ] TypeName .
630 // Tag = string_lit .
631
632 readToken (token);
633 if (!isType (token, TOKEN_OPEN_CURLY))
634 return;
635
636 readToken (token);
637 while (!isType (token, TOKEN_EOF) && !isType (token, TOKEN_CLOSE_CURLY))
638 {
639 tokenInfo *memberCandidate = NULL;
640 bool first = true;
641
642 while (!isType (token, TOKEN_EOF))
643 {
644 if (isType (token, TOKEN_IDENTIFIER))
645 {
646 if (first)
647 {
648 // could be anonymous field like in 'struct {int}' - we don't know yet
649 memberCandidate = copyToken (token);
650 first = false;
651 }
652 else
653 {
654 if (memberCandidate)
655 {
656 // if we are here, there was a comma and memberCandidate isn't an anonymous field
657 makeTag (memberCandidate, GOTAG_MEMBER, parent_token, GOTAG_STRUCT, NULL, NULL);
658 deleteToken (memberCandidate);
659 memberCandidate = NULL;
660 }
661 makeTag (token, GOTAG_MEMBER, parent_token, GOTAG_STRUCT, NULL, NULL);
662 }
663 readToken (token);
664 }
665 if (!isType (token, TOKEN_COMMA))
666 break;
667 readToken (token);
668 }
669
670 // in the case of an anonymous field, we already read part of the
671 // type into memberCandidate and skipType() should return false so no tag should
672 // be generated in this case.
673 if (skipType (token) && memberCandidate)
674 makeTag (memberCandidate, GOTAG_MEMBER, parent_token, GOTAG_STRUCT, NULL, NULL);
675
676 if (memberCandidate)
677 deleteToken (memberCandidate);
678
679 while (!isType (token, TOKEN_SEMICOLON) && !isType (token, TOKEN_CLOSE_CURLY)
680 && !isType (token, TOKEN_EOF))
681 {
682 readToken (token);
683 skipToMatched (token);
684 }
685
686 if (!isType (token, TOKEN_CLOSE_CURLY))
687 {
688 // we are at TOKEN_SEMICOLON
689 readToken (token);
690 }
691 }
692}
693
694static void parseConstTypeVar (tokenInfo *const token, goKind kind)
695{
696 // ConstDecl = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
697 // ConstSpec = IdentifierList [ [ Type ] "=" ExpressionList ] .
698 // IdentifierList = identifier { "," identifier } .
699 // ExpressionList = Expression { "," Expression } .
700 // TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
701 // TypeSpec = identifier Type .
702 // VarDecl = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
703 // VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
704 bool usesParens = false;
705
706 readToken (token);
707
708 if (isType (token, TOKEN_OPEN_PAREN))
709 {
710 usesParens = true;
711 readToken (token);
712 }
713
714 do
715 {
716 tokenInfo *typeToken = NULL;
717
718 while (!isType (token, TOKEN_EOF))
719 {
720 if (isType (token, TOKEN_IDENTIFIER))
721 {
722 if (kind == GOTAG_TYPE)
723 {
724 typeToken = copyToken (token);
725 readToken (token);
726 if (isKeyword (token, KEYWORD_struct))
728 else if (isKeyword (token, KEYWORD_interface))
730 else
731 makeTag (typeToken, kind, NULL, GOTAG_UNDEFINED, NULL, NULL);
732 break;
733 }
734 else
735 makeTag (token, kind, NULL, GOTAG_UNDEFINED, NULL, NULL);
736 readToken (token);
737 }
738 if (!isType (token, TOKEN_COMMA))
739 break;
740 readToken (token);
741 }
742
743 if (typeToken)
744 {
745 if (isKeyword (token, KEYWORD_struct))
746 parseStructMembers (token, typeToken);
747 else
748 skipType (token);
749 deleteToken (typeToken);
750 }
751 else
752 skipType (token);
753
754 while (!isType (token, TOKEN_SEMICOLON) && !isType (token, TOKEN_CLOSE_PAREN)
755 && !isType (token, TOKEN_EOF))
756 {
757 readToken (token);
758 skipToMatched (token);
759 }
760
761 if (usesParens && !isType (token, TOKEN_CLOSE_PAREN))
762 {
763 // we are at TOKEN_SEMICOLON
764 readToken (token);
765 }
766 }
767 while (!isType (token, TOKEN_EOF) &&
768 usesParens && !isType (token, TOKEN_CLOSE_PAREN));
769}
770
771static void parseGoFile (tokenInfo *const token)
772{
773 do
774 {
775 readToken (token);
776
777 if (isType (token, TOKEN_KEYWORD))
778 {
779 switch (token->keyword)
780 {
781 case KEYWORD_package:
782 parsePackage (token);
783 break;
784 case KEYWORD_func:
785 parseFunctionOrMethod (token);
786 break;
787 case KEYWORD_const:
789 break;
790 case KEYWORD_type:
792 break;
793 case KEYWORD_var:
795 break;
796 default:
797 break;
798 }
799 }
800 else if (isType (token, TOKEN_OPEN_PAREN) || isType (token, TOKEN_OPEN_CURLY) ||
801 isType (token, TOKEN_OPEN_SQUARE))
802 {
803 skipToMatched (token);
804 }
805 } while (token->type != TOKEN_EOF);
806}
807
808static void findGoTags (void)
809{
810 tokenInfo *const token = newToken ();
811
812 parseGoFile (token);
813
814 deleteToken (token);
816 scope = NULL;
817}
818
820{
821 static const char *const extensions[] = { "go", NULL };
822 parserDefinition *def = parserNew ("Go");
823 def->kindTable = GoKinds;
825 def->extensions = extensions;
826 def->parser = findGoTags;
827 def->initialize = initialize;
830 return def;
831}
const gchar * name
Definition: document.c:3219
int makeTagEntry(const tagEntryInfo *const tag)
Definition: entry.c:1675
void initTagEntry(tagEntryInfo *const e, const char *const name, int kindIndex)
Definition: entry.c:1823
eTokenType
Definition: geany_bibtex.c:63
eKeywordId
Definition: geany_bibtex.c:44
tokenType
Definition: geany_css.c:42
static void parsePackage(tokenInfo *const token)
Definition: geany_go.c:555
struct sTokenInfo tokenInfo
#define MAX_SIGNATURE_LENGTH
Definition: geany_go.c:22
static tokenInfo * newToken(void)
Definition: geany_go.c:139
static void parseConstTypeVar(tokenInfo *const token, goKind kind)
Definition: geany_go.c:694
static bool isStartIdentChar(const int c)
Definition: geany_go.c:122
static vString * signature
Definition: geany_go.c:79
static void parseStructMembers(tokenInfo *const token, tokenInfo *const parent_token)
Definition: geany_go.c:625
@ TOKEN_CLOSE_CURLY
Definition: geany_go.c:54
@ TOKEN_STAR
Definition: geany_go.c:58
@ TOKEN_KEYWORD
Definition: geany_go.c:48
@ TOKEN_OPEN_CURLY
Definition: geany_go.c:53
@ TOKEN_CLOSE_SQUARE
Definition: geany_go.c:56
@ TOKEN_LEFT_ARROW
Definition: geany_go.c:59
@ TOKEN_OPEN_SQUARE
Definition: geany_go.c:55
@ TOKEN_CLOSE_PAREN
Definition: geany_go.c:52
@ TOKEN_IDENTIFIER
Definition: geany_go.c:49
@ TOKEN_COMMA
Definition: geany_go.c:61
@ TOKEN_EOF
Definition: geany_go.c:62
@ TOKEN_OTHER
Definition: geany_go.c:47
@ TOKEN_DOT
Definition: geany_go.c:60
@ TOKEN_OPEN_PAREN
Definition: geany_go.c:51
@ TOKEN_SEMICOLON
Definition: geany_go.c:57
@ TOKEN_NONE
Definition: geany_go.c:45
@ TOKEN_STRING
Definition: geany_go.c:50
static bool skipType(tokenInfo *const token)
Definition: geany_go.c:436
static void deleteToken(tokenInfo *const token)
Definition: geany_go.c:161
goKind
Definition: geany_go.c:81
@ GOTAG_STRUCT
Definition: geany_go.c:88
@ GOTAG_TYPE
Definition: geany_go.c:86
@ GOTAG_VAR
Definition: geany_go.c:87
@ GOTAG_UNDEFINED
Definition: geany_go.c:82
@ GOTAG_MEMBER
Definition: geany_go.c:90
@ GOTAG_FUNCTION
Definition: geany_go.c:84
@ GOTAG_CONST
Definition: geany_go.c:85
@ GOTAG_PACKAGE
Definition: geany_go.c:83
@ GOTAG_INTERFACE
Definition: geany_go.c:89
enum eTokenType tokenType
static bool skipToMatchedNoRead(tokenInfo *const token)
Definition: geany_go.c:392
static kindDefinition GoKinds[]
Definition: geany_go.c:93
static int Lang_go
Definition: geany_go.c:77
static void initialize(const langType language)
Definition: geany_go.c:134
static void parseString(vString *const string, const int delimiter)
Definition: geany_go.c:174
static const keywordTable GoKeywordTable[]
Definition: geany_go.c:104
static void findGoTags(void)
Definition: geany_go.c:808
static vString * scope
Definition: geany_go.c:78
static void parseIdentifier(vString *const string, const int firstChar)
Definition: geany_go.c:196
@ KEYWORD_func
Definition: geany_go.c:36
@ KEYWORD_var
Definition: geany_go.c:35
@ KEYWORD_interface
Definition: geany_go.c:38
@ KEYWORD_package
Definition: geany_go.c:31
@ KEYWORD_type
Definition: geany_go.c:34
@ KEYWORD_const
Definition: geany_go.c:33
@ KEYWORD_map
Definition: geany_go.c:39
@ KEYWORD_chan
Definition: geany_go.c:40
@ KEYWORD_import
Definition: geany_go.c:32
@ KEYWORD_struct
Definition: geany_go.c:37
#define isKeyword(token, k)
Definition: geany_go.c:24
static tokenInfo * copyToken(tokenInfo *other)
Definition: geany_go.c:150
static bool isIdentChar(const int c)
Definition: geany_go.c:128
parserDefinition * GoParser(void)
Definition: geany_go.c:819
static void parseFunctionOrMethod(tokenInfo *const token)
Definition: geany_go.c:569
static void skipToMatched(tokenInfo *const token)
Definition: geany_go.c:430
int keywordId
Definition: geany_go.c:42
#define isType(token, t)
Definition: geany_go.c:23
static void parseGoFile(tokenInfo *const token)
Definition: geany_go.c:771
static void makeTag(tokenInfo *const token, const goKind kind, tokenInfo *const parent_token, const goKind parent_kind, const char *argList, const char *varType)
Definition: geany_go.c:517
static void readToken(tokenInfo *const token)
Definition: geany_go.c:207
keywordId
Definition: geany_html.c:44
int lookupKeyword(const char *const string, langType language)
Definition: keyword.c:160
#define KEYWORD_NONE
Definition: keyword.h:21
parserDefinition * parserNew(const char *name)
Definition: parse.c:237
#define NULL
Definition: rbtree.h:150
unsigned long getInputLineNumber(void)
Definition: read.c:142
int getcFromInputFile(void)
Definition: read.c:923
MIOPos getInputFilePosition(void)
Definition: read.c:161
void ungetcToInputFile(int c)
Definition: read.c:813
int skipToCharacterInInputFile(int c)
Definition: read.c:972
void eFree(void *const ptr)
Definition: routines.c:252
#define xMalloc(n, Type)
Definition: routines.h:23
#define ARRAY_SIZE(X)
Definition: routines.h:27
MIOPos:
Definition: mio.h:101
parserInitialize initialize
Definition: parse.h:81
const char *const * extensions
Definition: parse.h:78
simpleParser parser
Definition: parse.h:83
const keywordTable * keywordTable
Definition: parse.h:93
kindDefinition * kindTable
Definition: parse.h:76
unsigned int kindCount
Definition: parse.h:77
unsigned int keywordCount
Definition: parse.h:94
struct sTagEntryInfo::@3 extensionFields
MIOPos filePosition
Definition: entry.h:60
const char * name
Definition: entry.h:63
unsigned long lineNumber
Definition: entry.h:56
const char * typeRef[2]
Definition: entry.h:88
int scopeKindIndex
Definition: entry.h:78
const char * signature
Definition: entry.h:85
const char * scopeName
Definition: entry.h:79
vString * string
Definition: tokeninfo.h:27
unsigned long lineNumber
Definition: tokeninfo.h:29
tokenKeyword keyword
Definition: tokeninfo.h:26
tokenType type
Definition: tokeninfo.h:25
MIOPos filePosition
Definition: tokeninfo.h:30
char * buffer
Definition: vstring.h:50
tokenType type
Definition: geany_css.c:50
vString * string
Definition: geany_css.c:51
MIOPos filePosition
Definition: geany_json.c:61
unsigned long lineNumber
Definition: geany_json.c:60
keywordId keyword
Definition: geany_php.c:217
int langType
Definition: types.h:13
void vStringStripTrailing(vString *const string)
Definition: vstring.c:186
vString * vStringNew(void)
Definition: vstring.c:70
vString * vStringNewCopy(const vString *const string)
Definition: vstring.c:83
void vStringDelete(vString *const string)
Definition: vstring.c:60
void vStringStripLeading(vString *const string)
Definition: vstring.c:171
void vStringCatS(vString *const string, const char *const s)
Definition: vstring.c:146
void vStringChop(vString *const string)
Definition: vstring.c:198
void vStringCat(vString *const string, const vString *const s)
Definition: vstring.c:139
void vStringCopy(vString *const string, const vString *const s)
Definition: vstring.c:207
#define vStringClear(string)
Definition: vstring.h:36
#define vStringLength(vs)
Definition: vstring.h:31
#define vStringValue(vs)
Definition: vstring.h:28
static void vStringPut(vString *const string, const int c)
Definition: vstring.h:101
bool isXtagEnabled(xtagType type)
Definition: xtag.c:235
@ XTAG_QUALIFIED_TAGS
Definition: xtag.h:31