show.c

来自「Android 一些工具」· C语言 代码 · 共 426 行

C
426
字号
/*	$NetBSD: show.c,v 1.26 2003/11/14 10:46:13 dsl Exp $	*//*- * Copyright (c) 1991, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Kenneth Almquist. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include <sys/cdefs.h>#ifndef lint#if 0static char sccsid[] = "@(#)show.c	8.3 (Berkeley) 5/4/95";#else__RCSID("$NetBSD: show.c,v 1.26 2003/11/14 10:46:13 dsl Exp $");#endif#endif /* not lint */#include <stdio.h>#include <stdarg.h>#include <stdlib.h>#include "shell.h"#include "parser.h"#include "nodes.h"#include "mystring.h"#include "show.h"#include "options.h"#ifdef DEBUGstatic void shtree(union node *, int, char *, FILE*);static void shcmd(union node *, FILE *);static void sharg(union node *, FILE *);static void indent(int, char *, FILE *);static void trstring(char *);voidshowtree(union node *n){	trputs("showtree called\n");	shtree(n, 1, NULL, stdout);}static voidshtree(union node *n, int ind, char *pfx, FILE *fp){	struct nodelist *lp;	const char *s;	if (n == NULL)		return;	indent(ind, pfx, fp);	switch(n->type) {	case NSEMI:		s = "; ";		goto binop;	case NAND:		s = " && ";		goto binop;	case NOR:		s = " || ";binop:		shtree(n->nbinary.ch1, ind, NULL, fp);	   /*    if (ind < 0) */			fputs(s, fp);		shtree(n->nbinary.ch2, ind, NULL, fp);		break;	case NCMD:		shcmd(n, fp);		if (ind >= 0)			putc('\n', fp);		break;	case NPIPE:		for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {			shcmd(lp->n, fp);			if (lp->next)				fputs(" | ", fp);		}		if (n->npipe.backgnd)			fputs(" &", fp);		if (ind >= 0)			putc('\n', fp);		break;	default:		fprintf(fp, "<node type %d>", n->type);		if (ind >= 0)			putc('\n', fp);		break;	}}static voidshcmd(union node *cmd, FILE *fp){	union node *np;	int first;	const char *s;	int dftfd;	first = 1;	for (np = cmd->ncmd.args ; np ; np = np->narg.next) {		if (! first)			putchar(' ');		sharg(np, fp);		first = 0;	}	for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {		if (! first)			putchar(' ');		switch (np->nfile.type) {			case NTO:	s = ">";  dftfd = 1; break;			case NCLOBBER:	s = ">|"; dftfd = 1; break;			case NAPPEND:	s = ">>"; dftfd = 1; break;			case NTOFD:	s = ">&"; dftfd = 1; break;			case NFROM:	s = "<";  dftfd = 0; break;			case NFROMFD:	s = "<&"; dftfd = 0; break;			case NFROMTO:	s = "<>"; dftfd = 0; break;			default:  	s = "*error*"; dftfd = 0; break;		}		if (np->nfile.fd != dftfd)			fprintf(fp, "%d", np->nfile.fd);		fputs(s, fp);		if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {			fprintf(fp, "%d", np->ndup.dupfd);		} else {			sharg(np->nfile.fname, fp);		}		first = 0;	}}static voidsharg(union node *arg, FILE *fp){	char *p;	struct nodelist *bqlist;	int subtype;	if (arg->type != NARG) {		printf("<node type %d>\n", arg->type);		abort();	}	bqlist = arg->narg.backquote;	for (p = arg->narg.text ; *p ; p++) {		switch (*p) {		case CTLESC:			putc(*++p, fp);			break;		case CTLVAR:			putc('$', fp);			putc('{', fp);			subtype = *++p;			if (subtype == VSLENGTH)				putc('#', fp);			while (*p != '=')				putc(*p++, fp);			if (subtype & VSNUL)				putc(':', fp);			switch (subtype & VSTYPE) {			case VSNORMAL:				putc('}', fp);				break;			case VSMINUS:				putc('-', fp);				break;			case VSPLUS:				putc('+', fp);				break;			case VSQUESTION:				putc('?', fp);				break;			case VSASSIGN:				putc('=', fp);				break;			case VSTRIMLEFT:				putc('#', fp);				break;			case VSTRIMLEFTMAX:				putc('#', fp);				putc('#', fp);				break;			case VSTRIMRIGHT:				putc('%', fp);				break;			case VSTRIMRIGHTMAX:				putc('%', fp);				putc('%', fp);				break;			case VSLENGTH:				break;			default:				printf("<subtype %d>", subtype);			}			break;		case CTLENDVAR:		     putc('}', fp);		     break;		case CTLBACKQ:		case CTLBACKQ|CTLQUOTE:			putc('$', fp);			putc('(', fp);			shtree(bqlist->n, -1, NULL, fp);			putc(')', fp);			break;		default:			putc(*p, fp);			break;		}	}}static voidindent(int amount, char *pfx, FILE *fp){	int i;	for (i = 0 ; i < amount ; i++) {		if (pfx && i == amount - 1)			fputs(pfx, fp);		putc('\t', fp);	}}#endif/* * Debugging stuff. */FILE *tracefile;#ifdef DEBUGvoidtrputc(int c){	if (debug != 1)		return;	putc(c, tracefile);}#endifvoidtrace(const char *fmt, ...){#ifdef DEBUG	va_list va;	if (debug != 1)		return;	va_start(va, fmt);	(void) vfprintf(tracefile, fmt, va);	va_end(va);#endif}voidtracev(const char *fmt, va_list va){#ifdef DEBUG	if (debug != 1)		return;	(void) vfprintf(tracefile, fmt, va);#endif}#ifdef DEBUGvoidtrputs(const char *s){	if (debug != 1)		return;	fputs(s, tracefile);}static voidtrstring(char *s){	char *p;	char c;	if (debug != 1)		return;	putc('"', tracefile);	for (p = s ; *p ; p++) {		switch (*p) {		case '\n':  c = 'n';  goto backslash;		case '\t':  c = 't';  goto backslash;		case '\r':  c = 'r';  goto backslash;		case '"':  c = '"';  goto backslash;		case '\\':  c = '\\';  goto backslash;		case CTLESC:  c = 'e';  goto backslash;		case CTLVAR:  c = 'v';  goto backslash;		case CTLVAR+CTLQUOTE:  c = 'V';  goto backslash;		case CTLBACKQ:  c = 'q';  goto backslash;		case CTLBACKQ+CTLQUOTE:  c = 'Q';  goto backslash;backslash:	  putc('\\', tracefile);			putc(c, tracefile);			break;		default:			if (*p >= ' ' && *p <= '~')				putc(*p, tracefile);			else {				putc('\\', tracefile);				putc(*p >> 6 & 03, tracefile);				putc(*p >> 3 & 07, tracefile);				putc(*p & 07, tracefile);			}			break;		}	}	putc('"', tracefile);}#endifvoidtrargs(char **ap){#ifdef DEBUG	if (debug != 1)		return;	while (*ap) {		trstring(*ap++);		if (*ap)			putc(' ', tracefile);		else			putc('\n', tracefile);	}#endif}#ifdef DEBUGvoidopentrace(void){	char s[100];#ifdef O_APPEND	int flags;#endif	if (debug != 1) {		if (tracefile)			fflush(tracefile);		/* leave open because libedit might be using it */		return;	}#ifdef not_this_way	{		char *p;		if ((p = getenv("HOME")) == NULL) {			if (geteuid() == 0)				p = "/";			else				p = "/tmp";		}		scopy(p, s);		strcat(s, "/trace");	}#else	scopy("./trace", s);#endif /* not_this_way */	if (tracefile) {		if (!freopen(s, "a", tracefile)) {			fprintf(stderr, "Can't re-open %s\n", s);			debug = 0;			return;		}	} else {		if ((tracefile = fopen(s, "a")) == NULL) {			fprintf(stderr, "Can't open %s\n", s);			debug = 0;			return;		}	}#ifdef O_APPEND	if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)		fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);#endif	setlinebuf(tracefile);	fputs("\nTracing started.\n", tracefile);}#endif /* DEBUG */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?