Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@ tests/test-fix-unescaping
tests/test-fix-unescaping-input-fields
tests/test-fix-unescaping-input-fields-exuberant
tests/test-fix-unescaping-input-fields-no-mode
tests/test-fix-unescaping-input-fields-backslash
tests/test-fix-unescaping-input-fields-no-filesep
3 changes: 2 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Version ???

- read input fields, values at the second column in a tag file, with
unescaping if !_TAG_OUTPUT_MODE in the tag file is "u-ctags".
unescaping if !_TAG_OUTPUT_MODE is "u-ctags" and
!_TAG_OUTPUT_FILESEP is "slash" in the tag file.

- LT_VERSION ?:?:?

Expand Down
16 changes: 14 additions & 2 deletions readtags.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ struct sTagFile {
/* format of tag file */
unsigned char format;
/* 1 "u-ctags" is set to !_TAG_OUTPUT_MODE pseudo tag
* in the tags file. */
* and "slash" is set to !_TAG_OUTPUT_FILESEP
* pseudo tag in the tags file. */
unsigned char inputUCtagsMode;
/* how is the tag file sorted? */
tagSortType sortMethod;
Expand Down Expand Up @@ -691,6 +692,8 @@ static tagResult readPseudoTags (tagFile *const file, tagFileInfo *const info)
int err = 0;
tagResult result = TagSuccess;
const size_t prefixLength = strlen (PseudoTagPrefix);
int tag_output_mode_u_ctags = 0;
int tag_output_filesep_slash = 0;

info->file.format = 1;
info->file.sort = TAG_UNSORTED;
Expand Down Expand Up @@ -779,7 +782,12 @@ static tagResult readPseudoTags (tagFile *const file, tagFileInfo *const info)
else if (strcmp (key, "TAG_OUTPUT_MODE") == 0)
{
if (strcmp (value, "u-ctags") == 0)
file->inputUCtagsMode = 1;
tag_output_mode_u_ctags = 1;
}
else if (strcmp (key, "TAG_OUTPUT_FILESEP") == 0)
{
if (strcmp (value, "slash") == 0)
tag_output_filesep_slash = 1;
}

info->file.format = file->format;
Expand All @@ -790,6 +798,10 @@ static tagResult readPseudoTags (tagFile *const file, tagFileInfo *const info)
info->program.version = file->program.version;
}
}

if (tag_output_mode_u_ctags && tag_output_filesep_slash)
file->inputUCtagsMode = 1;

if (fsetpos (file->fp, &startOfLine) < 0)
err = errno;

Expand Down
12 changes: 12 additions & 0 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ TESTS = \
test-fix-unescaping-input-fields \
test-fix-unescaping-input-fields-exuberant \
test-fix-unescaping-input-fields-no-mode \
test-fix-unescaping-input-fields-backslash \
test-fix-unescaping-input-fields-no-filesep \
\
$(NULL)

Expand All @@ -33,6 +35,8 @@ check_PROGRAMS = \
test-fix-unescaping-input-fields \
test-fix-unescaping-input-fields-exuberant \
test-fix-unescaping-input-fields-no-mode \
test-fix-unescaping-input-fields-backslash \
test-fix-unescaping-input-fields-no-filesep \
\
$(NULL)

Expand Down Expand Up @@ -108,3 +112,11 @@ EXTRA_DIST += unescaping-input-fields-exuberant.tags
test_fix_unescaping_input_fields_no_mode = test-fix-unescaping-input-fields-no-mode.c
test_fix_unescaping_input_fields_no_mode_DEPENDENCIES = $(DEPS)
EXTRA_DIST += unescaping-input-fields-no-mode.tags

test_fix_unescaping_input_fields_backslash = test-fix-unescaping-input-fields-backslash.c
test_fix_unescaping_input_fields_backslash_DEPENDENCIES = $(DEPS)
EXTRA_DIST += unescaping-input-fields-backslash.tags

test_fix_unescaping_input_fields_no_filesep = test-fix-unescaping-input-fields-no-filesep.c
test_fix_unescaping_input_fields_no_filesep_DEPENDENCIES = $(DEPS)
EXTRA_DIST += unescaping-input-fields-no-filesep.tags
94 changes: 94 additions & 0 deletions tests/test-fix-unescaping-input-fields-backslash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2022, Masatake YAMATO
*
* This source code is released into the public domain.
*
* Testing the fix for handling unescaping
*/

#include "readtags.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "test-fields.h"


