Skip to content

Commit 62467ec

Browse files
committed
main: implement the setter and getter for parser specific fields defined in an optlib parser
Signed-off-by: Masatake YAMATO <[email protected]>
1 parent 7b991c9 commit 62467ec

File tree

10 files changed

+154
-19
lines changed

10 files changed

+154
-19
lines changed
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#LETTER NAME ENABLED LANGUAGE JSTYPE FIXED OP DESCRIPTION
2-
- boolfield no FIELDTEST --b no -- a field having boolean value
2+
- boolfield no FIELDTEST --b no rw a field having boolean value
33
- deffield no FIELDTEST s-- no -- a field that type is not specified
4-
- intfield no FIELDTEST -i- no -- a field having integer value
5-
- strfield no FIELDTEST s-- no -- a field having string value
4+
- intfield no FIELDTEST -i- no rw a field having integer value
5+
- strfield no FIELDTEST s-- no rw a field having string value
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
#LETTER NAME DESCRIPTION
2-
- datatype=TYPE acceaptable datatype of the field ([str]|bool|int)
2+
- datatype=TYPE acceaptable datatype of the field (str|bool|int)

Tmain/parser-own-fields-for-foreign-lang.d/input.unknownx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ protected func bar(n);
33
private func baz(n,...);
44
X:tagme@iamowner
55
Y:iamowner2=tagme2
6+
Z:tagme-z@iamowner-z
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
--langdef=knownz
22
--kinddef-knownz=m,mark,makers
33

4-
--_fielddef-knownz=owner,the owner of the markers
4+
--_fielddef-knownz=owner,the owner of the markers{datatype=str}
5+
6+
--_fielddef-knownz=len,the length of owner string{datatype=int}
7+
--fields-knownz=+{len}
8+
--_fielddef-knownz=lenplus,the length of owner string + 1{datatype=int}
9+
--fields-knownz=+{lenplus}

Tmain/parser-own-fields-for-foreign-lang.d/stdout-expected.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ bar input.unknownx /^protected func bar(n);$/;" f language:unknownx protection:p
22
baz input.unknownx /^private func baz(n,...);$/;" f language:unknownx protection:private signature:(n,...)
33
foo input.unknownx /^public func foo(n, m);$/;" f language:unknownx protection:public signature:(n, m)
44
tagme input.unknownx /^X:tagme@iamowner$/;" m language:knownz owner:iamowner
5+
tagme-z input.unknownx /^Z:tagme-z@iamowner-z$/;" m language:knownz owner:iamowner-z len:10 lenplus:11
56
tagme2 input.unknownx /^Y:iamowner2=tagme2$/;" m language:knownz owner:iamowner2

