18462SApril.Chin@Sun.COM#!/usr/bin/ksh93 28462SApril.Chin@Sun.COM 38462SApril.Chin@Sun.COM# 48462SApril.Chin@Sun.COM# CDDL HEADER START 58462SApril.Chin@Sun.COM# 68462SApril.Chin@Sun.COM# The contents of this file are subject to the terms of the 78462SApril.Chin@Sun.COM# Common Development and Distribution License (the "License"). 88462SApril.Chin@Sun.COM# You may not use this file except in compliance with the License. 98462SApril.Chin@Sun.COM# 108462SApril.Chin@Sun.COM# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 118462SApril.Chin@Sun.COM# or http://www.opensolaris.org/os/licensing. 128462SApril.Chin@Sun.COM# See the License for the specific language governing permissions 138462SApril.Chin@Sun.COM# and limitations under the License. 148462SApril.Chin@Sun.COM# 158462SApril.Chin@Sun.COM# When distributing Covered Code, include this CDDL HEADER in each 168462SApril.Chin@Sun.COM# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 178462SApril.Chin@Sun.COM# If applicable, add the following below this CDDL HEADER, with the 188462SApril.Chin@Sun.COM# fields enclosed by brackets "[]" replaced with your own identifying 198462SApril.Chin@Sun.COM# information: Portions Copyright [yyyy] [name of copyright owner] 208462SApril.Chin@Sun.COM# 218462SApril.Chin@Sun.COM# CDDL HEADER END 228462SApril.Chin@Sun.COM# 238462SApril.Chin@Sun.COM 248462SApril.Chin@Sun.COM# 25*10898Sroland.mainz@nrubsig.org# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 268462SApril.Chin@Sun.COM# Use is subject to license terms. 278462SApril.Chin@Sun.COM# 288462SApril.Chin@Sun.COM 298462SApril.Chin@Sun.COM# Solaris needs /usr/xpg6/bin:/usr/xpg4/bin because the tools in /usr/bin are not POSIX-conformant 308462SApril.Chin@Sun.COMexport PATH=/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin 318462SApril.Chin@Sun.COM 328462SApril.Chin@Sun.COMfunction fatal_error 338462SApril.Chin@Sun.COM{ 348462SApril.Chin@Sun.COM print -u 2 "${progname}: $*" 358462SApril.Chin@Sun.COM exit 1 368462SApril.Chin@Sun.COM} 378462SApril.Chin@Sun.COM 388462SApril.Chin@Sun.COMfunction attrstrtoattrarray 398462SApril.Chin@Sun.COM{ 408462SApril.Chin@Sun.COM#set -o xtrace 418462SApril.Chin@Sun.COM typeset s="$1" 428462SApril.Chin@Sun.COM nameref aa=$2 # attribute array 438462SApril.Chin@Sun.COM integer aa_count=0 448462SApril.Chin@Sun.COM integer aa_count=0 458462SApril.Chin@Sun.COM typeset nextattr 468462SApril.Chin@Sun.COM integer currattrlen=0 478462SApril.Chin@Sun.COM typeset tagstr 488462SApril.Chin@Sun.COM typeset tagval 498462SApril.Chin@Sun.COM 508462SApril.Chin@Sun.COM while (( ${#s} > 0 )) ; do 518462SApril.Chin@Sun.COM # skip whitespaces 528462SApril.Chin@Sun.COM while [[ "${s:currattrlen:1}" == ~(E)[[:blank:][:space:]] ]] ; do 538462SApril.Chin@Sun.COM (( currattrlen++ )) 548462SApril.Chin@Sun.COM done 558462SApril.Chin@Sun.COM s="${s:currattrlen:${#s}}" 568462SApril.Chin@Sun.COM 578462SApril.Chin@Sun.COM # anything left ? 588462SApril.Chin@Sun.COM (( ${#s} == 0 )) && break 598462SApril.Chin@Sun.COM 608462SApril.Chin@Sun.COM # Pattern tests: 618462SApril.Chin@Sun.COM #x="foo=bar huz=123" ; print "${x##~(E)[[:alnum:]_-:]*=[^[:blank:]\"]*}" 628462SApril.Chin@Sun.COM #x='foo="ba=r o" huz=123' ; print "${x##~(E)[[:alnum:]_-:]*=\"[^\"]*\"}" 638462SApril.Chin@Sun.COM #x="foo='ba=r o' huz=123" ; print "${x##~(E)[[:alnum:]_-:]*=\'[^\"]*\'}" 648462SApril.Chin@Sun.COM #x="foox huz=123" ; print "${x##~(E)[[:alnum:]_-:]*}" 658462SApril.Chin@Sun.COM # All pattern combined via eregex (w|x|y|z): 668462SApril.Chin@Sun.COM #x='foo="bar=o" huz=123' ; print "${x##~(E)([[:alnum:]_-:]*=[^[:blank:]\"]*|[[:alnum:]_-:]*=\"[^\"]*\"|[[:alnum:]_-:]*=\'[^\"]*\')}" 678462SApril.Chin@Sun.COM nextattr="${s##~(E)([[:alnum:]_-:]*=[^[:blank:]\"]*|[[:alnum:]_-:]*=\"[^\"]*\"|[[:alnum:]_-:]*=\'[^\"]*\'|[[:alnum:]_-:]*)}" 688462SApril.Chin@Sun.COM currattrlen=$(( ${#s} - ${#nextattr})) 698462SApril.Chin@Sun.COM 708462SApril.Chin@Sun.COM # add entry 718462SApril.Chin@Sun.COM tagstr="${s:0:currattrlen}" 728462SApril.Chin@Sun.COM if [[ "${tagstr}" == *=* ]] ; then 738462SApril.Chin@Sun.COM # normal case: attribute with value 748462SApril.Chin@Sun.COM 758462SApril.Chin@Sun.COM tagval="${tagstr#*=}" 768462SApril.Chin@Sun.COM 778462SApril.Chin@Sun.COM # strip quotes ('' or "") 788462SApril.Chin@Sun.COM if [[ "${tagval}" == ~(Elr)(\'.*\'|\".*\") ]] ; then 798462SApril.Chin@Sun.COM tagval="${tagval:1:${#tagval}-2}" 808462SApril.Chin@Sun.COM fi 818462SApril.Chin@Sun.COM 828462SApril.Chin@Sun.COM aa[${aa_count}]=( name="${tagstr%%=*}" value="${tagval}" ) 838462SApril.Chin@Sun.COM else 848462SApril.Chin@Sun.COM # special case for HTML where you have something like <foo baz> 858462SApril.Chin@Sun.COM aa[${aa_count}]=( name="${tagstr}" ) 868462SApril.Chin@Sun.COM fi 878462SApril.Chin@Sun.COM (( aa_count++ )) 888462SApril.Chin@Sun.COM (( aa_count > 1000 )) && fatal_error "$0: aa_count too large" # assert 898462SApril.Chin@Sun.COM done 908462SApril.Chin@Sun.COM} 918462SApril.Chin@Sun.COM 928462SApril.Chin@Sun.COM 938462SApril.Chin@Sun.COMfunction handle_document 948462SApril.Chin@Sun.COM{ 958462SApril.Chin@Sun.COM#set -o xtrace 968462SApril.Chin@Sun.COM nameref callbacks=${1} 978462SApril.Chin@Sun.COM typeset tag_type="${2}" 988462SApril.Chin@Sun.COM typeset tag_value="${3}" 998462SApril.Chin@Sun.COM typeset tag_attributes="${4}" 1008462SApril.Chin@Sun.COM nameref doc=${callbacks["arg_tree"]} 1018462SApril.Chin@Sun.COM nameref nodepath="${stack.items[stack.pos]}" 1028462SApril.Chin@Sun.COM nameref nodesnum="${stack.items[stack.pos]}num" 1038462SApril.Chin@Sun.COM 1048462SApril.Chin@Sun.COM case "${tag_type}" in 1058462SApril.Chin@Sun.COM tag_begin) 1068462SApril.Chin@Sun.COM nodepath[${nodesnum}]+=( 1078462SApril.Chin@Sun.COM typeset tagtype="element" 1088462SApril.Chin@Sun.COM typeset tagname="${tag_value}" 109*10898Sroland.mainz@nrubsig.org compound -A tagattributes 110*10898Sroland.mainz@nrubsig.org compound -A nodes 1118462SApril.Chin@Sun.COM integer nodesnum=0 1128462SApril.Chin@Sun.COM ) 1138462SApril.Chin@Sun.COM 1148462SApril.Chin@Sun.COM # fill attributes 1158462SApril.Chin@Sun.COM if [[ "${tag_attributes}" != "" ]] ; then 1168462SApril.Chin@Sun.COM attrstrtoattrarray "${tag_attributes}" "nodepath[${nodesnum}].tagattributes" 1178462SApril.Chin@Sun.COM fi 1188462SApril.Chin@Sun.COM 1198462SApril.Chin@Sun.COM (( stack.pos++ )) 1208462SApril.Chin@Sun.COM stack.items[stack.pos]="${stack.items[stack.pos-1]}[${nodesnum}].nodes" 1218462SApril.Chin@Sun.COM (( nodesnum++ )) 1228462SApril.Chin@Sun.COM ;; 1238462SApril.Chin@Sun.COM tag_end) 1248462SApril.Chin@Sun.COM (( stack.pos-- )) 1258462SApril.Chin@Sun.COM ;; 1268462SApril.Chin@Sun.COM tag_text) 1278462SApril.Chin@Sun.COM nodepath[${nodesnum}]+=( 1288462SApril.Chin@Sun.COM typeset tagtype="text" 1298462SApril.Chin@Sun.COM typeset tagvalue="${tag_value}" 1308462SApril.Chin@Sun.COM ) 1318462SApril.Chin@Sun.COM (( nodesnum++ )) 1328462SApril.Chin@Sun.COM ;; 1338462SApril.Chin@Sun.COM tag_comment) 1348462SApril.Chin@Sun.COM nodepath[${nodesnum}]+=( 1358462SApril.Chin@Sun.COM typeset tagtype="comment" 1368462SApril.Chin@Sun.COM typeset tagvalue="${tag_value}" 1378462SApril.Chin@Sun.COM ) 1388462SApril.Chin@Sun.COM (( nodesnum++ )) 1398462SApril.Chin@Sun.COM ;; 1408462SApril.Chin@Sun.COM document_start) 1418462SApril.Chin@Sun.COM ;; 1428462SApril.Chin@Sun.COM document_end) 1438462SApril.Chin@Sun.COM ;; 1448462SApril.Chin@Sun.COM esac 1458462SApril.Chin@Sun.COM 1468462SApril.Chin@Sun.COM# print "xmltok: '${tag_type}' = '${tag_value}'" 1478462SApril.Chin@Sun.COM} 1488462SApril.Chin@Sun.COM 1498462SApril.Chin@Sun.COMfunction xml_tok 1508462SApril.Chin@Sun.COM{ 1518462SApril.Chin@Sun.COM typeset buf="" 1528462SApril.Chin@Sun.COM typeset namebuf="" 1538462SApril.Chin@Sun.COM typeset attrbuf="" 1548462SApril.Chin@Sun.COM typeset c="" 1558462SApril.Chin@Sun.COM typeset isendtag # bool: true/false 1568462SApril.Chin@Sun.COM typeset issingletag # bool: true/false (used for tags like "<br />") 1578462SApril.Chin@Sun.COM nameref callbacks=${1} 1588462SApril.Chin@Sun.COM 1598462SApril.Chin@Sun.COM [[ ! -z "${callbacks["document_start"]}" ]] && ${callbacks["document_start"]} "${1}" "document_start" 1608462SApril.Chin@Sun.COM 1618462SApril.Chin@Sun.COM while IFS='' read -r -N 1 c ; do 1628462SApril.Chin@Sun.COM isendtag=false 1638462SApril.Chin@Sun.COM 1648462SApril.Chin@Sun.COM if [[ "$c" == "<" ]] ; then 1658462SApril.Chin@Sun.COM # flush any text content 1668462SApril.Chin@Sun.COM if [[ "$buf" != "" ]] ; then 1678462SApril.Chin@Sun.COM [[ ! -z "${callbacks["tag_text"]}" ]] && ${callbacks["tag_text"]} "${1}" "tag_text" "$buf" 1688462SApril.Chin@Sun.COM buf="" 1698462SApril.Chin@Sun.COM fi 1708462SApril.Chin@Sun.COM 1718462SApril.Chin@Sun.COM IFS='' read -r -N 1 c 1728462SApril.Chin@Sun.COM if [[ "$c" == "/" ]] ; then 1738462SApril.Chin@Sun.COM isendtag=true 1748462SApril.Chin@Sun.COM else 1758462SApril.Chin@Sun.COM buf="$c" 1768462SApril.Chin@Sun.COM fi 1778462SApril.Chin@Sun.COM IFS='' read -r -d '>' c 1788462SApril.Chin@Sun.COM buf+="$c" 1798462SApril.Chin@Sun.COM 1808462SApril.Chin@Sun.COM # handle comments 1818462SApril.Chin@Sun.COM if [[ "$buf" == ~(El)!-- ]] ; then 1828462SApril.Chin@Sun.COM # did we read the comment completely ? 1838462SApril.Chin@Sun.COM if [[ "$buf" != ~(Elr)!--.*-- ]] ; then 1848462SApril.Chin@Sun.COM buf+=">" 1858462SApril.Chin@Sun.COM while [[ "$buf" != ~(Elr)!--.*-- ]] ; do 1868462SApril.Chin@Sun.COM IFS='' read -r -N 1 c || break 1878462SApril.Chin@Sun.COM buf+="$c" 1888462SApril.Chin@Sun.COM done 1898462SApril.Chin@Sun.COM fi 1908462SApril.Chin@Sun.COM 1918462SApril.Chin@Sun.COM [[ ! -z "${callbacks["tag_comment"]}" ]] && ${callbacks["tag_comment"]} "${1}" "tag_comment" "${buf:3:${#buf}-5}" 1928462SApril.Chin@Sun.COM buf="" 1938462SApril.Chin@Sun.COM continue 1948462SApril.Chin@Sun.COM fi 1958462SApril.Chin@Sun.COM 1968462SApril.Chin@Sun.COM # check if the tag starts and ends at the same time (like "<br />") 1978462SApril.Chin@Sun.COM if [[ "${buf}" == ~(Er).*/ ]] ; then 1988462SApril.Chin@Sun.COM issingletag=true 1998462SApril.Chin@Sun.COM buf="${buf%*/}" 2008462SApril.Chin@Sun.COM else 2018462SApril.Chin@Sun.COM issingletag=false 2028462SApril.Chin@Sun.COM fi 2038462SApril.Chin@Sun.COM 2048462SApril.Chin@Sun.COM # check if the tag has attributes (e.g. space after name) 2058462SApril.Chin@Sun.COM if [[ "$buf" == ~(E)[[:space:][:blank:]] ]] ; then 2068462SApril.Chin@Sun.COM namebuf="${buf%%~(E)[[:space:][:blank:]].*}" 2078462SApril.Chin@Sun.COM attrbuf="${buf#~(E).*[[:space:][:blank:]]}" 2088462SApril.Chin@Sun.COM else 2098462SApril.Chin@Sun.COM namebuf="$buf" 2108462SApril.Chin@Sun.COM attrbuf="" 2118462SApril.Chin@Sun.COM fi 2128462SApril.Chin@Sun.COM 2138462SApril.Chin@Sun.COM if ${isendtag} ; then 2148462SApril.Chin@Sun.COM [[ ! -z "${callbacks["tag_end"]}" ]] && ${callbacks["tag_end"]} "${1}" "tag_end" "$namebuf" 2158462SApril.Chin@Sun.COM else 2168462SApril.Chin@Sun.COM [[ ! -z "${callbacks["tag_begin"]}" ]] && ${callbacks["tag_begin"]} "${1}" "tag_begin" "$namebuf" "$attrbuf" 2178462SApril.Chin@Sun.COM 2188462SApril.Chin@Sun.COM # handle tags like <br/> (which are start- and end-tag in one piece) 2198462SApril.Chin@Sun.COM if ${issingletag} ; then 2208462SApril.Chin@Sun.COM [[ ! -z "${callbacks["tag_end"]}" ]] && ${callbacks["tag_end"]} "${1}" "tag_end" "$namebuf" 2218462SApril.Chin@Sun.COM fi 2228462SApril.Chin@Sun.COM fi 2238462SApril.Chin@Sun.COM buf="" 2248462SApril.Chin@Sun.COM else 2258462SApril.Chin@Sun.COM buf+="$c" 2268462SApril.Chin@Sun.COM fi 2278462SApril.Chin@Sun.COM done 2288462SApril.Chin@Sun.COM 2298462SApril.Chin@Sun.COM [[ ! -z "${callbacks["document_end"]}" ]] && ${callbacks["document_end"]} "${1}" "document_end" "exit_success" 2308462SApril.Chin@Sun.COM 2318462SApril.Chin@Sun.COM print # final newline to make filters like "sed" happy 2328462SApril.Chin@Sun.COM} 2338462SApril.Chin@Sun.COM 2348462SApril.Chin@Sun.COMfunction print_sample1_xml 2358462SApril.Chin@Sun.COM{ 2368462SApril.Chin@Sun.COMcat <<EOF 2378462SApril.Chin@Sun.COM<br /> 2388462SApril.Chin@Sun.COM<score-partwise instrument="flute1"> 2398462SApril.Chin@Sun.COM <identification> 2408462SApril.Chin@Sun.COM <kaiman>nocrocodile</kaiman> 2418462SApril.Chin@Sun.COM </identification> 2428462SApril.Chin@Sun.COM <!-- a comment --> 2438462SApril.Chin@Sun.COM <partlist> 2448462SApril.Chin@Sun.COM <foo>myfootext</foo> 2458462SApril.Chin@Sun.COM <bar>mybartext</bar> 2468462SApril.Chin@Sun.COM <snap /> 2478462SApril.Chin@Sun.COM <!-- another 2488462SApril.Chin@Sun.COM comment --> 2498462SApril.Chin@Sun.COM <ttt>myttttext</ttt> 2508462SApril.Chin@Sun.COM </partlist> 2518462SApril.Chin@Sun.COM</score-partwise> 2528462SApril.Chin@Sun.COMEOF 2538462SApril.Chin@Sun.COM} 2548462SApril.Chin@Sun.COM 2558462SApril.Chin@Sun.COMfunction usage 2568462SApril.Chin@Sun.COM{ 2578462SApril.Chin@Sun.COM OPTIND=0 2588462SApril.Chin@Sun.COM getopts -a "${progname}" "${xmldocumenttree1_usage}" OPT '-?' 2598462SApril.Chin@Sun.COM exit 2 2608462SApril.Chin@Sun.COM} 2618462SApril.Chin@Sun.COM 2628462SApril.Chin@Sun.COM# program start 2638462SApril.Chin@Sun.COMbuiltin basename 2648462SApril.Chin@Sun.COMbuiltin cat 2658462SApril.Chin@Sun.COMbuiltin date 2668462SApril.Chin@Sun.COMbuiltin uname 2678462SApril.Chin@Sun.COM 2688462SApril.Chin@Sun.COMtypeset progname="${ basename "${0}" ; }" 2698462SApril.Chin@Sun.COM 2708462SApril.Chin@Sun.COMtypeset -r xmldocumenttree1_usage=$'+ 271*10898Sroland.mainz@nrubsig.org[-?\n@(#)\$Id: xmldocumenttree1 (Roland Mainz) 2009-05-09 \$\n] 2728462SApril.Chin@Sun.COM[-author?Roland Mainz <roland.mainz@nrubsig.org>] 2738462SApril.Chin@Sun.COM[+NAME?xmldocumenttree1 - XML tree demo] 2748462SApril.Chin@Sun.COM[+DESCRIPTION?\bxmldocumenttree\b is a small ksh93 compound variable demo 2758462SApril.Chin@Sun.COM which reads a XML input file, converts it into an internal 2768462SApril.Chin@Sun.COM variable tree representation and outputs it in the format 277*10898Sroland.mainz@nrubsig.org specified by viewmode (either "list", "namelist", "tree" or "compacttree").] 2788462SApril.Chin@Sun.COM 2798462SApril.Chin@Sun.COMfile viewmode 2808462SApril.Chin@Sun.COM 2818462SApril.Chin@Sun.COM[+SEE ALSO?\bksh93\b(1)] 2828462SApril.Chin@Sun.COM' 2838462SApril.Chin@Sun.COM 2848462SApril.Chin@Sun.COMwhile getopts -a "${progname}" "${xmldocumenttree1_usage}" OPT ; do 2858462SApril.Chin@Sun.COM# printmsg "## OPT=|${OPT}|, OPTARG=|${OPTARG}|" 2868462SApril.Chin@Sun.COM case ${OPT} in 2878462SApril.Chin@Sun.COM *) usage ;; 2888462SApril.Chin@Sun.COM esac 2898462SApril.Chin@Sun.COMdone 2908462SApril.Chin@Sun.COMshift $((OPTIND-1)) 2918462SApril.Chin@Sun.COM 2928462SApril.Chin@Sun.COMtypeset xmlfile="$1" 2938462SApril.Chin@Sun.COMtypeset viewmode="$2" 2948462SApril.Chin@Sun.COM 2958462SApril.Chin@Sun.COMif [[ "${xmlfile}" == "" ]] ; then 2968462SApril.Chin@Sun.COM fatal_error $"No file given." 2978462SApril.Chin@Sun.COMfi 2988462SApril.Chin@Sun.COM 299*10898Sroland.mainz@nrubsig.orgif [[ "${viewmode}" != ~(Elr)(list|namelist|tree|compacttree) ]] ; then 3008462SApril.Chin@Sun.COM fatal_error $"Invalid view mode \"${viewmode}\"." 3018462SApril.Chin@Sun.COMfi 3028462SApril.Chin@Sun.COM 303*10898Sroland.mainz@nrubsig.orgcompound xdoc 304*10898Sroland.mainz@nrubsig.orgcompound -A xdoc.nodes 3058462SApril.Chin@Sun.COMinteger xdoc.nodesnum=0 3068462SApril.Chin@Sun.COM 307*10898Sroland.mainz@nrubsig.orgcompound stack 3088462SApril.Chin@Sun.COMtypeset -a stack.items=( [0]="doc.nodes" ) 3098462SApril.Chin@Sun.COMinteger stack.pos=0 3108462SApril.Chin@Sun.COM 3118462SApril.Chin@Sun.COM# setup callbacks for xml_tok 3128462SApril.Chin@Sun.COMtypeset -A document_cb # callbacks for xml_tok 3138462SApril.Chin@Sun.COMdocument_cb["document_start"]="handle_document" 3148462SApril.Chin@Sun.COMdocument_cb["document_end"]="handle_document" 3158462SApril.Chin@Sun.COMdocument_cb["tag_begin"]="handle_document" 3168462SApril.Chin@Sun.COMdocument_cb["tag_end"]="handle_document" 3178462SApril.Chin@Sun.COMdocument_cb["tag_text"]="handle_document" 3188462SApril.Chin@Sun.COMdocument_cb["tag_comment"]="handle_document" 3198462SApril.Chin@Sun.COM# argument for "handle_document" 3208462SApril.Chin@Sun.COMdocument_cb["arg_tree"]="xdoc" 3218462SApril.Chin@Sun.COM 3228462SApril.Chin@Sun.COM 3238462SApril.Chin@Sun.COMif [[ "${xmlfile}" == "#sample1" ]] ; then 3248462SApril.Chin@Sun.COM print_sample1_xml | xml_tok document_cb 3258462SApril.Chin@Sun.COMelif [[ "${xmlfile}" == "#sample2" ]] ; then 3268462SApril.Chin@Sun.COM /usr/sfw/bin/wget \ 3278462SApril.Chin@Sun.COM --user-agent='ksh93_xmldocumenttree' \ 3288462SApril.Chin@Sun.COM --output-document=- \ 3298462SApril.Chin@Sun.COM 'http://www.google.com/custom?q=gummi+bears' | 3308462SApril.Chin@Sun.COM /usr/bin/iconv -f "ISO8859-1" | 3318462SApril.Chin@Sun.COM xml_tok document_cb 3328462SApril.Chin@Sun.COMelse 3338462SApril.Chin@Sun.COM cat "${xmlfile}" | xml_tok document_cb 3348462SApril.Chin@Sun.COMfi 3358462SApril.Chin@Sun.COM 3368462SApril.Chin@Sun.COMprint -u2 "#parsing completed." 3378462SApril.Chin@Sun.COM 3388462SApril.Chin@Sun.COMcase "${viewmode}" in 3398462SApril.Chin@Sun.COM list) 3408462SApril.Chin@Sun.COM set | egrep "xdoc.*(tagname|tagtype|tagval|tagattributes)" | fgrep -v ']=$' 3418462SApril.Chin@Sun.COM ;; 3428462SApril.Chin@Sun.COM namelist) 3438462SApril.Chin@Sun.COM typeset + | egrep "xdoc.*(tagname|tagtype|tagval|tagattributes)" 3448462SApril.Chin@Sun.COM ;; 3458462SApril.Chin@Sun.COM tree) 346*10898Sroland.mainz@nrubsig.org print -v xdoc 347*10898Sroland.mainz@nrubsig.org ;; 348*10898Sroland.mainz@nrubsig.org compacttree) 349*10898Sroland.mainz@nrubsig.org print -C xdoc 3508462SApril.Chin@Sun.COM ;; 3518462SApril.Chin@Sun.COM *) 3528462SApril.Chin@Sun.COM fatal_error $"Invalid view mode \"${viewmode}\"." 3538462SApril.Chin@Sun.COM ;; 3548462SApril.Chin@Sun.COMesac 3558462SApril.Chin@Sun.COM 3568462SApril.Chin@Sun.COMprint -u2 "#done." 3578462SApril.Chin@Sun.COM 3588462SApril.Chin@Sun.COMexit 0 3598462SApril.Chin@Sun.COM# EOF. 360