1 /*
2 * Copyright (c) 2022, Masatake YAMATO
3 *
4 * This source code is released into the public domain.
5 *
6 * Testing the way to report "too large tags file".
7 */
8
9 #include "readtags.h"
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15 #include <errno.h>
16
17 #define TAGS "./remove-me-after-testing.tags"
18 #define KEY "xdigitValue"
19
20 static int
make_large_tags(const char * output)21 make_large_tags (const char *output)
22 {
23 FILE *fp = fopen(output, "w");
24 if (fp == NULL)
25 return 1;
26
27 int r = 0;
28 const char *ptags [] = {
29 "!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;\" to lines/",
30 "!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/",
31 "!_TAG_OUTPUT_EXCMD mixed /number, pattern, mixed, or combineV2/",
32 "!_TAG_OUTPUT_FILESEP slash /slash or backslash/",
33 "!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/",
34 "!_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/",
35 "!_TAG_PROC_CWD /home/jet/var/libreadtags-new/ //",
36 "!_TAG_PROGRAM_AUTHOR Universal Ctags Team //",
37 "!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/",
38 "!_TAG_PROGRAM_URL https://ctags.io/ /official site/",
39 "!_TAG_PROGRAM_VERSION 5.9.0 /966e51373/",
40 };
41
42 for (unsigned int i = 0; i < sizeof (ptags) / sizeof (ptags[0]); i++)
43 {
44 if (fputs(ptags[i], fp) < 0)
45 {
46 r = 1;
47 break;
48 }
49 if (fputc('\n', fp) == EOF)
50 {
51 r = 1;
52 break;
53 }
54 }
55
56 const unsigned int count = 21474836; /* $(( (2 ** 31) / 100)) */
57 for (unsigned int i = 0; i < count; i++)
58 {
59 if (fputs("EmptyString", fp) < 0)
60 {
61 r = 1;
62 break;
63 }
64
65 if (fprintf(fp, "%u", i) < 1)
66 {
67 r = 1;
68 break;
69 }
70 if (fputs(" readtags.c /^static const char *const EmptyString", fp) < 0)
71 {
72 r = 1;
73 break;
74 }
75
76 if (fprintf(fp, "%u", i) < 1)
77 {
78 r = 1;
79 break;
80 }
81 if (fputs(" = \"\";$/;\" v typeref:typename:const char * const file:\n", fp) < 0)
82 {
83 r = 1;
84 break;
85 }
86 }
87
88 if (r == 0)
89 {
90 if (fputs(KEY, fp) < 0)
91 r = 1;
92 else if (fputs(" readtags.c /^static int xdigitValue (char digit)$/;\" f typeref:typename:int file:\n", fp) < 0)
93 r = 1;
94 }
95
96 if (fclose (fp))
97 r = 1;
98
99 return r;
100 }
101
102 int
main(void)103 main (void)
104 {
105 fprintf (stderr, "generating a large (> 2G) tags file (%s)...", TAGS);
106
107 errno = 0;
108 int r = make_large_tags (TAGS);
109 if (r)
110 {
111 fprintf(stderr, "unexpected result: %s%s%d\n",
112 errno? strerror(errno): "",
113 errno? ": ": "",
114 r);
115 return 99;
116 }
117 fprintf(stderr, "done\n");
118
119 fprintf(stderr, "opening tags file (%s)...", TAGS);
120 tagFileInfo info;
121 tagFile *t = tagsOpen (TAGS, &info);
122 if ((info.status.opened == 0
123 && (
124 info.status.error_number == EFBIG
125 || info.status.error_number == TagErrnoFileMaybeTooBig)))
126 {
127 r = 1;
128 fprintf(stderr, "failed with expected error: %d\n", info.status.error_number);
129 }
130 else if (t && info.status.opened)
131 fprintf(stderr, "done\n");
132 else
133 {
134 r = 1;
135 fprintf (stderr, "unexpected result (t: %p, opened: %d, error_number: %d<%s>)\n",
136 t, info.status.opened, info.status.error_number,
137 (info.status.error_number >= 0)? strerror (info.status.error_number): "");
138 }
139
140 if (t)
141 {
142 tagEntry e;
143 fprintf (stderr, "finding \"%s\"...", KEY);
144 if (tagsFind (t, &e, KEY, TAG_FULLMATCH) == TagSuccess)
145 fprintf (stderr, "found as expected\n");
146 else
147 {
148 r = 1;
149 fprintf (stderr, "not found unexpectedly\n");
150 }
151 tagsClose (t);
152 }
153
154 remove(TAGS);
155 return r;
156 }
157