[geany/geany] 589a34: Update to version p5.9.20211031.0 of ctags
Jiří Techet
git-noreply at xxxxx
Thu Nov 25 11:02:52 UTC 2021
Branch: refs/heads/master
Author: Jiří Techet <techet at gmail.com>
Committer: Enrico Tröger <enrico.troeger at uvena.de>
Date: Thu, 25 Nov 2021 11:02:52 UTC
Commit: 589a3429e6f083c67ccb4d2ce5eae967aebd2632
https://github.com/geany/geany/commit/589a3429e6f083c67ccb4d2ce5eae967aebd2632
Log Message:
-----------
Update to version p5.9.20211031.0 of ctags
This change was mostly made by the update-ctags.py script. Apart from
that, the ctags/Makefile.am file was updated to add newly added files
in ctags and also include headers from the new dsl directory
(inclusion of the dsl directory had to be performed in
src/tagmanager/Makefile.am file too).
Modified Paths:
--------------
ctags/Makefile.am
ctags/dsl/es.c
ctags/dsl/es.h
ctags/dsl/optscript.c
ctags/dsl/optscript.h
ctags/main/CommonPrelude.c
ctags/main/args.c
ctags/main/dependency.c
ctags/main/entry.c
ctags/main/entry.h
ctags/main/entry_p.h
ctags/main/error.c
ctags/main/field.c
ctags/main/field.h
ctags/main/field_p.h
ctags/main/flags.c
ctags/main/flags_p.h
ctags/main/fmt.c
ctags/main/htable.c
ctags/main/htable.h
ctags/main/kind_p.h
ctags/main/lregex-default.c
ctags/main/lregex-pcre2.c
ctags/main/lregex.c
ctags/main/lregex_p.h
ctags/main/main.c
ctags/main/mio.c
ctags/main/options.c
ctags/main/options.h
ctags/main/options_p.h
ctags/main/parse.c
ctags/main/parse.h
ctags/main/parse_p.h
ctags/main/parsers_p.h
ctags/main/promise.c
ctags/main/promise.h
ctags/main/ptag.c
ctags/main/ptag_p.h
ctags/main/ptrarray.c
ctags/main/ptrarray.h
ctags/main/read.c
ctags/main/read_p.h
ctags/main/repoinfo.h
ctags/main/routines.c
ctags/main/routines.h
ctags/main/routines_p.h
ctags/main/script.c
ctags/main/script_p.h
ctags/main/seccomp.c
ctags/main/selectors.c
ctags/main/selectors.h
ctags/main/strlist.c
ctags/main/strlist.h
ctags/main/subparser.h
ctags/main/tokeninfo.c
ctags/main/tokeninfo.h
ctags/main/trace.c
ctags/main/trace.h
ctags/main/vstring.c
ctags/main/vstring.h
ctags/main/writer-ctags.c
ctags/main/writer-json.c
ctags/main/writer.c
ctags/main/writer_p.h
ctags/main/xtag.c
ctags/main/xtag_p.h
src/tagmanager/Makefile.am
Modified: ctags/Makefile.am
10 lines changed, 10 insertions(+), 0 deletions(-)
===================================================================
@@ -1,6 +1,7 @@
AM_CPPFLAGS = \
-I$(srcdir)/main \
-I$(srcdir)/parsers \
+ -I$(srcdir)/dsl \
-DEXTERNAL_PARSER_LIST_FILE=\"$(top_srcdir)/src/tagmanager/tm_parsers.h\" \
-DG_LOG_DOMAIN=\"CTags\"
AM_CFLAGS = \
@@ -58,11 +59,17 @@ parsers = \
parsers/geany_vhdl.c
# skip cmd.c and mini-geany.c which define main()
+# also skip lregex-pcre2.c which we don't use
libctags_la_SOURCES = \
+ dsl/optscript.c \
+ dsl/optscript.h \
+ dsl/es.c \
+ dsl/es.h \
main/args.c \
main/args_p.h \
main/colprint.c \
main/colprint_p.h \
+ main/CommonPrelude.c \
main/ctags.h \
main/debug.c \
main/debug.h \
@@ -99,6 +106,7 @@ libctags_la_SOURCES = \
main/lregex.c \
main/lregex.h \
main/lregex_p.h \
+ main/lregex-default.c \
main/lxpath.c \
main/lxpath.h \
main/lxpath_p.h \
@@ -144,6 +152,8 @@ libctags_la_SOURCES = \
main/routines.c \
main/routines.h \
main/routines_p.h \
+ main/script.c \
+ main/script_p.h \
main/seccomp.c \
main/selectors.c \
main/selectors.h \
Modified: ctags/dsl/es.c
3332 lines changed, 3332 insertions(+), 0 deletions(-)
===================================================================
No diff available, check online
Modified: ctags/dsl/es.h
274 lines changed, 274 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,274 @@
+/*
+ Copyright (c) 2009 Masatake YAMATO
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE. */
+
+#ifndef __ES_LANG_C_STDC99_H__
+#define __ES_LANG_C_STDC99_H__
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdio.h>
+
+#include "mio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum _EsType {
+ ES_TYPE_NIL,
+ ES_TYPE_INTEGER,
+ ES_TYPE_REAL,
+ ES_TYPE_BOOLEAN,
+ ES_TYPE_SYMBOL,
+ ES_TYPE_STRING,
+ ES_TYPE_CONS,
+ ES_TYPE_REGEX,
+ /* ... */
+ ES_TYPE_ERROR,
+ /* ... */
+ ES_TYPE_BUILTIN_LAST = ES_TYPE_ERROR,
+ ES_TYPE_FOREIGNER_START,
+};
+typedef enum _EsType EsType;
+
+struct _EsObject;
+typedef struct _EsObject EsObject;
+
+const char* es_type_get_name (int t);
+
+EsType es_object_get_type (const EsObject* object);
+
+
+EsObject* es_object_ref (EsObject* object);
+void es_object_unref (EsObject* object);
+void es_object_unref_batch (EsObject* array[],
+ unsigned int count);
+EsObject* es_object_autounref (EsObject* object);
+
+int es_object_equal (const EsObject* self,
+ const EsObject* other);
+
+int es_atom (const EsObject* object);
+
+#define ES_ERROR_MEMORY es_error_intern("MEMORY-EXHAUSTED")
+#define ES_ERROR_REGEX es_error_intern("WRONG-REGEX-SYNTAX")
+
+/*
+ * Nil
+ */
+#define es_nil ((EsObject*)0)
+int es_null (const EsObject* object);
+
+/*
+ * Integer
+ */
+EsObject* es_integer_new (int value);
+int es_integer_p (const EsObject* object);
+int es_integer_get (const EsObject* object);
+
+
+/*
+ * Real
+ */
+EsObject* es_real_new (double value);
+int es_real_p (const EsObject* object);
+double es_real_get (const EsObject* object);
+
+
+/*
+ * Use Integer as Real
+ */
+int es_number_p (const EsObject* object);
+double es_number_get (const EsObject* object);
+
+
+/*
+ * Boolean
+ */
+#define es_true (es_boolean_new(1))
+#define es_false (es_boolean_new(0))
+EsObject* es_boolean_new (int value);
+int es_boolean_p (const EsObject* object);
+int es_boolean_get (const EsObject* object);
+
+/*
+ * String
+ */
+EsObject* es_string_new (const char* value);
+EsObject* es_string_newL (const char* value, size_t length);
+int es_string_p (const EsObject* object);
+const char* es_string_get (const EsObject* object);
+
+
+/*
+ * Symbol
+ */
+EsObject* es_symbol_intern (const char* name);
+int es_symbol_p (const EsObject* object);
+const char* es_symbol_get (const EsObject* object);
+
+void* es_symbol_set_data (const EsObject* object, void *data);
+void* es_symbol_get_data (const EsObject* object);
+
+/*
+ * Error
+ */
+
+EsObject* es_error_intern (const char* name);
+int es_error_p (const EsObject* object);
+const char* es_error_name (const EsObject* object);
+EsObject* es_error_set_object (EsObject* error, EsObject* object);
+EsObject* es_error_get_object (const EsObject* error);
+
+
+/*
+ * Cons
+ */
+EsObject* es_cons (EsObject* car, EsObject* cdr);
+int es_cons_p (const EsObject* object);
+int es_list_p (const EsObject* object);
+EsObject* es_car (const EsObject* object);
+EsObject* es_cdr (const EsObject* object);
+
+
+/*
+ * Regex
+ */
+EsObject* es_regex_compile (const char* pat,
+ int case_insensitive);
+int es_regex_p (const EsObject* object);
+EsObject* es_regex_exec (const EsObject* regex,
+ const EsObject* str);
+
+/*
+ * Foreign pointer
+ */
+EsType es_type_define_pointer (const char *name,
+ void (* freefn) (void *),
+ int (* equalfn) (const void*, const void*),
+ void (* printfn) (const void*, MIO *));
+
+/* If the type has sized fat area, the area is filled with zero. */
+EsObject* es_pointer_new (EsType type, void *ptr);
+void* es_pointer_get (const EsObject *object);
+void* es_pointer_take (EsObject *object);
+
+/*
+ * Fatptr: Foreign pointer with extra data
+ *
+ * init_fat () returns es_true if the initialization ends successfully.
+ * In failure case, init_fat () returns an error object.
+ */
+EsType es_type_define_fatptr (const char *name,
+ size_t fat_size,
+ EsObject *(* initfat_fn) (void *fat, void * ptr, void *extra),
+ void (* freefn) (void * ptr, void *fat),
+ int (* equalfn) (const void* ptr_a, const void* fat_a,
+ const void* ptr_b, const void* fat_b),
+ void (* printfn) (const void* ptr, const void *fat, MIO *));
+/* If initfat_fn is given in the type, the new fat area will is
+ * initialized with the method.
+ * If initfat_fn is not given, and extra is not NULL, the contents
+ * pointed by extra is copied to the fat area.
+ * If initfat_fn is not given, and extra is NULL, the fat area
+ * is filled with zero as es_pointer_new does. */
+EsObject* es_fatptr_new (EsType type, void *ptr, void *extra);
+/* Access to the fat area. Use es_pointer_get to access the pointer. */
+void* es_fatptr_get (const EsObject *object);
+
+/*
+ * Print
+ */
+void es_print (const EsObject* object,
+ MIO* out);
+char* es_print_to_string (EsObject* object);
+
+/*
+ * Read
+ */
+EsObject* es_read (MIO* in);
+EsObject* es_read_from_string(const char* in,
+ const char** saveptr);
+
+#define ES_READER_ERROR es_error_intern("READ-ERROR")
+#define ES_READER_EOF es_error_intern("EOF")
+
+/*
+ * Comment
+ */
+void es_comment (const char* comment,
+ MIO* out);
+char* es_comment_to_string (const char* comment);
+
+/*
+ * Autounref pool
+ */
+void es_autounref_pool_push(void);
+void es_autounref_pool_pop (void);
+
+
+
+/*
+ * List builders
+ */
+EsObject* es_list (EsObject* object,...);
+EsObject* es_append (EsObject* list,...);
+EsObject* es_reverse (EsObject* cons);
+
+#define ES_PROC_UNIMPLEMENTED es_error_intern("PROC-UNIMPLEMENTED")
+EsObject* es_realize (EsObject* fmt_object,...);
+EsObject* es_srealize (const char* fmt,...);
+
+/* The value returned from FN treated as if it is returned from
+ * a *_new function. es_map may call es_object_unref() for the value.
+ * The value returned from es_map should be treated as if it is
+ * returned from a *_new function. The caller must free the returned
+ * value.
+ */
+EsObject* es_map (EsObject * (*fn) (EsObject *, void *),
+ EsObject *list, void *user_data);
+
+/* Unlike es_map, the value returnd from FN is not accumulated.
+ * If FN returns a value other than #f, es_foreach stops the
+ * iteration immediately and returns the value.
+ */
+EsObject* es_foreach (EsObject * (*fn) (EsObject *, void *),
+ EsObject *list, void *user_data);
+
+/* The memory management of es_map is also applicable to es_fold. */
+EsObject* es_fold (EsObject * (*kons) (EsObject *, EsObject *, void *),
+ EsObject * knil, EsObject * list, void *user_data);
+
+/*
+ * Rich element accessors
+ */
+int es_match (EsObject* input, EsObject* fmt_object,...);
+int es_smatch (EsObject* input, const char* fmt,...);
+
+
+EsObject* es_pget (EsObject* plist, EsObject* key, EsObject* default_value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Not def: __ES_LANG_C_STDC_H__ */
Modified: ctags/dsl/optscript.c
4422 lines changed, 4422 insertions(+), 0 deletions(-)
===================================================================
No diff available, check online
Modified: ctags/dsl/optscript.h
88 lines changed, 88 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,88 @@
+/*
+* Copyright (c) 2020, Masatake YAMATO
+* Copyright (c) 2020, Red Hat, Inc.
+*
+* This source code is released for free distribution under the terms of the
+* GNU General Public License version 2 or (at your option) any later version.
+*/
+
+#ifndef OPTSCRIPT_H
+#define OPTSCRIPT_H
+
+#include "general.h"
+
+#include "es.h"
+#include "mio.h"
+#include "ptrarray.h"
+
+typedef struct sOptVM OptVM;
+typedef EsObject* (* OptOperatorFn) (OptVM *, EsObject *);
+
+struct OptHelpExtender {
+ void (* add) (ptrArray *, void *);
+ const char* (* get_help_str) (EsObject *, void *);
+};
+
+int opt_init (void);
+
+OptVM *opt_vm_new (MIO *in, MIO *out, MIO *err);
+void opt_vm_delete (OptVM *vm);
+
+EsObject *opt_vm_read (OptVM *vm, MIO *in);
+EsObject *opt_vm_eval (OptVM *vm, EsObject *obj);
+void opt_vm_report_error (OptVM *vm, EsObject *eobj, MIO *err);
+
+void *opt_vm_set_app_data (OptVM *vm, void *app_data);
+void *opt_vm_get_app_data (OptVM *vm);
+
+char *opt_vm_set_prompt (OptVM *vm, char *prompt);
+void opt_vm_print_prompt (OptVM *vm);
+
+int opt_vm_help (OptVM *vm, MIO *out,
+ struct OptHelpExtender *extop, void *data);
+
+void opt_vm_clear (OptVM *vm);
+void opt_vm_dstack_push (OptVM *vm, EsObject *dict);
+void opt_vm_dstack_pop (OptVM *vm);
+
+EsObject* opt_vm_ostack_top (OptVM *vm);
+EsObject* opt_vm_ostack_peek (OptVM *vm, int index_from_top);
+EsObject* opt_vm_ostack_pop (OptVM *vm);
+void opt_vm_ostack_push (OptVM *vm, EsObject *obj);
+unsigned int opt_vm_ostack_count (OptVM *vm);
+
+EsObject *opt_dict_new (unsigned int size);
+bool opt_dict_known_and_get_cstr (EsObject *dict, const char* name, EsObject **val);
+bool opt_dict_foreach (EsObject *dict, bool (* fn) (EsObject *, EsObject *, void*), void *data);
+void opt_dict_def (EsObject *dict, EsObject *sym, EsObject *val);
+bool opt_dict_undef (EsObject *dict, EsObject *sym);
+void opt_dict_clear (EsObject *dict);
+
+EsObject *opt_array_new (void);
+EsObject *opt_array_get (const EsObject *array, unsigned int index);
+void opt_array_put (EsObject *array, unsigned int index, EsObject *obj);
+void opt_array_add (EsObject *array, EsObject *elt);
+
+unsigned int opt_array_length(const EsObject *array);
+
+EsObject *opt_operator_new (OptOperatorFn op, const char *name, int arity, const char *help_str);
+
+EsObject *opt_string_new_from_cstr (const char *cstr);
+const char* opt_string_get_cstr (const EsObject *str);
+
+EsObject *opt_name_new_from_cstr (const char *cstr);
+const char* opt_name_get_cstr (const EsObject *name);
+
+extern EsObject *OPT_ERR_TYPECHECK;
+extern EsObject *OPT_ERR_QUIT;
+extern EsObject *OPT_ERR_RANGECHECK;
+extern EsObject *OPT_ERR_UNDERFLOW;
+
+extern int OPT_TYPE_ARRAY;
+extern int OPT_TYPE_DICT;
+extern int OPT_TYPE_OPERATOR;
+extern int OPT_TYPE_STRING;
+extern int OPT_TYPE_NAME;
+extern int OPT_TYPE_MARK;
+
+#endif
Modified: ctags/main/CommonPrelude.c
162 lines changed, 162 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,162 @@
+const char ctagsCommonPrelude []=
+"%\n"
+"% Copyright (c) 2021, Masatake YAMATO\n"
+"% Copyright (c) 2021, Red Hat, Inc.\n"
+"%\n"
+"% This source code is released for free distribution under the terms of the\n"
+"% GNU General Public License version 2 or (at your option) any later version.\n"
+"%\n"
+"\n"
+"%\n"
+"% The documentation table\n"
+"%\n"
+"\n"
+"% __PROCDOCS:dict<proc:name, doc:string>\n"
+"/__procdocs 30 dict def\n"
+"\n"
+"% name value __BDEF -\n"
+"/__bdef { bind def } bind def\n"
+"\n"
+"% doc:string key:name any:val __DOCDEF -\n"
+"/__bddef {\n"
+" 1 index exch __bdef\n"
+" exch __procdocs 3 1 roll put\n"
+"} __bdef\n"
+"\n"
+"\n"
+"%\n"
+"% procedures\n"
+"%\n"
+"(any n:int _NDUP any1 ... anyn)\n"
+"/_ndup { { dup } repeat } __bddef\n"
+"\n"
+"(x:any x:any _DEDUP x:any\n"
+" x:any y:any _DEDUP x:any y:any)\n"
+"/_dedup {\n"
+" count 1 gt {\n"
+" 2 copy eq {\n"
+" pop\n"
+" } if\n"
+" } if\n"
+"} __bddef\n"
+"\n"
+"(space:int space:int _DEDUP_SPACES space:int\n"
+" otherthanspace:int space:int _DEDUP_SPACES otherthanspace:int space:int)\n"
+"/_dedup_spaces {\n"
+" count 0 gt {\n"
+" dup ?\\_ eq {\n"
+" _dedup\n"
+" } if\n"
+" } if\n"
+"} __bddef\n"
+"\n"
+"% 32 32 _dedup_spaces pstack clear (---) ==\n"
+"% 32 41 _dedup_spaces pstack clear (---) ==\n"
+"% 41 32 _dedup_spaces pstack clear (---) ==\n"
+"% 32 _dedup_spaces pstack clear (---) ==\n"
+"% 41 _dedup_spaces pstack clear (---) ==\n"
+"% quit\n"
+"\n"
+"/__buildstring {\n"
+" {\n"
+" counttomark dup 1 eq {\n"
+" pop exch pop\n"
+" exit\n"
+" } {\n"
+" -1 roll 1 index exch _putlast!\n"
+" } ifelse\n"
+" } loop\n"
+"} __bdef\n"
+"\n"
+"(mark char:int|substring:string... _BUILDSTRING string)\n"
+"/_buildstring {\n"
+" 0 string __buildstring\n"
+"} __bddef\n"
+"\n"
+"(string char:int|string _PUTLAST! -)\n"
+"/_putlast! {\n"
+" 1 index length exch\n"
+" dup type /integertype eq {\n"
+" put\n"
+" } {\n"
+" putinterval\n"
+" } ifelse\n"
+"} __bddef\n"
+"\n"
+"(target:string fromto:str _TR! -)\n"
+"/_tr! {\n"
+" %\n"
+" % () is not allowed.\n"
+" % The reason must be be documented.\n"
+" %\n"
+" 0 string\n"
+" % str [int<from> int<to>] str'\n"
+" 2 index {\n"
+" % str [int<from> int<to>] str' int<chr>\n"
+" dup 3 index 0 get\n"
+" % str [int<from> int<to>] str' int<chr> int<chr> int<from>\n"
+" eq {% str [int<from> int<to>] str' int<chr>\n"
+" pop\n"
+" dup 2 index 1 get _putlast!\n"
+" } {% str [int<from> int<to>] str' int<chr>\n"
+" 1 index exch _putlast!\n"
+" } ifelse\n"
+" } forall\n"
+" % str [int<from> int<to>] str'\n"
+" exch pop\n"
+" 0 exch putinterval\n"
+"} __bddef\n"
+"\n"
+"(string _NORMALIZE_SPACES! -)\n"
+"/_normalize_spaces! {\n"
+" dup\n"
+" dup (\\n ) _tr!\n"
+" dup (\\t ) _tr!\n"
+" dup (\\r ) _tr!\n"
+" dup (\\f ) _tr!\n"
+" dup (\\v ) _tr!\n"
+" mark exch { _dedup_spaces } forall _buildstring\n"
+" exch copy pop\n"
+"} __bddef\n"
+"\n"
+"% /x mark 40 (a) 32 32 10 (b) 10 10 9 9 (xyz) 9 9 41 _buildstring def\n"
+"% x _normalize_spaces! x pstack\n"
+"\n"
+"(tag:int _SCOPEREF -)\n"
+"/_scoperef {\n"
+" _scopetop not { 0 } if scope:\n"
+"} __bddef\n"
+"\n"
+"(tag:int _SCOPEPUSH -)\n"
+"/_scopepush {\n"
+" dup _scoperef _scopeset\n"
+"} __bddef\n"
+"\n"
+"(string _ISSTRING string true\n"
+" any:!string _ISSTRING false)\n"
+"/_isstring {\n"
+" dup type /stringtype eq {\n"
+" true\n"
+" } {\n"
+" pop false\n"
+" } ifelse\n"
+"} __bddef\n"
+"\n"
+"(array key _AMEMBER true|fales)\n"
+"/_amember {\n"
+" false 3 1 roll\n"
+" % false array key\n"
+" exch {\n"
+" % false key elt\n"
+" 1 index\n"
+" % false key elt key\n"
+" eq {\n"
+" % false key\n"
+" exch pop true exch\n"
+" exit\n"
+" } if\n"
+" % false key\n"
+" } forall\n"
+" pop\n"
+"} __bddef\n"
+;
Modified: ctags/main/args.c
106 lines changed, 104 insertions(+), 2 deletions(-)
===================================================================
@@ -145,8 +145,8 @@ static char* nextFileLine (FILE* const fp)
c = ungetc (c, fp);
}
vStringStripTrailing (vs);
- result = xMalloc (vStringLength (vs) + 1, char);
vStringStripLeading (vs);
+ result = xMalloc (vStringLength (vs) + 1, char);
strcpy (result, vStringValue (vs));
}
vStringDelete (vs);
@@ -161,18 +161,120 @@ static bool isCommentLine (char* line)
return (*line == '#');
}
+static bool isOptscriptLine (char *line)
+{
+ size_t len = strlen (line);
+ if (len < 2)
+ return false;
+ if (line [len - 1] == '{' && line [len - 2] == '{')
+ return true;
+ return false;
+}
+
+static char* nextOptscriptLines (FILE* const fp, char *line)
+{
+ vString *vstr = vStringNewInit (line);
+ vStringPut (vstr, '\n');
+ eFree (line);
+
+ /* \n}}, \n=>1, }=>2, }=>3 */
+ int endMarkers = 0;
+ int c;
+ while (true)
+ {
+ c = fgetc (fp);
+ if (c == EOF)
+ break;
+
+ if (c == '\r' || c == '\n')
+ {
+ if (c == '\r')
+ {
+ c = fgetc (fp);
+ if (c != '\n')
+ {
+ ungetc(c, fp);
+ c = '\n';
+ }
+ }
+ if (c == '\n')
+ {
+ vStringPut (vstr, c);
+ if (endMarkers != 1)
+ endMarkers = 1;
+ }
+ }
+ else if (c == '}')
+ {
+ vStringPut (vstr, c);
+ if (endMarkers == 1 || endMarkers == 2)
+ endMarkers++;
+ if (endMarkers == 3)
+ break;
+ }
+ else
+ {
+ endMarkers = 0;
+ vStringPut (vstr, c);
+ }
+ }
+
+ if (c == EOF)
+ {
+ switch (endMarkers)
+ {
+ case 0:
+ vStringPut (vstr, '\n');
+ /* Fall through */
+ case 1:
+ vStringPut (vstr, '}');
+ /* Fall through */
+ case 2:
+ vStringPut (vstr, '}');
+ default:
+ break;
+ }
+ }
+
+ c = fgetc (fp);
+ while (c != EOF)
+ {
+ if (c == '\n')
+ break;
+ if (c == '\r')
+ {
+ c = fgetc (fp);
+ if (c == '\n')
+ break;
+ ungetc (c, fp);
+ }
+ c = fgetc (fp);
+ }
+ return vStringDeleteUnwrap (vstr);
+}
+
static char* nextFileLineSkippingComments (FILE* const fp)
{
char* result;
bool comment;
+ bool optscript;
do
{
result = nextFileLine (fp);
- comment = (result && isCommentLine (result));
+ comment = false;
+ optscript = false;
+ if (result)
+ {
+ comment = isCommentLine (result);
+ optscript = isOptscriptLine (result);
+ }
if (comment)
eFree (result);
+ else if (optscript)
+ result = nextOptscriptLines (fp, result);
} while (comment);
+
return result;
}
Modified: ctags/main/dependency.c
47 lines changed, 31 insertions(+), 16 deletions(-)
===================================================================
@@ -145,36 +145,38 @@ extern void notifyInputStart (void)
{
subparser *s;
- foreachSubparser(s, false)
- {
- langType lang = getSubparserLanguage (s);
- notifyLanguageRegexInputStart (lang);
+ /* for running prelude of optlib */
+ langType lang = getInputLanguage ();
+ notifyLanguageRegexInputStart (lang);
+ foreachSubparser(s, true)
+ {
+ enterSubparser(s);
if (s->inputStart)
- {
- enterSubparser(s);
s->inputStart (s);
- leaveSubparser();
- }
+ /* propagate the event recursively */
+ notifyInputStart ();
+ leaveSubparser();
}
}
extern void notifyInputEnd (void)
{
subparser *s;
- foreachSubparser(s, false)
+ foreachSubparser(s, true)
{
+ enterSubparser(s);
+ /* propagate the event recursively */
+ notifyInputEnd ();
if (s->inputEnd)
- {
- enterSubparser(s);
s->inputEnd (s);
- leaveSubparser();
- }
-
- langType lang = getSubparserLanguage (s);
- notifyLanguageRegexInputEnd (lang);
+ leaveSubparser();
}
+
+ /* for running sequel of optlib */
+ langType lang = getInputLanguage ();
+ notifyLanguageRegexInputEnd (lang);
}
extern void notifyMakeTagEntry (const tagEntryInfo *tag, int corkIndex)
@@ -292,6 +294,19 @@ extern slaveParser *getFirstSlaveParser (struct slaveControlBlock *scb)
return NULL;
}
+extern subparser *getLanguageSubparser (langType sublang,
+ bool including_none_crafted_parser)
+{
+ subparser *s;
+
+ foreachSubparser (s, including_none_crafted_parser)
+ {
+ if (getSubparserLanguage (s) == sublang)
+ return s;
+ }
+ return NULL;
+}
+
extern struct colprintTable * subparserColprintTableNew (void)
{
return colprintTableNew ("L:NAME", "L:BASEPARSER", "L:DIRECTIONS", NULL);
Modified: ctags/main/entry.c
48 lines changed, 37 insertions(+), 11 deletions(-)
===================================================================
@@ -203,6 +203,9 @@ extern void makeFileTag (const char *const fileName)
tag.extensionFields.endLine = getInputLineNumber ();
}
+ if (isFieldEnabled (FIELD_EPOCH))
+ tag.extensionFields.epoch = getInputFileMtime ();
+
makeTagEntry (&tag);
}
@@ -1066,8 +1069,6 @@ static tagEntryInfoX *copyTagEntry (const tagEntryInfo *const tag,
slot->name = eStrdup (slot->name);
if (slot->extensionFields.access)
slot->extensionFields.access = eStrdup (slot->extensionFields.access);
- if (slot->extensionFields.fileScope)
- slot->extensionFields.fileScope = eStrdup (slot->extensionFields.fileScope);
if (slot->extensionFields.implementation)
slot->extensionFields.implementation = eStrdup (slot->extensionFields.implementation);
if (slot->extensionFields.inheritance)
@@ -1144,8 +1145,6 @@ static void deleteTagEnry (void *data)
if (slot->extensionFields.access)
eFree ((char *)slot->extensionFields.access);
- if (slot->extensionFields.fileScope)
- eFree ((char *)slot->extensionFields.fileScope);
if (slot->extensionFields.implementation)
eFree ((char *)slot->extensionFields.implementation);
if (slot->extensionFields.inheritance)
@@ -1450,6 +1449,7 @@ static int queueTagEntry(const tagEntryInfo *const tag)
corkIndex = (int)ptrArrayAdd (TagFile.corkQueue, entry);
entry->corkIndex = corkIndex;
+ entry->slot.inCorkQueue = 1;
return corkIndex;
}
@@ -1652,12 +1652,17 @@ extern size_t countEntryInCorkQueue (void)
return ptrArrayCount (TagFile.corkQueue);
}
+extern void markTagPlaceholder (tagEntryInfo *e, bool placeholder)
+{
+ e->placeholder = placeholder;
+}
+
extern int makePlaceholder (const char *const name)
{
tagEntryInfo e;
initTagEntry (&e, name, KIND_GHOST_INDEX);
- e.placeholder = 1;
+ markTagPlaceholder(&e, true);
/*
* makePlaceholder may be called even before reading any bytes
@@ -1766,6 +1771,13 @@ extern int makeQualifiedTagEntry (const tagEntryInfo *const e)
return r;
}
+extern void setTagPositionFromTag (tagEntryInfo *const dst,
+ const tagEntryInfo *const src)
+{
+ dst->lineNumber = src->lineNumber;
+ dst->filePosition = src->filePosition;
+}
+
static void initTagEntryFull (tagEntryInfo *const e, const char *const name,
unsigned long lineNumber,
langType langType_,
@@ -1802,6 +1814,8 @@ static void initTagEntryFull (tagEntryInfo *const e, const char *const name,
if (roleBits)
markTagExtraBit (e, XTAG_REFERENCE_TAGS);
+ e->extensionFields.nth = NO_NTH_FIELD;
+
if (doesParserRunAsGuest ())
markTagExtraBit (e, XTAG_GUEST);
if (doesSubparserRun ())
@@ -1885,8 +1899,9 @@ static void markTagExtraBitFull (tagEntryInfo *const tag, xtagType extra,
int n = countXtags () - XTAG_COUNT;
tag->extraDynamic = xCalloc ((n / 8) + 1, uint8_t);
- PARSER_TRASH_BOX(tag->extraDynamic, eFree);
- markTagExtraBit (tag, extra);
+ if (!tag->inCorkQueue)
+ PARSER_TRASH_BOX(tag->extraDynamic, eFree);
+ markTagExtraBitFull (tag, extra, mark);
return;
}
@@ -1914,7 +1929,6 @@ extern bool isTagExtraBitMarked (const tagEntryInfo *const tag, xtagType extra)
index = (extra / 8);
offset = (extra % 8);
slot = tag->extra;
-
}
else if (!tag->extraDynamic)
return false;
@@ -1924,14 +1938,13 @@ extern bool isTagExtraBitMarked (const tagEntryInfo *const tag, xtagType extra)
index = ((extra - XTAG_COUNT) / 8);
offset = ((extra - XTAG_COUNT) % 8);
slot = tag->extraDynamic;
-
}
return !! ((slot [ index ]) & (1 << offset));
}
extern bool isTagExtra (const tagEntryInfo *const tag)
{
- for (unsigned int i = 0; i < XTAG_COUNT; i++)
+ for (unsigned int i = 0; i < countXtags(); i++)
if (isTagExtraBitMarked (tag, i))
return true;
return false;
@@ -2010,15 +2023,28 @@ extern void tagFilePosition (MIOPos *p)
"failed to get file position of the tag file\n");
}
-extern void setTagFilePosition (MIOPos *p)
+extern void setTagFilePosition (MIOPos *p, bool truncation)
{
/* mini-geany doesn't set TagFile.mio. */
if (TagFile.mio == NULL)
return;
+
+ long t0 = 0;
+ if (truncation)
+ t0 = mio_tell (TagFile.mio);
+
if (mio_setpos (TagFile.mio, p) == -1)
error (FATAL|PERROR,
"failed to set file position of the tag file\n");
+
+ if (truncation)
+ {
+ long t1 = mio_tell (TagFile.mio);
+ if (!mio_try_resize (TagFile.mio, (size_t)t1))
+ error (FATAL|PERROR,
+ "failed to truncate the tag file %ld -> %ld\n", t0, t1);
+ }
}
extern const char* getTagFileDirectory (void)
Modified: ctags/main/entry.h
17 lines changed, 13 insertions(+), 4 deletions(-)
===================================================================
@@ -16,13 +16,16 @@
#include "types.h"
#include <stdint.h>
+#include <time.h>
#include "field.h"
#include "xtag.h"
#include "mio.h"
#include "ptrarray.h"
#include "nestlevel.h"
+#include "script_p.h"
+
/*
* MACROS
*/
@@ -45,13 +48,14 @@ struct sTagEntryInfo {
unsigned int isFileScope :1; /* is tag visible only within input file? */
unsigned int isFileEntry :1; /* is this just an entry for a file name? */
unsigned int truncateLineAfterTag :1; /* truncate tag line at end of tag name? */
- unsigned int placeholder :1; /* This is just a part of scope context.
+ unsigned int placeholder :1; /* is used only for keeping corkIndex based scope chain.
Put this entry to cork queue but
don't print it to tags file. */
unsigned int skipAutoFQEmission:1; /* If a parser makes a fq tag for the
current tag by itself, set this. */
unsigned int isPseudoTag:1; /* Used only in xref output.
If a tag is a pseudo, set this. */
+ unsigned int inCorkQueue:1;
unsigned long lineNumber; /* line number of tag */
const char* pattern; /* pattern for locating input line
@@ -67,7 +71,6 @@ struct sTagEntryInfo {
struct {
const char* access;
- const char* fileScope;
const char* implementation;
const char* inheritance;
@@ -96,6 +99,9 @@ struct sTagEntryInfo {
const char* xpath;
#endif
unsigned long endLine;
+ time_t epoch;
+#define NO_NTH_FIELD -1
+ short nth;
} extensionFields; /* list of extension fields*/
/* `usedParserFields' tracks how many parser own fields are
@@ -141,6 +147,7 @@ extern bool isRoleAssigned(const tagEntryInfo *const e, int roleIndex);
extern int makeQualifiedTagEntry (const tagEntryInfo *const e);
+extern void setTagPositionFromTag (tagEntryInfo *const dst, const tagEntryInfo *const src);
#define CORK_NIL 0
tagEntryInfo *getEntryInCorkQueue (int n);
@@ -162,8 +169,9 @@ void registerEntry (int corkIndex);
* under the scope.
*
* If FUNC returns false, this function returns false.
- * If FUNC never returns false, this func returns true.
- * If FUNC is not called because no node for NAME in the symbol table.
+ * If FUNC never returns false, this function returns true.
+ * If FUNC is not called because no node for NAME in the symbol table,
+ * this function returns true.
*/
bool foreachEntriesInScope (int corkIndex,
const char *name, /* or NULL */
@@ -256,6 +264,7 @@ extern void attachParserFieldToCorkEntry (int index, fieldType ftype, const char
extern const char* getParserFieldValueForType (tagEntryInfo *const tag, fieldType ftype);
extern int makePlaceholder (const char *const name);
+extern void markTagPlaceholder (tagEntryInfo *e, bool placeholder);
/* Marking all tag entries entries under the scope specified
* with index recursively.
Modified: ctags/main/entry_p.h
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -39,7 +39,7 @@ extern unsigned long numTagsTotal(void);
extern unsigned long maxTagsLine(void);
extern void invalidatePatternCache(void);
extern void tagFilePosition (MIOPos *p);
-extern void setTagFilePosition (MIOPos *p);
+extern void setTagFilePosition (MIOPos *p, bool truncation);
extern const char* getTagFileDirectory (void);
extern void getTagScopeInformation (tagEntryInfo *const tag,
const char **kind, const char **name);
Modified: ctags/main/error.c
8 lines changed, 7 insertions(+), 1 deletions(-)
===================================================================
@@ -35,7 +35,8 @@ extern bool stderrDefaultErrorPrinter (const errorSelection selection,
va_list ap, void *data CTAGS_ATTR_UNUSED)
{
fprintf (stderr, "%s: %s", getExecutableName (),
- selected (selection, WARNING) ? "Warning: " : "");
+ selected (selection, WARNING) ? "Warning: " :
+ selected (selection, NOTICE) ? "Notice: " : "");
vfprintf (stderr, format, ap);
if (selected (selection, PERROR))
{
@@ -56,6 +57,9 @@ extern void error (const errorSelection selection,
va_list ap;
bool shouldExit;
+ if (Option.quiet && selected (selection, NOTICE))
+ return;
+
va_start (ap, format);
shouldExit = (* errorPrinter) (selection, format, ap, errorPrinterData);
va_end (ap);
@@ -77,6 +81,8 @@ bool jsonErrorPrinter (const errorSelection selection, const char *const format,
json_t *response = json_object ();
json_object_set_new (response, "_type", json_string ("error"));
json_object_set_new (response, "message", json_string (reason));
+ if (selected (selection, NOTICE))
+ json_object_set_new (response, "notice", json_true ());
if (selected (selection, WARNING))
json_object_set_new (response, "warning", json_true ());
if (selected (selection, FATAL))
Modified: ctags/main/field.c
1036 lines changed, 846 insertions(+), 190 deletions(-)
===================================================================
@@ -31,6 +31,8 @@
#include "writer_p.h"
#include "xtag_p.h"
+#include "optscript.h"
+
#define FIELD_NULL_LETTER_CHAR '-'
#define FIELD_NULL_LETTER_STRING "-"
@@ -67,13 +69,14 @@ static const char *renderFieldExtras (const tagEntryInfo *const tag, const char
static const char *renderFieldXpath (const tagEntryInfo *const tag, const char *value, vString* b);
static const char *renderFieldScopeKindName(const tagEntryInfo *const tag, const char *value, vString* b);
static const char *renderFieldEnd (const tagEntryInfo *const tag, const char *value, vString* b);
+static const char *renderFieldEpoch (const tagEntryInfo *const tag, const char *value, vString* b);
+static const char *renderFieldNth (const tagEntryInfo *const tag, const char *value, vString* b);
static bool doesContainAnyCharInName (const tagEntryInfo *const tag, const char *value, const char *chars);
static bool doesContainAnyCharInInput (const tagEntryInfo *const tag, const char*value, const char *chars);
static bool doesContainAnyCharInFieldScope (const tagEntryInfo *const tag, const char *value, const char *chars);
static bool doesContainAnyCharInSignature (const tagEntryInfo *const tag, const char *value, const char *chars);
-static bool isLanguageFieldAvailable (const tagEntryInfo *const tag);
static bool isTyperefFieldAvailable (const tagEntryInfo *const tag);
static bool isFileFieldAvailable (const tagEntryInfo *const tag);
static bool isInheritsFieldAvailable (const tagEntryInfo *const tag);
@@ -83,150 +86,372 @@ static bool isSignatureFieldAvailable (const tagEntryInfo *const tag);
static bool isExtrasFieldAvailable (const tagEntryInfo *const tag);
static bool isXpathFieldAvailable (const tagEntryInfo *const tag);
static bool isEndFieldAvailable (const tagEntryInfo *const tag);
-
-
-#define DEFINE_FIELD(L, N, V, H, DT, RE) \
- DEFINE_FIELD_FULL (L, N, V, H, NULL, DT, RE, NULL, NULL)
-#define DEFINE_FIELD_FULL(L, N, V, H, A, DT, RE, RN, DCAC) \
- { \
- .letter = L, \
- .name = N, \
- .description = H, \
- .enabled = V, \
- .render = RE, \
- .renderNoEscaping= RN, \
- .doesContainAnyChar = DCAC, \
- .isValueAvailable = A, \
- .dataType = DT, \
- }
+static bool isEpochAvailable (const tagEntryInfo *const tag);
+static bool isNthAvailable (const tagEntryInfo *const tag);
+
+static EsObject* getFieldValueForName (const tagEntryInfo *, const fieldDefinition *);
+static EsObject* setFieldValueForName (tagEntryInfo *, const fieldDefinition *, const EsObject *);
+static EsObject* getFieldValueForInput (const tagEntryInfo *, const fieldDefinition *);
+static EsObject* getFieldValueForKind (const tagEntryInfo *, const fieldDefinition *);
+static EsObject* getFieldValueForTyperef (const tagEntryInfo *, const fieldDefinition *);
+static EsObject* setFieldValueForTyperef (tagEntryInfo *, const fieldDefinition *, const EsObject *);
+static EsObject* checkFieldValueForTyperef (const fieldDefinition *, const EsObject *);
+static EsObject* getFieldValueForScope (const tagEntryInfo *, const fieldDefinition *);
+static EsObject* setFieldValueForScope (tagEntryInfo *, const fieldDefinition *, const EsObject *);
+static EsObject* checkFieldValueForScope (const fieldDefinition *, const EsObject *);
+static EsObject* getFieldValueForExtras (const tagEntryInfo *, const fieldDefinition *);
+static EsObject* getFieldValueForSignature (const tagEntryInfo *, const fieldDefinition *);
+static EsObject* setFieldValueForSignature (tagEntryInfo *, const fieldDefinition *, const EsObject *);
+static EsObject* getFieldValueForRoles (const tagEntryInfo *, const fieldDefinition *);
+static EsObject* getFieldValueForLineCommon (const tagEntryInfo *, const fieldDefinition *);
+static EsObject* checkFieldValueForLineCommon (const fieldDefinition *, const EsObject *);
+static EsObject* setFieldValueForLineCommon (tagEntryInfo *, const fieldDefinition *, const EsObject *);
+static EsObject* setFieldValueForInherits (tagEntryInfo *, const fieldDefinition *, const EsObject *);
#define WITH_DEFUALT_VALUE(str) ((str)?(str):FIELD_NULL_LETTER_STRING)
static fieldDefinition fieldDefinitionsFixed [] = {
- /* FIXED FIELDS */
- DEFINE_FIELD_FULL ('N', "name", true,
- "tag name",
- NULL,
- FIELDTYPE_STRING,
- renderFieldName, renderFieldNameNoEscape,
- doesContainAnyCharInName),
- DEFINE_FIELD_FULL ('F', "input", true,
- "input file",
- NULL,
- FIELDTYPE_STRING,
- renderFieldInput, renderFieldInputNoEscape,
- doesContainAnyCharInInput),
- DEFINE_FIELD ('P', "pattern", true,
- "pattern",
- FIELDTYPE_STRING|FIELDTYPE_BOOL,
- renderFieldPattern),
+ [FIELD_NAME] = {
+ .letter = 'N',
+ .name = "name",
+ .description = "tag name",
+ .enabled = true,
+ .render = renderFieldName,
+ .renderNoEscaping = renderFieldNameNoEscape,
+ .doesContainAnyChar = doesContainAnyCharInName,
+ .isValueAvailable = NULL,
+ .dataType = FIELDTYPE_STRING,
+ .getterValueType = NULL,
+ .getValueObject = getFieldValueForName,
+ .setterValueType = NULL,
+ .checkValueForSetter= NULL,
+ .setValueObject = setFieldValueForName,
+ },
+ [FIELD_INPUT_FILE] = {
+ .letter = 'F',
+ .name = "input",
+ .description = "input file",
+ .enabled = true,
+ .render = renderFieldInput,
+ .renderNoEscaping = renderFieldInputNoEscape,
+ .doesContainAnyChar = doesContainAnyCharInInput,
+ .isValueAvailable = NULL,
+ .dataType = FIELDTYPE_STRING,
+ .getterValueType = NULL,
+ .getValueObject = getFieldValueForInput,
+ .setterValueType = NULL,
+ .checkValueForSetter= NULL,
+ .setValueObject = NULL,
+ },
+ [FIELD_PATTERN] = {
+ .letter = 'P',
+ .name = "pattern",
+ .description = "pattern",
+ .enabled = true,
+ .render = renderFieldPattern,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = NULL,
+ .dataType = FIELDTYPE_STRING|FIELDTYPE_BOOL,
+ },
};
static fieldDefinition fieldDefinitionsExuberant [] = {
- DEFINE_FIELD ('C', "compact", false,
- "compact input line (used only in xref output)",
- FIELDTYPE_STRING,
- renderFieldCompactInputLine),
-
- /* EXTENSION FIELDS */
- DEFINE_FIELD_FULL ('a', "access", false,
- "Access (or export) of class members",
- isAccessFieldAvailable,
- FIELDTYPE_STRING,
- renderFieldAccess, NULL, NULL),
- DEFINE_FIELD_FULL ('f', "file", true,
- "File-restricted scoping",
- isFileFieldAvailable,
- FIELDTYPE_BOOL,
- renderFieldFile, NULL, NULL),
- DEFINE_FIELD_FULL ('i', "inherits", false,
- "Inheritance information",
- isInheritsFieldAvailable,
- FIELDTYPE_STRING|FIELDTYPE_BOOL,
- renderFieldInherits, NULL, NULL),
- DEFINE_FIELD ('K', NULL, false,
- "Kind of tag in long-name form",
- FIELDTYPE_STRING,
- renderFieldKindName),
- DEFINE_FIELD ('k', NULL, true,
- "Kind of tag in one-letter form",
- FIELDTYPE_STRING,
- renderFieldKindLetter),
- DEFINE_FIELD_FULL ('l', "language", false,
- "Language of input file containing tag",
- isLanguageFieldAvailable,
- FIELDTYPE_STRING,
- renderFieldLanguage, NULL, NULL),
- DEFINE_FIELD_FULL ('m', "implementation", false,
- "Implementation information",
- isImplementationFieldAvailable,
- FIELDTYPE_STRING,
- renderFieldImplementation, NULL, NULL),
- DEFINE_FIELD ('n', "line", false,
- "Line number of tag definition",
- FIELDTYPE_INTEGER,
- renderFieldLineNumber),
- DEFINE_FIELD_FULL ('S', "signature", false,
- "Signature of routine (e.g. prototype or parameter list)",
- isSignatureFieldAvailable,
- FIELDTYPE_STRING,
- renderFieldSignature, renderFieldSignatureNoEscape,
- doesContainAnyCharInSignature),
- DEFINE_FIELD_FULL ('s', NULL, true,
- "[tags output] scope (kind:name) of tag definition, [xref and json output] name of scope",
- NULL,
- FIELDTYPE_STRING,
- renderFieldScope, renderFieldScopeNoEscape,
- doesContainAnyCharInFieldScope),
- DEFINE_FIELD_FULL ('t', "typeref", true,
- "Type and name of a variable or typedef",
- isTyperefFieldAvailable,
- FIELDTYPE_STRING,
- renderFieldTyperef, NULL, NULL),
- DEFINE_FIELD ('z', "kind", false,
- "[tags output] prepend \"kind:\" to k/ (or K/) field output, [xref and json output] kind in long-name form",
- FIELDTYPE_STRING,
- /* Following renderer is for handling --_xformat=%{kind};
- and is not for tags output. */
- renderFieldKindName),
+ [FIELD_COMPACT_INPUT_LINE - FIELD_ECTAGS_START] = {
+ .letter = 'C',
+ .name = "compact",
+ .description = "compact input line (used only in xref output)",
+ .enabled = false,
+ .render = renderFieldCompactInputLine,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = NULL,
+ .dataType = FIELDTYPE_STRING,
+ },
+ [FIELD_FILE_SCOPE - FIELD_ECTAGS_START] = {
+ .letter = 'f',
+ .name = "file",
+ .description = "File-restricted scoping",
+ .enabled = true,
+ .render = renderFieldFile,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = isFileFieldAvailable,
+ .dataType = FIELDTYPE_BOOL,
+ },
+ [FIELD_KIND_LONG - FIELD_ECTAGS_START] = {
+ .letter = 'K',
+ .name = NULL,
+ .description = "Kind of tag in long-name form",
+ .enabled = false,
+ .render = renderFieldKindName,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = NULL,
+ .dataType = FIELDTYPE_STRING,
+ },
+ [FIELD_KIND - FIELD_ECTAGS_START] = {
+ .letter ='k',
+ .name = NULL,
+ .description = "Kind of tag in one-letter form",
+ .enabled = true,
+ .render = renderFieldKindLetter,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = NULL,
+ .dataType = FIELDTYPE_STRING,
+ },
+ [FIELD_LANGUAGE - FIELD_ECTAGS_START] = {
+ .letter = 'l',
+ .name = "language",
+ .description = "Language of input file containing tag",
+ .enabled = false,
+ .render = renderFieldLanguage,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .dataType = FIELDTYPE_STRING,
+ },
+ [FIELD_LINE_NUMBER - FIELD_ECTAGS_START] = {
+ .letter = 'n',
+ .name = "line",
+ .description = "Line number of tag definition",
+ .enabled = false,
+ .render = renderFieldLineNumber,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = NULL,
+ .dataType = FIELDTYPE_INTEGER,
+ .getterValueType = "int",
+ .getValueObject = getFieldValueForLineCommon,
+ .setterValueType = "matchlok|int",
+ .checkValueForSetter= checkFieldValueForLineCommon,
+ .setValueObject = setFieldValueForLineCommon,
+ },
+ [FIELD_SCOPE - FIELD_ECTAGS_START] = {
+ .letter = 's',
+ .name = NULL,
+ .description = "[tags output] scope (kind:name) of tag definition, [xref and json output] name of scope",
+ .enabled = true,
+ .render = renderFieldScope,
+ .renderNoEscaping = renderFieldScopeNoEscape,
+ .doesContainAnyChar = doesContainAnyCharInFieldScope,
+ .isValueAvailable = NULL,
+ .dataType = FIELDTYPE_STRING,
+ },
+ [FIELD_TYPE_REF - FIELD_ECTAGS_START] = {
+ .letter = 't',
+ .name = "typeref",
+ .description = "Type and name of a variable or typedef",
+ .enabled = true,
+ .render = renderFieldTyperef,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = isTyperefFieldAvailable,
+ .dataType = FIELDTYPE_STRING,
+ .getterValueType = "[string string]",
+ .getValueObject = getFieldValueForTyperef,
+ .setterValueType = "[string string]|string|index:int|false",
+ .checkValueForSetter= checkFieldValueForTyperef,
+ .setValueObject = setFieldValueForTyperef,
+ },
+ [FIELD_KIND_KEY - FIELD_ECTAGS_START] = {
+ .letter = 'z',
+ .name = "kind",
+ .description = "[tags output] prepend \"kind:\" to k/ (or K/) field output, [xref and json output] kind in long-name form",
+ .enabled = false,
+ /* Following renderer is for handling --_xformat=%{kind};
+ and is not for tags output. */
+ .render = renderFieldKindName,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = NULL,
+ .dataType = FIELDTYPE_STRING,
+ .getterValueType = "name",
+ .getValueObject = getFieldValueForKind,
+ .setterValueType = NULL,
+ .checkValueForSetter= NULL,
+ .setValueObject = NULL,
+ },
+ [FIELD_INHERITANCE - FIELD_ECTAGS_START] = {
+ .letter = 'i',
+ .name = "inherits",
+ .description = "Inheritance information",
+ .enabled = false,
+ .render = renderFieldInherits,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = isInheritsFieldAvailable,
+ .dataType = FIELDTYPE_STRING|FIELDTYPE_BOOL,
+ .getterValueType = NULL,
+ .getValueObject = NULL,
+ .setterValueType = NULL,
+ .checkValueForSetter= NULL,
+ .setValueObject = setFieldValueForInherits,
+ },
+ [FIELD_ACCESS - FIELD_ECTAGS_START] = {
+ .letter = 'a',
+ .name = "access",
+ .description = "Access (or export) of class members",
+ .enabled = false,
+ .render = renderFieldAccess,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = isAccessFieldAvailable,
+ .dataType = FIELDTYPE_STRING,
+ },
+ [FIELD_IMPLEMENTATION - FIELD_ECTAGS_START] = {
+ .letter = 'm',
+ .name = "implementation",
+ .description = "Implementation information",
+ .enabled = false,
+ .render = renderFieldImplementation,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = isImplementationFieldAvailable,
+ .dataType = FIELDTYPE_STRING,
+
+ },
+ [FIELD_SIGNATURE - FIELD_ECTAGS_START] = {
+ .letter = 'S',
+ .name = "signature",
+ .description = "Signature of routine (e.g. prototype or parameter list)",
+ .enabled = false,
+ .render = renderFieldSignature,
+ .renderNoEscaping = renderFieldSignatureNoEscape,
+ .doesContainAnyChar = doesContainAnyCharInSignature,
+ .isValueAvailable = isSignatureFieldAvailable,
+ .dataType = FIELDTYPE_STRING,
+ .getterValueType = NULL,
+ .getValueObject = getFieldValueForSignature,
+ .setterValueType = NULL,
+ .checkValueForSetter= NULL,
+ .setValueObject = setFieldValueForSignature,
+ },
};
static fieldDefinition fieldDefinitionsUniversal [] = {
- DEFINE_FIELD ('r', "roles", false,
- "Roles",
- FIELDTYPE_STRING,
- renderFieldRoles),
- DEFINE_FIELD ('R', NULL, false,
- "Marker (R or D) representing whether tag is definition or reference",
- FIELDTYPE_STRING,
- renderFieldRefMarker),
- DEFINE_FIELD_FULL ('Z', "scope", false,
- "[tags output] prepend \"scope:\" key to s/scope field output, [xref and json output] the same as s/ field",
- NULL,
- FIELDTYPE_STRING,
- /* Following renderer is for handling --_xformat=%{scope};
- and is not for tags output. */
- renderFieldScope, renderFieldScopeNoEscape,
- doesContainAnyCharInFieldScope),
- DEFINE_FIELD_FULL ('E', "extras", false,
- "Extra tag type information",
- isExtrasFieldAvailable,
- FIELDTYPE_STRING,
- renderFieldExtras, NULL, NULL),
- DEFINE_FIELD_FULL ('x', "xpath", false,
- "xpath for the tag",
- isXpathFieldAvailable,
- FIELDTYPE_STRING,
- renderFieldXpath, NULL, NULL),
- DEFINE_FIELD ('p', "scopeKind", false,
- "[tags output] no effect, [xref and json output] kind of scope in long-name form",
- FIELDTYPE_STRING,
- renderFieldScopeKindName),
- DEFINE_FIELD_FULL ('e', "end", false,
- "end lines of various items",
- isEndFieldAvailable,
- FIELDTYPE_INTEGER,
- renderFieldEnd, NULL, NULL),
+ [FIELD_REF_MARK - FIELDS_UCTAGS_START] = {
+ .letter = 'R',
+ .name = NULL,
+ .description = "Marker (R or D) representing whether tag is definition or reference",
+ .enabled = false,
+ .render = renderFieldRefMarker,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = NULL,
+ .dataType = FIELDTYPE_STRING,
+ },
+ [FIELD_SCOPE_KEY - FIELDS_UCTAGS_START] = {
+ .letter = 'Z',
+ .name = "scope",
+ .description = "[tags output] prepend \"scope:\" key to s/scope field output, [xref and json output] the same as s/ field",
+ .enabled = false,
+ /* Following renderer is for handling --_xformat=%{scope};
+ and is not for tags output. */
+ .render = renderFieldScope,
+ .renderNoEscaping = renderFieldScopeNoEscape,
+ .doesContainAnyChar = doesContainAnyCharInFieldScope,
+ .isValueAvailable = NULL,
+ .dataType = FIELDTYPE_STRING,
+ .getterValueType = "int",
+ .getValueObject = getFieldValueForScope,
+ .setterValueType = "int",
+ .checkValueForSetter= checkFieldValueForScope,
+ .setValueObject = setFieldValueForScope,
+ },
+ [FIELD_SCOPE_KIND_LONG - FIELDS_UCTAGS_START] = {
+ .letter = 'p',
+ .name = "scopeKind",
+ .description = "[tags output] no effect, [xref and json output] kind of scope in long-name form",
+ .enabled = false,
+ .render = renderFieldScopeKindName,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = NULL,
+ .dataType = FIELDTYPE_STRING,
+ },
+ [FIELD_ROLES - FIELDS_UCTAGS_START] = {
+ .letter = 'r',
+ .name = "roles",
+ .description = "Roles",
+ .enabled = false,
+ .render = renderFieldRoles,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = NULL,
+ .dataType = FIELDTYPE_STRING,
+ .getterValueType = "[ role1:name ... rolen:name ]",
+ .getValueObject = getFieldValueForRoles,
+ .setterValueType = NULL,
+ .checkValueForSetter= NULL,
+ .setValueObject = NULL,
+ },
+ [FIELD_EXTRAS - FIELDS_UCTAGS_START] = {
+ .letter = 'E',
+ .name = "extras",
+ .description = "Extra tag type information",
+ .enabled = false,
+ .render = renderFieldExtras,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = isExtrasFieldAvailable,
+ .dataType = FIELDTYPE_STRING,
+ .getterValueType = "[ extra1:name ... extran:name ]",
+ .getValueObject = getFieldValueForExtras,
+ .setterValueType = NULL,
+ .checkValueForSetter= NULL,
+ .setValueObject = NULL,
+ },
+ [FIELD_XPATH - FIELDS_UCTAGS_START] = {
+ .letter = 'x',
+ .name = "xpath",
+ .description = "xpath for the tag",
+ .enabled = false,
+ .render = renderFieldXpath,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = isXpathFieldAvailable,
+ .dataType = FIELDTYPE_STRING,
+ },
+ [FIELD_END_LINE - FIELDS_UCTAGS_START] = {
+ .letter = 'e',
+ .name = "end",
+ .description = "end lines of various items",
+ .enabled = false,
+ .render = renderFieldEnd,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = isEndFieldAvailable,
+ .dataType = FIELDTYPE_INTEGER,
+ .getterValueType = "int",
+ .getValueObject = getFieldValueForLineCommon,
+ .setterValueType = "matchlok|int",
+ .checkValueForSetter= checkFieldValueForLineCommon,
+ .setValueObject = setFieldValueForLineCommon,
+
+ },
+ [FIELD_EPOCH - FIELDS_UCTAGS_START] = {
+ .letter = 'T',
+ .name = "epoch",
+ .description = "the last modified time of the input file (only for F/file kind tag)",
+ .enabled = true,
+ .render = renderFieldEpoch,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = isEpochAvailable,
+ .dataType = FIELDTYPE_INTEGER,
+ },
+ [FIELD_NTH - FIELDS_UCTAGS_START] = {
+ .letter = 'o',
+ .name = "nth",
+ .description = "the order in the parent scope",
+ .enabled = false,
+ .render = renderFieldNth,
+ .renderNoEscaping = NULL,
+ .doesContainAnyChar = NULL,
+ .isValueAvailable = isNthAvailable,
+ .dataType = FIELDTYPE_INTEGER,
+ },
};
@@ -258,6 +483,7 @@ extern void initFieldObjects (void)
fobj->nameWithPrefix = fobj->def->name;
fobj->language = LANG_IGNORE;
fobj->sibling = FIELD_UNKNOWN;
+ fobj->def->ftype = i + fieldObjectUsed;
}
fieldObjectUsed += ARRAY_SIZE (fieldDefinitionsFixed);
@@ -269,6 +495,7 @@ extern void initFieldObjects (void)
fobj->nameWithPrefix = fobj->def->name;
fobj->language = LANG_IGNORE;
fobj->sibling = FIELD_UNKNOWN;
+ fobj->def->ftype = i + fieldObjectUsed;
}
fieldObjectUsed += ARRAY_SIZE (fieldDefinitionsExuberant);
@@ -293,6 +520,7 @@ extern void initFieldObjects (void)
fobj->nameWithPrefix = NULL;
fobj->language = LANG_IGNORE;
fobj->sibling = FIELD_UNKNOWN;
+ fobj->def->ftype = i + fieldObjectUsed;
}
fieldObjectUsed += ARRAY_SIZE (fieldDefinitionsUniversal);
@@ -704,32 +932,51 @@ static const char *renderFieldLineNumber (const tagEntryInfo *const tag,
return vStringValue (b);
}
-static const char *renderFieldRoles (const tagEntryInfo *const tag,
- const char *value CTAGS_ATTR_UNUSED,
- vString* b)
+struct renderRoleData {
+ vString* b;
+ int nRoleWritten;
+};
+
+static void renderRoleByIndex (const tagEntryInfo *const tag, int roleIndex, void *data)
+{
+ struct renderRoleData *rdata = data;
+
+ if (!isLanguageRoleEnabled (tag->langType, tag->kindIndex, roleIndex))
+ return;
+
+ if (rdata->nRoleWritten > 0)
+ vStringPut(rdata->b, ',');
+
+ const roleDefinition * role = getTagRole(tag, roleIndex);
+ renderRole (role, rdata->b);
+ rdata->nRoleWritten++;
+}
+
+static roleBitsType foreachRoleBits (const tagEntryInfo *const tag,
+ void (* fn) (const tagEntryInfo *const, int, void *),
+ void *data)
{
roleBitsType rbits = tag->extensionFields.roleBits;
- const roleDefinition * role;
- if (rbits)
- {
- int roleCount = countLanguageRoles (tag->langType, tag->kindIndex);
- int nRoleWritten = 0;
+ if (!rbits)
+ return rbits;
- for (int roleIndex = 0; roleIndex < roleCount; roleIndex++)
- {
- if (((rbits >> roleIndex) & (roleBitsType)1)
- && isLanguageRoleEnabled (tag->langType, tag->kindIndex, roleIndex))
- {
- if (nRoleWritten > 0)
- vStringPut(b, ',');
+ int roleCount = countLanguageRoles (tag->langType, tag->kindIndex);
- role = getTagRole(tag, roleIndex);
- renderRole (role, b);
- nRoleWritten++;
- }
- }
+ for (int roleIndex = 0; roleIndex < roleCount; roleIndex++)
+ {
+ if ((rbits >> roleIndex) & (roleBitsType)1)
+ fn (tag, roleIndex, data);
}
- else
+ return rbits;
+}
+
+static const char *renderFieldRoles (const tagEntryInfo *const tag,
+ const char *value CTAGS_ATTR_UNUSED,
+ vString* b)
+{
+ struct renderRoleData data = { .b = b, .nRoleWritten = 0 };
+
+ if (!foreachRoleBits (tag, renderRoleByIndex, &data))
vStringCatS (b, ROLE_DEFINITION_NAME);
return vStringValue (b);
}
@@ -743,7 +990,10 @@ static const char *renderFieldLanguage (const tagEntryInfo *const tag,
if (Option.lineDirectives && (tag->sourceLangType != LANG_IGNORE))
l = getLanguageName(tag->sourceLangType);
else
+ {
+ Assert (tag->langType != LANG_IGNORE);
l = getLanguageName(tag->langType);
+ }
return renderAsIs (b, WITH_DEFUALT_VALUE(l));
}
@@ -878,9 +1128,31 @@ static const char *renderFieldEnd (const tagEntryInfo *const tag,
return NULL;
}
-static bool isLanguageFieldAvailable (const tagEntryInfo *const tag)
+static const char *renderFieldEpoch (const tagEntryInfo *const tag,
+ const char *value, vString* b)
{
- return (tag->langType == LANG_IGNORE)? false: true;
+#define buf_len 21
+ static char buf[buf_len];
+
+ if (snprintf (buf, buf_len, "%lld", (long long)tag->extensionFields.epoch) > 0)
+ return renderAsIs (b, buf);
+ else
+ return NULL;
+#undef buf_len
+}
+
+static const char *renderFieldNth (const tagEntryInfo *const tag,
+ const char *value, vString* b)
+{
+#define buf_len 12
+ static char buf[buf_len];
+
+ if (tag->extensionFields.nth > NO_NTH_FIELD
+ && snprintf (buf, buf_len, "%d", (int)tag->extensionFields.nth) > 0)
+ return renderAsIs (b, buf);
+ else
+ return NULL;
+#undef buf_len
}
static bool isTyperefFieldAvailable (const tagEntryInfo *const tag)
@@ -917,13 +1189,12 @@ static bool isSignatureFieldAvailable (const tagEntryInfo *const tag)
static bool isExtrasFieldAvailable (const tagEntryInfo *const tag)
{
unsigned int i;
+
+ if (tag->extraDynamic)
+ return true;
for (i = 0; i < sizeof (tag->extra); i++)
- {
if (tag->extra [i])
return true;
- else if (tag->extraDynamic)
- return true;
- }
return false;
}
@@ -942,46 +1213,39 @@ static bool isEndFieldAvailable (const tagEntryInfo *const tag)
return (tag->extensionFields.endLine != 0)? true: false;
}
+static bool isEpochAvailable (const tagEntryInfo *const tag)
+{
+ return (tag->kindIndex == KIND_FILE_INDEX)
+ ? true
+ : false;
+}
+
+static bool isNthAvailable (const tagEntryInfo *const tag)
+{
+ Assert (tag->langType >= NO_NTH_FIELD);
+ return (tag->extensionFields.nth != NO_NTH_FIELD)? true: false;
+}
+
extern bool isFieldEnabled (fieldType type)
{
return getFieldObject(type)->def->enabled;
}
-extern bool enableField (fieldType type, bool state, bool warnIfFixedField)
+extern bool enableField (fieldType type, bool state)
{
fieldDefinition *def = getFieldObject(type)->def;
bool old = def->enabled;
- if (writerDoesTreatFieldAsFixed (type))
- {
- if ((!state) && warnIfFixedField)
- {
- if (def->name && def->letter != NUL_FIELD_LETTER)
- error(WARNING, "Cannot disable fixed field: '%c'{%s}",
- def->letter, def->name);
- else if (def->name)
- error(WARNING, "Cannot disable fixed field: {%s}",
- def->name);
- else if (def->letter != NUL_FIELD_LETTER)
- error(WARNING, "Cannot disable fixed field: '%c'",
- getFieldObject(type)->def->letter);
- else
- AssertNotReached();
- }
- }
- else
- {
- getFieldObject(type)->def->enabled = state;
+ getFieldObject(type)->def->enabled = state;
- if (isCommonField (type))
- verbose ("enable field \"%s\": %s\n",
+ if (isCommonField (type))
+ verbose ("enable field \"%s\": %s\n",
getFieldObject(type)->def->name,
(state? "yes": "no"));
- else
- verbose ("enable field \"%s\"<%s>: %s\n",
+ else
+ verbose ("enable field \"%s\"<%s>: %s\n",
getFieldObject(type)->def->name,
getLanguageName (getFieldOwner(type)),
(state? "yes": "no"));
- }
return old;
}
@@ -1000,6 +1264,11 @@ extern unsigned int getFieldDataType (fieldType type)
return getFieldObject(type)->def->dataType;
}
+extern bool isFieldValueAvailableAlways (fieldType type)
+{
+ return getFieldObject(type)->def->isValueAvailable == NULL;
+}
+
extern bool doesFieldHaveRenderer (fieldType type, bool noEscaping)
{
if (noEscaping)
@@ -1101,11 +1370,14 @@ extern int defineField (fieldDefinition *def, langType language)
#define FIELD_COL_LANGUAGE 3
#define FIELD_COL_JSTYPE 4
#define FIELD_COL_FIXED 5
-#define FIELD_COL_DESCRIPTION 6
+#define FIELD_COL_OPERATOR 6
+#define FIELD_COL_DESCRIPTION 7
+
extern struct colprintTable * fieldColprintTableNew (void)
{
return colprintTableNew ("L:LETTER", "L:NAME", "L:ENABLED",
- "L:LANGUAGE", "L:JSTYPE", "L:FIXED", "L:DESCRIPTION", NULL);
+ "L:LANGUAGE", "L:JSTYPE", "L:FIXED",
+ "L:OP", "L:DESCRIPTION", NULL);
}
static void fieldColprintAddLine (struct colprintTable *table, int i)
@@ -1140,6 +1412,13 @@ static void fieldColprintAddLine (struct colprintTable *table, int i)
}
colprintLineAppendColumnCString (line, typefields);
colprintLineAppendColumnBool (line, writerDoesTreatFieldAsFixed (i));
+
+ char operator[] = {'-', '-', '\0'};
+ if (fdef->getValueObject)
+ operator[0] = 'r';
+ if (fdef->setValueObject)
+ operator[1] = 'w';
+ colprintLineAppendColumnCString (line, operator);
colprintLineAppendColumnCString (line, fdef->description);
}
@@ -1235,3 +1514,380 @@ extern void fieldColprintTablePrint (struct colprintTable *table,
colprintTableSort (table, fieldColprintCompareLines);
colprintTablePrint (table, 0, withListHeader, machinable, fp);
}
+
+extern const char * getFieldGetterValueType (fieldType type)
+{
+ fieldObject *fobj = getFieldObject (type);
+ return (fobj? fobj->def->getterValueType: NULL);
+}
+
+extern EsObject * getFieldValue (fieldType type, const tagEntryInfo *tag)
+{
+ fieldObject* fobj;
+
+ fobj = getFieldObject (type);
+ if (fobj && fobj->def->getValueObject)
+ return fobj->def->getValueObject (tag, fobj->def);
+ return es_nil;
+}
+
+extern bool hasFieldGetter (fieldType type)
+{
+ fieldObject *fobj = getFieldObject (type);
+ return (fobj && fobj->def->getValueObject);
+}
+
+extern const char * getFieldSetterValueType (fieldType type)
+{
+ fieldObject *fobj = getFieldObject (type);
+ return (fobj? fobj->def->setterValueType: NULL);
+}
+
+extern EsObject * setFieldValue (fieldType type, tagEntryInfo *tag, const EsObject *val)
+{
+ fieldObject *fobj;
+
+ fobj = getFieldObject (type);
+ if (fobj && fobj->def->setValueObject)
+ return fobj->def->setValueObject (tag, fobj->def, val);
+ return es_false;
+}
+
+extern bool hasFieldSetter (fieldType type)
+{
+ fieldObject *fobj = getFieldObject (type);
+ return (fobj && fobj->def->setValueObject);
+}
+
+
+extern bool hasFieldValueCheckerForSetter (fieldType type)
+{
+ fieldObject *fobj = getFieldObject (type);
+ return (fobj && fobj->def->checkValueForSetter);
+}
+
+extern EsObject* checkFieldValueForSetter (fieldType type, const EsObject *val)
+{
+ fieldObject *fobj = getFieldObject (type);
+ return fobj->def->checkValueForSetter (fobj->def, val);
+}
+
+static EsObject* getFieldValueForName (const tagEntryInfo *tag, const fieldDefinition *fdef)
+{
+ return opt_string_new_from_cstr (tag->name);
+}
+
+static EsObject* setFieldValueForName (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *val)
+{
+ eFree ((char*) tag->name);
+ const char *cstr = opt_string_get_cstr (val);
+ tag->name = eStrdup (cstr);
+ return es_false;
+}
+
+static EsObject* getFieldValueForInput (const tagEntryInfo *tag, const fieldDefinition *fdef)
+{
+ return opt_string_new_from_cstr (tag->inputFileName);
+}
+
+static EsObject* getFieldValueForKind (const tagEntryInfo *tag, const fieldDefinition *fdef)
+{
+ const char *kind_name = getLanguageKindName (tag->langType, tag->kindIndex);
+ return opt_name_new_from_cstr (kind_name);
+}
+
+static EsObject* getFieldValueForTyperef (const tagEntryInfo *tag, const fieldDefinition *fdef)
+{
+ if (tag->extensionFields.typeRef [0] == NULL
+ && tag->extensionFields.typeRef [1] == NULL)
+ return es_nil;
+
+ EsObject *a = opt_array_new ();
+ EsObject *e0 = tag->extensionFields.typeRef [0]
+ ? opt_string_new_from_cstr(tag->extensionFields.typeRef [0])
+ : es_false;
+ EsObject *e1 = tag->extensionFields.typeRef [1]
+ ? opt_string_new_from_cstr(tag->extensionFields.typeRef [1])
+ : es_false;
+ opt_array_put (a, 0, e0);
+ opt_array_put (a, 1, e1);
+ es_object_unref (e0);
+ es_object_unref (e1);
+ return a;
+}
+
+static EsObject* setFieldValueForTyperef (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *obj)
+{
+ const char *tmp[2] = {NULL, NULL};
+
+ for (int i = 0 ; i < 2; i++)
+ {
+ if (tag->extensionFields.typeRef [i])
+ tmp [i] = tag->extensionFields.typeRef [i];
+ }
+
+ if (es_boolean_p (obj))
+ {
+ for (int i = 0 ; i < 2; i++)
+ {
+ if (tag->extensionFields.typeRef [i])
+ tag->extensionFields.typeRef [i] = NULL;
+ }
+ }
+ else if (es_object_get_type (obj) == OPT_TYPE_ARRAY)
+ {
+ for (int i = 0 ; i < 2; i++)
+ {
+ EsObject *e = opt_array_get (obj, i);
+ if (es_boolean_p (e))
+ {
+ if (tag->extensionFields.typeRef [i])
+ tag->extensionFields.typeRef [i] = NULL;
+ }
+ else if (es_object_get_type (e) == OPT_TYPE_STRING)
+ {
+ tag->extensionFields.typeRef [i] = eStrdup (opt_string_get_cstr (e));
+ }
+ }
+ }
+ else if (es_object_get_type (obj) == OPT_TYPE_STRING)
+ {
+ const char *str = opt_string_get_cstr (obj);
+ tag->extensionFields.typeRef [0] = eStrdup ("typename");
+ tag->extensionFields.typeRef [1] = eStrdup (str);
+ }
+ else if (es_integer_p (obj))
+ {
+ int index = es_integer_get (obj);
+ tagEntryInfo *e = getEntryInCorkQueue (index);
+ if (e)
+ {
+ const char *name = e->name;
+ const char *kindName = getLanguageKindName (e->langType, e->kindIndex);
+
+ tag->extensionFields.typeRef [0] = eStrdup (kindName);
+ tag->extensionFields.typeRef [1] = eStrdup (name);
+ }
+ }
+ else
+ {
+ AssertNotReached();
+ return OPT_ERR_TYPECHECK;
+ }
+
+ for (int i = 0; i < 2; i++)
+ if (tmp [i])
+ eFree ((char*)tmp[i]);
+
+ return es_false;
+}
+
+static EsObject* checkFieldValueForTyperef (const fieldDefinition *fdef, const EsObject *obj)
+{
+ if (es_boolean_p (obj))
+ {
+ if (!es_object_equal (es_false, obj))
+ return OPT_ERR_TYPECHECK;
+ }
+ else if (es_object_get_type (obj) == OPT_TYPE_ARRAY)
+ {
+ if (opt_array_length (obj) != 2)
+ return OPT_ERR_TYPECHECK;
+
+ for (unsigned int i = 0; i < 2; i++)
+ {
+ EsObject *e = opt_array_get (obj, i);
+ if (es_object_get_type (e) != OPT_TYPE_STRING)
+ return OPT_ERR_TYPECHECK;
+ }
+ }
+ else if (es_object_get_type (obj) == OPT_TYPE_STRING)
+ ;
+ else if (es_integer_p (obj))
+ {
+ int index = es_integer_get (obj);
+ if (index >= countEntryInCorkQueue ())
+ return OPTSCRIPT_ERR_NOTAGENTRY;
+ }
+ else
+ return OPT_ERR_TYPECHECK;
+ return es_false;
+}
+
+static EsObject* getFieldValueForScope (const tagEntryInfo *tag, const fieldDefinition *fdef)
+{
+ return es_integer_new (tag->extensionFields.scopeIndex);
+}
+
+static EsObject* setFieldValueForScope (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *obj)
+{
+ int index = es_integer_get (obj);
+ if (index < countEntryInCorkQueue ())
+ {
+ tag->extensionFields.scopeIndex = index;
+ return es_false;
+ }
+
+ return OPTSCRIPT_ERR_NOTAGENTRY;
+}
+
+static EsObject* checkFieldValueForScope (const fieldDefinition *fdef, const EsObject *obj)
+{
+ if (!es_integer_p (obj))
+ return OPT_ERR_TYPECHECK;
+
+ if (es_integer_get (obj) < 0)
+ return OPT_ERR_RANGECHECK;
+
+ return es_false;
+}
+
+static EsObject* getFieldValueForExtras (const tagEntryInfo *tag, const fieldDefinition *fdef)
+{
+ if (!isTagExtra (tag))
+ return es_nil;
+
+ EsObject* a = opt_array_new ();
+
+ for (int i = 0; i < countXtags (); i++)
+ {
+ if (!isTagExtraBitMarked (tag, i))
+ continue;
+
+ langType lang = getXtagOwner (i);
+ const char *lang_name = (lang == LANG_IGNORE)
+ ? NULL
+ : getLanguageName (lang);
+ const char *extra_name = getXtagName (i);
+
+ EsObject *extra;
+ if (lang_name == NULL)
+ extra = opt_name_new_from_cstr (extra_name);
+ else
+ {
+ vString *tmp = vStringNewInit (lang_name);
+ vStringPut (tmp, '.');
+ vStringCatS (tmp, extra_name);
+ extra = opt_name_new_from_cstr (vStringValue (tmp));
+ vStringDelete (tmp);
+ }
+ opt_array_add (a, extra);
+ es_object_unref (extra);
+ }
+ return a;
+}
+
+static EsObject* getFieldValueForSignature (const tagEntryInfo *tag, const fieldDefinition *fdef)
+{
+ if (!tag->extensionFields.signature)
+ return es_nil;
+ return (opt_name_new_from_cstr (tag->extensionFields.signature));
+}
+
+static EsObject* setFieldValueForSignature (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *obj)
+{
+ if (tag->extensionFields.signature)
+ eFree ((char *)tag->extensionFields.signature);
+
+ const char *str = opt_string_get_cstr (obj);
+ tag->extensionFields.signature = eStrdup (str);
+ return es_false;
+}
+
+static void makeRolesArray (const tagEntryInfo *const tag, int roleIndex, void *data)
+{
+ EsObject *a = data;
+
+ const roleDefinition *role = getTagRole (tag, roleIndex);
+ EsObject *r = opt_name_new_from_cstr (role->name);
+ opt_array_add (a, r);
+ es_object_unref (r);
+}
+
+static EsObject* getFieldValueForRoles (const tagEntryInfo *tag, const fieldDefinition *fdef)
+{
+ EsObject *a = opt_array_new ();
+
+ if (!foreachRoleBits (tag, makeRolesArray, a))
+ {
+ EsObject *r = opt_name_new_from_cstr (ROLE_DEFINITION_NAME);
+ opt_array_add (a, r);
+ es_object_unref (r);
+ }
+ return a;
+}
+
+static EsObject* getFieldValueForLineCommon (const tagEntryInfo *tag, const fieldDefinition *fdef)
+{
+ if (fdef->ftype == FIELD_END_LINE)
+ return ((int)tag->extensionFields.endLine == 0)
+ ? es_nil
+ : es_integer_new ((int)tag->extensionFields.endLine);
+ else
+ return ((int)tag->lineNumber == 0)
+ ? es_nil
+ : es_integer_new ((int)tag->lineNumber);
+}
+
+static EsObject* checkFieldValueForLineCommon (const fieldDefinition *fdef, const EsObject *obj)
+{
+ return es_false;
+}
+
+static EsObject* setFieldValueForLineCommon (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *obj)
+{
+ int l;
+ if (es_object_get_type (obj) == OPT_TYPE_MATCHLOC)
+ {
+ matchLoc *loc = es_pointer_get (obj);
+ l = loc->line;
+ }
+ else if (es_integer_p (obj))
+ {
+ l = es_integer_get (obj);
+ if (l < 1)
+ return OPT_ERR_RANGECHECK;
+
+ /* If the new line number is too large,
+ we cannot fill tag->filePosition wit
+ getInputFilePositionForLine(); */
+ if (fdef->ftype == FIELD_LINE_NUMBER
+ && l < getInputLineNumber())
+ return OPT_ERR_RANGECHECK;
+ }
+ else
+ return OPT_ERR_TYPECHECK;
+
+ if (fdef->ftype == FIELD_END_LINE)
+ tag->extensionFields.endLine = l;
+ else
+ {
+ tag->lineNumber = l;
+ tag->filePosition = getInputFilePositionForLine (l);
+ }
+
+ return es_false;
+}
+
+static EsObject* setFieldValueForInherits (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *obj)
+{
+ if (es_object_get_type (obj) == OPT_TYPE_STRING)
+ {
+ if (tag->extensionFields.inheritance)
+ eFree ((void *)tag->extensionFields.inheritance);
+ const char *str = opt_string_get_cstr (obj);
+ tag->extensionFields.inheritance = eStrdup (str);
+ }
+ else if (es_object_equal (es_false, obj))
+ {
+ if (tag->extensionFields.inheritance)
+ {
+ eFree ((void *)tag->extensionFields.inheritance);
+ tag->extensionFields.inheritance = NULL;
+ }
+ }
+ else
+ return OPT_ERR_RANGECHECK; /* true is not acceptable. */
+
+ return es_false;
+}
Modified: ctags/main/field.h
43 lines changed, 31 insertions(+), 12 deletions(-)
===================================================================
@@ -20,6 +20,7 @@
#include "types.h"
#include "vstring.h"
+#include "optscript.h"
/*
* DATA DECLARATIONS
@@ -32,32 +33,41 @@ typedef enum eFieldType { /* extension field content control */
FIELD_NAME,
FIELD_INPUT_FILE,
FIELD_PATTERN,
- FIELD_COMPACT_INPUT_LINE,
+
+ FIELD_ECTAGS_START,
+ FIELD_COMPACT_INPUT_LINE = FIELD_ECTAGS_START,
/* EXTENSION FIELDS */
- FIELD_EXTENSION_START,
- FIELD_ACCESS = FIELD_EXTENSION_START,
- FIELD_FILE_SCOPE,
- FIELD_INHERITANCE,
+ FIELD_JSON_LOOP_START,
+ FIELD_FILE_SCOPE = FIELD_JSON_LOOP_START,
FIELD_KIND_LONG,
FIELD_KIND,
FIELD_LANGUAGE,
- FIELD_IMPLEMENTATION,
FIELD_LINE_NUMBER,
- FIELD_SIGNATURE,
FIELD_SCOPE,
FIELD_TYPE_REF,
FIELD_KIND_KEY,
+ FIELD_ECTAGS_LOOP_START,
+ FIELD_INHERITANCE = FIELD_ECTAGS_LOOP_START,
+ FIELD_ACCESS,
+ FIELD_IMPLEMENTATION,
+ FIELD_SIGNATURE,
+ FIELD_ECTAGS_LOOP_LAST = FIELD_SIGNATURE,
- /* EXTENSION FIELDS NEWLY INTRODUCED IN UCTAGS */
- FIELD_ROLES,
- FIELD_REF_MARK,
+ /* Extension fields newly introduced in Universal Ctags. */
+ FIELDS_UCTAGS_START,
+ FIELD_REF_MARK = FIELDS_UCTAGS_START,
FIELD_SCOPE_KEY,
+ FIELD_SCOPE_KIND_LONG,
+ FIELD_UCTAGS_LOOP_START,
+ FIELD_ROLES = FIELD_UCTAGS_LOOP_START,
FIELD_EXTRAS,
FIELD_XPATH,
- FIELD_SCOPE_KIND_LONG,
FIELD_END_LINE,
- FIELD_BUILTIN_LAST = FIELD_END_LINE,
+ FIELD_EPOCH,
+ FIELD_NTH,
+
+ FIELD_BUILTIN_LAST = FIELD_NTH,
} fieldType ;
#define fieldDataTypeFalgs "sib" /* used in --list-fields */
@@ -90,6 +100,15 @@ struct sFieldDefinition {
bool (* isValueAvailable) (const tagEntryInfo *const);
+ const char * getterValueType;
+ EsObject * (* getValueObject) (const tagEntryInfo *, const fieldDefinition *);
+ const char * setterValueType;
+
+ /* Return es_false if passed value is acceptable.
+ Return an error object is unacceptable. */
+ EsObject * (* checkValueForSetter) (const fieldDefinition *, const EsObject *);
+ EsObject * (* setValueObject) (tagEntryInfo *, const fieldDefinition *, const EsObject *);
+
fieldDataType dataType; /* used in json output */
unsigned int ftype; /* Given from the main part */
Modified: ctags/main/field_p.h
15 lines changed, 13 insertions(+), 2 deletions(-)
===================================================================
@@ -18,6 +18,7 @@
#include "general.h"
#include "colprint_p.h"
#include "field.h"
+#include "optscript.h"
/*
* DATA DECLARATIONS
@@ -43,14 +44,14 @@ extern fieldType getFieldTypeForOption (char letter);
internally, each parser is not initialized. `LANG_IGNORE' is a bit faster. */
extern fieldType getFieldTypeForName (const char *name);
extern fieldType getFieldTypeForNameAndLanguage (const char *fieldName, langType language);
-extern bool enableField (fieldType type, bool state, bool warnIfFixedField);
+extern bool enableField (fieldType type, bool state);
extern bool isCommonField (fieldType type);
extern int getFieldOwner (fieldType type);
extern const char* getFieldDescription (fieldType type);
extern const char* getFieldName (fieldType type);
extern unsigned char getFieldLetter (fieldType type);
extern unsigned int getFieldDataType (fieldType type);
-extern void printFields (int language);
+extern bool isFieldValueAvailableAlways (fieldType type);
/* Whether the field specified with TYPE has a
method for rendering in the current format. */
@@ -77,4 +78,14 @@ extern void fieldColprintAddLanguageLines (struct colprintTable *table, langType
extern void fieldColprintTablePrint (struct colprintTable *table,
bool withListHeader, bool machinable, FILE *fp);
+/* tag is assumed that it is in the cork queue. */
+extern EsObject * getFieldValue (fieldType type, const tagEntryInfo *tag);
+extern bool hasFieldGetter (fieldType type);
+extern const char * getFieldGetterValueType (fieldType type);
+extern EsObject * setFieldValue (fieldType type, tagEntryInfo *tag, const EsObject *val);
+extern bool hasFieldSetter (fieldType type);
+extern const char * getFieldSetterValueType (fieldType type);
+extern bool hasFieldValueCheckerForSetter (fieldType type);
+extern EsObject *checkFieldValueForSetter (fieldType type, const EsObject *val);
+
#endif /* CTAGS_MAIN_FIELD_PRIVATE_H */
Modified: ctags/main/flags.c
13 lines changed, 10 insertions(+), 3 deletions(-)
===================================================================
@@ -21,18 +21,24 @@
#include "vstring.h"
#include "routines.h"
-void flagsEval (const char* flags_original, flagDefinition* defs, unsigned int ndefs, void* data)
+extern const char *flagsEval (const char* flags_original, flagDefinition* defs, unsigned int ndefs, void* data)
{
unsigned int i, j;
char *flags;
+ const char *optscript = NULL;
if (!flags_original)
- return;
+ return NULL;
flags = eStrdup (flags_original);
for (i = 0 ; flags [i] != '\0' ; ++i)
{
- if (flags [i] == LONG_FLAGS_OPEN)
+ if (flags [i] == LONG_FLAGS_OPEN && flags [i + 1] == LONG_FLAGS_OPEN)
+ {
+ optscript = flags_original + i;
+ break;
+ }
+ else if (flags [i] == LONG_FLAGS_OPEN)
{
const char* aflag = flags + i + 1;
char* needle_close_paren = strchr(aflag, LONG_FLAGS_CLOSE);
@@ -74,6 +80,7 @@ void flagsEval (const char* flags_original, flagDefinition* defs, unsigned int n
defs[j].shortProc(flags[i], data);
}
eFree (flags);
+ return optscript;
}
extern struct colprintTable * flagsColprintTableNew (void)
Modified: ctags/main/flags_p.h
3 lines changed, 2 insertions(+), 1 deletions(-)
===================================================================
@@ -27,7 +27,8 @@ typedef struct sFlagDefinition {
const char *description;
} flagDefinition;
-extern void flagsEval (const char* flags, flagDefinition* defs, unsigned int ndefs, void* data);
+/* Return {{optscript}} part. */
+extern const char* flagsEval (const char* flags, flagDefinition* defs, unsigned int ndefs, void* data);
extern struct colprintTable * flagsColprintTableNew (void);
extern void flagsColprintAddDefinitions (struct colprintTable *table, flagDefinition* def, unsigned int ndefs);
extern void flagsColprintTablePrint (struct colprintTable *table,
Modified: ctags/main/fmt.c
4 lines changed, 2 insertions(+), 2 deletions(-)
===================================================================
@@ -230,13 +230,13 @@ static fmtElement** queueTagField (fmtElement **last, long width, bool truncatio
else
cur->spec.field.raw_fmtstr = NULL;
- enableField (ftype, true, false);
+ enableField (ftype, true);
if (language == LANG_AUTO)
{
fieldType ftype_next = ftype;
while ((ftype_next = nextSiblingField (ftype_next)) != FIELD_UNKNOWN)
- enableField (ftype_next, true, false);
+ enableField (ftype_next, true);
}
cur->printer = printTagField;
Modified: ctags/main/htable.c
94 lines changed, 70 insertions(+), 24 deletions(-)
===================================================================
@@ -43,8 +43,10 @@ struct sHashTable {
unsigned int size;
hashTableHashFunc hashfn;
hashTableEqualFunc equalfn;
- hashTableFreeFunc keyfreefn;
- hashTableFreeFunc valfreefn;
+ hashTableDeleteFunc keyfreefn;
+ hashTableDeleteFunc valfreefn;
+ void *valForNotUnknownKey;
+ hashTableDeleteFunc valForNotUnknownKeyfreefn;
};
struct chainTracker {
@@ -65,45 +67,55 @@ static hentry* entry_new (void *key, void *value, hentry* next)
return entry;
}
-static hentry* entry_destroy (hentry* entry,
- hashTableFreeFunc keyfreefn,
- hashTableFreeFunc valfreefn)
+static void entry_reset (hentry* entry,
+ void *newkey,
+ void *newval,
+ hashTableDeleteFunc keyfreefn,
+ hashTableDeleteFunc valfreefn)
{
- hentry* tmp;
-
if (keyfreefn)
keyfreefn (entry->key);
if (valfreefn)
valfreefn (entry->value);
- entry->key = NULL;
- entry->value = NULL;
+ entry->key = newkey;
+ entry->value = newval;
+}
+
+static hentry* entry_destroy (hentry* entry,
+ hashTableDeleteFunc keyfreefn,
+ hashTableDeleteFunc valfreefn)
+{
+ hentry* tmp;
+
+ entry_reset (entry, NULL, NULL, keyfreefn, valfreefn);
tmp = entry->next;
eFree (entry);
return tmp;
}
static void entry_reclaim (hentry* entry,
- hashTableFreeFunc keyfreefn,
- hashTableFreeFunc valfreefn)
+ hashTableDeleteFunc keyfreefn,
+ hashTableDeleteFunc valfreefn)
{
while (entry)
entry = entry_destroy (entry, keyfreefn, valfreefn);
}
-static void *entry_find (hentry* entry, const void* const key, hashTableEqualFunc equalfn)
+static void *entry_find (hentry* entry, const void* const key, hashTableEqualFunc equalfn,
+ void *valForNotUnknownKey)
{
while (entry)
{
if (equalfn( key, entry->key))
return entry->value;
entry = entry->next;
}
- return NULL;
+ return valForNotUnknownKey;
}
static bool entry_delete (hentry **entry, const void *key, hashTableEqualFunc equalfn,
- hashTableFreeFunc keyfreefn, hashTableFreeFunc valfreefn)
+ hashTableDeleteFunc keyfreefn, hashTableDeleteFunc valfreefn)
{
while (*entry)
{
@@ -112,7 +124,22 @@ static bool entry_delete (hentry **entry, const void *key, hashTableEqualFunc e
*entry = entry_destroy (*entry, keyfreefn, valfreefn);
return true;
}
+ entry = &((*entry)->next);
+ }
+ return false;
+}
+static bool entry_update (hentry *entry, void *key, void *value, hashTableEqualFunc equalfn,
+ hashTableDeleteFunc keyfreefn, hashTableDeleteFunc valfreefn)
+{
+ while (entry)
+ {
+ if (equalfn (key, entry->key))
+ {
+ entry_reset (entry, key, value, keyfreefn, valfreefn);
+ return true;
+ }
+ entry = entry->next;
}
return false;
}
@@ -131,8 +158,8 @@ static bool entry_foreach (hentry *entry, hashTableForeachFunc proc, void *user
extern hashTable *hashTableNew (unsigned int size,
hashTableHashFunc hashfn,
hashTableEqualFunc equalfn,
- hashTableFreeFunc keyfreefn,
- hashTableFreeFunc valfreefn)
+ hashTableDeleteFunc keyfreefn,
+ hashTableDeleteFunc valfreefn)
{
hashTable *htable;
@@ -144,16 +171,21 @@ extern hashTable *hashTableNew (unsigned int size,
htable->equalfn = equalfn;
htable->keyfreefn = keyfreefn;
htable->valfreefn = valfreefn;
+ htable->valForNotUnknownKey = NULL;
+ htable->valForNotUnknownKeyfreefn = NULL;
return htable;
}
-extern hashTable* hashTableIntNew (unsigned int size,
- hashTableHashFunc hashfn,
- hashTableEqualFunc equalfn,
- hashTableFreeFunc keyfreefn)
+extern void hashTableSetValueForUnknownKey (hashTable *htable,
+ void *val,
+ hashTableDeleteFunc valfreefn)
{
- return hashTableNew (size, hashfn, equalfn, keyfreefn, NULL);
+ if (htable->valfreefn)
+ htable->valfreefn (htable->valForNotUnknownKey);
+
+ htable->valForNotUnknownKey = val;
+ htable->valForNotUnknownKeyfreefn = valfreefn;
}
extern void hashTableDelete (hashTable *htable)
@@ -163,6 +195,8 @@ extern void hashTableDelete (hashTable *htable)
hashTableClear (htable);
+ if (htable->valForNotUnknownKeyfreefn)
+ htable->valForNotUnknownKeyfreefn (htable->valForNotUnknownKey);
eFree (htable->table);
eFree (htable);
}
@@ -196,7 +230,7 @@ extern void* hashTableGetItem (hashTable *htable, const void * key)
unsigned int i;
i = htable->hashfn (key) % htable->size;
- return entry_find(htable->table[i], key, htable->equalfn);
+ return entry_find(htable->table[i], key, htable->equalfn, htable->valForNotUnknownKey);
}
extern bool hashTableDeleteItem (hashTable *htable, const void *key)
@@ -208,9 +242,21 @@ extern bool hashTableDeleteItem (hashTable *htable, const void *key)
htable->equalfn, htable->keyfreefn, htable->valfreefn);
}
+extern bool hashTableUpdateItem (hashTable *htable, void *key, void *value)
+{
+ unsigned int i;
+
+ i = htable->hashfn (key) % htable->size;
+ bool r = entry_update(htable->table[i], key, value,
+ htable->equalfn, htable->keyfreefn, htable->valfreefn);
+ if (!r)
+ htable->table[i] = entry_new(key, value, htable->table[i]);
+ return r;
+}
+
extern bool hashTableHasItem (hashTable *htable, const void *key)
{
- return hashTableGetItem (htable, key)? true: false;
+ return hashTableGetItem (htable, key) == htable->valForNotUnknownKey? false: true;
}
extern bool hashTableForeachItem (hashTable *htable, hashTableForeachFunc proc, void *user_data)
@@ -258,7 +304,7 @@ static bool count (const void *const key CTAGS_ATTR_UNUSED, void *value CTAGS_AT
return true;
}
-extern int hashTableCountItem (hashTable *htable)
+extern unsigned int hashTableCountItem (hashTable *htable)
{
int c = 0;
hashTableForeachItem (htable, count, &c);
Modified: ctags/main/htable.h
23 lines changed, 15 insertions(+), 8 deletions(-)
===================================================================
@@ -30,7 +30,7 @@
typedef struct sHashTable hashTable;
typedef unsigned int (* hashTableHashFunc) (const void * const key);
typedef bool (* hashTableEqualFunc) (const void* a, const void* b);
-typedef void (* hashTableFreeFunc) (void * ptr);
+typedef void (* hashTableDeleteFunc) (void * ptr);
/* To continue interation, return true.
* To break interation, return false. */
@@ -51,15 +51,26 @@ bool hashInteq (const void * a, const void * b);
extern hashTable* hashTableNew (unsigned int size,
hashTableHashFunc hashfn,
hashTableEqualFunc equalfn,
- hashTableFreeFunc keyfreefn,
- hashTableFreeFunc valfreefn);
+ hashTableDeleteFunc keyfreefn,
+ hashTableDeleteFunc valfreefn);
+
+/* By default, hashTableGetItem() returns NULL for a unknown key.
+ * It means you cannot store NULL as a value for a key.
+ * With hashTableSetValueForUnknownKey(), you can specific
+ * an alternative address representing the value for for unknown
+ * keys.
+ */
+extern void hashTableSetValueForUnknownKey (hashTable *htable,
+ void *val,
+ hashTableDeleteFunc valfreefn);
extern void hashTableDelete (hashTable *htable);
extern void hashTableClear (hashTable *htable);
extern void hashTablePutItem (hashTable *htable, void *key, void *value);
extern void* hashTableGetItem (hashTable *htable, const void * key);
extern bool hashTableHasItem (hashTable * htable, const void * key);
extern bool hashTableDeleteItem (hashTable *htable, const void *key);
+extern bool hashTableUpdateItem (hashTable *htable, void *key, void *value);
/* Return true if proc never returns false; proc returns true for all
* the items, or htable holds no item.
@@ -74,12 +85,8 @@ extern bool hashTableForeachItem (hashTable *htable, hashTableForeachFunc
* key. */
extern bool hashTableForeachItemOnChain (hashTable *htable, const void *key, hashTableForeachFunc proc, void *user_data);
-extern int hashTableCountItem (hashTable *htable);
+extern unsigned int hashTableCountItem (hashTable *htable);
-extern hashTable* hashTableIntNew (unsigned int size,
- hashTableHashFunc hashfn,
- hashTableEqualFunc equalfn,
- hashTableFreeFunc keyfreefn);
#define HT_PTR_TO_INT(P) ((int)(intptr_t)(P))
#define HT_INT_TO_PTR(P) ((void*)(intptr_t)(P))
#define HT_PTR_TO_UINT(P) ((unsigned int)(uintptr_t)(P))
Modified: ctags/main/kind_p.h
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -13,6 +13,7 @@
*/
#include "general.h"
+#include "kind.h"
#include "vstring.h"
Modified: ctags/main/lregex-default.c
127 lines changed, 127 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,127 @@
+/*
+* Copyright (c) 2000-2003, Darren Hiebert
+*
+* This source code is released for free distribution under the terms of the
+* GNU General Public License version 2 or (at your option) any later version.
+*
+* This module contains functions for applying regular expression matching.
+*
+* The code for utilizing the Gnu regex package with regards to processing the
+* regex option and checking for regex matches was adapted from routines in
+* Gnu etags.
+*/
+
+/*
+* INCLUDE FILES
+*/
+#include "general.h" /* must always come first */
+
+#include <regex.h>
+#include "lregex_p.h"
+
+/*
+* FUNCTION DECLARATIONS
+*/
+static int match (struct regexBackend *backend,
+ void *code, const char *input, size_t size,
+ regmatch_t pmatch[BACK_REFERENCE_COUNT]);
+static regexCompiledCode compile (struct regexBackend *backend,
+ const char *const regexp,
+ int flags);
+static void delete_code (void *code);
+static void set_icase_flag (int *flags);
+
+/*
+* DATA DEFINITIONS
+*/
+static struct regexBackend defaultRegexBackend = {
+ .fdefs = NULL,
+ .fdef_count = 0,
+ .set_icase_flag = set_icase_flag,
+ .compile = compile,
+ .match = match,
+ .delete_code = delete_code,
+};
+
+/*
+* FUNCTOIN DEFINITIONS
+*/
+extern void basic_regex_flag_short (char c, void* data)
+{
+ struct flagDefsDescriptor *desc = data;
+
+ if (desc->backend)
+ error (FATAL, "regex backed is specified twice: %c", c);
+
+ desc->backend = &defaultRegexBackend;
+ desc->flags = (desc->regptype == REG_PARSER_MULTI_TABLE)? 0: REG_NEWLINE;
+}
+
+extern void basic_regex_flag_long (const char* const s, const char* const unused CTAGS_ATTR_UNUSED, void* data)
+{
+ struct flagDefsDescriptor *desc = data;
+
+ if (desc->backend)
+ error (FATAL, "regex backed is specified twice: %s", s);
+
+ basic_regex_flag_short ('b', data);
+}
+
+extern void extend_regex_flag_short (char c, void* data)
+{
+ struct flagDefsDescriptor *desc = data;
+
+ if (desc->backend)
+ error (FATAL, "regex backed is specified twice: %c", c);
+
+ desc->backend = &defaultRegexBackend;
+ desc->flags = REG_EXTENDED;
+ desc->flags |= (desc->regptype == REG_PARSER_MULTI_TABLE)? 0: REG_NEWLINE;
+}
+
+extern void extend_regex_flag_long (const char* const s, const char* const unused CTAGS_ATTR_UNUSED, void* data)
+{
+ struct flagDefsDescriptor *desc = data;
+
+ if (desc->backend)
+ error (FATAL, "regex backed is specified twice: %s", s);
+
+ extend_regex_flag_short('e', data);
+}
+
+static void delete_code (void *code)
+{
+ regex_t *regex_code = code;
+ regfree (regex_code);
+ eFree (regex_code);
+}
+
+static regexCompiledCode compile (struct regexBackend *backend,
+ const char *const regexp,
+ int flags)
+{
+ regex_t *regex_code = xMalloc (1, regex_t);
+ int errcode = regcomp (regex_code, regexp, flags);
+ if (errcode != 0)
+ {
+ char errmsg[256];
+ regerror (errcode, regex_code, errmsg, 256);
+ error (WARNING, "regcomp: %s", errmsg);
+ regfree (regex_code);
+ eFree (regex_code);
+ return (regexCompiledCode) { .backend = NULL, .code = NULL };
+ }
+ return (regexCompiledCode) { .backend = &defaultRegexBackend, .code = regex_code };
+}
+
+static int match (struct regexBackend *backend,
+ void *code, const char *input, size_t size CTAGS_ATTR_UNUSED,
+ regmatch_t pmatch[BACK_REFERENCE_COUNT])
+{
+ return regexec ((regex_t *)code, input, BACK_REFERENCE_COUNT, pmatch, 0);
+}
+
+static void set_icase_flag (int *flags)
+{
+ *flags |= REG_ICASE;
+}
Modified: ctags/main/lregex-pcre2.c
140 lines changed, 140 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,140 @@
+/*
+* Copyright (c) 2021, Red Hat, Inc.
+* Copyright (c) 2021, Masatake YAMATO
+*
+* This source code is released for free distribution under the terms of the
+* GNU General Public License version 2 or (at your option) any later version.
+*
+* This module contains functions for applying regular expression matching.
+*
+* The code for utilizing the Gnu regex package with regards to processing the
+* regex option and checking for regex matches was adapted from routines in
+* Gnu etags.
+*/
+
+/*
+* INCLUDE FILES
+*/
+#include "general.h" /* must always come first */
+
+#ifdef HAVE_PCRE2
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
+#endif
+
+#include "lregex_p.h"
+#include "trashbox.h"
+
+#include <string.h>
+
+/*
+* FUNCTION DECLARATIONS
+*/
+static int match (struct regexBackend *backend,
+ void *code, const char *input, size_t size,
+ regmatch_t pmatch[BACK_REFERENCE_COUNT]);
+static regexCompiledCode compile (struct regexBackend *backend,
+ const char *const regexp,
+ int flags);
+static void delete_code (void *code);
+static void set_icase_flag (int *flags);
+
+/*
+* DATA DEFINITIONS
+*/
+static struct regexBackend pcre2RegexBackend = {
+ .fdefs = NULL,
+ .fdef_count = 0,
+ .set_icase_flag = set_icase_flag,
+ .compile = compile,
+ .match = match,
+ .delete_code = delete_code,
+};
+
+/*
+* FUNCTOIN DEFINITIONS
+*/
+extern void pcre2_regex_flag_short (char c, void* data)
+{
+ struct flagDefsDescriptor *desc = data;
+
+ if (desc->backend)
+ error (FATAL, "regex backed is specified twice: %c", c);
+
+ desc->backend = &pcre2RegexBackend;
+ desc->flags = (desc->regptype == REG_PARSER_MULTI_TABLE)? PCRE2_DOTALL: PCRE2_MULTILINE;
+}
+
+extern void pcre2_regex_flag_long (const char* const s, const char* const unused CTAGS_ATTR_UNUSED, void* data)
+{
+ struct flagDefsDescriptor *desc = data;
+
+ if (desc->backend)
+ error (FATAL, "regex backed is specified twice: %s", s);
+
+ pcre2_regex_flag_short ('p', data);
+}
+
+static void delete_code (void *code)
+{
+ pcre2_code_free (code);
+}
+
+static regexCompiledCode compile (struct regexBackend *backend,
+ const char *const regexp,
+ int flags)
+{
+ int errornumber;
+ PCRE2_SIZE erroroffset;
+ pcre2_code *regex_code = pcre2_compile((PCRE2_SPTR)regexp,
+ PCRE2_ZERO_TERMINATED,
+ (uint32_t) flags,
+ &errornumber,
+ &erroroffset,
+ NULL);
+ if (regex_code == NULL)
+ {
+ PCRE2_UCHAR buffer[256];
+ pcre2_get_error_message(errornumber, buffer, sizeof(buffer));
+ error (WARNING, "PCRE2 compilation failed at offset %d: %s", (int)erroroffset,
+ buffer);
+ return (regexCompiledCode) { .backend = NULL, .code = NULL };
+ }
+ return (regexCompiledCode) { .backend = &pcre2RegexBackend, .code = regex_code };
+}
+
+static int match (struct regexBackend *backend,
+ void *code, const char *input, size_t size,
+ regmatch_t pmatch[BACK_REFERENCE_COUNT])
+{
+ static pcre2_match_data *match_data;
+ if (match_data == NULL)
+ {
+ match_data = pcre2_match_data_create (BACK_REFERENCE_COUNT, NULL);
+ DEFAULT_TRASH_BOX (match_data, pcre2_match_data_free);
+ }
+
+ int rc = pcre2_match (code, (PCRE2_SPTR)input, size,
+ 0, 0, match_data, NULL);
+ if (rc > 0)
+ {
+ PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
+ if (ovector[0] <= ovector[1])
+ {
+ memset (pmatch, 0, sizeof(pmatch[0]) * BACK_REFERENCE_COUNT);
+ for (int i = 0; i < BACK_REFERENCE_COUNT; i++)
+ {
+ pmatch [i].rm_so = (i < rc)? ovector [2*i] : -1;
+ pmatch [i].rm_eo = (i < rc)? ovector [2*i+1]: -1;
+
+ }
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void set_icase_flag (int *flags)
+{
+ *flags |= PCRE2_CASELESS;
+}
Modified: ctags/main/lregex.c
1542 lines changed, 1406 insertions(+), 136 deletions(-)
===================================================================
@@ -23,7 +23,6 @@
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h> /* declare off_t (not known to regex.h on FreeBSD) */
#endif
-#include <regex.h>
#include <inttypes.h>
@@ -35,12 +34,15 @@
#include "htable.h"
#include "kind.h"
#include "options.h"
+#include "optscript.h"
#include "parse_p.h"
#include "promise.h"
#include "read.h"
#include "read_p.h"
#include "routines.h"
#include "routines_p.h"
+#include "script_p.h"
+#include "trace.h"
#include "trashbox.h"
#include "xtag_p.h"
@@ -50,9 +52,6 @@ static bool regexAvailable = false;
* MACROS
*/
-/* Back-references \0 through \9 */
-#define BACK_REFERENCE_COUNT 10
-
/* The max depth of taction=enter/leave stack */
#define MTABLE_STACK_MAX_DEPTH 64
@@ -64,6 +63,7 @@ static bool regexAvailable = false;
Tmain cases. */
#define MTABLE_MOTIONLESS_MAX (MTABLE_STACK_MAX_DEPTH + 1)
+#define DEFAULT_REGEX_BACKEND "e"
/*
* DATA DECLARATIONS
@@ -137,7 +137,7 @@ struct mTableActionSpec {
};
typedef struct {
- regex_t *pattern;
+ regexCompiledCode pattern;
enum pType type;
bool exclusive;
bool accept_empty_name;
@@ -172,6 +172,9 @@ typedef struct {
char *message_string;
} message;
+ char *optscript_src;
+ EsObject *optscript;
+
int refcount;
} regexPattern;
@@ -206,6 +209,17 @@ struct guestRequest {
struct boundaryInRequest boundary[2];
};
+typedef struct {
+ const char *line;
+ const char *start;
+ const regexPattern* const patbuf;
+ const regmatch_t* const pmatch;
+ int nmatch;
+ struct mTableActionSpec taction;
+ bool advanceto;
+ unsigned int advanceto_delta;
+} scriptWindow;
+
struct lregexControlBlock {
int currentScope;
ptrArray *entries [2];
@@ -215,12 +229,21 @@ struct lregexControlBlock {
struct guestRequest *guest_req;
+ EsObject *local_dict;
+
+ ptrArray *hook[SCRIPT_HOOK_MAX];
+ ptrArray *hook_code[SCRIPT_HOOK_MAX];
+
langType owner;
+
+ scriptWindow *window;
};
/*
* DATA DEFINITIONS
*/
+static OptVM *optvm;
+static EsObject *lregex_dict = es_nil;
/*
* FUNCTION DEFINITIONS
@@ -237,6 +260,15 @@ static bool guestRequestIsFilled(struct guestRequest *);
static void guestRequestClear (struct guestRequest *);
static void guestRequestSubmit (struct guestRequest *);
+static EsObject *scriptRead (OptVM *vm, const char *src);
+static void scriptSetup (OptVM *vm, struct lregexControlBlock *lcb, int corkIndex, scriptWindow *window);
+static EsObject* scriptEval (OptVM *vm, EsObject *optscript);
+static void scriptEvalHook (OptVM *vm, struct lregexControlBlock *lcb, enum scriptHook hook);
+static void scriptTeardown (OptVM *vm, struct lregexControlBlock *lcb);
+
+static char* make_match_string (scriptWindow *window, int group);
+static matchLoc *make_mloc (scriptWindow *window, int group, bool start);
+
static void deleteTable (void *ptrn)
{
struct regexTable *t = ptrn;
@@ -261,9 +293,7 @@ static void deletePattern (regexPattern *p)
if (p->refcount > 0)
return;
- regfree (p->pattern);
- eFree (p->pattern);
- p->pattern = NULL;
+ p->pattern.backend->delete_code (p->pattern.code);
if (p->type == PTRN_TAG)
{
@@ -285,6 +315,11 @@ static void deletePattern (regexPattern *p)
if (p->anonymous_tag_prefix)
eFree (p->anonymous_tag_prefix);
+ if (p->optscript)
+ es_object_unref (p->optscript);
+ if (p->optscript_src)
+ eFree (p->optscript_src);
+
eFree (p);
}
@@ -304,6 +339,13 @@ extern struct lregexControlBlock* allocLregexControlBlock (parserDefinition *par
lcb->tables = ptrArrayNew(deleteTable);
lcb->tstack = ptrArrayNew(NULL);
lcb->guest_req = guestRequestNew ();
+ lcb->local_dict = es_nil;
+
+ for (int i = 0; i< SCRIPT_HOOK_MAX; i++)
+ {
+ lcb->hook[i] = ptrArrayNew (eFree);
+ lcb->hook_code[i] = ptrArrayNew ((ptrArrayDeleteFunc)es_object_unref);
+ }
lcb->owner = parser->id;
return lcb;
@@ -327,6 +369,18 @@ extern void freeLregexControlBlock (struct lregexControlBlock* lcb)
guestRequestDelete (lcb->guest_req);
lcb->guest_req = NULL;
+ es_object_unref (lcb->local_dict);
+ lcb->local_dict = es_nil;
+
+ for (int i = 0; i < SCRIPT_HOOK_MAX; i++)
+ {
+ ptrArrayDelete (lcb->hook[i]);
+ lcb->hook[i] = NULL;
+
+ ptrArrayDelete (lcb->hook_code[i]);
+ lcb->hook_code[i] = NULL;
+ }
+
eFree (lcb);
}
@@ -335,11 +389,11 @@ extern void freeLregexControlBlock (struct lregexControlBlock* lcb)
*/
static void initRegexTag (tagEntryInfo *e,
- const vString* const name, int kindIndex, int roleIndex, int scopeIndex, int placeholder,
+ const char * name, int kindIndex, int roleIndex, int scopeIndex, int placeholder,
unsigned long line, MIOPos *pos, int xtag_type)
{
- Assert (name != NULL && ((vStringLength (name) > 0) || placeholder));
- initRefTagEntry (e, vStringValue (name), kindIndex, roleIndex);
+ Assert (name != NULL && ((name[0] != '\0') || placeholder));
+ initRefTagEntry (e, name, kindIndex, roleIndex);
e->extensionFields.scopeIndex = scopeIndex;
e->placeholder = !!placeholder;
if (line)
@@ -364,7 +418,7 @@ static void initRegexTag (tagEntryInfo *e,
* Returns pointer to terminating separator. Works in place. Null
* terminates name string.
*/
-static char* scanSeparators (char* name, enum regexParserType regptype)
+static char* scanSepara@@ Diff output truncated at 100000 characters. @@
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Commits
mailing list