#define CHECK3(NAME,FILE,PAT) \
CHECK ((NAME), name); \
CHECK ((FILE), file); \
CHECK ((PAT), address.pattern)

#define NEXT_CHECK3(NAME,FILE,PAT) \
NEXT (); \
CHECK3 (NAME,FILE,PAT)

int
main (void)
{
char *srcdir = getenv ("srcdir");
if (srcdir)
{
if (chdir (srcdir) == -1)
{
perror ("chdir");
return 99;
}
}

tagFile *t;
tagFileInfo info;

const char *tags0 = "./unescaping-input-fields-backslash.tags";
t = tagsOpen (tags0, &info);
if (t == NULL
|| info.status.opened == 0)
{
fprintf (stderr, "unexpected result (t: %p, opened: %d)\n",
t, info.status.opened);
return 1;
}
fprintf (stderr, "ok\n");

tagEntry e;
tagResult r;

r = tagsFirst (t, &e);
if (r != TagSuccess)
{
fprintf (stderr, "error in tagsFirst\n");
return 1;
}

CHECK3 ("tab0", "\\tabc", "/^tab0$/");
NEXT_CHECK3 ("tab1", "a\\tbc", "/^tab1$/");
NEXT_CHECK3 ("tab2", "ab\\tc", "/^tab2$/");
NEXT_CHECK3 ("tab3", "abc\\t", "/^tab3$/");
NEXT_CHECK3 ("tab4", "\\\\abc", "/^tab4$/");
NEXT_CHECK3 ("tab5", "a\\\\bc", "/^tab5$/");
NEXT_CHECK3 ("tab6", "ab\\\\c", "/^tab6$/");
NEXT_CHECK3 ("tab7", "abc\\\\", "/^tab7$/");
NEXT_CHECK3 ("tab8", "\\nabc", "/^tab8$/");
NEXT_CHECK3 ("tab9", "a\\nbc", "/^tab9$/");
NEXT_CHECK3 ("taba", "ab\\nc", "/^taba$/");
NEXT_CHECK3 ("tabb", "abc\\n", "/^tabb$/");
NEXT_CHECK3 ("tabc", "\\n\\\\abc", "/^tabc$/");
NEXT_CHECK3 ("tabd", "\\\\\\nabc", "/^tabd$/");
NEXT_CHECK3 ("tabe", "a\\n\\\\bc", "/^tabe$/");
NEXT_CHECK3 ("tabf", "a\\\\\\nbc", "/^tabf$/");
NEXT_CHECK3 ("tabg", "abc\\n\\\\", "/^tabg$/");
NEXT_CHECK3 ("tabh", "abc\\\\\\n", "/^tabh$/");
NEXT_CHECK3 ("tabi", "\\t\\\\\\n", "/^tabi$/");
NEXT_CHECK3 ("tabj", "ab\\t\\\\\\nc", "/^tabj$/");

r = tagsClose(t);
if (r != TagSuccess)
{
fprintf (stderr, "error in tagsClose\n");
return 1;
}

return 0;
}
94 changes: 94 additions & 0 deletions tests/test-fix-unescaping-input-fields-no-filesep.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2022, Masatake YAMATO
*
* This source code is released into the public domain.
*
* Testing the fix for handling unescaping
*/

#include "readtags.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "test-fields.h"


#define CHECK3(NAME,FILE,PAT) \
CHECK ((NAME), name); \
CHECK ((FILE), file); \
CHECK ((PAT), address.pattern)

#define NEXT_CHECK3(NAME,FILE,PAT) \
NEXT (); \
CHECK3 (NAME,FILE,PAT)

