xref: /Universal-ctags/libreadtags/tests/test-api-tagsFirst.c (revision a41b16516f3da7c2ee4d19b4240bc27562d4b442)
1 /*
2 *   Copyright (c) 2020, Masatake YAMATO
3 *
4 *   This source code is released into the public domain.
5 *
6 *   Testing tagsFirst() and tagsNext() API functions
7 */
8 
9 #include "readtags.h"
10 
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 
16 struct entryExpectaion {
17 	tagResult result;
18 	const char *name;
19 	int err;
20 };
21 
22 #define LAST {											\
23 		.result = TagFailure,							\
24 		.name   = "last",								\
25 	}
26 
27 #define isLast(ex) ((ex)->result == TagFailure && (ex)->name)
28 
29 struct expectation {
30 	char *file;
31 	struct entryExpectaion first;
32 	struct entryExpectaion *next;
33 };
34 
35 static int
check_one(tagFile * t,struct entryExpectaion * ex,tagEntry * e,int first)36 check_one (tagFile *t, struct entryExpectaion *ex, tagEntry *e, int first)
37 
38 {
39 	fprintf (stderr, "getting the %s entry...", first? "first": "next");
40 	tagResult r;
41 
42 	r = (first? tagsFirst: tagsNext) (t, e);
43 	if (r == ex->result)
44 	{
45 		if (r == TagSuccess)
46 		{
47 			if (strcmp (e->name, ex->name) == 0)
48 				fprintf (stderr, "found expected one: %s\n", e->name);
49 			else
50 			{
51 				fprintf (stderr, "found unexpected one: %s (expected: %s)\n", e->name, ex->name);
52 				return 1;
53 			}
54 		}
55 		else
56 		{
57 			fprintf (stderr, "nothing found expectedly\n");
58 
59 			fprintf (stderr, "comparing errno...");
60 			int err = tagsGetErrno (t);
61 			if (err == ex->err)
62 				fprintf (stderr, "matched: %d\n", err);
63 			else
64 			{
65 				fprintf (stderr, "unmatched: %d (expected: %d)\n", err, ex->err);
66 				return 1;
67 			}
68 		}
69 	}
70 	else if (ex->result == TagSuccess)
71 	{
72 		fprintf (stderr, "nothing found unexpectedly\n");
73 		return 1;
74 	}
75 	else
76 	{
77 		fprintf (stderr, "something found unexpectedly: %s\n", e->name);
78 		return 1;
79 	}
80 
81 
82 	return 0;
83 }
84 
85 static int
check(struct expectation * x)86 check (struct expectation *x)
87 {
88 	tagFile *t;
89 	tagFileInfo info;
90 	const char *tags = x->file;
91 
92 	fprintf (stderr, "opening %s...", tags);
93 	t = tagsOpen (tags, &info);
94 	if (!t)
95 	{
96 		fprintf (stderr, "unexpected result (t: %p, opened: %d, error_number: %d)\n",
97 				 t, info.status.opened, info.status.error_number);
98 		return 1;
99 	}
100 	fprintf (stderr, "ok\n");
101 
102 	tagEntry e;
103 	if (check_one (t, &x->first, &e, 1))
104 		return 1;
105 
106 	for (int i = 0; !isLast (x->next + i); i++)
107 		if (check_one (t, x->next + i, &e, 0))
108 			return 1;
109 
110 	fprintf (stderr, "closing the tag file...");
111 	if (tagsClose (t) != TagSuccess)
112 	{
113 		fprintf (stderr, "unexpected result\n");
114 		return 1;
115 	}
116 	fprintf (stderr, "ok\n");
117 
118 	return 0;
119 }
120 
121 int
main(void)122 main (void)
123 {
124 	char *srcdir = getenv ("srcdir");
125 	if (srcdir)
126 	{
127 		if (chdir (srcdir) == -1)
128 		{
129 			perror ("chdir");
130 			return 99;
131 		}
132 	}
133 
134 	struct expectation expectations [] = {
135 		{
136 			.file = "duplicated-names--sorted-yes.tags",
137 			.first = {
138 				.result = TagSuccess,
139 				.name = "M",
140 			},
141 			.next = ((struct entryExpectaion[]) {
142 					{TagSuccess, "N"},
143 					{TagSuccess, "O"},
144 					{TagSuccess, "m"},
145 					{TagSuccess, "main"},
146 					{TagSuccess, "n"},
147 					{TagSuccess, "n"},
148 					{TagSuccess, "n"},
149 					{TagSuccess, "n"},
150 					{TagSuccess, "n"},
151 					{TagSuccess, "n"},
152 					{TagSuccess, "o"},
153 					LAST,
154 				}),
155 		},
156 		{
157 			.file = "empty.tags",
158 			.first = {
159 				.result = TagFailure,
160 				.err    = 0,
161 			},
162 			.next = ((struct entryExpectaion []) {
163 					{TagFailure, NULL, 0},
164 					LAST,
165 				}),
166 		},
167 		{
168 			.file = "empty-no-newline.tags",
169 			.first = {
170 				.result = TagFailure,
171 				.err    = 0,
172 			},
173 			.next = ((struct entryExpectaion []) {
174 					{TagFailure, NULL, 0},
175 					LAST,
176 				}),
177 		},
178 		{
179 			.file = "broken-line-field.tags",
180 			.first = {
181 				.result = TagFailure,
182 				.name   = NULL,
183 				.err = TagErrnoUnexpectedLineno,
184 			},
185 			.next = ((struct entryExpectaion []) {
186 					LAST,
187 				}),
188 		},
189 		{
190 			.file = "broken-line-field-other-than-first.tags",
191 			.first = {
192 				.result = TagSuccess,
193 				.name   = "M",
194 			},
195 			.next = ((struct entryExpectaion []) {
196 					{
197 						.result = TagSuccess,
198 						.name   = "N",
199 					},
200 					{
201 						.result = TagFailure,
202 						.name   = NULL,
203 						.err    = TagErrnoUnexpectedLineno,
204 
205 					},
206 					LAST,
207 				}),
208 		},
209 	};
210 
211 	for (int i = 0; i < sizeof (expectations) / sizeof (expectations[0]); i++)
212 		if (check (expectations + i))
213 			return 1;
214 	return 0;
215 }
216