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]);
+}
+
+/* ______________________________________________________________________ */