Skip to content

Commit

Permalink
Merge pull request #1964 from masatake/cleanup-inclusions
Browse files Browse the repository at this point in the history
Defining interface for parsers (part 6 of 6)
  • Loading branch information
masatake authored Jan 6, 2019
2 parents 0b04c12 + c08c70d commit 284610b
Show file tree
Hide file tree
Showing 15 changed files with 328 additions and 260 deletions.
350 changes: 175 additions & 175 deletions main/field.c

Large diffs are not rendered by default.

75 changes: 22 additions & 53 deletions main/field.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@
#ifndef CTAGS_MAIN_FIELD_H
#define CTAGS_MAIN_FIELD_H

/*
* INCLUDE FILES
*/

#include "general.h"
#include "colprint_p.h"
#include "writer_p.h"
#include "types.h"

#include "vstring.h"

/*
* DATA DECLARATIONS
*/

typedef enum eFieldType { /* extension field content control */
FIELD_UNKNOWN = -1,

Expand Down Expand Up @@ -54,12 +60,6 @@ typedef enum eFieldType { /* extension field content control */
FIELD_BUILTIN_LAST = FIELD_END_LINE,
} fieldType ;

typedef const char* (* renderEscaped) (const tagEntryInfo *const tag,
const char *value,
vString * buffer,
bool *rejected);
typedef bool (* isValueAvailable) (const struct sTagEntryInfo *const tag);

#define fieldDataTypeFalgs "sib" /* used in --list-fields */
typedef enum eFieldDataType {
FIELDTYPE_STRING = 1 << 0,
Expand All @@ -70,6 +70,10 @@ typedef enum eFieldDataType {
FIELDTYPE_END_MARKER = 1 << 3,
} fieldDataType;

typedef const char* (*fieldRenderer)(const tagEntryInfo *const,
const char *,
vString *);

#define FIELD_LETTER_NO_USE '\0'
struct sFieldDefinition {
/* letter, and ftype are initialized in the main part,
Expand All @@ -79,58 +83,23 @@ struct sFieldDefinition {
const char* name;
const char* description;
bool enabled;
renderEscaped renderEscaped [WRITER_COUNT];
isValueAvailable isValueAvailable;

fieldRenderer render;
fieldRenderer renderNoEscaping;
bool (*hasWhitespaceChar) (const tagEntryInfo *const, const char*);

bool (* isValueAvailable) (const tagEntryInfo *const);

fieldDataType dataType; /* used in json output */

unsigned int ftype; /* Given from the main part */
};


extern fieldType getFieldTypeForOption (char letter);

/*
`getFieldTypeForName' is for looking for a field not owned by any parser,
`getFieldTypeForNameAndLanguage' can be used for getting all fields having
the same name; specify `LANG_AUTO' as `language' parameter to get the first
field having the name. With the returned fieldType, `nextSiblingField' gets
the next field having the same name. `nextSiblingField' returns `FIELD_UNKNOWN'
at the end of iteration.
Specifying `LANG_IGNORE' has the same effects as `LANG_AUTO'. However,
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);
* FUNCTION PROTOTYPES
*/

extern bool isFieldEnabled (fieldType type);
extern bool enableField (fieldType type, bool state, bool warnIfFixedField);
extern bool isCommonField (fieldType type);
extern int getFieldOwner (fieldType type);
extern const char* getFieldName (fieldType type);
extern unsigned int getFieldDataType (fieldType type);
extern void printFields (int language);

/* Whether the field specified with TYPE has a
method for rendering in the current format. */
extern bool isFieldRenderable (fieldType type);

extern bool doesFieldHaveValue (fieldType type, const tagEntryInfo *tag);
extern const char* renderFieldEscaped (writerType writer, fieldType type, const tagEntryInfo *tag, int index,
bool *rejected);

extern void initFieldObjects (void);
extern int countFields (void);

/* language should be typed to langType.
Use int here to avoid circular dependency */
extern int defineField (fieldDefinition *spec, langType language);
extern fieldType nextSiblingField (fieldType type);

/* --list-fields implementation. LANGUAGE must be initialized. */
extern struct colprintTable * fieldColprintTableNew (void);
extern void fieldColprintAddCommonLines (struct colprintTable *table);
extern void fieldColprintAddLanguageLines (struct colprintTable *table, langType language);
extern void fieldColprintTablePrint (struct colprintTable *table,
bool withListHeader, bool machinable, FILE *fp);

#endif /* CTAGS_MAIN_FIELD_H */
78 changes: 78 additions & 0 deletions main/field_p.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
*
* Copyright (c) 2015, Red Hat, Inc.
* Copyright (c) 2015, Masatake YAMATO
*
* Author: Masatake YAMATO <yamato@redhat.com>
*
* 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 CTAGS_MAIN_FIELD_PRIVATE_H
#define CTAGS_MAIN_FIELD_PRIVATE_H

/*
* INCLUDE FILES
*/
#include "general.h"
#include "colprint_p.h"
#include "field.h"

/*
* DATA DECLARATIONS
*/


/*
* FUNCTION PROTOTYPES
*/

extern fieldType getFieldTypeForOption (char letter);

/*
`getFieldTypeForName' is for looking for a field not owned by any parser,
`getFieldTypeForNameAndLanguage' can be used for getting all fields having
the same name; specify `LANG_AUTO' as `language' parameter to get the first
field having the name. With the returned fieldType, `nextSiblingField' gets
the next field having the same name. `nextSiblingField' returns `FIELD_UNKNOWN'
at the end of iteration.
Specifying `LANG_IGNORE' has the same effects as `LANG_AUTO'. However,
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 isCommonField (fieldType type);
extern int getFieldOwner (fieldType type);
extern const char* getFieldName (fieldType type);
extern unsigned int getFieldDataType (fieldType type);
extern void printFields (int language);

/* Whether the field specified with TYPE has a
method for rendering in the current format. */
extern bool doesFieldHaveRenderer (fieldType type, bool noEscaping);

extern bool doesFieldHaveValue (fieldType type, const tagEntryInfo *tag);

extern const char* renderField (fieldType type, const tagEntryInfo *tag, int index);
extern const char* renderFieldNoEscaping (fieldType type, const tagEntryInfo *tag, int index);
extern bool doesFieldHaveWhitespaceChar (fieldType type, const tagEntryInfo *tag, int index);

extern void initFieldObjects (void);
extern int countFields (void);

/* language should be typed to langType.
Use int here to avoid circular dependency */
extern int defineField (fieldDefinition *spec, langType language);
extern fieldType nextSiblingField (fieldType type);

/* --list-fields implementation. LANGUAGE must be initialized. */
extern struct colprintTable * fieldColprintTableNew (void);
extern void fieldColprintAddCommonLines (struct colprintTable *table);
extern void fieldColprintAddLanguageLines (struct colprintTable *table, langType language);
extern void fieldColprintTablePrint (struct colprintTable *table,
bool withListHeader, bool machinable, FILE *fp);

#endif /* CTAGS_MAIN_FIELD_PRIVATE_H */
10 changes: 4 additions & 6 deletions main/fmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "entry_p.h"
#include "fmt_p.h"
#include "field.h"
#include "field_p.h"
#include "parse.h"
#include "routines.h"
#include <string.h>
Expand Down Expand Up @@ -60,8 +61,7 @@ static int printTagField (fmtSpec* fspec, MIO* fp, const tagEntryInfo * tag)
ftype = fspec->field.ftype;

if (isCommonField (ftype))
/* TODO: Don't use WRITER_XREF directly */
str = renderFieldEscaped (WRITER_XREF, ftype, tag, NO_PARSER_FIELD, NULL);
str = renderField (ftype, tag, NO_PARSER_FIELD);
else
{
unsigned int findex;
Expand All @@ -77,9 +77,7 @@ static int printTagField (fmtSpec* fspec, MIO* fp, const tagEntryInfo * tag)
if (findex == tag->usedParserFields)
str = "";
else if (isFieldEnabled (f->ftype))
/* TODO: Don't use WRITER_XREF directly */
str = renderFieldEscaped (WRITER_XREF, f->ftype,
tag, findex, NULL);
str = renderField (f->ftype, tag, findex);
}

if (str == NULL)
Expand Down Expand Up @@ -192,7 +190,7 @@ static fmtElement** queueTagField (fmtElement **last, long width, bool truncatio
error (FATAL, "No such field letter: %c", field_letter);
}

if (!isFieldRenderable (ftype))
if (!doesFieldHaveRenderer (ftype, false))
{
Assert (field_letter != NUL_FIELD_LETTER);
error (FATAL, "The field cannot be printed in format output: %c", field_letter);
Expand Down
1 change: 1 addition & 0 deletions main/kind.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <stdio.h>
#include <string.h>

#include "colprint_p.h"
#include "ctags.h"
#include "debug.h"
#include "entry.h"
Expand Down
1 change: 1 addition & 0 deletions main/lregex.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "debug.h"
#include "colprint_p.h"
#include "entry_p.h"
#include "field_p.h"
#include "flags_p.h"
#include "htable.h"
#include "kind.h"
Expand Down
2 changes: 1 addition & 1 deletion main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
#include "debug.h"
#include "entry_p.h"
#include "error_p.h"
#include "field.h"
#include "field_p.h"
#include "keyword_p.h"
#include "main_p.h"
#include "options_p.h"
Expand Down
2 changes: 1 addition & 1 deletion main/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

#include "ctags.h"
#include "debug.h"
#include "field.h"
#include "field_p.h"
#include "gvars.h"
#include "keyword_p.h"
#include "main_p.h"
Expand Down
1 change: 1 addition & 0 deletions main/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "ctags.h"
#include "debug.h"
#include "entry_p.h"
#include "field_p.h"
#include "flags_p.h"
#include "htable.h"
#include "keyword.h"
Expand Down
37 changes: 24 additions & 13 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_p.h"
#include "mio.h"
#include "options_p.h"
#include "parse_p.h"
Expand Down Expand Up @@ -70,14 +71,17 @@ tagWriter eCtagsWriter = {

static const char* escapeFieldValue (tagWriter *writer, const tagEntryInfo * tag, fieldType ftype)
{
bool *reject = NULL;

if (writer->private)
{
struct rejection * rej = writer->private;
reject = &rej->rejectedInThisRendering;
if (!rej->rejectedInThisRendering)
rej->rejectedInThisRendering = doesFieldHaveWhitespaceChar (ftype, tag, NO_PARSER_FIELD);
}
return renderFieldEscaped (writer->type, ftype, tag, NO_PARSER_FIELD, reject);

if (writer->type == WRITER_E_CTAGS && doesFieldHaveRenderer(ftype, true))
return renderFieldNoEscaping (ftype, tag, NO_PARSER_FIELD);
else
return renderField (ftype, tag, NO_PARSER_FIELD);
}

static int renderExtensionFieldMaybe (tagWriter *writer, int xftype, const tagEntryInfo *const tag, char sep[2], MIO *mio)
Expand All @@ -99,24 +103,26 @@ static int addParserFields (tagWriter *writer, MIO * mio, const tagEntryInfo *co
{
unsigned int i;
int length = 0;
bool *reject = NULL;

if (writer->private)
{
struct rejection *rej = writer->private;
reject = &rej->rejectedInThisRendering;
}
struct rejection * rej = writer->private;

for (i = 0; i < tag->usedParserFields; i++)
{
const tagField *f = getParserField(tag, i);
if (! isFieldEnabled (f->ftype))
continue;

if (rej && (!rej->rejectedInThisRendering))
rej->rejectedInThisRendering = doesFieldHaveWhitespaceChar (f->ftype, tag, NO_PARSER_FIELD);

const char *v;
if (writer->type == WRITER_E_CTAGS && doesFieldHaveRenderer(f->ftype, true))
v = renderFieldNoEscaping (f->ftype, tag, i);
else
v = renderField (f->ftype, tag, i);

length += mio_printf(mio, "\t%s:%s",
getFieldName (f->ftype),
renderFieldEscaped (writer->type,
f->ftype, tag, i, reject));
v);
}
return length;
}
Expand Down Expand Up @@ -241,6 +247,11 @@ static int writeCtagsEntry (tagWriter *writer,
escapeFieldValue (writer, tag, FIELD_NAME),
escapeFieldValue (writer, tag, FIELD_INPUT_FILE));

/* This is for handling 'common' of 'fortran'. See the
description of --excmd=mixed in ctags.1. In tags output, what
we call "pattern" is instructions for vi.
However, in the other formats, pattern should be pattern as its name. */
if (tag->lineNumberEntry)
length += writeLineNumberEntry (writer, mio, tag);
else
Expand Down
17 changes: 11 additions & 6 deletions main/writer-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "debug.h"
#include "entry_p.h"
#include "field_p.h"
#include "mio.h"
#include "options_p.h"
#include "read.h"
Expand Down Expand Up @@ -51,7 +52,13 @@ tagWriter jsonWriter = {

static json_t* escapeFieldValue (const tagEntryInfo * tag, fieldType ftype, bool returnEmptyStringAsNoValue)
{
const char *str = renderFieldEscaped (jsonWriter.type, ftype, tag, NO_PARSER_FIELD, NULL);
const char *str;

if (doesFieldHaveRenderer (ftype, true))
str = renderFieldNoEscaping (ftype, tag, NO_PARSER_FIELD);
else
str = renderField (ftype, tag, NO_PARSER_FIELD);

if (str)
{
unsigned int dt = getFieldDataType(ftype);
Expand Down Expand Up @@ -90,7 +97,7 @@ static void renderExtensionFieldMaybe (int xftype, const tagEntryInfo *const tag
{
const char *fname = getFieldName (xftype);

if (fname && isFieldRenderable (xftype) && isFieldEnabled (xftype) && doesFieldHaveValue (xftype, tag))
if (fname && doesFieldHaveRenderer (xftype, false) && isFieldEnabled (xftype) && doesFieldHaveValue (xftype, tag))
{
switch (xftype)
{
Expand Down Expand Up @@ -181,10 +188,8 @@ static int writeJsonEntry (tagWriter *writer CTAGS_ATTR_UNUSED,

static void buildJsonFqTagCache (tagWriter *writer, tagEntryInfo *const tag)
{
renderFieldEscaped (writer->type, FIELD_SCOPE_KIND_LONG, tag,
NO_PARSER_FIELD, NULL);
renderFieldEscaped (writer->type, FIELD_SCOPE, tag,
NO_PARSER_FIELD, NULL);
renderField (FIELD_SCOPE_KIND_LONG, tag, NO_PARSER_FIELD);
renderField (FIELD_SCOPE, tag, NO_PARSER_FIELD);
}

static int writeJsonPtagEntry (tagWriter *writer CTAGS_ATTR_UNUSED,
Expand Down
Loading

0 comments on commit 284610b

Please sign in to comment.