Mercurial > illumos > onarm
comparison usr/src/cmd/man/src/util/instant.src/browse.c @ 0:c9caec207d52 b86
Initial porting based on b86
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Tue, 02 Jun 2009 18:56:50 +0900 |
parents | |
children | 1a15d5aaf794 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c9caec207d52 |
---|---|
1 /* | |
2 * Copyright 1993 Open Software Foundation, Inc., Cambridge, Massachusetts. | |
3 * All rights reserved. | |
4 */ | |
5 /* | |
6 #pragma ident "@(#)browse.c 1.3 00/07/17 SMI" | |
7 * Copyright (c) 1994 | |
8 * Open Software Foundation, Inc. | |
9 * | |
10 * Permission is hereby granted to use, copy, modify and freely distribute | |
11 * the software in this file and its documentation for any purpose without | |
12 * fee, provided that the above copyright notice appears in all copies and | |
13 * that both the copyright notice and this permission notice appear in | |
14 * supporting documentation. Further, provided that the name of Open | |
15 * Software Foundation, Inc. ("OSF") not be used in advertising or | |
16 * publicity pertaining to distribution of the software without prior | |
17 * written permission from OSF. OSF makes no representations about the | |
18 * suitability of this software for any purpose. It is provided "as is" | |
19 * without express or implied warranty. | |
20 */ | |
21 /* | |
22 * Copyright (c) 1996 X Consortium | |
23 * Copyright (c) 1995, 1996 Dalrymple Consulting | |
24 * | |
25 * Permission is hereby granted, free of charge, to any person obtaining a copy | |
26 * of this software and associated documentation files (the "Software"), to deal | |
27 * in the Software without restriction, including without limitation the rights | |
28 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
29 * copies of the Software, and to permit persons to whom the Software is | |
30 * furnished to do so, subject to the following conditions: | |
31 * | |
32 * The above copyright notice and this permission notice shall be included in | |
33 * all copies or substantial portions of the Software. | |
34 * | |
35 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
36 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
37 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
38 * X CONSORTIUM OR DALRYMPLE CONSULTING BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
39 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
40 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
41 * OTHER DEALINGS IN THE SOFTWARE. | |
42 * | |
43 * Except as contained in this notice, the names of the X Consortium and | |
44 * Dalrymple Consulting shall not be used in advertising or otherwise to | |
45 * promote the sale, use or other dealings in this Software without prior | |
46 * written authorization. | |
47 */ | |
48 | |
49 /* ________________________________________________________________________ | |
50 * | |
51 * Module for interactive browsing. | |
52 * | |
53 * Entry points for this module: | |
54 * Browse() interactive browser | |
55 * ________________________________________________________________________ | |
56 */ | |
57 | |
58 #ifndef lint | |
59 static char *RCSid = | |
60 "$Header: /usr/src/docbook-to-man/Instant/RCS/browse.c,v 1.2 1996/06/02 21:46:10 fld Exp $"; | |
61 #endif | |
62 | |
63 #include <stdio.h> | |
64 #include <stdlib.h> | |
65 #include <ctype.h> | |
66 #include <string.h> | |
67 | |
68 #include "general.h" | |
69 | |
70 static void PrElemPlusID(Element_t *); | |
71 static void ls_node(Element_t *, int, char **); | |
72 static void do_query(Element_t *, char *, char *); | |
73 static void do_find(Element_t *, char **); | |
74 | |
75 /* ______________________________________________________________________ */ | |
76 | |
77 static char *br_help_msg[] = { | |
78 " ls List info about current element in tree", | |
79 " (context, children, attributes, etc.)", | |
80 " cd N ... Change to Nth elememt child, where N is shown by 'ls'.", | |
81 " N may also be '/' (top) or '..' (up).", | |
82 " cd id I Change to elememt whose ID is I", | |
83 " data N Show data of Nth data node", | |
84 " where Show current position in the tree", | |
85 " id I Show path to element with id I", | |
86 " (using '?' for I will lists all IDs and their paths)", | |
87 " find S Find elements matching spec S. Recognized syntaxes:", | |
88 " find attr <name> <value>", | |
89 " find cont <string>", | |
90 " find parent <gi-name>", | |
91 " find child <gi-name>", | |
92 " find gi <gi-name>", | |
93 " q rel gi Query: report if elem 'gi' has relation to current elem", | |
94 " ('rel' is one of 'child parent ancestor descendant", | |
95 " sibling sibling+ sibling+1 sibling- sibling-1 cousin')", | |
96 "", | |
97 " tran file [outfile]", | |
98 " With trans spec in 'file' translate into 'outfile' (stdout)", | |
99 " sdata file Read SDATA map file (for translations).", | |
100 " cmap file Read character map file (for translations).", | |
101 " stat Print statistics (how often elements occur, etc.)", | |
102 " sum Print elem usage summary (# of children, depth, etc.)", | |
103 " tree Print document hierarchy as a tree", | |
104 " cont Print context of each element", | |
105 NULL | |
106 }; | |
107 | |
108 /* ______________________________________________________________________ */ | |
109 | |
110 void | |
111 Browse() | |
112 { | |
113 char buf[256], *cmd, **av, **sv, *cmapfile, *sdatafile; | |
114 char *Prompt; | |
115 Element_t *ce; /* current element */ | |
116 Element_t *e; | |
117 int i, n, ac; | |
118 | |
119 if (slave) Prompt = "=>\n"; | |
120 else Prompt = "=> "; | |
121 | |
122 ce = DocTree; | |
123 while (fputs(Prompt, stdout)) { | |
124 if (!fgets(buf, 256, stdin)) break; | |
125 stripNL(buf); | |
126 if (buf[0] == EOS) { | |
127 fputs(Prompt, stdout); | |
128 continue; | |
129 } | |
130 ac = 20; | |
131 av = Split(buf, &ac, S_ALVEC); | |
132 if (ac > 0) cmd = av[0]; | |
133 if (!cmd || !(*cmd)) continue; | |
134 | |
135 if (!strcmp(cmd, "ls")) ls_node(ce, ac, av); | |
136 | |
137 else if (!strcmp(cmd, "cd")) { | |
138 if (av[1]) { | |
139 if (ac == 3 && !strcmp(av[1], "id")) { | |
140 if ((e = FindElemByID(av[2]))) ce = e; | |
141 else printf("Element with ID '%s' not found.\n", av[2]); | |
142 continue; | |
143 } | |
144 for (i=1; i<ac; i++) { | |
145 if (!strcmp(av[i], "..")) { | |
146 if (ce->parent) ce = ce->parent; | |
147 continue; | |
148 } | |
149 if (!strcmp(av[i], "/")) { | |
150 if (ce->parent) ce = DocTree; | |
151 continue; | |
152 } | |
153 if (!isdigit(*av[i])) { | |
154 printf("Expecting digit, '..', or '/', got '%s'.\n", | |
155 av[i]); | |
156 break; | |
157 } | |
158 n = atoi(av[i]); | |
159 if (n < ce->necont) ce = ce->econt[n]; | |
160 else { | |
161 printf("Must be in range 0 - %d.\n", ce->necont); | |
162 break; | |
163 } | |
164 } | |
165 } | |
166 } | |
167 | |
168 else if (!strcmp(cmd, "data")) { | |
169 if (av[1] && isdigit(*av[1])) { | |
170 n = atoi(av[1]); | |
171 if (n < ce->ndcont) { | |
172 printf(ce->dcont[n]); | |
173 fputs("\n", stdout); | |
174 } | |
175 else if (ce->ndcont == 0) | |
176 printf("No data at this node.\n"); | |
177 else printf("Must be in range 0 - %d.\n", ce->ndcont); | |
178 } | |
179 } | |
180 | |
181 /* show where we are in the tree */ | |
182 else if (!strcmp(cmd, "where")) PrintLocation(ce, stdout); | |
183 | |
184 /* show where we are in the tree */ | |
185 else if (!strcmp(cmd, "pwd")) PrElemPlusID(ce); | |
186 | |
187 /* perform query with yes/no answer */ | |
188 else if (!strcmp(cmd, "q") && av[1] && av[2]) | |
189 do_query(ce, av[1], av[2]); | |
190 | |
191 /* perform query printing paths to matching elements */ | |
192 else if (!strcmp(cmd, "find") && av[1] && av[2]) | |
193 do_find(ce, av); | |
194 | |
195 /* list locations where specified ID(s) occur */ | |
196 else if (!strcmp(cmd, "id")) { | |
197 if (ac <= 1) continue; | |
198 if (*av[1] == '?') PrintIDList(); | |
199 else { | |
200 /* short: "id i1 i2 ...", long: "id -l i1 i2 ..." */ | |
201 if (!strcmp(av[1], "-l")) n = 2; | |
202 else n = 1; | |
203 for (i=n; i<ac; i++) { | |
204 if ((e = FindElemByID(av[i]))) { | |
205 if (n == 2) { /* long (multiline) format */ | |
206 if (n != i) putchar('\n'); | |
207 PrintLocation(e, stdout); | |
208 } | |
209 else PrElemPlusID(e); | |
210 } | |
211 else printf("Element with ID '%s' not found.\n", av[i]); | |
212 } | |
213 } | |
214 } | |
215 | |
216 /* show and set variables */ | |
217 else if (!strcmp(cmd, "show") && av[1]) { | |
218 printf("%s\n", FindMappingVal(Variables, av[1])); | |
219 } | |
220 else if (!strcmp(cmd, "set") && av[1] && av[2]) { | |
221 SetMappingNV(Variables, av[1], av[2]); | |
222 } | |
223 | |
224 /* print summary of tag usage */ | |
225 else if (!strcmp(cmd, "sum")) { | |
226 if (ac > 1) PrintElemSummary(ce); | |
227 else PrintElemSummary(DocTree); | |
228 } | |
229 /* print element tree */ | |
230 else if (!strcmp(cmd, "tree")) { | |
231 if (ac > 1) PrintElemTree(ce); | |
232 else PrintElemTree(DocTree); | |
233 } | |
234 /* print statistics */ | |
235 else if (!strcmp(cmd, "stat")) { | |
236 if (ac > 1) PrintStats(ce); | |
237 else PrintStats(DocTree); | |
238 } | |
239 /* print context of each element of tree */ | |
240 else if (!strcmp(cmd, "cont")) { | |
241 if (ac > 1) PrintContext(ce); | |
242 else PrintContext(DocTree); | |
243 } | |
244 /* print translation, given transpec */ | |
245 else if (!strcmp(cmd, "tran")) { | |
246 FILE *fp; | |
247 if (ac > 2){ | |
248 if (!(fp = fopen(av[2], "w"))) { | |
249 perror("Can not open output file"); | |
250 continue; | |
251 } | |
252 } | |
253 else fp = stdout; | |
254 DoTranslate(ce, av[1], fp); | |
255 if (ac > 2) fclose(fp); | |
256 } | |
257 else if (!strcmp(cmd, "sdata")){ | |
258 sdatafile = strdup(av[1]); | |
259 ReadSDATA(sdatafile); | |
260 } | |
261 else if (!strcmp(cmd, "cmap")){ | |
262 cmapfile = strdup(av[1]); | |
263 ReadCharMap(cmapfile); | |
264 } | |
265 | |
266 else if (!strcmp(cmd, "help") || *cmd == '?') { | |
267 sv = br_help_msg; | |
268 while (*sv) puts(*sv++); | |
269 } | |
270 | |
271 /* quit (control-D also works) */ | |
272 else if (!strcmp(cmd, "quit")) break; | |
273 | |
274 else | |
275 fprintf(stderr, "Unknown command '%s' - ingored.\n", cmd); | |
276 } | |
277 putc(NL, stdout); | |
278 } | |
279 | |
280 /* ______________________________________________________________________ */ | |
281 /* Do the "ls" command. | |
282 * Arguments: | |
283 * Pointer to element under consideration. | |
284 * Arg count from command line (this command, not the shell command). | |
285 * Arg vector. | |
286 */ | |
287 | |
288 static void | |
289 ls_node( | |
290 Element_t *e, | |
291 int ac, | |
292 char **av | |
293 ) | |
294 { | |
295 int i; | |
296 char buf[LINESIZE]; | |
297 | |
298 if (ac > 1 && !strcmp(av[1], "-n")) { | |
299 for(i=0; i<e->ncont; i++) { | |
300 if (IsContElem(e,i)) printf("%s\n", ContElem(e,i)->gi); | |
301 else if (IsContData(e,i)) printf("#data %s\n", ContData(e,i)); | |
302 else if (IsContPI(e,i)) printf("#pi %s\n", ContData(e,i)); | |
303 } | |
304 return; | |
305 } | |
306 | |
307 printf("Element: %s\tLineNumber: %d\n", e->gi, e->lineno); | |
308 if (e->parent) | |
309 printf("Context: %s\n", FindContext(e, 20, buf)); | |
310 | |
311 if (e->natts) { | |
312 printf("%d attributes:\n", e->natts); | |
313 for (i=0; i<e->natts; i++) | |
314 printf("\t%2d: %s = '%s'\n", i, e->atts[i].name, e->atts[i].sval); | |
315 } | |
316 if (e->entity) { | |
317 printf("Entity & notation information:\n"); | |
318 if (e->entity->ename) | |
319 printf("Entity name: %s\n", e->entity->ename); | |
320 if (e->entity->nname) | |
321 printf("Notation name: %s\n", e->entity->nname); | |
322 if (e->entity->sysid) | |
323 printf("Sys id: %s\n", e->entity->sysid); | |
324 if (e->entity->pubid) | |
325 printf("Pub id: %s\n", e->entity->pubid); | |
326 if (e->entity->fname) | |
327 printf("Filename: %s\n", e->entity->fname); | |
328 } | |
329 | |
330 if (e->my_eorder >= 0) | |
331 printf("My order among my siblings: %d\n", e->my_eorder); | |
332 | |
333 if (e->necont) { | |
334 printf("%d child element nodes:\n", e->necont); | |
335 for(i=0; i<e->necont; i++) printf("\t%2d: %s\n", i, e->econt[i]->gi); | |
336 } | |
337 | |
338 if (e->ndcont) { | |
339 printf("%d child data nodes:\n", e->ndcont); | |
340 for(i=0; i<e->ndcont; i++) { | |
341 if (strlen(e->dcont[i]) < 40) | |
342 printf("\t%2d: %s\n", i, e->dcont[i]); | |
343 else | |
344 printf("\t%2d: %-40.40s...\n", i, e->dcont[i]); | |
345 } | |
346 } | |
347 } | |
348 | |
349 /* ______________________________________________________________________ */ | |
350 /* Perform query. Syntax: find relationship gi. Tells whether gi has | |
351 * given relationship to current element. Result (message) sent to stdout. | |
352 * Args: | |
353 * Pointer to element under consideration. | |
354 * Pointer to name of relationship. (see FindRelByName() for names) | |
355 * Pointer to GI to look for. | |
356 */ | |
357 | |
358 static void | |
359 do_query( | |
360 Element_t *e, | |
361 char *rel, | |
362 char *gi | |
363 ) | |
364 { | |
365 char *cp; | |
366 Relation_t r; | |
367 Element_t *ep; | |
368 | |
369 for (cp=gi; *cp; cp++) if (islower(*cp)) *cp = toupper(*cp); | |
370 | |
371 if ((r = FindRelByName(rel)) == REL_Unknown) { | |
372 return; | |
373 } | |
374 ep = QRelation(e, gi, r); | |
375 printf("%s, '%s' is%s %s of '%s'.\n", (ep ? "Yes" : "No"), gi, | |
376 (ep ? "" : " not"), rel, e->gi); | |
377 } | |
378 | |
379 /* ______________________________________________________________________ */ | |
380 /* Print path to the element and its ID (if it has one) on a single line. | |
381 * Arguments: | |
382 * Pointer to element under consideration. | |
383 */ | |
384 static void | |
385 PrElemPlusID( | |
386 Element_t *e | |
387 ) | |
388 { | |
389 char buf[LINESIZE]; | |
390 | |
391 if (e->id) printf("%s -- ID=%s\n", FindElementPath(e, buf), e->id); | |
392 else printf("%s\n", FindElementPath(e, buf)); | |
393 } | |
394 | |
395 /* ______________________________________________________________________ */ | |
396 /* Print path to the element and its ID (if it has one) on a single line. | |
397 * Arguments: | |
398 * Pointer to element under consideration. | |
399 */ | |
400 | |
401 static void | |
402 match_gi( | |
403 Element_t *e, | |
404 char **av | |
405 ) | |
406 { | |
407 if (!strcmp(av[1], e->gi)) PrElemPlusID(e); | |
408 } | |
409 | |
410 /* Shorthand for defining simple finctions, which are just interfaces to | |
411 * calling QRelation(). DescendTree() only passes ptr to element. */ | |
412 #define MATCH(Fun,Rel) \ | |
413 static void Fun(Element_t *e, char **av) \ | |
414 { if (QRelation(e, av[1], Rel)) PrElemPlusID(e); } | |
415 | |
416 MATCH(match_parent, REL_Parent) | |
417 MATCH(match_child, REL_Child) | |
418 MATCH(match_anc, REL_Ancestor) | |
419 MATCH(match_desc, REL_Descendant) | |
420 MATCH(match_sib, REL_Sibling) | |
421 | |
422 static void | |
423 match_attr( | |
424 Element_t *e, | |
425 char **av | |
426 ) | |
427 { | |
428 char *atval; | |
429 | |
430 if ((atval = FindAttValByName(e, av[1])) && !strcmp(av[2], atval)) | |
431 PrElemPlusID(e); | |
432 } | |
433 | |
434 static void | |
435 match_cont( | |
436 Element_t *e, | |
437 char **av | |
438 ) | |
439 { | |
440 int i; | |
441 for (i=0; i<e->ncont; i++) { | |
442 if (IsContData(e,i) && strstr(ContData(e,i), av[1])) { | |
443 PrElemPlusID(e); | |
444 return; | |
445 } | |
446 } | |
447 } | |
448 | |
449 /* Find an element, given the criteria on its command line. | |
450 * Arguments: | |
451 * Pointer to element under consideration. | |
452 */ | |
453 static void | |
454 do_find( | |
455 Element_t *e, | |
456 char **av | |
457 ) | |
458 { | |
459 av++; | |
460 if (!strcmp(av[0], ".")) av++; | |
461 else e = DocTree; | |
462 if (!strcmp(av[0], "gi")) DescendTree(e, match_gi, 0, 0, av); | |
463 else if (!strcmp(av[0], "attr")) DescendTree(e, match_attr, 0, 0, av); | |
464 else if (!strcmp(av[0], "parent")) DescendTree(e, match_parent, 0, 0, av); | |
465 else if (!strcmp(av[0], "child")) DescendTree(e, match_child, 0, 0, av); | |
466 else if (!strcmp(av[0], "cont")) DescendTree(e, match_cont, 0, 0, av); | |
467 else if (!strcmp(av[0], "sib")) DescendTree(e, match_sib, 0, 0, av); | |
468 else if (!strcmp(av[0], "desc")) DescendTree(e, match_desc, 0, 0, av); | |
469 else if (!strcmp(av[0], "anc")) DescendTree(e, match_anc, 0, 0, av); | |
470 else fprintf(stderr, "Unknown find command: %s.\n", av[0]); | |
471 } | |
472 | |
473 /* ______________________________________________________________________ */ |