2 * Copyright 2003-2010, Haiku, Inc.
3 * Distributed under the terms of the MIT License.
6 * Oliver Tappe, zooey@hirschkaefer.de
7 * Adrien Destugues, pulkomandy@gmail.com
18 #include <PlainTextCatalog.h>
20 #include <StorageDefs.h>
24 using BPrivate::PlainTextCatalog
;
27 bool showKeys
= false;
28 bool showSummary
= false;
29 bool showWarnings
= false;
30 const char *inputFile
= NULL
;
32 const char *catalogSig
= NULL
;
33 const char *catalogLang
= "English";
34 BString
rxString("B_CATKEY\\s*");
37 BString str
, ctx
, cmt
;
42 PlainTextCatalog
*catalog
= NULL
;
49 "usage: collectcatkeys [-pvw] [-r <regex>] [-o <outfile>] "
50 "[-l <catalogLanguage>]\n"
51 " -s <catalogSig> <prepCppFile>\n"
53 " -l <catalogLang>\tlanguage of the target-catalog (default is "
55 " -o <outfile>\t\texplicitly specifies the name of the output-file\n"
56 " -p\t\t\tprint keys as they are found\n"
57 " -r <regex>\t\tchanges the regex used by the key-scanner to the one "
59 " \t\t\tthe default is: ");
60 fprintf(stderr
, "%s", rxString
.String());
61 fprintf(stderr
,"\n -s <catalogSig>\tsignature of the target-catalog\n"
62 " -v\t\t\tbe verbose, show summary\n"
63 " -w\t\t\tshow warnings about catalog-accesses that couldn't be "
64 " resolved completely\n");
70 fetchStr(const char *&in
, BString
&str
, bool lookForID
)
73 while (isspace(*in
) || *in
== '(') {
82 while (parLevel
>= 0 && inString
)
84 // Collect string content until we find a quote marking end of
85 // string (skip escaped quotes)
86 while (*in
!= '"' || quoted
)
89 if (*in
== '\\' && !quoted
)
99 // Strip all whitespace until we find a closing parenthesis, or the
100 // beginning of another string
101 while (isspace(*in
) || *in
== ')') {
117 if (!memcmp(in
, "__null", 6)) {
118 // NULL is preprocessed into __null, which we parse as ""
120 } else if (lookForID
&& (isdigit(*in
) || *in
== '-' || *in
== '+')) {
121 // try to parse an ID (a long):
124 id
= strtol(in
, &next
, 10);
125 if (id
!= 0 || errno
== 0) {
132 while (isspace(*in
) || *in
== ')') {
146 fetchKey(const char *&in
)
148 str
= ctx
= cmt
= "";
150 // fetch native string or id:
151 if (!fetchStr(in
, str
, true)) {
157 if (!fetchStr(in
, ctx
, false)) {
158 fprintf(stderr
,"Context parsing error\n");
164 if (!fetchStr(in
, cmt
, false))
166 fprintf(stderr
,"Comment parsing error\n");
176 collectAllCatalogKeys(BString
& inputStr
)
179 struct regexp
*rxprg
= rx
.Compile(rxString
.String());
180 if (rx
.InitCheck() != B_OK
) {
181 fprintf(stderr
, "regex-compilation error %s\n", rx
.ErrorString());
185 const char *in
= inputStr
.String();
186 while (rx
.RunMatcher(rxprg
, in
)) {
187 const char *start
= rxprg
->startp
[0];
192 printf("CatKey(%d)\n", id
);
193 res
= catalog
->SetString(id
, "");
195 fprintf(stderr
, "Collectcatkeys: couldn't add key %d - "
196 "error: %s\n", id
, strerror(res
));
201 printf("CatKey(\"%s\", \"%s\", \"%s\")\n", str
.String(),
202 ctx
.String(), cmt
.String());
204 res
= catalog
->SetString(str
.String(), str
.String(),
205 ctx
.String(), cmt
.String());
207 fprintf(stderr
, "couldn't add key %s,%s,%s - error: %s\n",
208 str
.String(), ctx
.String(), cmt
.String(),
213 } else if (showWarnings
) {
214 const char *end
= strchr(in
, ';');
217 match
.SetTo(start
, end
-start
+1);
219 // can't determine end of statement, we output next 40 chars
220 match
.SetTo(start
, 40);
222 fprintf(stderr
, "Warning: couldn't resolve catalog-access:\n\t%s\n",
230 main(int argc
, char **argv
)
232 while ((++argv
)[0]) {
233 if (argv
[0][0] == '-' && argv
[0][1] != '-') {
234 char *arg
= argv
[0] + 1;
236 while ((c
= *arg
++) != '\0') {
240 catalogLang
= (++argv
)[0];
242 catalogSig
= (++argv
)[0];
248 outputFile
= (++argv
)[0];
250 } else if (c
== 'r') {
251 rxString
= (++argv
)[0];
255 } else if (!strcmp(argv
[0], "--help")) {
264 if (!outputFile
.Length() && inputFile
) {
265 // generate default output-file from input-file by replacing
266 // the extension with '.catkeys':
267 outputFile
= inputFile
;
268 int32 dot
= outputFile
.FindLast('.');
270 outputFile
.Truncate(dot
);
271 outputFile
<< ".catkeys";
273 if (!inputFile
|| !catalogSig
|| !outputFile
.Length() || !catalogLang
)
277 status_t res
= inFile
.SetTo(inputFile
, B_READ_ONLY
);
279 fprintf(stderr
, "unable to open inputfile %s - error: %s\n", inputFile
,
287 char *buf
= inputStr
.LockBuffer(sz
);
288 off_t rsz
= inFile
.Read(buf
, sz
);
290 fprintf(stderr
, "couldn't read %Ld bytes from %s (got only %Ld)\n",
294 inputStr
.UnlockBuffer(rsz
);
295 catalog
= new PlainTextCatalog(inputFile
, catalogSig
, catalogLang
);
296 collectAllCatalogKeys(inputStr
);
297 res
= catalog
->WriteToFile(outputFile
.String());
299 fprintf(stderr
, "couldn't write catalog to %s - error: %s\n",
300 outputFile
.String(), strerror(res
));
304 int32 count
= catalog
->CountItems();
306 fprintf(stderr
, "%d key%s found and written to %s\n",
307 count
, (count
==1 ? "": "s"), outputFile
.String());
309 fprintf(stderr
, "no keys found\n");
314 // BEntry inEntry(inputFile);