Skip to content

Commit

Permalink
main,json-writer: allow the writer to disable "fixed" fields
Browse files Browse the repository at this point in the history
Close #2065.

The tags format must include name, input, and pattern fields.
When running ctags, disabling them are not allowed. To implement
this rule, "fixed" fields were introduced to field.c.

However, this rule is applicable only to the ctags writer. The
other writer like json-writer doesn't need to follow the rule.

The fixed field is implemented in field.c. Now, it moves to writer-ctags.c.
As the result, json-writer can print the result with disabling
"name", "input", and/or "pattern".

Signed-off-by: Masatake YAMATO <[email protected]>
  • Loading branch information
masatake committed Apr 14, 2019
1 parent f07b0a9 commit 8182f84
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 22 deletions.
1 change: 1 addition & 0 deletions Tmain/fixed-field-handling.d/input.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
void main(void) {}
45 changes: 45 additions & 0 deletions Tmain/fixed-field-handling.d/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Copyright: 2019 Masatake YAMATO
# License: GPL-2

. ../utils.sh

CTAGS="$1"

is_feature_available "${CTAGS}" json

CTAGS="${CTAGS} --quiet --options=NONE"

echo '# writer=default'
${CTAGS} --machinable --list-fields | grep '^[NFP]'

list_fields()
{
local f=$1
shift

echo "# writer=$f $o"
${CTAGS} --output-format=$f --machinable $@ --list-fields | grep '^[NFP]'
}

for f in u-ctags e-ctags etags xref json; do
list_fields $f
done

for f in xref json; do
for o in N F P; do
list_fields $f --fields=-$o
done
done

for o in N F P; do
O="--fields=-$o"
echo "# writer=json $O"
${CTAGS} --output-format=json $O input.c
O="--fields=$o"
echo "# writer=json $O"
${CTAGS} --output-format=json $O input.c
done

O="--fields="
echo "# writer=json $O"
${CTAGS} --output-format=json $O input.c
Empty file.
61 changes: 61 additions & 0 deletions Tmain/fixed-field-handling.d/stdout-expected.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# writer=default
N name yes NONE s-- yes tag name
F input yes NONE s-- yes input file
P pattern yes NONE s-b yes pattern
# writer=u-ctags
N name yes NONE s-- yes tag name
F input yes NONE s-- yes input file
P pattern yes NONE s-b yes pattern
# writer=e-ctags
N name yes NONE s-- yes tag name
F input yes NONE s-- yes input file
P pattern yes NONE s-b yes pattern
# writer=etags
F input yes NONE s-- no input file
N name yes NONE s-- no tag name
P pattern yes NONE s-b no pattern
# writer=xref
F input yes NONE s-- no input file
N name yes NONE s-- no tag name
P pattern yes NONE s-b no pattern
# writer=json
F input yes NONE s-- no input file
N name yes NONE s-- no tag name
P pattern yes NONE s-b no pattern
# writer=xref N
F input yes NONE s-- no input file
N name no NONE s-- no tag name
P pattern yes NONE s-b no pattern
# writer=xref F
F input no NONE s-- no input file
N name yes NONE s-- no tag name
P pattern yes NONE s-b no pattern
# writer=xref P
F input yes NONE s-- no input file
N name yes NONE s-- no tag name
P pattern no NONE s-b no pattern
# writer=json N
F input yes NONE s-- no input file
N name no NONE s-- no tag name
P pattern yes NONE s-b no pattern
# writer=json F
F input no NONE s-- no input file
N name yes NONE s-- no tag name
P pattern yes NONE s-b no pattern
# writer=json P
F input yes NONE s-- no input file
N name yes NONE s-- no tag name
P pattern no NONE s-b no pattern
# writer=json --fields=-N
{"_type": "tag", "path": "input.c", "pattern": "/^void main(void) {}$/", "typeref": "typename:void", "kind": "function"}
# writer=json --fields=N
{"_type": "tag", "name": "main"}
# writer=json --fields=-F
{"_type": "tag", "name": "main", "pattern": "/^void main(void) {}$/", "typeref": "typename:void", "kind": "function"}
# writer=json --fields=F
{"_type": "tag", "path": "input.c"}
# writer=json --fields=-P
{"_type": "tag", "name": "main", "path": "input.c", "typeref": "typename:void", "kind": "function"}
# writer=json --fields=P
{"_type": "tag", "pattern": "/^void main(void) {}$/"}
# writer=json --fields=
15 changes: 3 additions & 12 deletions main/field.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@
#include "read.h"
#include "routines.h"
#include "trashbox.h"
#include "writer_p.h"
#include "xtag_p.h"