Tmain/parser-own-fields-for-foreign-lang.d/unknownx.ctags

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,13 @@
88
--regex-unknownx=/^((public|protected|private) +)?func ([^\(]+)\((.*)\)/\3/f/{_field=protection:\1}{_field=signature:(\4)}
99
--regex-unknownx=/^X:([a-z]+)@([a-z]+)/\1/m/{_language=knownz}{_field=owner:\2}
1010
--regex-unknownx=/^Y:([a-z0-9]+)=([a-z0-9]+)/\2/m/{_field=owner:\1}{_language=knownz}
11+
--regex-unknownx=/^Z:([-a-z]+)@([-a-z]+)/\1/m/{_language=knownz}{{
12+
. \2 knownz.owner:
13+
. :knownz.owner {
14+
. exch length knownz.len:
15+
} if
16+
. :knownz.len {
17+
1 add
18+
. exch knownz.lenplus:
19+
} if
20+
}}

main/field.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,3 +1925,62 @@ static EsObject* setFieldValueForInherits (tagEntryInfo *tag, const fieldDefinit
19251925

19261926
return es_false;
19271927
}
1928+
1929+
extern EsObject* getFieldValueGeneric (const tagEntryInfo *tag, const fieldDefinition *fdef)
1930+
{
1931+
const char *value = getParserFieldValueForType(tag, fdef->ftype);
1932+
1933+
if (value == NULL)
1934+
return es_nil;
1935+
1936+
unsigned int dt = fdef->dataType;
1937+
if (dt & FIELDTYPE_STRING)
1938+
return (dt & FIELDTYPE_BOOL && value[0] == '\0')
1939+
? es_false
1940+
: opt_string_new_from_cstr (value);
1941+
else if (dt & FIELDTYPE_INTEGER)
1942+
{
1943+
long tmp;
1944+
if (strToLong (value, 10, &tmp))
1945+
return es_integer_new ((int)tmp); /* TODO: if tmp is not in the range of int, return es_nil */
1946+
else
1947+
{
1948+
AssertNotReached ();
1949+
return es_nil;
1950+
}
1951+
}
1952+
else if (dt & FIELDTYPE_BOOL)
1953+
return value [0]? es_true: es_false;
1954+
else
1955+
{
1956+
AssertNotReached ();
1957+
return es_nil;
1958+
}
1959+
}
1960+
1961+
extern EsObject* setFieldValueGeneric (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *obj)
1962+
{
1963+
unsigned int dt = fdef->dataType;
1964+
const char * val;
1965+
char buf[1 /* [+-] */ + 20 + 1 /* for \0 */];
1966+
1967+
if (dt & FIELDTYPE_STRING)
1968+
val = opt_string_get_cstr (obj);
1969+
else if (dt & FIELDTYPE_INTEGER)
1970+
{
1971+
int tmp = es_integer_get (obj);
1972+
/* 2^64 => "18446744073709551616" */
1973+
snprintf(buf, 22, "%d", tmp);
1974+
val = buf;
1975+
}
1976+
else if (dt & FIELDTYPE_BOOL)
1977+
val = es_boolean_get (obj)? "t": "";
1978+
else
1979+
{
1980+
val = "";
1981+
AssertNotReached ();
1982+
}
1983+
1984+
attachParserField (tag, fdef->ftype, val);
1985+
return es_false;
1986+
}

main/field.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@ typedef enum eFieldDataType {
7777

7878
/* used in --list-fields */
7979
FIELDTYPE_END_MARKER = 1 << 3,
80+
81+
/* If you want to allow a parser code written in optscript
82+
* to access the field, append FIELDTYPE_SCRIPTABLE to
83+
* dataType field of your fieldDefinition.
84+
*
85+
* From a optlib parser, pass {datatype=TYPE} flag to
86+
* --_fielddef-<LANV>=... option. Just specifying a
87+
* type is enough; FIELDTYPE_SCRIPTABLE is automatically
88+
* append the filed definition. If you don't pass the
89+
* flag explicitly, FIELDTYPE_SCRIPTABLE is not set. */
90+
FIELDTYPE_SCRIPTABLE = FIELDTYPE_END_MARKER,
8091
} fieldDataType;
8192

8293
typedef const char* (*fieldRenderer)(const tagEntryInfo *const,
@@ -119,4 +130,7 @@ struct sFieldDefinition {
119130

120131
extern bool isFieldEnabled (fieldType type);
121132

133+
extern struct _EsObject* getFieldValueGeneric (const tagEntryInfo *tag, const fieldDefinition *fdef);
134+
extern struct _EsObject* setFieldValueGeneric (tagEntryInfo *tag, const fieldDefinition *fdef, const struct _EsObject *obj);
135+
122136
#endif /* CTAGS_MAIN_FIELD_H */

main/parse.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4018,20 +4018,20 @@ static void field_def_flag_datatype_long (const char *const optflag CTAGS_ATTR_U
40184018

40194019
if (strncmp (p, "integer", q - p) == 0
40204020
|| strncmp (p, "int", q - p) == 0)
4021-
fdef->dataType |= FIELDTYPE_INTEGER;
4021+
fdef->dataType |= (FIELDTYPE_INTEGER|FIELDTYPE_SCRIPTABLE);
40224022
else if (strncmp (p, "string", q - p) == 0
40234023
|| strncmp (p, "str", q - p) == 0)
4024-
fdef->dataType |= FIELDTYPE_STRING;
4024+
fdef->dataType |= (FIELDTYPE_STRING|FIELDTYPE_SCRIPTABLE);
40254025
else if (strncmp (p, "boolean", q - p) == 0
40264026
|| strncmp (p, "bool", q - p) == 0)
4027-
fdef->dataType |= FIELDTYPE_BOOL;
4027+
fdef->dataType |= (FIELDTYPE_BOOL|FIELDTYPE_SCRIPTABLE);
40284028
p = q;
40294029
}
40304030
}
40314031

40324032
static flagDefinition FieldDefFlagDef [] = {
40334033
{ '\0', "datatype", NULL, field_def_flag_datatype_long,
4034-
"TYPE", "acceaptable datatype of the field ([str]|bool|int)" },
4034+
"TYPE", "acceaptable datatype of the field (str|bool|int)" },
40354035
};
40364036

40374037
static bool processLangDefineField (const langType language,
@@ -4070,21 +4070,27 @@ static bool processLangDefineField (const langType language,
40704070
desc = extractDescriptionAndFlags (p, &flags);
40714071

40724072
fdef = xCalloc (1, fieldDefinition);
4073+
4074+
fdef->dataType = 0;
4075+
if (flags)
4076+
flagsEval (flags, FieldDefFlagDef, ARRAY_SIZE (FieldDefFlagDef), fdef);
4077+
if (!fdef->dataType)
4078+
fdef->dataType = FIELDTYPE_STRING;
4079+
40734080
fdef->enabled = false;
40744081
fdef->letter = NUL_FIELD_LETTER;
40754082
fdef->name = eStrndup(parameter, name_end - parameter);
40764083
fdef->description = desc;
40774084
fdef->isValueAvailable = NULL;
4078-
fdef->getValueObject = NULL;
4085+
fdef->getValueObject = (fdef->dataType & FIELDTYPE_SCRIPTABLE)
4086+
? getFieldValueGeneric
4087+
: NULL;
40794088
fdef->getterValueType = NULL;
4080-
fdef->setValueObject = NULL;
4089+
fdef->setValueObject = (fdef->dataType & FIELDTYPE_SCRIPTABLE)
4090+
? setFieldValueGeneric
4091+
: NULL;
40814092
fdef->setterValueType = NULL;
40824093
fdef->checkValueForSetter = NULL;
4083-
fdef->dataType = 0;
4084-
if (flags)
4085-
flagsEval (flags, FieldDefFlagDef, sizeof (FieldDefFlagDef), fdef);
4086-
if (!fdef->dataType)
4087-
fdef->dataType = FIELDTYPE_STRING;
40884094
fdef->ftype = FIELD_UNKNOWN;
40894095
DEFAULT_TRASH_BOX(fdef, fieldDefinitionDestroy);
40904096

misc/optlib2c

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,32 @@ my $langdef_flags =
5858
} ],
5959
];
6060

