xref: /Universal-ctags/libreadtags/tests/test-fix-unescaping.c (revision aeae4e550ddf73ca6064a841132a1aad8c322ab8)
1 /*
2 *   Copyright (c) 2020, Masatake YAMATO
3 *
4 *   This source code is released into the public domain.
5 *
6 *   Testing the fix for handling unescaping
7 */
8 
9 #include "readtags.h"
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15 
16 #define NEXT()										\
17 	r = tagsNext (t, &e);							\
18 	if (r != TagSuccess)							\
19 	{												\
20 		fprintf (stderr, "error in tagsNext\n");	\
21 		return 1;									\
22 	}												\
23 	do {} while (0)
24 
25 #define CHECK(EXP,FIELD)												\
26 	if (strcmp (EXP, e.FIELD) != 0)										\
27 	{																	\
28 		fprintf (stderr, "unexpected " #FIELD "(expected: %s, actual: %s) in tagsFirst\n", \
29 				 EXP, e.FIELD);											\
30 		return 1;														\
31 	} \
32 	do {} while (0)
33 
34 #define CHECK_X(FIELD,EXP)												\
35 	{																	\
36 		unsigned short i;												\
37 		for (i = 0; i < e.fields.count; i++)							\
38 		{																\
39 			if (strcmp (e.fields.list [i].key, FIELD) == 0)				\
40 			{															\
41 				if (strcmp(e.fields.list [i].value, EXP) == 0)			\
42 					break;												\
43 				else													\
44 				{														\
45 					fprintf (stderr, "unexpected " #FIELD "(expected: %s, actual: %s) in tagsFirst\n", \
46 							 EXP, e.fields.list [i].value);				\
47 					return 1;											\
48 				}														\
49 			}															\
50 		}																\
51 		if (i >= e.fields.count)										\
52 		{																\
53 			fprintf (stderr, "unexpected " #FIELD " field is not found in tagsFirst (count: %u)\n", \
54 					 e.fields.count);									\
55 			return 1;													\
56 		}																\
57 	}
58 
59 int
main(void)60 main (void)
61 {
62 	char *srcdir = getenv ("srcdir");
63 	if (srcdir)
64 	{
65 		if (chdir (srcdir) == -1)
66 		{
67 			perror ("chdir");
68 			return 99;
69 		}
70 	}
71 
72 	tagFile *t;
73 	tagFileInfo info;
74 
75 	const char *tags0 = "./unescaping.tags";
76 	t = tagsOpen (tags0, &info);
77 	if (t == NULL
78 		|| info.status.opened == 0)
79 	{
80 		fprintf (stderr, "unexpected result (t: %p, opened: %d)\n",
81 				 t, info.status.opened);
82 		return 1;
83 	}
84 	fprintf (stderr, "ok\n");
85 
86 	tagEntry e;
87 	tagResult r;
88 
89 	r = tagsFirst (t, &e);
90 	if (r != TagSuccess)
91 	{
92 		fprintf (stderr, "error in tagsFirst\n");
93 		return 1;
94 	}
95 	CHECK ("aa", name);
96 	CHECK ("main/Makefile", file);
97 	CHECK ("/^%:$/", address.pattern);
98 	CHECK ("t", kind);
99 
100 	NEXT ();
101 	CHECK ("\taa", name);
102 	CHECK ("parsers/Makefile", file);
103 	CHECK ("/^%:$/", address.pattern);
104 	CHECK ("t", kind);
105 
106 	NEXT ();
107 	CHECK ("bb", name);
108 	CHECK ("main/Makefile", file);
109 	CHECK ("/^%:$/", address.pattern);
110 	CHECK ("t", kind);
111 
112 	NEXT ();
113 	CHECK ("\\\aa", name);
114 	CHECK ("parsers/cxx/Makefile", file);
115 	CHECK ("/^%:$/", address.pattern);
116 	CHECK ("t", kind);
117 
118 	NEXT ();
119 	CHECK ("\x01level1", name);
120 	CHECK ("input.rst", file);
121 	CHECK ("/^\x01level1$/", address.pattern);
122 	CHECK ("c", kind);
123 
124 	NEXT ();
125 	CHECK ("level2", name);
126 	CHECK ("input.rst", file);
127 	CHECK ("/^level2$/", address.pattern);
128 	CHECK ("s", kind);
129 	CHECK_X ("scope", "chapter:\x01level1");
130 
131 	NEXT ();
132 	CHECK ("!level3\x03", name);
133 	CHECK ("input.rst", file);
134 	CHECK ("/^!level3\x03$/", address.pattern);
135 	CHECK ("S", kind);
136 	CHECK_X ("scope", "section:level2");
137 
138 	NEXT ();
139 	CHECK ("!level1+", name);
140 	CHECK ("input.rst", file);
141 	CHECK ("/^!level1+$/", address.pattern);
142 	CHECK ("c", kind);
143 
144 	NEXT ();
145 	CHECK ("level2+", name);
146 	CHECK ("input.rst", file);
147 	CHECK ("/^level2+$/", address.pattern);
148 	CHECK ("s", kind);
149 	CHECK_X ("scope", "chapter:!level1+");
150 
151 	NEXT ();
152 	CHECK ("\x02level3+\x04", name);
153 	CHECK ("input.rst", file);
154 	CHECK ("/^\x02level3+\x04$/", address.pattern);
155 	CHECK ("S", kind);
156 	CHECK_X ("scope", "section:level2+");
157 
158 	NEXT ();
159 	CHECK ("ClassFour", name);
160 	CHECK ("input.php", file);
161 	CHECK ("/^  use NS2\\\\{NS30 as NameSpaceTreePointO, NS31\\\\Cls4 as ClassFour};$/", address.pattern);
162 	CHECK ("a", kind);
163 	CHECK_X ("typeref", "unknown:NS2\\NS31\\Cls4");
164 
165 	r = tagsClose(t);
166 	if (r != TagSuccess)
167 	{
168 		fprintf (stderr, "error in tagsClose\n");
169 		return 1;
170 	}
171 
172 	return 0;
173 }
174