Mercurial > illumos > onarm
view usr/src/cmd/man/src/util/instant.src/browse.c @ 4:1a15d5aaf794
synchronized with onnv_86 (6202) in onnv-gate
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Mon, 31 Aug 2009 14:38:03 +0900 |
parents | c9caec207d52 |
children |
line wrap: on
line source
/* * Copyright 1993 Open Software Foundation, Inc., Cambridge, Massachusetts. * All rights reserved. */ /* #pragma ident "%Z%%M% %I% %E% SMI" * Copyright (c) 1994 * Open Software Foundation, Inc. * * Permission is hereby granted to use, copy, modify and freely distribute * the software in this file and its documentation for any purpose without * fee, provided that the above copyright notice appears in all copies and * that both the copyright notice and this permission notice appear in * supporting documentation. Further, provided that the name of Open * Software Foundation, Inc. ("OSF") not be used in advertising or * publicity pertaining to distribution of the software without prior * written permission from OSF. OSF makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. */ /* * Copyright (c) 1996 X Consortium * Copyright (c) 1995, 1996 Dalrymple Consulting * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * X CONSORTIUM OR DALRYMPLE CONSULTING BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the names of the X Consortium and * Dalrymple Consulting shall not be used in advertising or otherwise to * promote the sale, use or other dealings in this Software without prior * written authorization. */ /* ________________________________________________________________________ * * Module for interactive browsing. * * Entry points for this module: * Browse() interactive browser * ________________________________________________________________________ */ #ifndef lint static char *RCSid = "$Header: /usr/src/docbook-to-man/Instant/RCS/browse.c,v 1.2 1996/06/02 21:46:10 fld Exp $"; #endif #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include "general.h" static void PrElemPlusID(Element_t *); static void ls_node(Element_t *, int, char **); static void do_query(Element_t *, char *, char *); static void do_find(Element_t *, char **); /* ______________________________________________________________________ */ static char *br_help_msg[] = { " ls List info about current element in tree", " (context, children, attributes, etc.)", " cd N ... Change to Nth elememt child, where N is shown by 'ls'.", " N may also be '/' (top) or '..' (up).", " cd id I Change to elememt whose ID is I", " data N Show data of Nth data node", " where Show current position in the tree", " id I Show path to element with id I", " (using '?' for I will lists all IDs and their paths)", " find S Find elements matching spec S. Recognized syntaxes:", " find attr <name> <value>", " find cont <string>", " find parent <gi-name>", " find child <gi-name>", " find gi <gi-name>", " q rel gi Query: report if elem 'gi' has relation to current elem", " ('rel' is one of 'child parent ancestor descendant", " sibling sibling+ sibling+1 sibling- sibling-1 cousin')", "", " tran file [outfile]", " With trans spec in 'file' translate into 'outfile' (stdout)", " sdata file Read SDATA map file (for translations).", " cmap file Read character map file (for translations).", " stat Print statistics (how often elements occur, etc.)", " sum Print elem usage summary (# of children, depth, etc.)", " tree Print document hierarchy as a tree", " cont Print context of each element", NULL }; /* ______________________________________________________________________ */ void Browse() { char buf[256], *cmd, **av, **sv, *cmapfile, *sdatafile; char *Prompt; Element_t *ce; /* current element */ Element_t *e; int i, n, ac; if (slave) Prompt = "=>\n"; else Prompt = "=> "; ce = DocTree; while (fputs(Prompt, stdout)) { if (!fgets(buf, 256, stdin)) break; stripNL(buf); if (buf[0] == EOS) { fputs(Prompt, stdout); continue; } ac = 20; av = Split(buf, &ac, S_ALVEC); if (ac > 0) cmd = av[0]; if (!cmd || !(*cmd)) continue; if (!strcmp(cmd, "ls")) ls_node(ce, ac, av); else if (!strcmp(cmd, "cd")) { if (av[1]) { if (ac == 3 && !strcmp(av[1], "id")) { if ((e = FindElemByID(av[2]))) ce = e; else printf("Element with ID '%s' not found.\n", av[2]); continue; } for (i=1; i<ac; i++) { if (!strcmp(av[i], "..")) { if (ce->parent) ce = ce->parent; continue; } if (!strcmp(av[i], "/")) { if (ce->parent) ce = DocTree; continue; } if (!isdigit(*av[i])) { printf("Expecting digit, '..', or '/', got '%s'.\n", av[i]); break; } n = atoi(av[i]); if (n < ce->necont) ce = ce->econt[n]; else { printf("Must be in range 0 - %d.\n", ce->necont); break; } } } } else if (!strcmp(cmd, "data")) { if (av[1] && isdigit(*av[1])) { n = atoi(av[1]); if (n < ce->ndcont) { printf(ce->dcont[n]); fputs("\n", stdout); } else if (ce->ndcont == 0) printf("No data at this node.\n"); else printf("Must be in range 0 - %d.\n", ce->ndcont); } } /* show where we are in the tree */ else if (!strcmp(cmd, "where")) PrintLocation(ce, stdout); /* show where we are in the tree */ else if (!strcmp(cmd, "pwd")) PrElemPlusID(ce); /* perform query with yes/no answer */ else if (!strcmp(cmd, "q") && av[1] && av[2]) do_query(ce, av[1], av[2]); /* perform query printing paths to matching elements */ else if (!strcmp(cmd, "find") && av[1] && av[2]) do_find(ce, av); /* list locations where specified ID(s) occur */ else if (!strcmp(cmd, "id")) { if (ac <= 1) continue; if (*av[1] == '?') PrintIDList(); else { /* short: "id i1 i2 ...", long: "id -l i1 i2 ..." */ if (!strcmp(av[1], "-l")) n = 2; else n = 1; for (i=n; i<ac; i++) { if ((e = FindElemByID(av[i]))) { if (n == 2) { /* long (multiline) format */ if (n != i) putchar('\n'); PrintLocation(e, stdout); } else PrElemPlusID(e); } else printf("Element with ID '%s' not found.\n", av[i]); } } } /* show and set variables */ else if (!strcmp(cmd, "show") && av[1]) { printf("%s\n", FindMappingVal(Variables, av[1])); } else if (!strcmp(cmd, "set") && av[1] && av[2]) { SetMappingNV(Variables, av[1], av[2]); } /* print summary of tag usage */ else if (!strcmp(cmd, "sum")) { if (ac > 1) PrintElemSummary(ce); else PrintElemSummary(DocTree); } /* print element tree */ else if (!strcmp(cmd, "tree")) { if (ac > 1) PrintElemTree(ce); else PrintElemTree(DocTree); } /* print statistics */ else if (!strcmp(cmd, "stat")) { if (ac > 1) PrintStats(ce); else PrintStats(DocTree); } /* print context of each element of tree */ else if (!strcmp(cmd, "cont")) { if (ac > 1) PrintContext(ce); else PrintContext(DocTree); } /* print translation, given transpec */ else if (!strcmp(cmd, "tran")) { FILE *fp; if (ac > 2){ if (!(fp = fopen(av[2], "w"))) { perror("Can not open output file"); continue; } } else fp = stdout; DoTranslate(ce, av[1], fp); if (ac > 2) fclose(fp); } else if (!strcmp(cmd, "sdata")){ sdatafile = strdup(av[1]); ReadSDATA(sdatafile); } else if (!strcmp(cmd, "cmap")){ cmapfile = strdup(av[1]); ReadCharMap(cmapfile); } else if (!strcmp(cmd, "help") || *cmd == '?') { sv = br_help_msg; while (*sv) puts(*sv++); } /* quit (control-D also works) */ else if (!strcmp(cmd, "quit")) break; else fprintf(stderr, "Unknown command '%s' - ingored.\n", cmd); } putc(NL, stdout); } /* ______________________________________________________________________ */ /* Do the "ls" command. * Arguments: * Pointer to element under consideration. * Arg count from command line (this command, not the shell command). * Arg vector. */ static void ls_node( Element_t *e, int ac, char **av ) { int i; char buf[LINESIZE]; if (ac > 1 && !strcmp(av[1], "-n")) { for(i=0; i<e->ncont; i++) { if (IsContElem(e,i)) printf("%s\n", ContElem(e,i)->gi); else if (IsContData(e,i)) printf("#data %s\n", ContData(e,i)); else if (IsContPI(e,i)) printf("#pi %s\n", ContData(e,i)); } return; } printf("Element: %s\tLineNumber: %d\n", e->gi, e->lineno); if (e->parent) printf("Context: %s\n", FindContext(e, 20, buf)); if (e->natts) { printf("%d attributes:\n", e->natts); for (i=0; i<e->natts; i++) printf("\t%2d: %s = '%s'\n", i, e->atts[i].name, e->atts[i].sval); } if (e->entity) { printf("Entity & notation information:\n"); if (e->entity->ename) printf("Entity name: %s\n", e->entity->ename); if (e->entity->nname) printf("Notation name: %s\n", e->entity->nname); if (e->entity->sysid) printf("Sys id: %s\n", e->entity->sysid); if (e->entity->pubid) printf("Pub id: %s\n", e->entity->pubid); if (e->entity->fname) printf("Filename: %s\n", e->entity->fname); } if (e->my_eorder >= 0) printf("My order among my siblings: %d\n", e->my_eorder); if (e->necont) { printf("%d child element nodes:\n", e->necont); for(i=0; i<e->necont; i++) printf("\t%2d: %s\n", i, e->econt[i]->gi); } if (e->ndcont) { printf("%d child data nodes:\n", e->ndcont); for(i=0; i<e->ndcont; i++) { if (strlen(e->dcont[i]) < 40) printf("\t%2d: %s\n", i, e->dcont[i]); else printf("\t%2d: %-40.40s...\n", i, e->dcont[i]); } } } /* ______________________________________________________________________ */ /* Perform query. Syntax: find relationship gi. Tells whether gi has * given relationship to current element. Result (message) sent to stdout. * Args: * Pointer to element under consideration. * Pointer to name of relationship. (see FindRelByName() for names) * Pointer to GI to look for. */ static void do_query( Element_t *e, char *rel, char *gi ) { char *cp; Relation_t r; Element_t *ep; for (cp=gi; *cp; cp++) if (islower(*cp)) *cp = toupper(*cp); if ((r = FindRelByName(rel)) == REL_Unknown) { return; } ep = QRelation(e, gi, r); printf("%s, '%s' is%s %s of '%s'.\n", (ep ? "Yes" : "No"), gi, (ep ? "" : " not"), rel, e->gi); } /* ______________________________________________________________________ */ /* Print path to the element and its ID (if it has one) on a single line. * Arguments: * Pointer to element under consideration. */ static void PrElemPlusID( Element_t *e ) { char buf[LINESIZE]; if (e->id) printf("%s -- ID=%s\n", FindElementPath(e, buf), e->id); else printf("%s\n", FindElementPath(e, buf)); } /* ______________________________________________________________________ */ /* Print path to the element and its ID (if it has one) on a single line. * Arguments: * Pointer to element under consideration. */ static void match_gi( Element_t *e, char **av ) { if (!strcmp(av[1], e->gi)) PrElemPlusID(e); } /* Shorthand for defining simple finctions, which are just interfaces to * calling QRelation(). DescendTree() only passes ptr to element. */ #define MATCH(Fun,Rel) \ static void Fun(Element_t *e, char **av) \ { if (QRelation(e, av[1], Rel)) PrElemPlusID(e); } MATCH(match_parent, REL_Parent) MATCH(match_child, REL_Child) MATCH(match_anc, REL_Ancestor) MATCH(match_desc, REL_Descendant) MATCH(match_sib, REL_Sibling) static void match_attr( Element_t *e, char **av ) { char *atval; if ((atval = FindAttValByName(e, av[1])) && !strcmp(av[2], atval)) PrElemPlusID(e); } static void match_cont( Element_t *e, char **av ) { int i; for (i=0; i<e->ncont; i++) { if (IsContData(e,i) && strstr(ContData(e,i), av[1])) { PrElemPlusID(e); return; } } } /* Find an element, given the criteria on its command line. * Arguments: * Pointer to element under consideration. */ static void do_find( Element_t *e, char **av ) { av++; if (!strcmp(av[0], ".")) av++; else e = DocTree; if (!strcmp(av[0], "gi")) DescendTree(e, match_gi, 0, 0, av); else if (!strcmp(av[0], "attr")) DescendTree(e, match_attr, 0, 0, av); else if (!strcmp(av[0], "parent")) DescendTree(e, match_parent, 0, 0, av); else if (!strcmp(av[0], "child")) DescendTree(e, match_child, 0, 0, av); else if (!strcmp(av[0], "cont")) DescendTree(e, match_cont, 0, 0, av); else if (!strcmp(av[0], "sib")) DescendTree(e, match_sib, 0, 0, av); else if (!strcmp(av[0], "desc")) DescendTree(e, match_desc, 0, 0, av); else if (!strcmp(av[0], "anc")) DescendTree(e, match_anc, 0, 0, av); else fprintf(stderr, "Unknown find command: %s.\n", av[0]); } /* ______________________________________________________________________ */