61+
my $fielddef_flags =
62+
[
63+
[ qr/\{datatype=([^\}]+)\}/, sub {
64+
my $datatype = "FIELDTYPE_SCRIPTABLE|";
65+
66+
if (($1 eq 'str') || ($1 eq 'string'))
67+
{
68+
$datatype .= "FIELDTYPE_STRING";
69+
}
70+
elsif (($1 eq 'int') || ($1 eq 'integer'))
71+
{
72+
$datatype .= "FIELDTYPE_INTEGER";
73+
}
74+
elsif (($1 eq 'bool') || ($1 eq 'boolean'))
75+
{
76+
$datatype .= "FIELDTYPE_BOOL";
77+
}
78+
else
79+
{
80+
die "Unknown datatype specification: \"{datatype=$1}\" in \"--_fielddef-<LANG>=...\"";
81+
}
82+
83+
$_[0]->{'datatype'} = $datatype;
84+
} ],
85+
];
86+
6187
my $options =
6288
[
6389
[ qr/^--options=(.*)/, sub {
@@ -88,7 +114,7 @@ my $options =
88114
$_[0]->{'versionCurrent'} = 0;
89115
$_[0]->{'versionAge'} = 0;
90116
$_[0]->{'foreignLanguages'} = [];
91-
parse_flags ($rest, $_[0], $langdef_flags,);
117+
parse_flags ($rest, $_[0], $langdef_flags);
92118

93119
return 1;
94120
} ],
@@ -135,18 +161,22 @@ my $options =
135161
push @{$_[0]->{'extradefs'}}, { name => $name, desc => $desc };
136162
return 1;
137163
} ],
138-
[ qr/^--_fielddef-(.*)=([^,]+),([^\{]+)/, sub {
164+
[ qr/^--_fielddef-(.*)=([^,]+),([^\{]+)(.*)/, sub {
139165
die "Don't use --_fielddef-<LANG>=+ option before defining the language"
140166
if (! defined $_[0]->{'langdef'});
141167
die "Adding a field is allowed only to the language specified with --langdef: $1"
142168
unless ($_[0]->{'langdef'} eq $1);
143169

144170
my $name = $2;
145171
my $desc = $3;
172+
my $rest = $4;
146173
die "unacceptable character is used for field name: $name"
147174
unless ($name =~ /^[a-zA-Z]+$/);
148175

149-
push @{$_[0]->{'fielddefs'}}, { name => $name, desc => $desc };
176+
my $fdef = { name => $name, desc => $desc };
177+
push @{$_[0]->{'fielddefs'}}, $fdef;
178+
parse_flags ($rest, $fdef, $fielddef_flags);
179+
150180
return 1;
151181
} ],
152182
[ qr/^--_roledef-([^.]*)\.(?:([a-zA-Z])|\{([a-zA-Z][a-zA-Z0-9]*)\})=([a-zA-Z0-9]+),([^\{]+)/, sub {
@@ -1062,6 +1092,15 @@ EOF
10621092
.enabled = $enabled,
10631093
.name = "$_->{'name'}",
10641094
.description = "$desc",
1095+
EOF
1096+
if (defined $_->{'datatype'}) {
1097+
print <<EOF;
1098+
.dataType = $_->{'datatype'},
1099+
.getValueObject = getFieldValueGeneric,
1100+
.setValueObject = setFieldValueGeneric,
1101+
EOF
1102+
}
1103+
print <<EOF;
10651104
},
10661105
EOF
10671106
}

0 commit comments

Comments
 (0)