Mercurial > illumos > onarm
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/cmd/man/src/util/instant.src/browse.c Tue Jun 02 18:56:50 2009 +0900 @@ -0,0 +1,473 @@ +/* + * Copyright 1993 Open Software Foundation, Inc., Cambridge, Massachusetts. + * All rights reserved. + */ +/* +#pragma ident "@(#)browse.c 1.3 00/07/17 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]); +} + +/* ______________________________________________________________________ */