hbase

heirloom base
git clone git://git.2f30.org/hbase
Log | Files | Refs | README

sub1.c (17623B)


      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 2005 Sun Microsystems, Inc.
     24  * All rights reserved.
     25  * Use is subject to license terms.
     26  */
     27 
     28 /*	Copyright (c) 1988 AT&T	*/
     29 /*	All Rights Reserved	*/
     30 
     31 /*	from OpenSolaris "sub1.c	6.18	05/06/08 SMI"	*/
     32 
     33 /*
     34  * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany
     35  *
     36  * Sccsid @(#)sub1.c	1.5 (gritter) 11/26/05
     37  */
     38 
     39 #include "ldefs.c"
     40 #include <limits.h>
     41 #include <wchar.h>
     42 #include <ctype.h>
     43 #include <stdarg.h>
     44 
     45 /*
     46  * return next line of input, throw away trailing '\n'
     47  * and also throw away trailing blanks (spaces and tabs)
     48  * returns 0 if eof is had immediately
     49  */
     50 
     51 CHR *
     52 getl(CHR *p)
     53 {
     54 	int c;
     55 	CHR *s, *t, *u = NULL;
     56 	int blank = 0;
     57 
     58 	t = s = p;
     59 	while (((c = gch()) != 0) && c != '\n') {
     60 		if (t >= &p[BUF_SIZ])
     61 			error("definitions too long");
     62 		if (c == ' ' || c == '\t') {
     63 		    if (!blank) {
     64 			blank = 1;
     65 			u = t;
     66 		    }
     67 		} else
     68 			blank = 0;
     69 
     70 		*t++ = c;
     71 	}
     72 	if (blank)
     73 		*u = 0;
     74 	else
     75 		*t = 0;
     76 
     77 	if (c == 0 && s == t)
     78 		return ((CHR *) 0);
     79 	prev = '\n';
     80 	pres = '\n';
     81 	return (s);
     82 }
     83 
     84 int
     85 space(int ch)
     86 {
     87 	switch (ch) {
     88 		case ' ':
     89 		case '\t':
     90 		case '\n':
     91 			return (1);
     92 	}
     93 	return (0);
     94 }
     95 
     96 int
     97 digit(int c)
     98 {
     99 	return (c >= '0' && c <= '9');
    100 }
    101 
    102 /* VARARGS1 */
    103 void
    104 error(const char *s, ...)
    105 {
    106 	va_list	ap;
    107 
    108 	/* if(!eof) */
    109 	if (!yyline)
    110 		fprintf(errorf, "Command line: ");
    111 	else {
    112 		fprintf(errorf, !no_input ? "" : "\"%s\":", sargv[optind]);
    113 		fprintf(errorf, "line %d: ", yyline);
    114 	}
    115 	fprintf(errorf, "Error: ");
    116 	va_start(ap, s);
    117 	vfprintf(errorf, s, ap);
    118 	va_end(ap);
    119 	putc('\n', errorf);
    120 	if (fatal)
    121 		error_tail();
    122 }
    123 
    124 void
    125 error_tail(void)
    126 {
    127 #ifdef DEBUG
    128 	if (debug && sect != ENDSECTION) {
    129 		sect1dump();
    130 		sect2dump();
    131 	}
    132 #endif
    133 
    134 	if (report == 1)
    135 		statistics();
    136 	exit(1);
    137 	/* NOTREACHED */
    138 }
    139 
    140 /* VARARGS1 */
    141 void
    142 warning(const char *s, ...)
    143 {
    144 	va_list	ap;
    145 
    146 	if (!eof)
    147 		if (!yyline)
    148 			fprintf(errorf, "Command line: ");
    149 		else {
    150 			fprintf(errorf, !no_input?"":"\"%s\":", sargv[optind]);
    151 			fprintf(errorf, "line %d: ", yyline);
    152 		}
    153 	fprintf(errorf, "Warning: ");
    154 	va_start(ap, s);
    155 	vfprintf(errorf, s, ap);
    156 	va_end(ap);
    157 	putc('\n', errorf);
    158 	fflush(errorf);
    159 	if (fout)
    160 		fflush(fout);
    161 	fflush(stdout);
    162 }
    163 
    164 int
    165 index(int a, CHR *s)
    166 {
    167 	int k;
    168 	for (k = 0; s[k]; k++)
    169 		if (s[k] == a)
    170 			return (k);
    171 	return (-1);
    172 }
    173 
    174 int
    175 alpha(int c)
    176 {
    177 	return ('a' <= c && c <= 'z' ||
    178 		'A' <= c && c <= 'Z');
    179 }
    180 
    181 int
    182 printable(int c)
    183 {
    184 	return (c > 040 && c < 0177);
    185 }
    186 
    187 void
    188 lgate(void)
    189 {
    190 	char fname[20];
    191 
    192 	if (lgatflg)
    193 		return;
    194 	lgatflg = 1;
    195 	if (fout == NULL) {
    196 		sprintf(fname, "lex.yy.%c", ratfor ? 'r' : 'c');
    197 		fout = fopen(fname, "w");
    198 	}
    199 	if (fout == NULL)
    200 		error("Can't open %s", fname);
    201 	if (ratfor)
    202 		fprintf(fout, "#\n");
    203 	phead1();
    204 }
    205 
    206 /*
    207  * scopy(ptr to str, ptr to str) - copy first arg str to second
    208  * returns ptr to second arg
    209  */
    210 void
    211 scopy(CHR *s, CHR *t)
    212 {
    213 	CHR *i;
    214 	i = t;
    215 	while (*i++ = *s++);
    216 }
    217 
    218 /*
    219  * convert string t, return integer value
    220  */
    221 int
    222 siconv(CHR *t)
    223 {
    224 	int i, sw;
    225 	CHR *s;
    226 	s = t;
    227 	while (space(*s))
    228 		s++;
    229 	if (!digit(*s) && *s != '-')
    230 		error("missing translation value");
    231 	sw = 0;
    232 	if (*s == '-') {
    233 		sw = 1;
    234 		s++;
    235 	}
    236 	if (!digit(*s))
    237 		error("incomplete translation format");
    238 	i = 0;
    239 	while ('0' <= *s && *s <= '9')
    240 		i = i * 10 + (*(s++)-'0');
    241 	return (sw ? -i : i);
    242 }
    243 
    244 /*
    245  * slength(ptr to str) - return integer length of string arg
    246  * excludes '\0' terminator
    247  */
    248 int
    249 slength(CHR *s)
    250 {
    251 	int n;
    252 	CHR *t;
    253 	t = s;
    254 	for (n = 0; *t++; n++);
    255 	return (n);
    256 }
    257 
    258 /*
    259  * scomp(x,y) - return -1 if x < y,
    260  *		0 if x == y,
    261  *		return 1 if x > y, all lexicographically
    262  */
    263 int
    264 scomp(CHR *x, CHR *y)
    265 {
    266 	CHR *a, *d;
    267 	a = (CHR *) x;
    268 	d = (CHR *) y;
    269 	while (*a || *d) {
    270 		if (*a > *d)
    271 			return (1);
    272 		if (*a < *d)
    273 			return (-1);
    274 		a++;
    275 		d++;
    276 	}
    277 	return (0);
    278 }
    279 
    280 int
    281 ctrans(CHR **ss)
    282 {
    283 	int c, k;
    284 	if ((c = **ss) != '\\')
    285 		return (c);
    286 	switch (c = *++*ss) {
    287 	case 'a':
    288 		c = '\a';
    289 		warning("\\a is ANSI C \"alert\" character");
    290 		break;
    291 	case 'v': c = '\v'; break;
    292 	case 'n': c = '\n'; break;
    293 	case 't': c = '\t'; break;
    294 	case 'r': c = '\r'; break;
    295 	case 'b': c = '\b'; break;
    296 	case 'f': c = 014; break;		/* form feed for ascii */
    297 	case '\\': c = '\\'; break;
    298 	case 'x': {
    299 		int dd;
    300 		warning("\\x is ANSI C hex escape");
    301 		if (digit((dd = *++*ss)) ||
    302 			('a' <= dd && dd <= 'f') ||
    303 			('A' <= dd && dd <= 'F')) {
    304 			c = 0;
    305 			while (digit(dd) ||
    306 				('A' <= dd && dd <= 'F') ||
    307 				('a' <= dd && dd <= 'f')) {
    308 				if (digit(dd))
    309 					c = c*16 + dd - '0';
    310 				else if (dd >= 'a')
    311 					c = c*16 + 10 + dd - 'a';
    312 				else
    313 					c = c*16 + 10 + dd - 'A';
    314 				dd = *++*ss;
    315 			}
    316 		} else
    317 			c = 'x';
    318 		break;
    319 		}
    320 	case '0': case '1': case '2': case '3':
    321 	case '4': case '5': case '6': case '7':
    322 		c -= '0';
    323 		while ((k = *(*ss+1)) >= '0' && k <= '7') {
    324 			c = c*8 + k - '0';
    325 			(*ss)++;
    326 		}
    327 		break;
    328 	}
    329 	return (c);
    330 }
    331 
    332 void
    333 cclinter(int sw)
    334 {
    335 	/* sw = 1 ==> ccl */
    336 	int i, j, k;
    337 	int m;
    338 	if (!sw) { /* is NCCL */
    339 		for (i = 1; i < ncg; i++)
    340 			symbol[i] ^= 1;	/* reverse value */
    341 	}
    342 	for (i = 1; i < ncg; i++)
    343 		if (symbol[i])
    344 			break;
    345 	if (i >= ncg)
    346 		return;
    347 	i = cindex[i];
    348 	/* see if ccl is already in our table */
    349 	j = 0;
    350 	if (i) {
    351 		for (j = 1; j < ncg; j++) {
    352 			if ((symbol[j] && cindex[j] != i) ||
    353 				(!symbol[j] && cindex[j] == i))
    354 				break;
    355 		}
    356 	}
    357 	if (j >= ncg)
    358 		return;		/* already in */
    359 	m = 0;
    360 	k = 0;
    361 	for (i = 1; i < ncg; i++) {
    362 		if (symbol[i]) {
    363 			if (!cindex[i]) {
    364 				cindex[i] = ccount;
    365 				symbol[i] = 0;
    366 				m = 1;
    367 			} else
    368 				k = 1;
    369 		}
    370 	}
    371 	/* m == 1 implies last value of ccount has been used */
    372 	if (m)
    373 		ccount++;
    374 	if (k == 0)
    375 		return;	/* is now in as ccount wholly */
    376 	/* intersection must be computed */
    377 	for (i = 1; i < ncg; i++) {
    378 		if (symbol[i]) {
    379 			m = 0;
    380 			j = cindex[i];	/* will be non-zero */
    381 			for (k = 1; k < ncg; k++) {
    382 				if (cindex[k] == j) {
    383 					if (symbol[k])
    384 						symbol[k] = 0;
    385 					else {
    386 						cindex[k] = ccount;
    387 						m = 1;
    388 					}
    389 				}
    390 			}
    391 			if (m)
    392 				ccount++;
    393 		}
    394 	}
    395 }
    396 
    397 int
    398 usescape(int c)
    399 {
    400 	char d;
    401 	switch (c) {
    402 	case 'a':
    403 		c = '\a';
    404 		warning("\\a is ANSI C \"alert\" character"); break;
    405 	case 'v': c = '\v'; break;
    406 	case 'n': c = '\n'; break;
    407 	case 'r': c = '\r'; break;
    408 	case 't': c = '\t'; break;
    409 	case 'b': c = '\b'; break;
    410 	case 'f': c = 014; break;		/* form feed for ascii */
    411 	case 'x': {
    412 		int dd;
    413 		if (digit((dd = gch())) ||
    414 			('A' <= dd && dd <= 'F') ||
    415 			('a' <= dd && dd <= 'f')) {
    416 			c = 0;
    417 			while (digit(dd) ||
    418 				('A' <= dd && dd <= 'F') ||
    419 				('a' <= dd && dd <= 'f')) {
    420 				if (digit(dd))
    421 					c = c*16 + dd - '0';
    422 				else if (dd >= 'a')
    423 					c = c*16 + 10 + dd - 'a';
    424 				else
    425 					c = c*16 + 10 + dd - 'A';
    426 				if (!digit(peek) &&
    427 					!('A' <= peek && peek <= 'F') &&
    428 					!('a' <= peek && peek <= 'f'))
    429 					break;
    430 				dd = gch();
    431 			}
    432 
    433 		} else
    434 			c = 'x';
    435 		break;
    436 	}
    437 	case '0': case '1': case '2': case '3':
    438 	case '4': case '5': case '6': case '7':
    439 		c -= '0';
    440 		while ('0' <= (d = gch()) && d <= '7') {
    441 			c = c * 8 + (d-'0');
    442 			if (!('0' <= peek && peek <= '7')) break;
    443 			}
    444 
    445 		break;
    446 	}
    447 
    448 	if (handleeuc && !isascii(c)) {
    449 		char tmpchar = c & 0x00ff;
    450 		wchar_t	wc;
    451 		mbtowc(&wc, &tmpchar, sizeof (tmpchar));
    452 		c = wc;
    453 	}
    454 	return (c);
    455 }
    456 
    457 int
    458 lookup(CHR *s, CHR **t)
    459 {
    460 	int i;
    461 	i = 0;
    462 	while (*t) {
    463 		if (scomp(s, *t) == 0)
    464 			return (i);
    465 		i++;
    466 		t++;
    467 	}
    468 	return (-1);
    469 }
    470 
    471 void
    472 cpycom(CHR *p)
    473 {
    474 	static CHR *t;
    475 	static int c;
    476 	t = p;
    477 
    478 	if (sargv[optind] == NULL)
    479 		fprintf(fout, "\n# line %d\n", yyline);
    480 	else
    481 		fprintf(fout, "\n# line %d \"%s\"\n", yyline, sargv[optind]);
    482 
    483 	putc(*t, fout), t++;
    484 	putc(*t, fout), t++;
    485 	while (*t) {
    486 		while (*t == '*') {
    487 			putc(*t, fout), t++;
    488 			if (*t == '/')
    489 				goto backcall;
    490 		}
    491 		/*
    492 		 * FIX BUG #1058428, not parsing comments correctly
    493 		 * that span more than one line
    494 		 */
    495 		if (*t != '\0')
    496 			putc(*t, fout), t++;
    497 	}
    498 	putc('\n', fout);
    499 	while (c = gch()) {
    500 		while (c == '*') {
    501 			putc(c, fout);
    502 			if ((c = gch()) == '/') {
    503 				while ((c = gch()) == ' ' || c == '\t');
    504 				if (!space(c))
    505 					error("unacceptable statement");
    506 				prev = '\n';
    507 				goto backcall;
    508 			}
    509 		}
    510 		putc(c, fout);
    511 	}
    512 	error("unexpected EOF inside comment");
    513 backcall:
    514 	putc('/', fout);
    515 	putc('\n', fout);
    516 }
    517 
    518 /*
    519  * copy C action to the next ; or closing
    520  */
    521 int
    522 cpyact(void)
    523 {
    524 	int brac, c, mth;
    525 	static int sw, savline;
    526 
    527 	brac = 0;
    528 	sw = TRUE;
    529 	savline = yyline;
    530 
    531 	if (sargv[optind] == NULL)
    532 		fprintf(fout, "\n# line %d\n", yyline);
    533 	else
    534 		fprintf(fout, "\n# line %d \"%s\"\n", yyline, sargv[optind]);
    535 
    536 	while (!eof) {
    537 		c = gch();
    538 	swt:
    539 		switch (c) {
    540 		case '|':
    541 			if (brac == 0 && sw == TRUE) {
    542 				if (peek == '|')
    543 					gch(); /* eat up an extra '|' */
    544 				return (0);
    545 			}
    546 			break;
    547 		case ';':
    548 			if (brac == 0) {
    549 				putwc(c, fout);
    550 				putc('\n', fout);
    551 				return (1);
    552 			}
    553 			break;
    554 		case '{':
    555 			brac++;
    556 			savline = yyline;
    557 			break;
    558 		case '}':
    559 			brac--;
    560 			if (brac == 0) {
    561 				putwc(c, fout);
    562 				putc('\n', fout);
    563 				return (1);
    564 			}
    565 			break;
    566 		case '/':
    567 			putwc(c, fout);
    568 			c = gch();
    569 			if (c != '*')
    570 				goto swt;
    571 			putwc(c, fout);
    572 			savline = yyline;
    573 			while (c = gch()) {
    574 				while (c == '*') {
    575 					putwc(c, fout);
    576 					if ((c = gch()) == '/') {
    577 						putc('/', fout);
    578 						while ((c = gch()) == ' ' ||
    579 							c == '\t' || c == '\n')
    580 							putwc(c, fout);
    581 						goto swt;
    582 					}
    583 				}
    584 				putc(c, fout);
    585 			}
    586 			yyline = savline;
    587 			error("EOF inside comment");
    588 			/* NOTREACHED */
    589 			break;
    590 		case '\'': /* character constant */
    591 		case '"': /* character string */
    592 			mth = c;
    593 			putwc(c, fout);
    594 			while (c = gch()) {
    595 				if (c == '\\') {
    596 					putwc(c, fout);
    597 					c = gch();
    598 				}
    599 				else
    600 					if (c == mth)
    601 						goto loop;
    602 				putwc(c, fout);
    603 				if (c == '\n') {
    604 					yyline--;
    605 					error(
    606 "Non-terminated string or character constant");
    607 				}
    608 			}
    609 			error("EOF in string or character constant");
    610 			/* NOTREACHED */
    611 			break;
    612 		case '\0':
    613 			yyline = savline;
    614 			error("Action does not terminate");
    615 			/* NOTREACHED */
    616 			break;
    617 		default:
    618 			break; /* usual character */
    619 		}
    620 	loop:
    621 		if (c != ' ' && c != '\t' && c != '\n')
    622 			sw = FALSE;
    623 		putwc(c, fout);
    624 		if (peek == '\n' && !brac && copy_line) {
    625 			putc('\n', fout);
    626 			return (1);
    627 		}
    628 	}
    629 	error("Premature EOF");
    630 	return (0);
    631 }
    632 
    633 int
    634 gch(void)
    635 {
    636 	int c;
    637 	prev = pres;
    638 	c = pres = peek;
    639 	peek = pushptr > pushc ? *--pushptr : getwc(fin);
    640 	while (peek == EOF) {
    641 		if (no_input) {
    642 			if (!yyline)
    643 				error("Cannot read from -- %s",
    644 				sargv[optind]);
    645 			if (optind < sargc-1) {
    646 				yyline = 0;
    647 				if (fin != stdin)
    648 					fclose(fin);
    649 				fin = fopen(sargv[++optind], "r");
    650 				if (fin == NULL)
    651 					error("Cannot open file -- %s",
    652 					sargv[optind]);
    653 				peek = getwc(fin);
    654 			} else
    655 				break;
    656 		} else {
    657 			if (fin != stdin)
    658 				fclose(fin);
    659 			if (!yyline)
    660 				error("Cannot read from -- standard input");
    661 			else
    662 				break;
    663 		}
    664 	}
    665 	if (c == EOF) {
    666 		eof = TRUE;
    667 		return (0);
    668 	}
    669 	if (c == '\n')
    670 		yyline++;
    671 	return (c);
    672 }
    673 
    674 int
    675 mn2(int a, intptr_t d, intptr_t c)
    676 {
    677 	if (tptr >= treesize) {
    678 		tptr++;
    679 		error("Parse tree too big %s",
    680 			(treesize == TREESIZE ? "\nTry using %e num" : ""));
    681 	}
    682 	if (d >= treesize) {
    683 		error("Parse error");
    684 	}
    685 	name[tptr] = a;
    686 	left[tptr] = d;
    687 	right[tptr] = c;
    688 	parent[tptr] = 0;
    689 	nullstr[tptr] = 0;
    690 	switch (a) {
    691 	case RSTR:
    692 		parent[d] = tptr;
    693 		break;
    694 	case BAR:
    695 	case RNEWE:
    696 		if (nullstr[d] || nullstr[c])
    697 			nullstr[tptr] = TRUE;
    698 		parent[d] = parent[c] = tptr;
    699 		break;
    700 	case RCAT:
    701 	case DIV:
    702 		if (nullstr[d] && nullstr[c])
    703 			nullstr[tptr] = TRUE;
    704 		parent[d] = parent[c] = tptr;
    705 		break;
    706 	/* XCU4: add RXSCON */
    707 	case RXSCON:
    708 	case RSCON:
    709 		parent[d] = tptr;
    710 		nullstr[tptr] = nullstr[d];
    711 		break;
    712 #ifdef DEBUG
    713 	default:
    714 		warning("bad switch mn2 %d %d", a, d);
    715 		break;
    716 #endif
    717 	}
    718 	return (tptr++);
    719 }
    720 
    721 int
    722 mn1(int a, intptr_t d)
    723 {
    724 	if (tptr >= treesize) {
    725 		tptr++;
    726 		error("Parse tree too big %s",
    727 		(treesize == TREESIZE ? "\nTry using %e num" : ""));
    728 	}
    729 	name[tptr] = a;
    730 	left[tptr] = d;
    731 	parent[tptr] = 0;
    732 	nullstr[tptr] = 0;
    733 	switch (a) {
    734 	case RCCL:
    735 	case RNCCL:
    736 		if (slength((CHR *)d) == 0)
    737 			nullstr[tptr] = TRUE;
    738 		break;
    739 	case STAR:
    740 	case QUEST:
    741 		nullstr[tptr] = TRUE;
    742 		parent[d] = tptr;
    743 		break;
    744 	case PLUS:
    745 	case CARAT:
    746 		nullstr[tptr] = nullstr[d];
    747 		parent[d] = tptr;
    748 		break;
    749 	case S2FINAL:
    750 		nullstr[tptr] = TRUE;
    751 		break;
    752 #ifdef DEBUG
    753 	case FINAL:
    754 	case S1FINAL:
    755 		break;
    756 	default:
    757 		warning("bad switch mn1 %d %d", a, d);
    758 		break;
    759 #endif
    760 	}
    761 	return (tptr++);
    762 }
    763 
    764 int
    765 mn0(int a)
    766 {
    767 	if (tptr >= treesize) {
    768 		tptr++;
    769 		error("Parse tree too big %s",
    770 			(treesize == TREESIZE ? "\nTry using %e num" : ""));
    771 	}
    772 
    773 	name[tptr] = a;
    774 	parent[tptr] = 0;
    775 	nullstr[tptr] = 0;
    776 	if (ISOPERATOR(a)) {
    777 		switch (a) {
    778 		case DOT: break;
    779 		case RNULLS: nullstr[tptr] = TRUE; break;
    780 #ifdef DEBUG
    781 		default:
    782 			warning("bad switch mn0 %d", a);
    783 			break;
    784 #endif
    785 		}
    786 	}
    787 	return (tptr++);
    788 }
    789 
    790 void
    791 munput(int t, CHR *p)
    792 {
    793 	int i, j;
    794 	if (t == 'c') {
    795 		*pushptr++ = peek;
    796 		peek = *p;
    797 	} else if (t == 's') {
    798 		*pushptr++ = peek;
    799 		peek = p[0];
    800 		i = slength(p);
    801 		for (j = i - 1; j >= 1; j--)
    802 			*pushptr++ = p[j];
    803 	}
    804 	if (pushptr >= pushc + TOKENSIZE)
    805 		error("Too many characters pushed");
    806 }
    807 
    808 int
    809 dupl(int n)
    810 {
    811 	/* duplicate the subtree whose root is n, return ptr to it */
    812 	int i;
    813 	i = name[n];
    814 	if (!ISOPERATOR(i))
    815 		return (mn0(i));
    816 	switch (i) {
    817 	case DOT:
    818 	case RNULLS:
    819 		return (mn0(i));
    820 	case RCCL: case RNCCL: case FINAL: case S1FINAL: case S2FINAL:
    821 		return (mn1(i, left[n]));
    822 	case STAR: case QUEST: case PLUS: case CARAT:
    823 		return (mn1(i, dupl(left[n])));
    824 
    825 	/* XCU4: add RXSCON */
    826 	case RSTR: case RSCON: case RXSCON:
    827 		return (mn2(i, dupl(left[n]), right[n]));
    828 	case BAR: case RNEWE: case RCAT: case DIV:
    829 		return (mn2(i, dupl(left[n]), dupl(right[n])));
    830 	}
    831 	return (0);
    832 }
    833 
    834 #ifdef DEBUG
    835 void
    836 allprint(CHR c)
    837 {
    838 	switch (c) {
    839 	case 014:
    840 		printf("\\f");
    841 		charc++;
    842 		break;
    843 	case '\n':
    844 		printf("\\n");
    845 		charc++;
    846 		break;
    847 	case '\t':
    848 		printf("\\t");
    849 		charc++;
    850 		break;
    851 	case '\b':
    852 		printf("\\b");
    853 		charc++;
    854 		break;
    855 	case ' ':
    856 		printf("\\_");
    857 		break;
    858 	default:
    859 		if (!iswprint(c)) {
    860 			printf("\\x%-2x", c); /* up to fashion. */
    861 			charc += 3;
    862 		} else
    863 			putwc(c, stdout);
    864 		break;
    865 	}
    866 	charc++;
    867 }
    868 
    869 void
    870 strpt(CHR *s)
    871 {
    872 	charc = 0;
    873 	while (*s) {
    874 		allprint(*s++);
    875 		if (charc > LINESIZE) {
    876 			charc = 0;
    877 			printf("\n\t");
    878 		}
    879 	}
    880 }
    881 
    882 void
    883 sect1dump(void)
    884 {
    885 	int i;
    886 	printf("Sect 1:\n");
    887 	if (def[0]) {
    888 		printf("str	trans\n");
    889 		i = -1;
    890 		while (def[++i])
    891 			printf("%ls\t%ls\n", def[i], subs[i]);
    892 	}
    893 	if (sname[0]) {
    894 		printf("start names\n");
    895 		i = -1;
    896 		while (sname[++i])
    897 			printf("%ls\n", sname[i]);
    898 	}
    899 	if (chset == TRUE) {
    900 		printf("char set changed\n");
    901 		for (i = 1; i < NCH; i++) {
    902 			if (i != ctable[i]) {
    903 				allprint(i);
    904 				putchar(' ');
    905 				iswprint(ctable[i]) ?
    906 					putwc(ctable[i], stdout) :
    907 					printf("%d", ctable[i]);
    908 				putchar('\n');
    909 			}
    910 		}
    911 	}
    912 }
    913 
    914 void
    915 sect2dump(void)
    916 {
    917 	printf("Sect 2:\n");
    918 	treedump();
    919 }
    920 
    921 void
    922 treedump(void)
    923 {
    924 	int t;
    925 	CHR *p;
    926 	printf("treedump %d nodes:\n", tptr);
    927 	for (t = 0; t < tptr; t++) {
    928 		printf("%4d ", t);
    929 		parent[t] ? printf("p=%4d", parent[t]) : printf("      ");
    930 		printf("  ");
    931 		if (!ISOPERATOR(name[t])) {
    932 			allprint(name[t]);
    933 		} else
    934 			switch (name[t]) {
    935 			case RSTR:
    936 				printf("%ld ", (long)left[t]);
    937 				allprint(right[t]);
    938 				break;
    939 			case RCCL:
    940 				printf("ccl ");
    941 				strpt((CHR *)left[t]);
    942 				break;
    943 			case RNCCL:
    944 				printf("nccl ");
    945 				strpt((CHR *)left[t]);
    946 				break;
    947 			case DIV:
    948 				printf("/ %ld %ld",
    949 					(long)left[t], (long)right[t]);
    950 				break;
    951 			case BAR:
    952 				printf("| %ld %ld",
    953 					(long)left[t], (long)right[t]);
    954 				break;
    955 			case RCAT:
    956 				printf("cat %ld %ld",
    957 					(long)left[t], (long)right[t]);
    958 				break;
    959 			case PLUS:
    960 				printf("+ %ld", (long)left[t]);
    961 				break;
    962 			case STAR:
    963 				printf("* %ld", (long)left[t]);
    964 				break;
    965 			case CARAT:
    966 				printf("^ %ld", (long)left[t]);
    967 				break;
    968 			case QUEST:
    969 				printf("? %ld", (long)left[t]);
    970 				break;
    971 			case RNULLS:
    972 				printf("nullstring");
    973 				break;
    974 			case FINAL:
    975 				printf("final %ld", (long)left[t]);
    976 				break;
    977 			case S1FINAL:
    978 				printf("s1final %ld", (long)left[t]);
    979 				break;
    980 			case S2FINAL:
    981 				printf("s2final %ld", (long)left[t]);
    982 				break;
    983 			case RNEWE:
    984 				printf("new %ld %ld",
    985 					(long)left[t], (long)right[t]);
    986 				break;
    987 
    988 			/* XCU4: add RXSCON */
    989 			case RXSCON:
    990 				p = (CHR *)right[t];
    991 				printf("exstart %s", sname[*p++-1]);
    992 				while (*p)
    993 					printf(", %ls", sname[*p++-1]);
    994 				printf(" %ld", (long)left[t]);
    995 				break;
    996 			case RSCON:
    997 				p = (CHR *)right[t];
    998 				printf("start %s", sname[*p++-1]);
    999 				while (*p)
   1000 					printf(", %ls", sname[*p++-1]);
   1001 				printf(" %ld", (long)left[t]);
   1002 				break;
   1003 			case DOT:
   1004 				printf("dot");
   1005 				break;
   1006 			default:
   1007 				printf(
   1008 				"unknown %d %ld %ld", name[t],
   1009 					(long)left[t], (long)right[t]);
   1010 				break;
   1011 			}
   1012 		if (nullstr[t])
   1013 			printf("\t(null poss.)");
   1014 		putchar('\n');
   1015 	}
   1016 }
   1017 #endif