diff --git a/Tmain/json-output-boolean-fields.d/stdout-expected.txt b/Tmain/json-output-boolean-fields.d/stdout-expected.txt deleted file mode 100644 index 125a7f6e88..0000000000 --- a/Tmain/json-output-boolean-fields.d/stdout-expected.txt +++ /dev/null @@ -1,4 +0,0 @@ -{"_type": "tag", "name": "atag", "path": "input.ctst", "pattern": "/^f$/", "kind": "fieldMaker", "bField": true} -{"_type": "tag", "name": "btag", "path": "input.ctst", "pattern": "/^f$/", "kind": "fieldMaker"} -{"_type": "tag", "name": "ctag", "path": "input.ctst", "pattern": "/^f$/", "kind": "fieldMaker", "sbField": "val"} -{"_type": "tag", "name": "dtag", "path": "input.ctst", "pattern": "/^f$/", "kind": "fieldMaker", "sbField": false} diff --git a/Tmain/json-ptag-in-list-extras.d/run.sh b/Tmain/json-output-ptag-in-list-extras.d/run.sh similarity index 100% rename from Tmain/json-ptag-in-list-extras.d/run.sh rename to Tmain/json-output-ptag-in-list-extras.d/run.sh diff --git a/Tmain/json-output-boolean-fields.d/stderr-expected.txt b/Tmain/json-output-ptag-in-list-extras.d/stderr-expected.txt similarity index 100% rename from Tmain/json-output-boolean-fields.d/stderr-expected.txt rename to Tmain/json-output-ptag-in-list-extras.d/stderr-expected.txt diff --git a/Tmain/json-ptag-in-list-extras.d/stdout-expected.txt b/Tmain/json-output-ptag-in-list-extras.d/stdout-expected.txt similarity index 100% rename from Tmain/json-ptag-in-list-extras.d/stdout-expected.txt rename to Tmain/json-output-ptag-in-list-extras.d/stdout-expected.txt diff --git a/Tmain/json-output-typed-fields.d/input.c b/Tmain/json-output-typed-fields.d/input.c new file mode 100644 index 0000000000..e96b6c32cf --- /dev/null +++ b/Tmain/json-output-typed-fields.d/input.c @@ -0,0 +1,2 @@ +static int local; +int global; diff --git a/Tmain/json-output-boolean-fields.d/input.ctst b/Tmain/json-output-typed-fields.d/input.ctst similarity index 100% rename from Tmain/json-output-boolean-fields.d/input.ctst rename to Tmain/json-output-typed-fields.d/input.ctst diff --git a/Tmain/json-output-typed-fields.d/input.rst b/Tmain/json-output-typed-fields.d/input.rst new file mode 100644 index 0000000000..83cf2bcd37 --- /dev/null +++ b/Tmain/json-output-typed-fields.d/input.rst @@ -0,0 +1,6 @@ +============================================== +TITLE +============================================== + +section +------- diff --git a/Tmain/json-output-boolean-fields.d/run.sh b/Tmain/json-output-typed-fields.d/run.sh similarity index 54% rename from Tmain/json-output-boolean-fields.d/run.sh rename to Tmain/json-output-typed-fields.d/run.sh index 62ee354fd6..e3720a9b40 100644 --- a/Tmain/json-output-boolean-fields.d/run.sh +++ b/Tmain/json-output-typed-fields.d/run.sh @@ -10,4 +10,10 @@ if is_feature_available "${CTAGS}" json; then ${CTAGS} --quiet --options=NONE -o - \ --output-format=json \ --language-force=CTagsSelfTest input.ctst + ${CTAGS} --quiet --options=NONE -o - \ + --output-format=json \ + --fields-RestructuredText=+'{overline}' input.rst + ${CTAGS} --quiet --options=NONE -o - \ + --output-format=json \ + input.c fi diff --git a/Tmain/json-ptag-in-list-extras.d/stderr-expected.txt b/Tmain/json-output-typed-fields.d/stderr-expected.txt similarity index 100% rename from Tmain/json-ptag-in-list-extras.d/stderr-expected.txt rename to Tmain/json-output-typed-fields.d/stderr-expected.txt diff --git a/Tmain/json-output-typed-fields.d/stdout-expected.txt b/Tmain/json-output-typed-fields.d/stdout-expected.txt new file mode 100644 index 0000000000..4d27befc89 --- /dev/null +++ b/Tmain/json-output-typed-fields.d/stdout-expected.txt @@ -0,0 +1,11 @@ +{"_type": "tag", "name": "atag", "path": "input.ctst", "pattern": "/^f$/", "kind": "fieldMaker"} +{"_type": "tag", "name": "btag", "path": "input.ctst", "pattern": "/^f$/", "kind": "fieldMaker", "bField": true} +{"_type": "tag", "name": "ctag", "path": "input.ctst", "pattern": "/^f$/", "kind": "fieldMaker", "bField": true} +{"_type": "tag", "name": "dtag", "path": "input.ctst", "pattern": "/^f$/", "kind": "fieldMaker", "sbField": "val"} +{"_type": "tag", "name": "etag", "path": "input.ctst", "pattern": "/^f$/", "kind": "fieldMaker", "sbField": false} +{"_type": "tag", "name": "ftag", "path": "input.ctst", "pattern": "/^f$/", "kind": "fieldMaker", "sField": "val"} +{"_type": "tag", "name": "gtag", "path": "input.ctst", "pattern": "/^f$/", "kind": "fieldMaker", "sField": ""} +{"_type": "tag", "name": "TITLE", "path": "input.rst", "pattern": "/^TITLE$/", "kind": "title", "overline": true} +{"_type": "tag", "name": "section", "path": "input.rst", "pattern": "/^section$/", "kind": "subtitle", "scope": "TITLE", "scopeKind": "title"} +{"_type": "tag", "name": "global", "path": "input.c", "pattern": "/^int global;$/", "typeref": "typename:int", "kind": "variable"} +{"_type": "tag", "name": "local", "path": "input.c", "pattern": "/^static int local;$/", "file": true, "typeref": "typename:int", "kind": "variable"} diff --git a/Tmain/json-limit-recursion.d/exit-expected.txt b/Tmain/json-parser-limit-recursion.d/exit-expected.txt similarity index 100% rename from Tmain/json-limit-recursion.d/exit-expected.txt rename to Tmain/json-parser-limit-recursion.d/exit-expected.txt diff --git a/Tmain/json-limit-recursion.d/input512-one.json b/Tmain/json-parser-limit-recursion.d/input512-one.json similarity index 100% rename from Tmain/json-limit-recursion.d/input512-one.json rename to Tmain/json-parser-limit-recursion.d/input512-one.json diff --git a/Tmain/json-limit-recursion.d/input512-two.json b/Tmain/json-parser-limit-recursion.d/input512-two.json similarity index 100% rename from Tmain/json-limit-recursion.d/input512-two.json rename to Tmain/json-parser-limit-recursion.d/input512-two.json diff --git a/Tmain/json-limit-recursion.d/input513-one.json b/Tmain/json-parser-limit-recursion.d/input513-one.json similarity index 100% rename from Tmain/json-limit-recursion.d/input513-one.json rename to Tmain/json-parser-limit-recursion.d/input513-one.json diff --git a/Tmain/json-limit-recursion.d/input513-two.json b/Tmain/json-parser-limit-recursion.d/input513-two.json similarity index 100% rename from Tmain/json-limit-recursion.d/input513-two.json rename to Tmain/json-parser-limit-recursion.d/input513-two.json diff --git a/Tmain/json-limit-recursion.d/run.sh b/Tmain/json-parser-limit-recursion.d/run.sh similarity index 100% rename from Tmain/json-limit-recursion.d/run.sh rename to Tmain/json-parser-limit-recursion.d/run.sh diff --git a/Tmain/json-limit-recursion.d/stderr-expected.txt b/Tmain/json-parser-limit-recursion.d/stderr-expected.txt similarity index 100% rename from Tmain/json-limit-recursion.d/stderr-expected.txt rename to Tmain/json-parser-limit-recursion.d/stderr-expected.txt diff --git a/Tmain/json-limit-recursion.d/stdout-expected.txt b/Tmain/json-parser-limit-recursion.d/stdout-expected.txt similarity index 100% rename from Tmain/json-limit-recursion.d/stdout-expected.txt rename to Tmain/json-parser-limit-recursion.d/stdout-expected.txt diff --git a/Tmain/tags-output-boolean-fields.d/run.sh b/Tmain/tags-output-boolean-fields.d/run.sh deleted file mode 100644 index 4da07139c0..0000000000 --- a/Tmain/tags-output-boolean-fields.d/run.sh +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright: 2016 Masatake YAMATO -# License: GPL-2 - -CTAGS=$1 - -${CTAGS} --quiet --options=NONE -o - \ - --output-format=u-ctags \ - --language-force=CTagsSelfTest input.ctst diff --git a/Tmain/tags-output-boolean-fields.d/stdout-expected.txt b/Tmain/tags-output-boolean-fields.d/stdout-expected.txt deleted file mode 100644 index 097c66769a..0000000000 --- a/Tmain/tags-output-boolean-fields.d/stdout-expected.txt +++ /dev/null @@ -1,4 +0,0 @@ -atag input.ctst /^f$/;" f bField: -btag input.ctst /^f$/;" f -ctag input.ctst /^f$/;" f sbField:val -dtag input.ctst /^f$/;" f sbField: diff --git a/Tmain/tags-output-typed-fields.d/input.c b/Tmain/tags-output-typed-fields.d/input.c new file mode 100644 index 0000000000..e96b6c32cf --- /dev/null +++ b/Tmain/tags-output-typed-fields.d/input.c @@ -0,0 +1,2 @@ +static int local; +int global; diff --git a/Tmain/tags-output-boolean-fields.d/input.ctst b/Tmain/tags-output-typed-fields.d/input.ctst similarity index 100% rename from Tmain/tags-output-boolean-fields.d/input.ctst rename to Tmain/tags-output-typed-fields.d/input.ctst diff --git a/Tmain/tags-output-typed-fields.d/input.rst b/Tmain/tags-output-typed-fields.d/input.rst new file mode 100644 index 0000000000..83cf2bcd37 --- /dev/null +++ b/Tmain/tags-output-typed-fields.d/input.rst @@ -0,0 +1,6 @@ +============================================== +TITLE +============================================== + +section +------- diff --git a/Tmain/tags-output-typed-fields.d/run.sh b/Tmain/tags-output-typed-fields.d/run.sh new file mode 100644 index 0000000000..4e28182cc7 --- /dev/null +++ b/Tmain/tags-output-typed-fields.d/run.sh @@ -0,0 +1,17 @@ +# Copyright: 2016 Masatake YAMATO +# License: GPL-2 + +CTAGS=$1 + +${CTAGS} --quiet --options=NONE -o - \ + --output-format=u-ctags \ + --language-force=CTagsSelfTest input.ctst + +${CTAGS} --quiet --options=NONE -o - \ + --output-format=u-ctags \ + --fields-RestructuredText=+'{overline}' \ + input.rst + +${CTAGS} --quiet --options=NONE -o - \ + --output-format=u-ctags \ + input.c diff --git a/Tmain/tags-output-boolean-fields.d/stderr-expected.txt b/Tmain/tags-output-typed-fields.d/stderr-expected.txt similarity index 100% rename from Tmain/tags-output-boolean-fields.d/stderr-expected.txt rename to Tmain/tags-output-typed-fields.d/stderr-expected.txt diff --git a/Tmain/tags-output-typed-fields.d/stdout-expected.txt b/Tmain/tags-output-typed-fields.d/stdout-expected.txt new file mode 100644 index 0000000000..dd8fde3706 --- /dev/null +++ b/Tmain/tags-output-typed-fields.d/stdout-expected.txt @@ -0,0 +1,11 @@ +atag input.ctst /^f$/;" f +btag input.ctst /^f$/;" f bField: +ctag input.ctst /^f$/;" f bField: +dtag input.ctst /^f$/;" f sbField:val +etag input.ctst /^f$/;" f sbField: +ftag input.ctst /^f$/;" f sField:val +gtag input.ctst /^f$/;" f sField: +TITLE input.rst /^TITLE$/;" H overline: +section input.rst /^section$/;" h title:TITLE +global input.c /^int global;$/;" v typeref:typename:int +local input.c /^static int local;$/;" v typeref:typename:int file: diff --git a/Tmain/xformat-boolean-fields.d/run.sh b/Tmain/xformat-boolean-fields.d/run.sh deleted file mode 100644 index 6040012198..0000000000 --- a/Tmain/xformat-boolean-fields.d/run.sh +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright: 2016 Masatake YAMATO -# License: GPL-2 - -CTAGS=$1 - -${CTAGS} --quiet --options=NONE -o - \ - --output-format=xref --_xformat='%{name} -> b=%{CTagsSelfTest.bField},sb=%{CTagsSelfTest.sbField}' \ - --language-force=CTagsSelfTest input.ctst diff --git a/Tmain/xformat-boolean-fields.d/stdout-expected.txt b/Tmain/xformat-boolean-fields.d/stdout-expected.txt deleted file mode 100644 index 209cf8aaea..0000000000 --- a/Tmain/xformat-boolean-fields.d/stdout-expected.txt +++ /dev/null @@ -1,4 +0,0 @@ -atag -> b=bField,sb= -btag -> b=,sb= -ctag -> b=,sb=val -dtag -> b=,sb=- diff --git a/Tmain/xformat-common-fields.d/input.py b/Tmain/xref-output-common-fields.d/input.py similarity index 100% rename from Tmain/xformat-common-fields.d/input.py rename to Tmain/xref-output-common-fields.d/input.py diff --git a/Tmain/xformat-common-fields.d/run.sh b/Tmain/xref-output-common-fields.d/run.sh similarity index 100% rename from Tmain/xformat-common-fields.d/run.sh rename to Tmain/xref-output-common-fields.d/run.sh diff --git a/Tmain/xformat-common-fields.d/stdout-expected.txt b/Tmain/xref-output-common-fields.d/stdout-expected.txt similarity index 100% rename from Tmain/xformat-common-fields.d/stdout-expected.txt rename to Tmain/xref-output-common-fields.d/stdout-expected.txt diff --git a/Tmain/xformat-and-parser-own-field.d/input.rst b/Tmain/xref-output-formatting-parser-own-field.d/input.rst similarity index 100% rename from Tmain/xformat-and-parser-own-field.d/input.rst rename to Tmain/xref-output-formatting-parser-own-field.d/input.rst diff --git a/Tmain/xformat-and-parser-own-field.d/run.sh b/Tmain/xref-output-formatting-parser-own-field.d/run.sh similarity index 100% rename from Tmain/xformat-and-parser-own-field.d/run.sh rename to Tmain/xref-output-formatting-parser-own-field.d/run.sh diff --git a/Tmain/xformat-and-parser-own-field.d/stderr-expected.txt b/Tmain/xref-output-formatting-parser-own-field.d/stderr-expected.txt similarity index 100% rename from Tmain/xformat-and-parser-own-field.d/stderr-expected.txt rename to Tmain/xref-output-formatting-parser-own-field.d/stderr-expected.txt diff --git a/Tmain/xformat-and-parser-own-field.d/stdout-expected.txt b/Tmain/xref-output-formatting-parser-own-field.d/stdout-expected.txt similarity index 100% rename from Tmain/xformat-and-parser-own-field.d/stdout-expected.txt rename to Tmain/xref-output-formatting-parser-own-field.d/stdout-expected.txt diff --git a/Tmain/xref-ptag-in-list-extras.d/run.sh b/Tmain/xref-output-ptag-in-list-extras.d/run.sh similarity index 100% rename from Tmain/xref-ptag-in-list-extras.d/run.sh rename to Tmain/xref-output-ptag-in-list-extras.d/run.sh diff --git a/Tmain/xref-ptag-in-list-extras.d/stdout-expected.txt b/Tmain/xref-output-ptag-in-list-extras.d/stdout-expected.txt similarity index 100% rename from Tmain/xref-ptag-in-list-extras.d/stdout-expected.txt rename to Tmain/xref-output-ptag-in-list-extras.d/stdout-expected.txt diff --git a/Tmain/xref-output-typed-fields.d/input.c b/Tmain/xref-output-typed-fields.d/input.c new file mode 100644 index 0000000000..e96b6c32cf --- /dev/null +++ b/Tmain/xref-output-typed-fields.d/input.c @@ -0,0 +1,2 @@ +static int local; +int global; diff --git a/Tmain/xformat-boolean-fields.d/input.ctst b/Tmain/xref-output-typed-fields.d/input.ctst similarity index 100% rename from Tmain/xformat-boolean-fields.d/input.ctst rename to Tmain/xref-output-typed-fields.d/input.ctst diff --git a/Tmain/xref-output-typed-fields.d/input.rst b/Tmain/xref-output-typed-fields.d/input.rst new file mode 100644 index 0000000000..e48fcea40c --- /dev/null +++ b/Tmain/xref-output-typed-fields.d/input.rst @@ -0,0 +1,6 @@ +============================================== +TITLE +============================================== + +section +....... diff --git a/Tmain/xref-output-typed-fields.d/run.sh b/Tmain/xref-output-typed-fields.d/run.sh new file mode 100644 index 0000000000..a10553347f --- /dev/null +++ b/Tmain/xref-output-typed-fields.d/run.sh @@ -0,0 +1,19 @@ +# Copyright: 2016 Masatake YAMATO +# License: GPL-2 + +CTAGS=$1 + +echo '# input.ctst' +${CTAGS} --quiet --options=NONE -o - \ + --output-format=xref --_xformat='%{name} -> b=%{CTagsSelfTest.bField},sb=%{CTagsSelfTest.sbField},s=%{CTagsSelfTest.sField}' \ + --language-force=CTagsSelfTest input.ctst + +echo '# input.rst' +${CTAGS} --quiet --options=NONE -o - \ + --output-format=xref --_xformat='%{name} -> %{RestructuredText.overline}' \ + input.rst + +echo '# input.c' +${CTAGS} --quiet --options=NONE -o - \ + --output-format=xref --_xformat='%{name} -> %{file}' \ + input.c diff --git a/Tmain/xformat-boolean-fields.d/stderr-expected.txt b/Tmain/xref-output-typed-fields.d/stderr-expected.txt similarity index 100% rename from Tmain/xformat-boolean-fields.d/stderr-expected.txt rename to Tmain/xref-output-typed-fields.d/stderr-expected.txt diff --git a/Tmain/xref-output-typed-fields.d/stdout-expected.txt b/Tmain/xref-output-typed-fields.d/stdout-expected.txt new file mode 100644 index 0000000000..e059c8bd5b --- /dev/null +++ b/Tmain/xref-output-typed-fields.d/stdout-expected.txt @@ -0,0 +1,14 @@ +# input.ctst +atag -> b=-,sb=,s= +btag -> b=bField,sb=,s= +ctag -> b=bField,sb=,s= +dtag -> b=-,sb=val,s= +etag -> b=-,sb=-,s= +ftag -> b=-,sb=,s=val +gtag -> b=-,sb=,s= +# input.rst +TITLE -> overline +section -> - +# input.c +global -> - +local -> file diff --git a/main/entry.h b/main/entry.h index ff3b9581f0..2cd09af3a1 100644 --- a/main/entry.h +++ b/main/entry.h @@ -341,23 +341,15 @@ extern void resetTagCorkState (tagEntryInfo *const tag, * * Interpretation of VALUE * ----------------------- - * For FIELDTYPE_STRING: - * Both json writer and xref writer print it as-is. - * - * For FIELDTYPE_STRING|FIELDTYPE_BOOL: - * If VALUE points "" (empty C string), the json writer prints it as - * false, and the xref writer prints it as -. - * If VALUE points a non-empty C string, Both json writer and xref - * writers print it as-is. - * - * For FIELDTYPE_BOOL - * The json writer always prints true. - * The xref writer always prints the name of field. - * Set "" explicitly though the value pointed by VALUE is not referred, - * - * - * The other data type and the combination of types are not implemented yet. + * The VALUE is interpreted very differently depending on the output + * format: ctags, xref, and json. See field.h. * + * WARNING: updating the VALUE + * --------------------------- + * In the current implementation, there is no way to update the value + * for a given field or detach the value from the given field. + * For the same combination of TAG and FTYPE, you can call the + * attachParser* function only once. */ extern void attachParserField (tagEntryInfo *const tag, fieldType ftype, const char* value); extern void attachParserFieldToCorkEntry (int index, fieldType ftype, const char* value); diff --git a/main/field.c b/main/field.c index 52dd28594c..c0e220a6ff 100644 --- a/main/field.c +++ b/main/field.c @@ -75,17 +75,17 @@ static bool doesContainAnyCharInInput (const tagEntryInfo *const tag, const char 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 isTyperefFieldAvailable (const tagEntryInfo *const tag); -static bool isFileFieldAvailable (const tagEntryInfo *const tag); -static bool isInheritsFieldAvailable (const tagEntryInfo *const tag); -static bool isAccessFieldAvailable (const tagEntryInfo *const tag); -static bool isImplementationFieldAvailable (const tagEntryInfo *const tag); -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); -static bool isEpochAvailable (const tagEntryInfo *const tag); -static bool isNthAvailable (const tagEntryInfo *const tag); +static bool isTyperefFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef); +static bool isFileFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef); +static bool isInheritsFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef); +static bool isAccessFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef); +static bool isImplementationFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef); +static bool isSignatureFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef); +static bool isExtrasFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef); +static bool isXpathFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef); +static bool isEndFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef); +static bool isEpochAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef); +static bool isNthAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef); static EsObject* getFieldValueForName (const tagEntryInfo *, const fieldDefinition *); static EsObject* setFieldValueForName (tagEntryInfo *, const fieldDefinition *, const EsObject *); @@ -614,7 +614,8 @@ extern unsigned char getFieldLetter (fieldType type) extern bool doesFieldHaveValue (fieldType type, const tagEntryInfo *tag) { if (getFieldObject(type)->def->isValueAvailable) - return getFieldObject(type)->def->isValueAvailable(tag); + return getFieldObject(type)->def->isValueAvailable(tag, + getFieldObject(type)->def); else return true; } @@ -1164,43 +1165,43 @@ static const char *renderFieldNth (const tagEntryInfo *const tag, #undef buf_len } -static bool isTyperefFieldAvailable (const tagEntryInfo *const tag) +static bool isTyperefFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED) { return (tag->extensionFields.typeRef [0] != NULL && tag->extensionFields.typeRef [1] != NULL)? true: false; } -static bool isFileFieldAvailable (const tagEntryInfo *const tag) +static bool isFileFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED) { return tag->isFileScope? true: false; } -static bool isInheritsFieldAvailable (const tagEntryInfo *const tag) +static bool isInheritsFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED) { return (tag->extensionFields.inheritance != NULL)? true: false; } -static bool isAccessFieldAvailable (const tagEntryInfo *const tag) +static bool isAccessFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED) { return (tag->extensionFields.access != NULL)? true: false; } -static bool isImplementationFieldAvailable (const tagEntryInfo *const tag) +static bool isImplementationFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED) { return (tag->extensionFields.implementation != NULL)? true: false; } -static bool isSignatureFieldAvailable (const tagEntryInfo *const tag) +static bool isSignatureFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED) { return (tag->extensionFields.signature != NULL)? true: false; } -static bool isExtrasFieldAvailable (const tagEntryInfo *const tag) +static bool isExtrasFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED) { return isTagExtra (tag); } -static bool isXpathFieldAvailable (const tagEntryInfo *const tag) +static bool isXpathFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED) { #ifdef HAVE_LIBXML return (tag->extensionFields.xpath != NULL)? true: false; @@ -1209,19 +1210,19 @@ static bool isXpathFieldAvailable (const tagEntryInfo *const tag) #endif } -static bool isEndFieldAvailable (const tagEntryInfo *const tag) +static bool isEndFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED) { return (tag->extensionFields._endLine != 0)? true: false; } -static bool isEpochAvailable (const tagEntryInfo *const tag) +static bool isEpochAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED) { return (tag->kindIndex == KIND_FILE_INDEX) ? true : false; } -static bool isNthAvailable (const tagEntryInfo *const tag) +static bool isNthAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED) { Assert (tag->langType >= NO_NTH_FIELD); return (tag->extensionFields.nth != NO_NTH_FIELD)? true: false; @@ -1315,6 +1316,11 @@ static const char* defaultRenderer (const tagEntryInfo *const tag CTAGS_ATTR_UNU return renderEscapedString (value, tag, buffer); } +static bool isValueAvailableGeneric (const tagEntryInfo *const e, const fieldDefinition *fdef) +{ + return getParserFieldValueForType(e, fdef->ftype)? true: false; +} + extern int defineField (fieldDefinition *def, langType language) { fieldObject *fobj; @@ -1347,6 +1353,9 @@ extern int defineField (fieldDefinition *def, langType language) if (! def->dataType) def->dataType = FIELDTYPE_STRING; + if (def->isValueAvailable == NULL) + def->isValueAvailable = isValueAvailableGeneric; + fobj->def = def; fobj->buffer = NULL; diff --git a/main/field.h b/main/field.h index 29e721389f..2a233fa4a2 100644 --- a/main/field.h +++ b/main/field.h @@ -78,6 +78,113 @@ typedef enum eFieldDataType { /* used in --list-fields */ FIELDTYPE_END_MARKER = 1 << 3, } fieldDataType; +/* Interpretation of VALUE of field + * + * With attachParserField() declared in entry.h, you can set a C string + * as a VALUE for the specified field. + * + * The VALUE is interpreted very differently depending on the output + * format: ctags, xref, and json. See field.h. + * + * For FIELDTYPE_STRING + * -------------------- + * Consider if you set "str" to the field "foo": + * + * WRITER | OUTPUT + * -------+----------- + * ctags | foo:str + * xref | str + * json | "foo": "str" + * + * Consider if you set "" to the field "foo": + * + * WRITER | OUTPUT + * -------+----------- + * ctags | foo: + * xref | (nothing) + * json | "foo": "" + * + * Consider if you don't set the field "foo": + * + * WRITER | OUTPUT + * -------+----------- + * ctags | (nothing) + * xref | (nothing) + * json | (nothing) + * + * + * For FIELDTYPE_STRING|FIELDTYPE_BOOL + * ----------------------------------- + * If the value points "" (empty C string), the json writer prints it as + * false, and the xref writer prints it as -. + * THEREFORE, in the xref format, there is no way to distinguish the + * output for the value "" and "-". Both are printed as "-". + * If the value points a non-empty C string, Both json writer and xref + * writers print it as-is. + * + * Consider if you set "str" to the field "foo": + * + * WRITER | OUTPUT + * -------+----------- + * ctags | foo:str + * xref | str + * json | "foo": "str" + * + * Consider if you set "" to the field "foo": + * + * WRITER | OUTPUT + * -------+----------- + * ctags | foo: + * xref | - (as specified as FIELD_NULL_LETTER_CHAR/FIELD_NULL_LETTER_STRING) + * json | "foo": false + * + * Consider if you don't set the field "foo": + * + * WRITER | OUTPUT + * -------+----------- + * ctags | (nothing) + * xref | (nothing) + * json | (nothing) + * + * + * For FIELDTYPE_BOOL + * ------------------ + * Either VALUE points "" (empty C string) or a non-epmty C string, + * the json writer always prints true. In the same condition, the xref + * writer always prints the name of field. + * + * If a value is not set, the field is treated as holding false. + * The json writer prints nothing for the field holding false. + * The xref writer prints - for the field holding false. + + * Consider if you set "str" to the field "foo": + * + * WRITER | OUTPUT + * -------+----------- + * ctags | foo: + * xref | foo + * json | "foo": true + * + * Consider if you set "" to the field "foo": + * + * WRITER | OUTPUT + * -------+----------- + * ctags | foo: + * xref | foo + * json | "foo": true + * + * Consider if you don't set the field "foo": + * + * WRITER | OUTPUT + * -------+----------- + * ctags | (nothing) + * xref | - (as specified as FIELD_NULL_LETTER_CHAR/FIELD_NULL_LETTER_STRING) + * json | (nothing) + * + * + * The other data type and the combination of types are not implemented yet. + * + */ typedef const char* (*fieldRenderer)(const tagEntryInfo *const, const char *, @@ -96,7 +203,7 @@ struct sFieldDefinition { fieldRenderer renderNoEscaping; bool (* doesContainAnyChar) (const tagEntryInfo *const, const char*, const char *); - bool (* isValueAvailable) (const tagEntryInfo *const); + bool (* isValueAvailable) (const tagEntryInfo *const, const fieldDefinition *); const char * getterValueType; struct _EsObject * (* getValueObject) (const tagEntryInfo *, const fieldDefinition *); diff --git a/main/fmt.c b/main/fmt.c index b8d3357ed8..0b0a962db2 100644 --- a/main/fmt.c +++ b/main/fmt.c @@ -74,11 +74,20 @@ static int printTagField (fmtSpec* fspec, MIO* fp, const tagEntryInfo * tag) break; } - if (f == NULL || findex == tag->usedParserFields) + if ( /* No parser specific field is attached. */ + f == NULL + /* Any parser specific fields attached to the tag doesn't compatible + * with the spec specified in the format string. */ + || findex == tag->usedParserFields) { - /* The condtion is redundant for suppressing the warning. */ str = ""; + + unsigned int dt = getFieldDataType (ftype); + if ((dt & FIELDTYPE_STRING) == 0 + && (dt & FIELDTYPE_BOOL)) + str = FIELD_NULL_LETTER_STRING; } + else if (isFieldEnabled (f->ftype)) { unsigned int dt = getFieldDataType (f->ftype); diff --git a/main/parse.c b/main/parse.c index 0fa7076253..2bc4cec7e6 100644 --- a/main/parse.c +++ b/main/parse.c @@ -5640,6 +5640,7 @@ static kindDefinition CTST_Kinds[KIND_COUNT] = { typedef enum { F_BOOLEAN_FIELD, F_BOOLEAN_AND_STRING_FIELD, + F_STRING_FIELD, COUNT_FIELD } CTSTField; @@ -5654,6 +5655,11 @@ static fieldDefinition CTSTFields[COUNT_FIELD] = { .dataType = FIELDTYPE_STRING|FIELDTYPE_BOOL, .enabled = true, }, + { .name = "sField", + .description = "field for testing string type", + .dataType = FIELDTYPE_STRING, + .enabled = true, + }, }; static void createCTSTTags (void) @@ -5797,6 +5803,10 @@ static void createCTSTTags (void) char c = 'a'; char name []= {'\0', 't', 'a', 'g', '\0' }; + name [0] = c++; + initTagEntry (&e, name, i); + makeTagEntry (&e); + name [0] = c++; initTagEntry (&e, name, i); attachParserField (&e, @@ -5805,6 +5815,8 @@ static void createCTSTTags (void) name [0] = c++; initTagEntry (&e, name, i); + attachParserField (&e, + CTSTFields[F_BOOLEAN_FIELD].ftype, "any-C-string-is-interpreted-as-true"); makeTagEntry (&e); name [0] = c++; @@ -5819,6 +5831,18 @@ static void createCTSTTags (void) CTSTFields[F_BOOLEAN_AND_STRING_FIELD].ftype, ""); makeTagEntry (&e); + name [0] = c++; + initTagEntry (&e, name, i); + attachParserField (&e, + CTSTFields[F_STRING_FIELD].ftype, "val"); + makeTagEntry (&e); + + name [0] = c++; + initTagEntry (&e, name, i); + attachParserField (&e, + CTSTFields[F_STRING_FIELD].ftype, ""); + makeTagEntry (&e); + break; } case K_TRIGGER_NOTICE: diff --git a/main/writer-ctags.c b/main/writer-ctags.c index 6ea99eba25..5d98fd374c 100644 --- a/main/writer-ctags.c +++ b/main/writer-ctags.c @@ -213,9 +213,14 @@ static int addParserFields (tagWriter *writer, MIO * mio, const tagEntryInfo *co if (! isFieldEnabled (ftype)) continue; + unsigned int dt = getFieldDataType (ftype); + const char *val = ((dt & FIELDTYPE_STRING) == 0 + && (dt & FIELDTYPE_BOOL)) + ? "" + : escapeFieldValueFull (writer, tag, ftype, i); + length += mio_printf(mio, "\t%s:%s", - getFieldName (ftype), - escapeFieldValueFull (writer, tag, ftype, i)); + getFieldName (ftype), val); } return length; }