17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 23*67a4bb8fSGary Mills * Copyright 2015 Gary Mills 247c478bd9Sstevel@tonic-gate * Copyright (c) 1996-1997 by Sun Microsystems, Inc. 257c478bd9Sstevel@tonic-gate * All rights reserved. 267c478bd9Sstevel@tonic-gate */ 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 297c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate /* Copyright (c) 1979 Regents of the University of California */ 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/ 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #include "curses_inc.h" 367c478bd9Sstevel@tonic-gate #include "curshdr.h" 377c478bd9Sstevel@tonic-gate #include "term.h" 387c478bd9Sstevel@tonic-gate #include <string.h> 397c478bd9Sstevel@tonic-gate #include <setjmp.h> 407c478bd9Sstevel@tonic-gate #include <stdlib.h> 417c478bd9Sstevel@tonic-gate #include <stdio.h> 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate #ifndef _CHCTRL 447c478bd9Sstevel@tonic-gate #define _CHCTRL(c) ((c) & 037) 457c478bd9Sstevel@tonic-gate #endif /* _CHCTRL */ 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate char *_branchto(char *, char); 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate /* 507c478bd9Sstevel@tonic-gate * Routine to perform parameter substitution. 517c478bd9Sstevel@tonic-gate * instring is a string containing printf type escapes. 527c478bd9Sstevel@tonic-gate * The whole thing uses a stack, much like an HP 35. 537c478bd9Sstevel@tonic-gate * The following escapes are defined for substituting row/column: 547c478bd9Sstevel@tonic-gate * 557c478bd9Sstevel@tonic-gate * %[:[-+ #0]][0-9][.][0-9][dsoxX] 567c478bd9Sstevel@tonic-gate * print pop() as in printf(3), as defined in the local 577c478bd9Sstevel@tonic-gate * sprintf(3), except that a leading + or - must be preceded 587c478bd9Sstevel@tonic-gate * with a colon (:) to distinguish from the plus/minus operators. 597c478bd9Sstevel@tonic-gate * 607c478bd9Sstevel@tonic-gate * %c print pop() like %c in printf(3) 617c478bd9Sstevel@tonic-gate * %l pop() a string address and push its length. 627c478bd9Sstevel@tonic-gate * %P[a-z] set dynamic variable a-z 637c478bd9Sstevel@tonic-gate * %g[a-z] get dynamic variable a-z 647c478bd9Sstevel@tonic-gate * %P[A-Z] set static variable A-Z 657c478bd9Sstevel@tonic-gate * %g[A-Z] get static variable A-Z 667c478bd9Sstevel@tonic-gate * 677c478bd9Sstevel@tonic-gate * %p[1-0] push ith parm 687c478bd9Sstevel@tonic-gate * %'c' char constant c 697c478bd9Sstevel@tonic-gate * %{nn} integer constant nn 707c478bd9Sstevel@tonic-gate * 717c478bd9Sstevel@tonic-gate * %+ %- %* %/ %m arithmetic (%m is mod): push(pop() op pop()) 727c478bd9Sstevel@tonic-gate * %& %| %^ bit operations: push(pop() op pop()) 737c478bd9Sstevel@tonic-gate * %= %> %< logical operations: push(pop() op pop()) 747c478bd9Sstevel@tonic-gate * %A %O logical AND, OR push(pop() op pop()) 757c478bd9Sstevel@tonic-gate * %! %~ unary operations push(op pop()) 767c478bd9Sstevel@tonic-gate * %% output % 777c478bd9Sstevel@tonic-gate * %? expr %t thenpart %e elsepart %; 787c478bd9Sstevel@tonic-gate * if-then-else, %e elsepart is optional. 797c478bd9Sstevel@tonic-gate * else-if's are possible ala Algol 68: 807c478bd9Sstevel@tonic-gate * %? c1 %t %e c2 %t %e c3 %t %e c4 %t %e %; 817c478bd9Sstevel@tonic-gate * % followed by anything else 827c478bd9Sstevel@tonic-gate * is not defined, it may output the character, 837c478bd9Sstevel@tonic-gate * and it may not. This is done so that further 847c478bd9Sstevel@tonic-gate * enhancements to the format capabilities may 857c478bd9Sstevel@tonic-gate * be made without worrying about being upwardly 867c478bd9Sstevel@tonic-gate * compatible from buggy code. 877c478bd9Sstevel@tonic-gate * 887c478bd9Sstevel@tonic-gate * all other characters are ``self-inserting''. %% gets % output. 897c478bd9Sstevel@tonic-gate * 907c478bd9Sstevel@tonic-gate * The stack structure used here is based on an idea by Joseph Yao. 917c478bd9Sstevel@tonic-gate */ 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate #define MAX 10 947c478bd9Sstevel@tonic-gate #define MEM_ALLOC_FAIL 1 957c478bd9Sstevel@tonic-gate #define STACK_UNDERFLOW 2 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate typedef struct { 987c478bd9Sstevel@tonic-gate long top; 997c478bd9Sstevel@tonic-gate int stacksize; 1007c478bd9Sstevel@tonic-gate long *stack; 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate }STACK; 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate static jmp_buf env; 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate static long 1077c478bd9Sstevel@tonic-gate tops(STACK *st) 1087c478bd9Sstevel@tonic-gate { 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate if (st->top < 0) { 1117c478bd9Sstevel@tonic-gate longjmp(env, STACK_UNDERFLOW); 1127c478bd9Sstevel@tonic-gate } 1137c478bd9Sstevel@tonic-gate return (st->stack[st->top]); 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate static void 1177c478bd9Sstevel@tonic-gate push(STACK *st, long i) 1187c478bd9Sstevel@tonic-gate { 1197c478bd9Sstevel@tonic-gate if (st->top >= (st->stacksize - 1)) { 1207c478bd9Sstevel@tonic-gate st->stacksize += MAX; 1217c478bd9Sstevel@tonic-gate if ((st->stack = (void *)realloc(st->stack, 1227c478bd9Sstevel@tonic-gate (st->stacksize * sizeof (long)))) == NULL) { 1237c478bd9Sstevel@tonic-gate longjmp(env, MEM_ALLOC_FAIL); 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate } 1267c478bd9Sstevel@tonic-gate st->stack[++st->top] = (i); 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate static long 1307c478bd9Sstevel@tonic-gate pop(STACK *st) 1317c478bd9Sstevel@tonic-gate { 1327c478bd9Sstevel@tonic-gate if (st->top < 0) { 1337c478bd9Sstevel@tonic-gate longjmp(env, STACK_UNDERFLOW); 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate return (st->stack[st->top--]); 1367c478bd9Sstevel@tonic-gate } 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate /* The following routine was added to make lint shut up about converting from 1397c478bd9Sstevel@tonic-gate * a long to a char *. It is identical to the pop routine, except for the 1407c478bd9Sstevel@tonic-gate * cast on the return statement. 1417c478bd9Sstevel@tonic-gate */ 1427c478bd9Sstevel@tonic-gate static char * 1437c478bd9Sstevel@tonic-gate pop_char_p(STACK *st) 1447c478bd9Sstevel@tonic-gate { 1457c478bd9Sstevel@tonic-gate if (st->top < 0) { 1467c478bd9Sstevel@tonic-gate longjmp(env, STACK_UNDERFLOW); 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate return ((char *)(st->stack[st->top--])); 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate static void 1527c478bd9Sstevel@tonic-gate init_stack(STACK *st) 1537c478bd9Sstevel@tonic-gate { 1547c478bd9Sstevel@tonic-gate st->top = -1; 1557c478bd9Sstevel@tonic-gate st->stacksize = MAX; 1567c478bd9Sstevel@tonic-gate if ((st->stack = (void *)malloc(MAX * sizeof (long))) == NULL) { 1577c478bd9Sstevel@tonic-gate longjmp(env, MEM_ALLOC_FAIL); 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate static void 1627c478bd9Sstevel@tonic-gate free_stack(STACK *st) 1637c478bd9Sstevel@tonic-gate { 1647c478bd9Sstevel@tonic-gate free(st->stack); 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate char * 1697c478bd9Sstevel@tonic-gate tparm_p0(char *instring) 1707c478bd9Sstevel@tonic-gate { 1717c478bd9Sstevel@tonic-gate long p[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate return (tparm(instring, p[0], p[1], p[2], p[3], p[4], p[5], p[6], 1747c478bd9Sstevel@tonic-gate p[7], p[8])); 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate char * 1787c478bd9Sstevel@tonic-gate tparm_p1(char *instring, long l1) 1797c478bd9Sstevel@tonic-gate { 1807c478bd9Sstevel@tonic-gate long p[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate p[0] = l1; 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate return (tparm(instring, p[0], p[1], p[2], p[3], p[4], p[5], p[6], 1857c478bd9Sstevel@tonic-gate p[7], p[8])); 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate char * 1897c478bd9Sstevel@tonic-gate tparm_p2(char *instring, long l1, long l2) 1907c478bd9Sstevel@tonic-gate { 1917c478bd9Sstevel@tonic-gate long p[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate p[0] = l1; 1947c478bd9Sstevel@tonic-gate p[1] = l2; 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate return (tparm(instring, p[0], p[1], p[2], p[3], p[4], p[5], p[6], 1977c478bd9Sstevel@tonic-gate p[7], p[8])); 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate char * 2017c478bd9Sstevel@tonic-gate tparm_p3(char *instring, long l1, long l2, long l3) 2027c478bd9Sstevel@tonic-gate { 2037c478bd9Sstevel@tonic-gate long p[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate p[0] = l1; 2067c478bd9Sstevel@tonic-gate p[1] = l2; 2077c478bd9Sstevel@tonic-gate p[2] = l3; 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate return (tparm(instring, p[0], p[1], p[2], p[3], p[4], p[5], p[6], 2107c478bd9Sstevel@tonic-gate p[7], p[8])); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate char * 2147c478bd9Sstevel@tonic-gate tparm_p4(char *instring, long l1, long l2, long l3, long l4) 2157c478bd9Sstevel@tonic-gate { 2167c478bd9Sstevel@tonic-gate long p[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate p[0] = l1; 2197c478bd9Sstevel@tonic-gate p[1] = l2; 2207c478bd9Sstevel@tonic-gate p[2] = l3; 2217c478bd9Sstevel@tonic-gate p[3] = l4; 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate return (tparm(instring, p[0], p[1], p[2], p[3], p[4], p[5], p[6], 2247c478bd9Sstevel@tonic-gate p[7], p[8])); 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate char * 2287c478bd9Sstevel@tonic-gate tparm_p7(char *instring, long l1, long l2, long l3, long l4, long l5, long l6, 2297c478bd9Sstevel@tonic-gate long l7) 2307c478bd9Sstevel@tonic-gate { 2317c478bd9Sstevel@tonic-gate long p[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate p[0] = l1; 2347c478bd9Sstevel@tonic-gate p[1] = l2; 2357c478bd9Sstevel@tonic-gate p[2] = l3; 2367c478bd9Sstevel@tonic-gate p[3] = l4; 2377c478bd9Sstevel@tonic-gate p[4] = l5; 2387c478bd9Sstevel@tonic-gate p[5] = l6; 2397c478bd9Sstevel@tonic-gate p[6] = l7; 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate return (tparm(instring, p[0], p[1], p[2], p[3], p[4], p[5], p[6], 2427c478bd9Sstevel@tonic-gate p[7], p[8])); 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate /* VARARGS */ 2467c478bd9Sstevel@tonic-gate char * 2477c478bd9Sstevel@tonic-gate tparm(char *instring, long fp1, long fp2, long p3, long p4, 2487c478bd9Sstevel@tonic-gate long p5, long p6, long p7, long p8, long p9) 2497c478bd9Sstevel@tonic-gate { 2507c478bd9Sstevel@tonic-gate static char result[512]; 2517c478bd9Sstevel@tonic-gate static char added[100]; 2527c478bd9Sstevel@tonic-gate long vars[26]; 2537c478bd9Sstevel@tonic-gate STACK stk; 2547c478bd9Sstevel@tonic-gate char *cp = instring; 2557c478bd9Sstevel@tonic-gate char *outp = result; 2567c478bd9Sstevel@tonic-gate char c; 2577c478bd9Sstevel@tonic-gate long op; 2587c478bd9Sstevel@tonic-gate long op2; 2597c478bd9Sstevel@tonic-gate int sign; 2607c478bd9Sstevel@tonic-gate int onrow = 0; 261*67a4bb8fSGary Mills volatile long p1 = fp1, p2 = fp2; /* copy in case < 2 actual parms */ 2627c478bd9Sstevel@tonic-gate char *xp; 2637c478bd9Sstevel@tonic-gate char formatbuffer[100]; 2647c478bd9Sstevel@tonic-gate char *format; 2657c478bd9Sstevel@tonic-gate int looping; 2667c478bd9Sstevel@tonic-gate short *regs = cur_term->_regs; 2677c478bd9Sstevel@tonic-gate int val; 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate if ((val = setjmp(env)) != 0) { 2717c478bd9Sstevel@tonic-gate #ifdef DEBUG 2727c478bd9Sstevel@tonic-gate switch (val) { 2737c478bd9Sstevel@tonic-gate case MEM_ALLOC_FAIL: 2747c478bd9Sstevel@tonic-gate fprintf(outf, "TPARM: Memory allocation" 2757c478bd9Sstevel@tonic-gate " failure."); 2767c478bd9Sstevel@tonic-gate break; 2777c478bd9Sstevel@tonic-gate case STACK_UNDERFLOW: 2787c478bd9Sstevel@tonic-gate fprintf(outf, "TPARM: Stack underflow."); 2797c478bd9Sstevel@tonic-gate break; 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate if (val == STACK_UNDERFLOW) 2847c478bd9Sstevel@tonic-gate free_stack(&stk); 2857c478bd9Sstevel@tonic-gate return (NULL); 2867c478bd9Sstevel@tonic-gate } 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate init_stack(&stk); 2897c478bd9Sstevel@tonic-gate push(&stk, 0); 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate if (instring == 0) { 2927c478bd9Sstevel@tonic-gate #ifdef DEBUG 2937c478bd9Sstevel@tonic-gate if (outf) 2947c478bd9Sstevel@tonic-gate fprintf(outf, "TPARM: null arg\n"); 2957c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 2967c478bd9Sstevel@tonic-gate free_stack(&stk); 2977c478bd9Sstevel@tonic-gate return (NULL); 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate added[0] = 0; 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate while ((c = *cp++) != 0) { 3037c478bd9Sstevel@tonic-gate if (c != '%') { 3047c478bd9Sstevel@tonic-gate *outp++ = c; 3057c478bd9Sstevel@tonic-gate continue; 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate op = tops(&stk); 3087c478bd9Sstevel@tonic-gate switch (c = *cp++) { 3097c478bd9Sstevel@tonic-gate /* PRINTING CASES */ 3107c478bd9Sstevel@tonic-gate case ':': 3117c478bd9Sstevel@tonic-gate case ' ': 3127c478bd9Sstevel@tonic-gate case '#': 3137c478bd9Sstevel@tonic-gate case '0': 3147c478bd9Sstevel@tonic-gate case '1': 3157c478bd9Sstevel@tonic-gate case '2': 3167c478bd9Sstevel@tonic-gate case '3': 3177c478bd9Sstevel@tonic-gate case '4': 3187c478bd9Sstevel@tonic-gate case '5': 3197c478bd9Sstevel@tonic-gate case '6': 3207c478bd9Sstevel@tonic-gate case '7': 3217c478bd9Sstevel@tonic-gate case '8': 3227c478bd9Sstevel@tonic-gate case '9': 3237c478bd9Sstevel@tonic-gate case '.': 3247c478bd9Sstevel@tonic-gate case 'd': 3257c478bd9Sstevel@tonic-gate case 's': 3267c478bd9Sstevel@tonic-gate case 'o': 3277c478bd9Sstevel@tonic-gate case 'x': 3287c478bd9Sstevel@tonic-gate case 'X': 3297c478bd9Sstevel@tonic-gate format = formatbuffer; 3307c478bd9Sstevel@tonic-gate *format++ = '%'; 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate /* leading ':' to allow +/- in format */ 3337c478bd9Sstevel@tonic-gate if (c == ':') 3347c478bd9Sstevel@tonic-gate c = *cp++; 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate /* take care of flags, width and precision */ 3377c478bd9Sstevel@tonic-gate looping = 1; 3387c478bd9Sstevel@tonic-gate while (c && looping) 3397c478bd9Sstevel@tonic-gate switch (c) { 3407c478bd9Sstevel@tonic-gate case '-': 3417c478bd9Sstevel@tonic-gate case '+': 3427c478bd9Sstevel@tonic-gate case ' ': 3437c478bd9Sstevel@tonic-gate case '#': 3447c478bd9Sstevel@tonic-gate case '0': 3457c478bd9Sstevel@tonic-gate case '1': 3467c478bd9Sstevel@tonic-gate case '2': 3477c478bd9Sstevel@tonic-gate case '3': 3487c478bd9Sstevel@tonic-gate case '4': 3497c478bd9Sstevel@tonic-gate case '5': 3507c478bd9Sstevel@tonic-gate case '6': 3517c478bd9Sstevel@tonic-gate case '7': 3527c478bd9Sstevel@tonic-gate case '8': 3537c478bd9Sstevel@tonic-gate case '9': 3547c478bd9Sstevel@tonic-gate case '.': 3557c478bd9Sstevel@tonic-gate *format++ = c; 3567c478bd9Sstevel@tonic-gate c = *cp++; 3577c478bd9Sstevel@tonic-gate break; 3587c478bd9Sstevel@tonic-gate default: 3597c478bd9Sstevel@tonic-gate looping = 0; 3607c478bd9Sstevel@tonic-gate } 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate /* add in the conversion type */ 3637c478bd9Sstevel@tonic-gate switch (c) { 3647c478bd9Sstevel@tonic-gate case 'd': 3657c478bd9Sstevel@tonic-gate case 's': 3667c478bd9Sstevel@tonic-gate case 'o': 3677c478bd9Sstevel@tonic-gate case 'x': 3687c478bd9Sstevel@tonic-gate case 'X': 3697c478bd9Sstevel@tonic-gate *format++ = c; 3707c478bd9Sstevel@tonic-gate break; 3717c478bd9Sstevel@tonic-gate default: 3727c478bd9Sstevel@tonic-gate #ifdef DEBUG 3737c478bd9Sstevel@tonic-gate if (outf) 3747c478bd9Sstevel@tonic-gate fprintf(outf, "TPARM: invalid " 3757c478bd9Sstevel@tonic-gate "conversion type\n"); 3767c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 3777c478bd9Sstevel@tonic-gate free_stack(&stk); 3787c478bd9Sstevel@tonic-gate return (NULL); 3797c478bd9Sstevel@tonic-gate } 3807c478bd9Sstevel@tonic-gate *format = '\0'; 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate /* 3837c478bd9Sstevel@tonic-gate * Pass off the dirty work to sprintf. 3847c478bd9Sstevel@tonic-gate * It's debatable whether we should just pull in 3857c478bd9Sstevel@tonic-gate * the appropriate code here. I decided not to for 3867c478bd9Sstevel@tonic-gate * now. 3877c478bd9Sstevel@tonic-gate */ 3887c478bd9Sstevel@tonic-gate if (c == 's') 3897c478bd9Sstevel@tonic-gate (void) sprintf(outp, formatbuffer, 3907c478bd9Sstevel@tonic-gate (char *) op); 3917c478bd9Sstevel@tonic-gate else 3927c478bd9Sstevel@tonic-gate (void) sprintf(outp, formatbuffer, op); 3937c478bd9Sstevel@tonic-gate /* 3947c478bd9Sstevel@tonic-gate * Advance outp past what sprintf just did. 3957c478bd9Sstevel@tonic-gate * sprintf returns an indication of its length on some 3967c478bd9Sstevel@tonic-gate * systems, others the first char, and there's 3977c478bd9Sstevel@tonic-gate * no easy way to tell which. The Sys V on 3987c478bd9Sstevel@tonic-gate * BSD emulations are particularly confusing. 3997c478bd9Sstevel@tonic-gate */ 4007c478bd9Sstevel@tonic-gate while (*outp) 4017c478bd9Sstevel@tonic-gate outp++; 4027c478bd9Sstevel@tonic-gate (void) pop(&stk); 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate continue; 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate case 'c': 4077c478bd9Sstevel@tonic-gate /* 4087c478bd9Sstevel@tonic-gate * This code is worth scratching your head at for a 4097c478bd9Sstevel@tonic-gate * while. The idea is that various weird things can 4107c478bd9Sstevel@tonic-gate * happen to nulls, EOT's, tabs, and newlines by the 4117c478bd9Sstevel@tonic-gate * tty driver, arpanet, and so on, so we don't send 4127c478bd9Sstevel@tonic-gate * them if we can help it. So we instead alter the 4137c478bd9Sstevel@tonic-gate * place being addessed and then move the cursor 4147c478bd9Sstevel@tonic-gate * locally using UP or RIGHT. 4157c478bd9Sstevel@tonic-gate * 4167c478bd9Sstevel@tonic-gate * This is a kludge, clearly. It loses if the 4177c478bd9Sstevel@tonic-gate * parameterized string isn't addressing the cursor 4187c478bd9Sstevel@tonic-gate * (but hopefully that is all that %c terminals do 4197c478bd9Sstevel@tonic-gate * with parms). Also, since tab and newline happen 4207c478bd9Sstevel@tonic-gate * to be next to each other in ASCII, if tab were 4217c478bd9Sstevel@tonic-gate * included a loop would be needed. Finally, note 4227c478bd9Sstevel@tonic-gate * that lots of other processing is done here, so 4237c478bd9Sstevel@tonic-gate * this hack won't always work (e.g. the Ann Arbor 4247c478bd9Sstevel@tonic-gate * 4080, which uses %B and then %c.) 4257c478bd9Sstevel@tonic-gate */ 4267c478bd9Sstevel@tonic-gate switch (op) { 4277c478bd9Sstevel@tonic-gate /* 4287c478bd9Sstevel@tonic-gate * Null. Problem is that our 4297c478bd9Sstevel@tonic-gate * output is, by convention, null terminated. 4307c478bd9Sstevel@tonic-gate */ 4317c478bd9Sstevel@tonic-gate case 0: 4327c478bd9Sstevel@tonic-gate op = 0200; /* Parity should */ 4337c478bd9Sstevel@tonic-gate /* be ignored. */ 4347c478bd9Sstevel@tonic-gate break; 4357c478bd9Sstevel@tonic-gate /* 4367c478bd9Sstevel@tonic-gate * Control D. Problem is that certain very 4377c478bd9Sstevel@tonic-gate * ancient hardware hangs up on this, so the 4387c478bd9Sstevel@tonic-gate * current(!) UNIX tty driver doesn't xmit 4397c478bd9Sstevel@tonic-gate * control D's. 4407c478bd9Sstevel@tonic-gate */ 4417c478bd9Sstevel@tonic-gate case _CHCTRL('d'): 4427c478bd9Sstevel@tonic-gate /* 4437c478bd9Sstevel@tonic-gate * Newline. Problem is that UNIX will expand 4447c478bd9Sstevel@tonic-gate * this to CRLF. 4457c478bd9Sstevel@tonic-gate */ 4467c478bd9Sstevel@tonic-gate case '\n': 4477c478bd9Sstevel@tonic-gate xp = (onrow ? cursor_down : 4487c478bd9Sstevel@tonic-gate cursor_right); 4497c478bd9Sstevel@tonic-gate if (onrow && xp && op < lines-1 && 4507c478bd9Sstevel@tonic-gate cursor_up) { 4517c478bd9Sstevel@tonic-gate op += 2; 4527c478bd9Sstevel@tonic-gate xp = cursor_up; 4537c478bd9Sstevel@tonic-gate } 4547c478bd9Sstevel@tonic-gate if (xp && instring == 4557c478bd9Sstevel@tonic-gate cursor_address) { 4567c478bd9Sstevel@tonic-gate (void) strcat(added, xp); 4577c478bd9Sstevel@tonic-gate op--; 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate break; 4607c478bd9Sstevel@tonic-gate /* 4617c478bd9Sstevel@tonic-gate * Tab used to be in this group too, 4627c478bd9Sstevel@tonic-gate * because UNIX might expand it to blanks. 4637c478bd9Sstevel@tonic-gate * We now require that this tab mode be turned 4647c478bd9Sstevel@tonic-gate * off by any program using this routine, 4657c478bd9Sstevel@tonic-gate * or using termcap in general, since some 4667c478bd9Sstevel@tonic-gate * terminals use tab for other stuff, like 4677c478bd9Sstevel@tonic-gate * nondestructive space. (Filters like ul 4687c478bd9Sstevel@tonic-gate * or vcrt will lose, since they can't stty.) 4697c478bd9Sstevel@tonic-gate * Tab was taken out to get the Ann Arbor 4707c478bd9Sstevel@tonic-gate * 4080 to work. 4717c478bd9Sstevel@tonic-gate */ 4727c478bd9Sstevel@tonic-gate } 4737c478bd9Sstevel@tonic-gate 4747c478bd9Sstevel@tonic-gate /* LINTED */ 4757c478bd9Sstevel@tonic-gate *outp++ = (char)op; 4767c478bd9Sstevel@tonic-gate (void) pop(&stk); 4777c478bd9Sstevel@tonic-gate break; 4787c478bd9Sstevel@tonic-gate 4797c478bd9Sstevel@tonic-gate case 'l': 4807c478bd9Sstevel@tonic-gate xp = pop_char_p(&stk); 4817c478bd9Sstevel@tonic-gate push(&stk, strlen(xp)); 4827c478bd9Sstevel@tonic-gate break; 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate case '%': 4857c478bd9Sstevel@tonic-gate *outp++ = c; 4867c478bd9Sstevel@tonic-gate break; 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate /* 4897c478bd9Sstevel@tonic-gate * %i: shorthand for increment first two parms. 4907c478bd9Sstevel@tonic-gate * Useful for terminals that start numbering from 4917c478bd9Sstevel@tonic-gate * one instead of zero(like ANSI terminals). 4927c478bd9Sstevel@tonic-gate */ 4937c478bd9Sstevel@tonic-gate case 'i': 4947c478bd9Sstevel@tonic-gate p1++; 4957c478bd9Sstevel@tonic-gate p2++; 4967c478bd9Sstevel@tonic-gate break; 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate /* %pi: push the ith parameter */ 4997c478bd9Sstevel@tonic-gate case 'p': 5007c478bd9Sstevel@tonic-gate switch (c = *cp++) { 5017c478bd9Sstevel@tonic-gate case '1': 5027c478bd9Sstevel@tonic-gate push(&stk, p1); 5037c478bd9Sstevel@tonic-gate break; 5047c478bd9Sstevel@tonic-gate case '2': 5057c478bd9Sstevel@tonic-gate push(&stk, p2); 5067c478bd9Sstevel@tonic-gate break; 5077c478bd9Sstevel@tonic-gate case '3': 5087c478bd9Sstevel@tonic-gate push(&stk, p3); 5097c478bd9Sstevel@tonic-gate break; 5107c478bd9Sstevel@tonic-gate case '4': 5117c478bd9Sstevel@tonic-gate push(&stk, p4); 5127c478bd9Sstevel@tonic-gate break; 5137c478bd9Sstevel@tonic-gate case '5': 5147c478bd9Sstevel@tonic-gate push(&stk, p5); 5157c478bd9Sstevel@tonic-gate break; 5167c478bd9Sstevel@tonic-gate case '6': 5177c478bd9Sstevel@tonic-gate push(&stk, p6); 5187c478bd9Sstevel@tonic-gate break; 5197c478bd9Sstevel@tonic-gate case '7': 5207c478bd9Sstevel@tonic-gate push(&stk, p7); 5217c478bd9Sstevel@tonic-gate break; 5227c478bd9Sstevel@tonic-gate case '8': 5237c478bd9Sstevel@tonic-gate push(&stk, p8); 5247c478bd9Sstevel@tonic-gate break; 5257c478bd9Sstevel@tonic-gate case '9': 5267c478bd9Sstevel@tonic-gate push(&stk, p9); 5277c478bd9Sstevel@tonic-gate break; 5287c478bd9Sstevel@tonic-gate default: 5297c478bd9Sstevel@tonic-gate #ifdef DEBUG 5307c478bd9Sstevel@tonic-gate if (outf) 5317c478bd9Sstevel@tonic-gate fprintf(outf, "TPARM:" 5327c478bd9Sstevel@tonic-gate " bad parm" 5337c478bd9Sstevel@tonic-gate " number\n"); 5347c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 5357c478bd9Sstevel@tonic-gate free_stack(&stk); 5367c478bd9Sstevel@tonic-gate return (NULL); 5377c478bd9Sstevel@tonic-gate } 5387c478bd9Sstevel@tonic-gate onrow = (c == '1'); 5397c478bd9Sstevel@tonic-gate break; 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate /* %Pi: pop from stack into variable i (a-z) */ 5427c478bd9Sstevel@tonic-gate case 'P': 5437c478bd9Sstevel@tonic-gate if (*cp >= 'a' && *cp <= 'z') { 5447c478bd9Sstevel@tonic-gate vars[*cp++ - 'a'] = pop(&stk); 5457c478bd9Sstevel@tonic-gate } else { 5467c478bd9Sstevel@tonic-gate if (*cp >= 'A' && *cp <= 'Z') { 5477c478bd9Sstevel@tonic-gate regs[*cp++ - 'A'] = 5487c478bd9Sstevel@tonic-gate /* LINTED */ 5497c478bd9Sstevel@tonic-gate (short) pop(&stk); 5507c478bd9Sstevel@tonic-gate } 5517c478bd9Sstevel@tonic-gate #ifdef DEBUG 5527c478bd9Sstevel@tonic-gate else if (outf) { 5537c478bd9Sstevel@tonic-gate fprintf(outf, "TPARM: bad" 5547c478bd9Sstevel@tonic-gate " register name\n"); 5557c478bd9Sstevel@tonic-gate } 5567c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 5577c478bd9Sstevel@tonic-gate } 5587c478bd9Sstevel@tonic-gate break; 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate /* %gi: push variable i (a-z) */ 5617c478bd9Sstevel@tonic-gate case 'g': 5627c478bd9Sstevel@tonic-gate if (*cp >= 'a' && *cp <= 'z') { 5637c478bd9Sstevel@tonic-gate push(&stk, vars[*cp++ - 'a']); 5647c478bd9Sstevel@tonic-gate } else { 5657c478bd9Sstevel@tonic-gate if (*cp >= 'A' && *cp <= 'Z') { 5667c478bd9Sstevel@tonic-gate push(&stk, regs[*cp++ - 'A']); 5677c478bd9Sstevel@tonic-gate } 5687c478bd9Sstevel@tonic-gate #ifdef DEBUG 5697c478bd9Sstevel@tonic-gate else if (outf) { 5707c478bd9Sstevel@tonic-gate fprintf(outf, "TPARM: bad" 5717c478bd9Sstevel@tonic-gate " register name\n"); 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate } 5747c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate break; 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate /* %'c' : character constant */ 5797c478bd9Sstevel@tonic-gate case '\'': 5807c478bd9Sstevel@tonic-gate push(&stk, *cp++); 5817c478bd9Sstevel@tonic-gate if (*cp++ != '\'') { 5827c478bd9Sstevel@tonic-gate #ifdef DEBUG 5837c478bd9Sstevel@tonic-gate if (outf) 5847c478bd9Sstevel@tonic-gate fprintf(outf, "TPARM: missing" 5857c478bd9Sstevel@tonic-gate " closing quote\n"); 5867c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 5877c478bd9Sstevel@tonic-gate free_stack(&stk); 5887c478bd9Sstevel@tonic-gate return (NULL); 5897c478bd9Sstevel@tonic-gate } 5907c478bd9Sstevel@tonic-gate break; 5917c478bd9Sstevel@tonic-gate 5927c478bd9Sstevel@tonic-gate /* %{nn} : integer constant. */ 5937c478bd9Sstevel@tonic-gate case '{': 5947c478bd9Sstevel@tonic-gate op = 0; 5957c478bd9Sstevel@tonic-gate sign = 1; 5967c478bd9Sstevel@tonic-gate if (*cp == '-') { 5977c478bd9Sstevel@tonic-gate sign = -1; 5987c478bd9Sstevel@tonic-gate cp++; 5997c478bd9Sstevel@tonic-gate } else 6007c478bd9Sstevel@tonic-gate if (*cp == '+') 6017c478bd9Sstevel@tonic-gate cp++; 6027c478bd9Sstevel@tonic-gate while ((c = *cp++) >= '0' && c <= '9') { 6037c478bd9Sstevel@tonic-gate op = 10 * op + c - '0'; 6047c478bd9Sstevel@tonic-gate } 6057c478bd9Sstevel@tonic-gate if (c != '}') { 6067c478bd9Sstevel@tonic-gate #ifdef DEBUG 6077c478bd9Sstevel@tonic-gate if (outf) 6087c478bd9Sstevel@tonic-gate fprintf(outf, "TPARM: missing " 6097c478bd9Sstevel@tonic-gate "closing brace\n"); 6107c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 6117c478bd9Sstevel@tonic-gate free_stack(&stk); 6127c478bd9Sstevel@tonic-gate return (NULL); 6137c478bd9Sstevel@tonic-gate } 6147c478bd9Sstevel@tonic-gate push(&stk, (sign * op)); 6157c478bd9Sstevel@tonic-gate break; 6167c478bd9Sstevel@tonic-gate 6177c478bd9Sstevel@tonic-gate /* binary operators */ 6187c478bd9Sstevel@tonic-gate case '+': 6197c478bd9Sstevel@tonic-gate op2 = pop(&stk); 6207c478bd9Sstevel@tonic-gate op = pop(&stk); 6217c478bd9Sstevel@tonic-gate push(&stk, (op + op2)); 6227c478bd9Sstevel@tonic-gate break; 6237c478bd9Sstevel@tonic-gate case '-': 6247c478bd9Sstevel@tonic-gate op2 = pop(&stk); 6257c478bd9Sstevel@tonic-gate op = pop(&stk); 6267c478bd9Sstevel@tonic-gate push(&stk, (op - op2)); 6277c478bd9Sstevel@tonic-gate break; 6287c478bd9Sstevel@tonic-gate case '*': 6297c478bd9Sstevel@tonic-gate op2 = pop(&stk); 6307c478bd9Sstevel@tonic-gate op = pop(&stk); 6317c478bd9Sstevel@tonic-gate push(&stk, (op * op2)); 6327c478bd9Sstevel@tonic-gate break; 6337c478bd9Sstevel@tonic-gate case '/': 6347c478bd9Sstevel@tonic-gate op2 = pop(&stk); 6357c478bd9Sstevel@tonic-gate op = pop(&stk); 6367c478bd9Sstevel@tonic-gate push(&stk, (op / op2)); 6377c478bd9Sstevel@tonic-gate break; 6387c478bd9Sstevel@tonic-gate case 'm': 6397c478bd9Sstevel@tonic-gate op2 = pop(&stk); 6407c478bd9Sstevel@tonic-gate op = pop(&stk); 6417c478bd9Sstevel@tonic-gate push(&stk, (op % op2)); 6427c478bd9Sstevel@tonic-gate break; /* %m: mod */ 6437c478bd9Sstevel@tonic-gate case '&': 6447c478bd9Sstevel@tonic-gate op2 = pop(&stk); 6457c478bd9Sstevel@tonic-gate op = pop(&stk); 6467c478bd9Sstevel@tonic-gate push(&stk, (op & op2)); 6477c478bd9Sstevel@tonic-gate break; 6487c478bd9Sstevel@tonic-gate case '|': 6497c478bd9Sstevel@tonic-gate op2 = pop(&stk); 6507c478bd9Sstevel@tonic-gate op = pop(&stk); 6517c478bd9Sstevel@tonic-gate push(&stk, (op | op2)); 6527c478bd9Sstevel@tonic-gate break; 6537c478bd9Sstevel@tonic-gate case '^': 6547c478bd9Sstevel@tonic-gate op2 = pop(&stk); 6557c478bd9Sstevel@tonic-gate op = pop(&stk); 6567c478bd9Sstevel@tonic-gate push(&stk, (op ^ op2)); 6577c478bd9Sstevel@tonic-gate break; 6587c478bd9Sstevel@tonic-gate case '=': 6597c478bd9Sstevel@tonic-gate op2 = pop(&stk); 6607c478bd9Sstevel@tonic-gate op = pop(&stk); 6617c478bd9Sstevel@tonic-gate push(&stk, (op == op2)); 6627c478bd9Sstevel@tonic-gate break; 6637c478bd9Sstevel@tonic-gate case '>': 6647c478bd9Sstevel@tonic-gate op2 = pop(&stk); 6657c478bd9Sstevel@tonic-gate op = pop(&stk); 6667c478bd9Sstevel@tonic-gate push(&stk, (op > op2)); 6677c478bd9Sstevel@tonic-gate break; 6687c478bd9Sstevel@tonic-gate case '<': 6697c478bd9Sstevel@tonic-gate op2 = pop(&stk); 6707c478bd9Sstevel@tonic-gate op = pop(&stk); 6717c478bd9Sstevel@tonic-gate push(&stk, (op < op2)); 6727c478bd9Sstevel@tonic-gate break; 6737c478bd9Sstevel@tonic-gate case 'A': 6747c478bd9Sstevel@tonic-gate op2 = pop(&stk); 6757c478bd9Sstevel@tonic-gate op = pop(&stk); 6767c478bd9Sstevel@tonic-gate push(&stk, (op && op2)); 6777c478bd9Sstevel@tonic-gate break; /* AND */ 6787c478bd9Sstevel@tonic-gate case 'O': 6797c478bd9Sstevel@tonic-gate op2 = pop(&stk); 6807c478bd9Sstevel@tonic-gate op = pop(&stk); 6817c478bd9Sstevel@tonic-gate push(&stk, (op || op2)); 6827c478bd9Sstevel@tonic-gate break; /* OR */ 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate /* Unary operators. */ 6857c478bd9Sstevel@tonic-gate case '!': 6867c478bd9Sstevel@tonic-gate push(&stk, !pop(&stk)); 6877c478bd9Sstevel@tonic-gate break; 6887c478bd9Sstevel@tonic-gate case '~': 6897c478bd9Sstevel@tonic-gate push(&stk, ~pop(&stk)); 6907c478bd9Sstevel@tonic-gate break; 6917c478bd9Sstevel@tonic-gate 6927c478bd9Sstevel@tonic-gate /* Sorry, no unary minus, because minus is binary. */ 6937c478bd9Sstevel@tonic-gate 6947c478bd9Sstevel@tonic-gate /* 6957c478bd9Sstevel@tonic-gate * If-then-else. Implemented by a low level hack of 6967c478bd9Sstevel@tonic-gate * skipping forward until the match is found, counting 6977c478bd9Sstevel@tonic-gate * nested if-then-elses. 6987c478bd9Sstevel@tonic-gate */ 6997c478bd9Sstevel@tonic-gate case '?': /* IF - just a marker */ 7007c478bd9Sstevel@tonic-gate break; 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate case 't': /* THEN - branch if false */ 7037c478bd9Sstevel@tonic-gate if (!pop(&stk)) 7047c478bd9Sstevel@tonic-gate cp = _branchto(cp, 'e'); 7057c478bd9Sstevel@tonic-gate break; 7067c478bd9Sstevel@tonic-gate 7077c478bd9Sstevel@tonic-gate case 'e': /* ELSE - branch to ENDIF */ 7087c478bd9Sstevel@tonic-gate cp = _branchto(cp, ';'); 7097c478bd9Sstevel@tonic-gate break; 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate case ';': /* ENDIF - just a marker */ 7127c478bd9Sstevel@tonic-gate break; 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate default: 7157c478bd9Sstevel@tonic-gate #ifdef DEBUG 7167c478bd9Sstevel@tonic-gate if (outf) 7177c478bd9Sstevel@tonic-gate fprintf(outf, "TPARM: bad % " 7187c478bd9Sstevel@tonic-gate "sequence\n"); 7197c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 7207c478bd9Sstevel@tonic-gate free_stack(&stk); 7217c478bd9Sstevel@tonic-gate return (NULL); 7227c478bd9Sstevel@tonic-gate } 7237c478bd9Sstevel@tonic-gate } 7247c478bd9Sstevel@tonic-gate (void) strcpy(outp, added); 7257c478bd9Sstevel@tonic-gate free_stack(&stk); 7267c478bd9Sstevel@tonic-gate return (result); 7277c478bd9Sstevel@tonic-gate } 7287c478bd9Sstevel@tonic-gate 7297c478bd9Sstevel@tonic-gate char * 7307c478bd9Sstevel@tonic-gate _branchto(register char *cp, char to) 7317c478bd9Sstevel@tonic-gate { 7327c478bd9Sstevel@tonic-gate register int level = 0; 7337c478bd9Sstevel@tonic-gate register char c; 7347c478bd9Sstevel@tonic-gate 7357c478bd9Sstevel@tonic-gate while (c = *cp++) { 7367c478bd9Sstevel@tonic-gate if (c == '%') { 7377c478bd9Sstevel@tonic-gate if ((c = *cp++) == to || c == ';') { 7387c478bd9Sstevel@tonic-gate if (level == 0) { 7397c478bd9Sstevel@tonic-gate return (cp); 7407c478bd9Sstevel@tonic-gate } 7417c478bd9Sstevel@tonic-gate } 7427c478bd9Sstevel@tonic-gate if (c == '?') 7437c478bd9Sstevel@tonic-gate level++; 7447c478bd9Sstevel@tonic-gate if (c == ';') 7457c478bd9Sstevel@tonic-gate level--; 7467c478bd9Sstevel@tonic-gate } 7477c478bd9Sstevel@tonic-gate } 7487c478bd9Sstevel@tonic-gate #ifdef DEBUG 7497c478bd9Sstevel@tonic-gate if (outf) 7507c478bd9Sstevel@tonic-gate fprintf(outf, "TPARM: no matching ENDIF"); 7517c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 7527c478bd9Sstevel@tonic-gate return (NULL); 7537c478bd9Sstevel@tonic-gate } 754