int
main (void)
{
char *srcdir = getenv ("srcdir");
if (srcdir)
{
if (chdir (srcdir) == -1)
{
perror ("chdir");
return 99;
}
}

tagFile *t;
tagFileInfo info;

const char *tags0 = "./unescaping-input-fields-no-filesep.tags";
t = tagsOpen (tags0, &info);
if (t == NULL
|| info.status.opened == 0)
{
fprintf (stderr, "unexpected result (t: %p, opened: %d)\n",
t, info.status.opened);
return 1;
}
fprintf (stderr, "ok\n");

tagEntry e;
tagResult r;

r = tagsFirst (t, &e);
if (r != TagSuccess)
{
fprintf (stderr, "error in tagsFirst\n");
return 1;
}

CHECK3 ("tab0", "\\tabc", "/^tab0$/");
NEXT_CHECK3 ("tab1", "a\\tbc", "/^tab1$/");
NEXT_CHECK3 ("tab2", "ab\\tc", "/^tab2$/");
NEXT_CHECK3 ("tab3", "abc\\t", "/^tab3$/");
NEXT_CHECK3 ("tab4", "\\\\abc", "/^tab4$/");
NEXT_CHECK3 ("tab5", "a\\\\bc", "/^tab5$/");
NEXT_CHECK3 ("tab6", "ab\\\\c", "/^tab6$/");
NEXT_CHECK3 ("tab7", "abc\\\\", "/^tab7$/");
NEXT_CHECK3 ("tab8", "\\nabc", "/^tab8$/");
NEXT_CHECK3 ("tab9", "a\\nbc", "/^tab9$/");
NEXT_CHECK3 ("taba", "ab\\nc", "/^taba$/");
NEXT_CHECK3 ("tabb", "abc\\n", "/^tabb$/");
NEXT_CHECK3 ("tabc", "\\n\\\\abc", "/^tabc$/");
NEXT_CHECK3 ("tabd", "\\\\\\nabc", "/^tabd$/");
NEXT_CHECK3 ("tabe", "a\\n\\\\bc", "/^tabe$/");
NEXT_CHECK3 ("tabf", "a\\\\\\nbc", "/^tabf$/");
NEXT_CHECK3 ("tabg", "abc\\n\\\\", "/^tabg$/");
NEXT_CHECK3 ("tabh", "abc\\\\\\n", "/^tabh$/");
NEXT_CHECK3 ("tabi", "\\t\\\\\\n", "/^tabi$/");
NEXT_CHECK3 ("tabj", "ab\\t\\\\\\nc", "/^tabj$/");

r = tagsClose(t);
if (r != TagSuccess)
{
fprintf (stderr, "error in tagsClose\n");
return 1;
}

return 0;
}
29 changes: 29 additions & 0 deletions tests/unescaping-input-fields-backslash.tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 0 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_OUTPUT_FILESEP backslash /slash or backslash/
!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/
!_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/
!_TAG_PROGRAM_AUTHOR Universal Ctags Team //
!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/
!_TAG_PROGRAM_URL https://ctags.io/ /official site/
!_TAG_PROGRAM_VERSION 0.0.0 /8d952eba/
tab0 \tabc /^tab0$/;" n
tab1 a\tbc /^tab1$/;" n
tab2 ab\tc /^tab2$/;" n
tab3 abc\t /^tab3$/;" n
tab4 \\abc /^tab4$/;" n
tab5 a\\bc /^tab5$/;" n
tab6 ab\\c /^tab6$/;" n
tab7 abc\\ /^tab7$/;" n
tab8 \nabc /^tab8$/;" n
tab9 a\nbc /^tab9$/;" n
taba ab\nc /^taba$/;" n
tabb abc\n /^tabb$/;" n
tabc \n\\abc /^tabc$/;" n
tabd \\\nabc /^tabd$/;" n
tabe a\n\\bc /^tabe$/;" n
tabf a\\\nbc /^tabf$/;" n
tabg abc\n\\ /^tabg$/;" n
tabh abc\\\n /^tabh$/;" n
tabi \t\\\n /^tabi$/;" n
tabj ab\t\\\nc /^tabj$/;" n
28 changes: 28 additions & 0 deletions tests/unescaping-input-fields-no-filesep.tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 0 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/
!_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/
!_TAG_PROGRAM_AUTHOR Universal Ctags Team //
!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/
!_TAG_PROGRAM_URL https://ctags.io/ /official site/
!_TAG_PROGRAM_VERSION 0.0.0 /8d952eba/
tab0 \tabc /^tab0$/;" n
tab1 a\tbc /^tab1$/;" n
tab2 ab\tc /^tab2$/;" n
tab3 abc\t /^tab3$/;" n
tab4 \\abc /^tab4$/;" n
tab5 a\\bc /^tab5$/;" n
tab6 ab\\c /^tab6$/;" n
tab7 abc\\ /^tab7$/;" n
tab8 \nabc /^tab8$/;" n
tab9 a\nbc /^tab9$/;" n
taba ab\nc /^taba$/;" n
tabb abc\n /^tabb$/;" n
tabc \n\\abc /^tabc$/;" n
tabd \\\nabc /^tabd$/;" n
tabe a\n\\bc /^tabe$/;" n
tabf a\\\nbc /^tabf$/;" n
tabg abc\n\\ /^tabg$/;" n
tabh abc\\\n /^tabh$/;" n
tabi \t\\\n /^tabi$/;" n
tabj ab\t\\\nc /^tabj$/;" n