English Language flag
// Log In
// CVSweb
Project: FreeWRT
// Summary // Activity // Search // Tracker // Lists // News // SCM // Wiki

SCM Repository

ViewVC logotype

Contents of /branches/common-nfo/tools/nfotiser/parser.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3452 - (show annotations) (download)
Thu Aug 9 11:22:16 2007 UTC (6 years, 6 months ago) by tg
File MIME type: text/plain
File size: 4021 byte(s)
sometimes, the best ideas come on the way to work
after mmapping the file, make a local NUL-terminated copy (i.e. read-writable)
this will greatly simplify the following algorithm.

1 /* $FreeWRT: src/share/misc/licence.template,v 1.20 2006/12/11 21:04:56 tg Rel $ */
2
3 /*-
4 * Copyright (c) 2007
5 * Thorsten Glaser <tg@mirbsd.de>
6 *
7 * Provided that these terms and disclaimer and all copyright notices
8 * are retained or reproduced in an accompanying document, permission
9 * is granted to deal in this work without restriction, including un-
10 * limited rights to use, publicly perform, distribute, sell, modify,
11 * merge, give away, or sublicence.
12 *
13 * Advertising materials mentioning features or use of this work must
14 * display the following acknowledgement:
15 * This product includes material provided by Thorsten Glaser.
16 * This acknowledgement does not need to be reprinted if this work is
17 * linked into a bigger work whose licence does not allow such clause
18 * and the author of this work is given due credit in the bigger work
19 * or its accompanying documents, where such information is generally
20 * kept, provided that said credits are retained.
21 *
22 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
23 * the utmost extent permitted by applicable law, neither express nor
24 * implied; without malicious intent or gross negligence. In no event
25 * may a licensor, author or contributor be held liable for indirect,
26 * direct, other damage, loss, or other issues arising in any way out
27 * of dealing in the work, even if advised of the possibility of such
28 * damage or existence of a defect, except proven that it results out
29 * of said person's immediate fault when using the work as intended.
30 */
31
32 #include <sys/param.h>
33 #include <sys/mman.h>
34 #include <sys/stat.h>
35
36 #include <err.h>
37 #include <errno.h>
38 #include <stdint.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43
44 #include "nfotiser.h"
45
46 /*
47 * Parsing works as follows:
48 *
49 * - strip completely empty line
50 * - strip line beginning with hash mark
51 * - if line ends with backslash, get next line that is not
52 * + empty
53 * + beginning with a hash mark
54 * and look if it begins with a tab (if not: syntax error)
55 * if so, strip backslash + newline + tab and repeat
56 * - if line begins with a tab, strip it and append line to
57 * the last line, including the newline separator
58 * - match line with '([A-Za-z_][A-Za-z0-9_]*)\t(.*)$' and
59 * call \1 the key and \2 the value (else: syntax error)
60 * - uppercase the key
61 * - enter the key/value pair in the system
62 *
63 * The following is also part of parsing, but left to the caller:
64 * - replace ${foo} with the value of key "foo"
65 * - undouble all backslashes
66 *
67 * We enter the key into the system up to three-fold:
68 * - KWT_NORMAL => ([A-Za-z_][A-Za-z0-9_]*)
69 * + \1 = keyword (toupper'd)
70 * - KWT_MULTI => ([A-Za-z_][A-Za-z0-9_]*)_([A-Za-z0-9_]*)
71 * + \1 = keyword (toupper'd)
72 * + \2 = kw_multi (case preserving)
73 * - KWT_ITERATED => ([A-Za-z_][A-Za-z0-9_]*)_([0-9]*)
74 * + \1 = keyword (toupper'd)
75 * + \2 = kw_iter (unsigned integer value)
76 * - KWT_MULTITER => ([A-Za-z_][A-Za-z0-9_]*)_([0-9]*)_([A-Za-z0-9_]*)
77 * + \1 = keyword (toupper'd)
78 * + \2 = kw_iter (unsigned integer value)
79 * + \3 = kw_multi (case preserving)
80 *
81 * Cf. https://www.freewrt.org/trac/wiki/Documentation/Specs/Freewrt_info_files
82 * for more examples and a more human-readable version of this specification.
83 */
84
85 struct parser_result *
86 nfo_parse(int fd, const struct parser_keywords *kws)
87 {
88 struct parser_result *res;
89 struct parser_res *entry;
90 char ch, *cp, *t, *buf;
91 size_t len, n;
92 struct stat sb;
93
94 res = xmalloc(sizeof (struct parser_result));
95 CIRCLEQ_INIT(res);
96
97 if (fstat(fd, &sb))
98 err(255, "cannot stat");
99
100 /* slurp whole file into mapped memory */
101 if ((cp = mmap(NULL, (len = sb.st_size), PROT_READ, MAP_FILE, fd, 0))
102 == MAP_FAILED)
103 err(255, "cannot mmap %zu bytes", len);
104 /* make a nice NUL-terminated copy (malloc'd) */
105 buf = str_nsave(cp, len);
106 if (munmap(cp, len))
107 err(255, "cannot munmap");
108 /* don't need the file any more */
109 close(fd);
110
111 /* now we can operate on the NUL-terminated R/W string “buf” */

root@freewrt.org:443
ViewVC Help
Powered by ViewVC 1.1.20