typedef struct sFieldObject {
fieldDefinition *def;
unsigned int fixed: 1; /* fields which cannot be disabled. */
vString *buffer;
const char* nameWithPrefix;
langType language;
Expand Down Expand Up @@ -252,7 +252,6 @@ extern void initFieldObjects (void)
{
fobj = fieldObjects + i + fieldObjectUsed;
fobj->def = fieldDefinitionsFixed + i;
fobj->fixed = 1;
fobj->buffer = NULL;
fobj->nameWithPrefix = fobj->def->name;
fobj->language = LANG_IGNORE;
Expand All @@ -264,7 +263,6 @@ extern void initFieldObjects (void)
{
fobj = fieldObjects + i + fieldObjectUsed;
fobj->def = fieldDefinitionsExuberant +i;
fobj->fixed = 0;
fobj->buffer = NULL;
fobj->nameWithPrefix = fobj->def->name;
fobj->language = LANG_IGNORE;
Expand All @@ -278,7 +276,6 @@ extern void initFieldObjects (void)

fobj = fieldObjects + i + fieldObjectUsed;
fobj->def = fieldDefinitionsUniversal + i;
fobj->fixed = 0;
fobj->buffer = NULL;

if (fobj->def->name)
Expand Down Expand Up @@ -925,16 +922,11 @@ extern bool isFieldEnabled (fieldType type)
return getFieldObject(type)->def->enabled;
}

static bool isFieldFixed (fieldType type)
{
return getFieldObject(type)->fixed? true: false;
}

extern bool enableField (fieldType type, bool state, bool warnIfFixedField)
{
fieldDefinition *def = getFieldObject(type)->def;
bool old = def->enabled;
if (isFieldFixed (type))
if (writerDoesTreatFieldAsFixed (type))
{
if ((!state) && warnIfFixedField)
{
Expand Down Expand Up @@ -1062,7 +1054,6 @@ extern int defineField (fieldDefinition *def, langType language)

fobj->def = def;

fobj->fixed = 0;
fobj->buffer = NULL;

nameWithPrefix = eMalloc (sizeof CTAGS_FIELD_PREFIX + strlen (def->name) + 1);
Expand Down Expand Up @@ -1123,7 +1114,7 @@ static void fieldColprintAddLine (struct colprintTable *table, int i)
typefields[offset] = fieldDataTypeFalgs[offset];
}
colprintLineAppendColumnCString (line, typefields);
colprintLineAppendColumnBool (line, fobj->fixed);
colprintLineAppendColumnBool (line, writerDoesTreatFieldAsFixed (i));
colprintLineAppendColumnCString (line, fdef->description);
}

Expand Down
17 changes: 17 additions & 0 deletions main/writer-ctags.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "general.h" /* must always come first */

#include "entry_p.h"
#include "field.h"
#include "field_p.h"
#include "mio.h"
#include "options_p.h"
Expand All @@ -29,6 +30,7 @@ static int writeCtagsPtagEntry (tagWriter *writer CTAGS_ATTR_UNUSED,
const char *const fileName,
const char *const pattern,
const char *const parserName);
static bool treatFieldAsFixed (int fieldType);

struct rejection {
bool rejectionInThisInput;
Expand All @@ -39,6 +41,7 @@ tagWriter uCtagsWriter = {
.writePtagEntry = writeCtagsPtagEntry,
.preWriteEntry = NULL,
.postWriteEntry = NULL,
.treatFieldAsFixed = treatFieldAsFixed,
.defaultFileName = CTAGS_FILE,
};

Expand All @@ -62,6 +65,7 @@ tagWriter eCtagsWriter = {
.writePtagEntry = writeCtagsPtagEntry,
.preWriteEntry = beginECtagsFile,
.postWriteEntry = endECTagsFile,
.treatFieldAsFixed = treatFieldAsFixed,
.defaultFileName = CTAGS_FILE,
};

Expand Down Expand Up @@ -343,3 +347,16 @@ static int writeCtagsPtagEntry (tagWriter *writer CTAGS_ATTR_UNUSED,
OPT(fileName), OPT(pattern));
#undef OPT
}

static bool treatFieldAsFixed (int fieldType)
{
switch (fieldType)
{
case FIELD_NAME:
case FIELD_INPUT_FILE:
case FIELD_PATTERN:
return true;
default:
return false;
}
}
1 change: 1 addition & 0 deletions main/writer-etags.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ tagWriter etagsWriter = {
.writePtagEntry = NULL,
.preWriteEntry = beginEtagsFile,
.postWriteEntry = endEtagsFile,
.treatFieldAsFixed = NULL,
.defaultFileName = ETAGS_FILE,
};

Expand Down
31 changes: 21 additions & 10 deletions main/writer-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ tagWriter jsonWriter = {
.writePtagEntry = writeJsonPtagEntry,
.preWriteEntry = NULL,
.postWriteEntry = NULL,
.treatFieldAsFixed = NULL,
.defaultFileName = NULL,
};

Expand Down Expand Up @@ -162,25 +163,35 @@ static void addExtensionFields (json_t *response, const tagEntryInfo *const tag)
static int writeJsonEntry (tagWriter *writer CTAGS_ATTR_UNUSED,
MIO * mio, const tagEntryInfo *const tag)
{
json_t *pat = escapeFieldValue(tag, FIELD_PATTERN, true);
json_t *response = json_pack ("{ss ss ss sO}",
"_type", "tag",
"name", tag->name,
"path", tag->sourceFileName,
"pattern", pat);
json_decref (pat);
int length = 0;
json_t *response = json_pack ("{ss}", "_type", "tag");

if (isFieldEnabled (FIELD_NAME))
{
json_t *name = json_string (tag->name);
if (name == NULL)
goto out;
json_object_set_new (response, "name", name);
}
if (isFieldEnabled (FIELD_INPUT_FILE))
json_object_set_new (response, "path", json_string (tag->sourceFileName));
if (isFieldEnabled (FIELD_PATTERN))
{
json_t *pat = escapeFieldValue(tag, FIELD_PATTERN, true);
json_object_set_new (response, "pattern", pat);
}

if (includeExtensionFlags ())
{
addExtensionFields (response, tag);
addParserFields (response, tag);
}

int length = 0;
char *buf = json_dumps (response, JSON_PRESERVE_ORDER);
if (!buf)
/* Print nothing if RESPONSE has only "_type" field. */
if (json_object_size (response) == 1)
goto out;

char *buf = json_dumps (response, JSON_PRESERVE_ORDER);
length = mio_printf (mio, "%s\n", buf);

free (buf);
Expand Down
1 change: 1 addition & 0 deletions main/writer-xref.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ tagWriter xrefWriter = {
.writePtagEntry = NULL,
.preWriteEntry = NULL,
.postWriteEntry = NULL,
.treatFieldAsFixed = NULL,
.defaultFileName = NULL,
};

Expand Down
7 changes: 7 additions & 0 deletions main/writer.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,10 @@ extern bool writerCanPrintPtag (void)
{
return (writer->writePtagEntry)? true: false;
}

extern bool writerDoesTreatFieldAsFixed (int fieldType)
{
if (writer->treatFieldAsFixed)
return writer->treatFieldAsFixed (fieldType);
return false;
}
2 changes: 2 additions & 0 deletions main/writer_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct sTagWriter {
/* Returning TRUE means the output file may be shrunk.
In such case the callee may do truncate output file. */
bool (* postWriteEntry) (tagWriter *writer, MIO * mio, const char* filename);
bool (* treatFieldAsFixed) (int fieldType);
const char *defaultFileName;

/* The value returned from preWriteEntry is stored `private' field.
Expand Down Expand Up @@ -71,5 +72,6 @@ extern bool ptagMakeJsonOutputVersion (ptagDesc *desc, void *data CTAGS_ATTR_UNU
extern bool ptagMakeCtagsOutputMode (ptagDesc *desc, void *data CTAGS_ATTR_UNUSED);

extern bool writerCanPrintPtag (void);
extern bool writerDoesTreatFieldAsFixed (int fieldType);

#endif /* CTAGS_MAIN_WRITER_PRIVATE_H */

0 comments on commit 8182f84

Please sign in to comment.