comparison helpgen/readhelp.syn @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:13d2b8934445
1 {
2 /*
3 * AnaGram, a System for Syntax Directed Programming
4 * Copyright 1993 Parsifal Software. All Rights Reserved.
5 * Copyright 2006 David A. Holland. All Rights Reserved.
6 * See the file COPYING for license and usage terms.
7 *
8 * readhelp.syn - Toplevel syntax for help source file.
9 */
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <assert.h>
13 #include <errno.h>
14 #include <fcntl.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <unistd.h>
19
20 #include "utils.h"
21 #include "topic.h"
22 #include "helpgen.h"
23 }
24
25 [
26 pointer input
27 pointer type = unsigned char *
28 context type = unsigned char *
29 default token type = void
30 line numbers
31 ]
32
33 left = 169
34 right = 170
35 quote = '\''
36
37 range = 0..255
38 eof = 0
39 tab = '\t'
40 nl = '\n'
41 cr = '\r'
42 blank = ' ' + tab
43 text = ~eof & ~cr & ~nl
44
45 (int) letter
46 -> text & ~blank & ~',' & ~(left + right):c = c;
47
48 (void) blanks
49 -> blank
50 -> blanks, blank
51
52 (void) eol
53 -> ["//", text...], cr?, nl
54
55 (void) new line
56 -> cr?, nl
57
58 (void) continue
59 -> blanks?, [eol, blanks?]
60
61 (void) name
62 -> letter:c = startstr(), addstr(c);
63 -> name, letter:c = addstr(c);
64 -> name, blanks, letter:c = addstr(' '), addstr(c);
65
66 (const char *) title
67 -> name, blanks? = getstr();
68
69 (void) titles
70 -> title:t = topic_addtitle(curtopic, t);
71 -> titles, ',', continue, title:t = topic_addtitle(curtopic, t);
72
73 (long) text lines
74 -> text unit..., new line = CONTEXT - inputdata;
75 -> text lines, text unit..., new line
76
77 (void) text unit
78 // -> text - (left + right + quote)
79 // -> quote, ~eof
80 -> text - (left + right)
81 -> cross reference
82
83 (void) cross reference
84 -> cross reference text, blanks?, right = see_xref(getstr());
85
86 (void) cross reference text
87 -> left = startstr();
88 -> cross reference text, letter:c = addstr(c);
89 -> cross reference text, blanks, letter:c = addstr(' '), addstr(c);
90 -> cross reference text, blanks?, cr?, nl = addstr(' ');
91
92 (long) block body
93 -> text lines
94 -> block body, blank lines, text lines
95
96 (long) blank lines
97 -> new line = CONTEXT - inputdata;
98 -> blank lines, new line
99
100 (long) end block
101 -> blank lines, "##"
102 -> "##" = CONTEXT - inputdata;
103
104 (void) block
105 -> !{ startblock(); }, titles, eol, real block body = endblock();
106
107 (void) real block body
108 -> blank lines?, block body:bb, end block:be = block(bb,be);
109 -> end block = block(0,0);
110
111 (void) file $
112 -> blocks, eof
113
114 (void) blocks
115 ->
116 -> blocks, blanks?, eol
117 -> blocks, block
118
119 ////////////////////////////////////////////////////////////
120 //
121 // string buffer
122
123 {
124 static char string_space[4096];
125 static size_t string_pos;
126
127 static void startstr(void) {
128 string_pos = 0;
129 }
130
131 static void addstr(int ch) {
132 if (string_pos >= sizeof(string_space)-1) {
133 fprintf(stderr, "String buffer overflow - make string_space larger\n");
134 exit(1);
135 }
136 string_space[string_pos++] = ch;
137 }
138
139 static const char *getstr(void) {
140 string_space[string_pos] = 0;
141 return string_space;
142 }
143 }
144
145 ////////////////////////////////////////////////////////////
146 //
147 // current topic
148 {
149 static struct topic *curtopic;
150
151 static void startblock(void) {
152 assert(curtopic == NULL);
153 curtopic = topic_create();
154 }
155
156 static void endblock(void) {
157 help_addtopic(curtopic);
158 curtopic = NULL;
159 }
160
161 static void see_xref(const char *ref) {
162 topic_addref(curtopic, ref);
163 }
164
165 }
166
167 ////////////////////////////////////////////////////////////
168 //
169 // pointer input support
170 {
171
172 #define GET_CONTEXT CONTEXT = PCB.pointer
173
174 static unsigned char *inputdata;
175
176 static void block(long head, long tail) {
177 long length = tail - head;
178 assert(length >= 0);
179 if (length > 0) {
180 topic_setbody(curtopic, (const char *)(inputdata+head), length);
181 }
182 }
183
184 static off_t getlength(int fd) {
185 struct stat st;
186 if (fstat(fd, &st) < 0) {
187 fprintf(stderr, "fstat failed: %s", strerror(errno));
188 exit(1);
189 }
190 return st.st_size;
191 }
192
193 void load(const char *path) {
194 char *buf;
195 off_t len;
196 int fd, r;
197
198 fd = open(path, O_RDONLY);
199 if (fd < 0) {
200 fprintf(stderr, "%s: %s\n", path, strerror(errno));
201 exit(1);
202 }
203
204 len = getlength(fd);
205 buf = domalloc(len+1);
206 r = read(fd, buf, len);
207 if (r < 0) {
208 fprintf(stderr, "%s: read: %s\n", path, strerror(errno));
209 exit(1);
210 }
211 if (r < len) {
212 fprintf(stderr, "%s: read: short count %d of %ld\n", path, r, (long) len);
213 exit(1);
214 }
215 buf[r] = 0;
216 close(fd);
217
218 inputdata = (unsigned char *) buf;
219 PCB.pointer = inputdata;
220 readhelp();
221 inputdata = NULL;
222 free(buf);
223 }
224
225 }
226