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 /* ______________________________________________________________________ */