10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 220Sstevel@tonic-gate /* 23*722Smuffin * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*722Smuffin * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate /* Copyright (c) 1984 AT&T */ 280Sstevel@tonic-gate /* All Rights Reserved */ 290Sstevel@tonic-gate 30*722Smuffin #pragma ident "%Z%%M% %I% %E% SMI" 310Sstevel@tonic-gate 320Sstevel@tonic-gate /*LINTLIBRARY*/ 330Sstevel@tonic-gate #include <stdio.h> 340Sstevel@tonic-gate #include <ctype.h> 35*722Smuffin #include <stdarg.h> 360Sstevel@tonic-gate #include <values.h> 370Sstevel@tonic-gate #include <floatingpoint.h> 380Sstevel@tonic-gate #include <errno.h> 39*722Smuffin #include <memory.h> 400Sstevel@tonic-gate 410Sstevel@tonic-gate #define NCHARS (1 << BITSPERBYTE) 420Sstevel@tonic-gate #define locgetc() (chcount+=1,getc(iop)) 430Sstevel@tonic-gate #define locungetc(x) (chcount-=1,ungetc(x,iop)) 440Sstevel@tonic-gate 450Sstevel@tonic-gate static int chcount,flag_eof; 460Sstevel@tonic-gate 47*722Smuffin static int number(int, int, int, int, FILE *, va_list *); 48*722Smuffin static int string(int, int, int, char *, FILE *, va_list *); 49*722Smuffin static unsigned char *setup(unsigned char *, char *); 50*722Smuffin 510Sstevel@tonic-gate #ifdef S5EMUL 520Sstevel@tonic-gate #define isws(c) isspace(c) 530Sstevel@tonic-gate #else 540Sstevel@tonic-gate /* 550Sstevel@tonic-gate * _sptab[c+1] is 1 iff 'c' is a white space character according to the 560Sstevel@tonic-gate * 4.2BSD "scanf" definition - namely, SP, TAB, and NL are the only 570Sstevel@tonic-gate * whitespace characters. 580Sstevel@tonic-gate */ 590Sstevel@tonic-gate static char _sptab[1+256] = { 600Sstevel@tonic-gate 0, /* EOF - not a whitespace char */ 610Sstevel@tonic-gate 0,0,0,0,0,0,0,0, 620Sstevel@tonic-gate 0,1,1,0,0,0,0,0, 630Sstevel@tonic-gate 0,0,0,0,0,0,0,0, 640Sstevel@tonic-gate 0,0,0,0,0,0,0,0, 650Sstevel@tonic-gate 1,0,0,0,0,0,0,0, 660Sstevel@tonic-gate 0,0,0,0,0,0,0,0, 670Sstevel@tonic-gate 0,0,0,0,0,0,0,0, 680Sstevel@tonic-gate 0,0,0,0,0,0,0,0, 690Sstevel@tonic-gate 0,0,0,0,0,0,0,0, 700Sstevel@tonic-gate 0,0,0,0,0,0,0,0, 710Sstevel@tonic-gate 0,0,0,0,0,0,0,0, 720Sstevel@tonic-gate 0,0,0,0,0,0,0,0, 730Sstevel@tonic-gate 0,0,0,0,0,0,0,0, 740Sstevel@tonic-gate 0,0,0,0,0,0,0,0, 750Sstevel@tonic-gate 0,0,0,0,0,0,0,0, 760Sstevel@tonic-gate 0,0,0,0,0,0,0,0, 770Sstevel@tonic-gate }; 780Sstevel@tonic-gate 790Sstevel@tonic-gate #define isws(c) ((_sptab + 1)[c] != 0) 800Sstevel@tonic-gate #endif 810Sstevel@tonic-gate 820Sstevel@tonic-gate int 83*722Smuffin _doscan(FILE *iop, unsigned char *fmt, va_list va_alist) 840Sstevel@tonic-gate { 850Sstevel@tonic-gate char tab[NCHARS]; 86*722Smuffin int ch; 870Sstevel@tonic-gate int nmatch = 0, len, inchar, stow, size; 880Sstevel@tonic-gate chcount=0; flag_eof=0; 890Sstevel@tonic-gate 900Sstevel@tonic-gate /******************************************************* 910Sstevel@tonic-gate * Main loop: reads format to determine a pattern, 920Sstevel@tonic-gate * and then goes to read input stream 930Sstevel@tonic-gate * in attempt to match the pattern. 940Sstevel@tonic-gate *******************************************************/ 950Sstevel@tonic-gate for ( ; ; ) 960Sstevel@tonic-gate { 970Sstevel@tonic-gate if ( (ch = *fmt++) == '\0') 980Sstevel@tonic-gate return(nmatch); /* end of format */ 990Sstevel@tonic-gate if (isws(ch)) 1000Sstevel@tonic-gate { 1010Sstevel@tonic-gate if (!flag_eof) 1020Sstevel@tonic-gate { 1030Sstevel@tonic-gate while (isws(inchar = locgetc())) 1040Sstevel@tonic-gate ; 1050Sstevel@tonic-gate if (inchar == EOF) { 1060Sstevel@tonic-gate chcount--; 1070Sstevel@tonic-gate flag_eof = 1; 1080Sstevel@tonic-gate } 1090Sstevel@tonic-gate else if (locungetc(inchar) == EOF) 1100Sstevel@tonic-gate flag_eof = 1; 1110Sstevel@tonic-gate } 1120Sstevel@tonic-gate continue; 1130Sstevel@tonic-gate } 1140Sstevel@tonic-gate if (ch != '%' || (ch = *fmt++) == '%') 1150Sstevel@tonic-gate { 1160Sstevel@tonic-gate if ( (inchar = locgetc()) == ch ) 1170Sstevel@tonic-gate continue; 1180Sstevel@tonic-gate if (inchar != EOF) { 1190Sstevel@tonic-gate if (locungetc(inchar) != EOF) 1200Sstevel@tonic-gate return(nmatch); /* failed to match input */ 1210Sstevel@tonic-gate } else { 1220Sstevel@tonic-gate chcount--; 1230Sstevel@tonic-gate } 1240Sstevel@tonic-gate break; 1250Sstevel@tonic-gate } 1260Sstevel@tonic-gate if (ch == '*') 1270Sstevel@tonic-gate { 1280Sstevel@tonic-gate stow = 0; 1290Sstevel@tonic-gate ch = *fmt++; 1300Sstevel@tonic-gate } 1310Sstevel@tonic-gate else 1320Sstevel@tonic-gate stow = 1; 1330Sstevel@tonic-gate 1340Sstevel@tonic-gate for (len = 0; isdigit(ch); ch = *fmt++) 1350Sstevel@tonic-gate len = len * 10 + ch - '0'; 1360Sstevel@tonic-gate if (len == 0) 1370Sstevel@tonic-gate len = MAXINT; 1380Sstevel@tonic-gate if ( (size = ch) == 'l' || (size == 'h') || (size == 'L') ) 1390Sstevel@tonic-gate ch = *fmt++; 1400Sstevel@tonic-gate if (ch == '\0' || 1410Sstevel@tonic-gate ch == '[' && (fmt = setup(fmt, tab)) == NULL) 1420Sstevel@tonic-gate return(EOF); /* unexpected end of format */ 1430Sstevel@tonic-gate if (isupper(ch)) /* no longer documented */ 1440Sstevel@tonic-gate { 1450Sstevel@tonic-gate /* 1460Sstevel@tonic-gate * The rationale behind excluding the size 1470Sstevel@tonic-gate * of 'L' is that the 'L' size specifier was 1480Sstevel@tonic-gate * introduced in ANSI/ISO-C. If the user 1490Sstevel@tonic-gate * specifies a format of %LG, it can mean 1500Sstevel@tonic-gate * nothing other than "long double", be the 1510Sstevel@tonic-gate * code ANSI or not. Mapping it to "double" 1520Sstevel@tonic-gate * makes no sense. 1530Sstevel@tonic-gate */ 1540Sstevel@tonic-gate if (size != 'L') 1550Sstevel@tonic-gate size = 'l'; 1560Sstevel@tonic-gate #ifdef S5EMUL 1570Sstevel@tonic-gate ch = _tolower(ch); 1580Sstevel@tonic-gate #else 1590Sstevel@tonic-gate ch = tolower(ch); 1600Sstevel@tonic-gate #endif 1610Sstevel@tonic-gate } 1620Sstevel@tonic-gate switch(ch) 1630Sstevel@tonic-gate { 1640Sstevel@tonic-gate case 'c': 1650Sstevel@tonic-gate case 's': 1660Sstevel@tonic-gate case '[': 1670Sstevel@tonic-gate if ((size = string(stow,ch,len,tab,iop,&va_alist)) < 0) 1680Sstevel@tonic-gate goto out; /* EOF seen, nothing converted */ 1690Sstevel@tonic-gate break; 1700Sstevel@tonic-gate case 'n': 1710Sstevel@tonic-gate if (stow == 0) 1720Sstevel@tonic-gate continue; 1730Sstevel@tonic-gate if (size == 'h') 1740Sstevel@tonic-gate *va_arg(va_alist, short *) = (short) chcount; 1750Sstevel@tonic-gate else if (size == 'l') 1760Sstevel@tonic-gate *va_arg(va_alist, long *) = (long) chcount; 1770Sstevel@tonic-gate else 1780Sstevel@tonic-gate *va_arg(va_alist, int *) = (int) chcount; 1790Sstevel@tonic-gate continue; 1800Sstevel@tonic-gate default: 1810Sstevel@tonic-gate if ((size = number(stow, ch, len, size, iop, &va_alist)) < 0) 1820Sstevel@tonic-gate goto out; /* EOF seen, nothing converted */ 1830Sstevel@tonic-gate break; 1840Sstevel@tonic-gate } 1850Sstevel@tonic-gate if (size) 1860Sstevel@tonic-gate nmatch += stow; 1870Sstevel@tonic-gate else 1880Sstevel@tonic-gate return((flag_eof && !nmatch) ? EOF : nmatch); 1890Sstevel@tonic-gate continue; 1900Sstevel@tonic-gate } 1910Sstevel@tonic-gate out: 1920Sstevel@tonic-gate return (nmatch != 0 ? nmatch : EOF); /* end of input */ 1930Sstevel@tonic-gate } 1940Sstevel@tonic-gate 195*722Smuffin /* 196*722Smuffin ************************************************************** 1970Sstevel@tonic-gate * Functions to read the input stream in an attempt to match incoming 1980Sstevel@tonic-gate * data to the current pattern from the main loop of _doscan(). 199*722Smuffin ************************************************************** 200*722Smuffin */ 2010Sstevel@tonic-gate static int 202*722Smuffin number(int stow, int type, int len, int size, FILE *iop, va_list *listp) 2030Sstevel@tonic-gate { 2040Sstevel@tonic-gate char numbuf[64], inchar, lookahead; 205*722Smuffin char *np = numbuf; 206*722Smuffin int c, base; 2070Sstevel@tonic-gate int digitseen = 0, floater = 0, negflg = 0; 2080Sstevel@tonic-gate long lcval = 0; 2090Sstevel@tonic-gate switch(type) 2100Sstevel@tonic-gate { 2110Sstevel@tonic-gate case 'e': 2120Sstevel@tonic-gate case 'f': 2130Sstevel@tonic-gate case 'g': 2140Sstevel@tonic-gate floater++; 2150Sstevel@tonic-gate case 'd': 2160Sstevel@tonic-gate case 'u': 2170Sstevel@tonic-gate case 'i': 2180Sstevel@tonic-gate base = 10; 2190Sstevel@tonic-gate break; 2200Sstevel@tonic-gate case 'o': 2210Sstevel@tonic-gate base = 8; 2220Sstevel@tonic-gate break; 2230Sstevel@tonic-gate case 'x': 2240Sstevel@tonic-gate base = 16; 2250Sstevel@tonic-gate break; 2260Sstevel@tonic-gate default: 2270Sstevel@tonic-gate return(0); /* unrecognized conversion character */ 2280Sstevel@tonic-gate } 2290Sstevel@tonic-gate if (!flag_eof) 2300Sstevel@tonic-gate { 2310Sstevel@tonic-gate while (isws(c = locgetc())) 2320Sstevel@tonic-gate ; 2330Sstevel@tonic-gate } 2340Sstevel@tonic-gate else 2350Sstevel@tonic-gate c = locgetc(); 2360Sstevel@tonic-gate if (c == EOF) { 2370Sstevel@tonic-gate chcount--; 2380Sstevel@tonic-gate return(-1); /* EOF before match */ 2390Sstevel@tonic-gate } 2400Sstevel@tonic-gate if (floater != 0) { /* Handle floating point with 2410Sstevel@tonic-gate * file_to_decimal. */ 2420Sstevel@tonic-gate decimal_mode dm; 2430Sstevel@tonic-gate decimal_record dr; 2440Sstevel@tonic-gate fp_exception_field_type efs; 2450Sstevel@tonic-gate enum decimal_string_form form; 2460Sstevel@tonic-gate char *echar; 2470Sstevel@tonic-gate int nread, ic; 2480Sstevel@tonic-gate char buffer[1024]; 2490Sstevel@tonic-gate char *nb = buffer; 2500Sstevel@tonic-gate 2510Sstevel@tonic-gate locungetc(c); 2520Sstevel@tonic-gate if (len > 1024) 2530Sstevel@tonic-gate len = 1024; 2540Sstevel@tonic-gate file_to_decimal(&nb, len, 0, &dr, &form, &echar, iop, &nread); 2550Sstevel@tonic-gate if (stow && (form != invalid_form)) { 2560Sstevel@tonic-gate dm.rd = fp_direction; 2570Sstevel@tonic-gate if (size == 'l') { /* double */ 2580Sstevel@tonic-gate decimal_to_double((double *) va_arg(*listp, double *), &dm, &dr, &efs); 2590Sstevel@tonic-gate } else if (size == 'L') { /* quad */ 2600Sstevel@tonic-gate decimal_to_quadruple((quadruple *)va_arg(*listp, double *), &dm, &dr, &efs); 2610Sstevel@tonic-gate } else {/* single */ 2620Sstevel@tonic-gate decimal_to_single((float *) va_arg(*listp, float *), &dm, &dr, &efs); 2630Sstevel@tonic-gate } 2640Sstevel@tonic-gate if ((efs & (1 << fp_overflow)) != 0) { 2650Sstevel@tonic-gate errno = ERANGE; 2660Sstevel@tonic-gate } 2670Sstevel@tonic-gate if ((efs & (1 << fp_underflow)) != 0) { 2680Sstevel@tonic-gate errno = ERANGE; 2690Sstevel@tonic-gate } 2700Sstevel@tonic-gate } 2710Sstevel@tonic-gate chcount += nread; /* Count characters read. */ 2720Sstevel@tonic-gate c = *nb; /* Get first unused character. */ 2730Sstevel@tonic-gate ic = c; 2740Sstevel@tonic-gate if (c == NULL) { 2750Sstevel@tonic-gate ic = locgetc(); 2760Sstevel@tonic-gate c = ic; 2770Sstevel@tonic-gate /* 2780Sstevel@tonic-gate * If null, first unused may have been put back 2790Sstevel@tonic-gate * already. 2800Sstevel@tonic-gate */ 2810Sstevel@tonic-gate } 2820Sstevel@tonic-gate if (ic == EOF) { 2830Sstevel@tonic-gate chcount--; 2840Sstevel@tonic-gate flag_eof = 1; 2850Sstevel@tonic-gate } else if (locungetc(c) == EOF) 2860Sstevel@tonic-gate flag_eof = 1; 2870Sstevel@tonic-gate return ((form == invalid_form) ? 0 : 1); /* successful match if 2880Sstevel@tonic-gate * non-zero */ 2890Sstevel@tonic-gate } 2900Sstevel@tonic-gate switch(c) { 2910Sstevel@tonic-gate case '-': 2920Sstevel@tonic-gate negflg++; 2930Sstevel@tonic-gate if (type == 'u') 2940Sstevel@tonic-gate break; 2950Sstevel@tonic-gate case '+': /* fall-through */ 2960Sstevel@tonic-gate if (--len <= 0) 2970Sstevel@tonic-gate break; 2980Sstevel@tonic-gate if ( (c = locgetc()) != '0') 2990Sstevel@tonic-gate break; 3000Sstevel@tonic-gate case '0': 3010Sstevel@tonic-gate if ( (type != 'i') || (len <= 1) ) 3020Sstevel@tonic-gate break; 3030Sstevel@tonic-gate if ( ((inchar = locgetc()) == 'x') || (inchar == 'X') ) 3040Sstevel@tonic-gate { 3050Sstevel@tonic-gate /* If not using sscanf and * 3060Sstevel@tonic-gate * at the buffer's end * 3070Sstevel@tonic-gate * then LOOK ahead */ 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate if ( (iop->_flag & _IOSTRG) || (iop->_cnt != 0) ) 3100Sstevel@tonic-gate lookahead = locgetc(); 3110Sstevel@tonic-gate else 3120Sstevel@tonic-gate { 3130Sstevel@tonic-gate if ( read(fileno(iop),np,1) == 1) 3140Sstevel@tonic-gate lookahead = *np; 3150Sstevel@tonic-gate else 3160Sstevel@tonic-gate lookahead = EOF; 3170Sstevel@tonic-gate chcount += 1; 3180Sstevel@tonic-gate } 3190Sstevel@tonic-gate if ( isxdigit(lookahead) ) 3200Sstevel@tonic-gate { 3210Sstevel@tonic-gate base =16; 3220Sstevel@tonic-gate 3230Sstevel@tonic-gate if ( len <= 2) 3240Sstevel@tonic-gate { 3250Sstevel@tonic-gate locungetc(lookahead); 3260Sstevel@tonic-gate len -= 1; /* Take into account the 'x'*/ 3270Sstevel@tonic-gate } 3280Sstevel@tonic-gate else 3290Sstevel@tonic-gate { 3300Sstevel@tonic-gate c = lookahead; 3310Sstevel@tonic-gate len -= 2; /* Take into account '0x'*/ 3320Sstevel@tonic-gate } 3330Sstevel@tonic-gate } 3340Sstevel@tonic-gate else 3350Sstevel@tonic-gate { 3360Sstevel@tonic-gate locungetc(lookahead); 3370Sstevel@tonic-gate locungetc(inchar); 3380Sstevel@tonic-gate } 3390Sstevel@tonic-gate } 3400Sstevel@tonic-gate else 3410Sstevel@tonic-gate { 3420Sstevel@tonic-gate locungetc(inchar); 3430Sstevel@tonic-gate base = 8; 3440Sstevel@tonic-gate } 3450Sstevel@tonic-gate } 3460Sstevel@tonic-gate if (!negflg || type != 'u') 3470Sstevel@tonic-gate for (; --len >= 0 ; *np++ = c, c = locgetc()) 3480Sstevel@tonic-gate { 3490Sstevel@tonic-gate if (np > numbuf + 62) 3500Sstevel@tonic-gate { 3510Sstevel@tonic-gate errno = ERANGE; 3520Sstevel@tonic-gate return(0); 3530Sstevel@tonic-gate } 3540Sstevel@tonic-gate if (isdigit(c)) 3550Sstevel@tonic-gate { 356*722Smuffin int digit; 3570Sstevel@tonic-gate digit = c - '0'; 3580Sstevel@tonic-gate if (base == 8) 3590Sstevel@tonic-gate { 3600Sstevel@tonic-gate if (digit >= 8) 3610Sstevel@tonic-gate break; 3620Sstevel@tonic-gate if (stow) 3630Sstevel@tonic-gate lcval = (lcval<<3) + digit; 3640Sstevel@tonic-gate } 3650Sstevel@tonic-gate else 3660Sstevel@tonic-gate { 3670Sstevel@tonic-gate if (stow) 3680Sstevel@tonic-gate { 3690Sstevel@tonic-gate if (base == 10) 3700Sstevel@tonic-gate lcval = (((lcval<<2) + lcval)<<1) + digit; 3710Sstevel@tonic-gate else /* base == 16 */ 3720Sstevel@tonic-gate lcval = (lcval<<4) + digit; 3730Sstevel@tonic-gate } 3740Sstevel@tonic-gate } 3750Sstevel@tonic-gate digitseen++; 3760Sstevel@tonic-gate 3770Sstevel@tonic-gate 3780Sstevel@tonic-gate continue; 3790Sstevel@tonic-gate } 3800Sstevel@tonic-gate else if (base == 16 && isxdigit(c)) 3810Sstevel@tonic-gate { 382*722Smuffin int digit; 3830Sstevel@tonic-gate digit = c - (isupper(c) ? 'A' - 10 : 'a' - 10); 3840Sstevel@tonic-gate if (stow) 3850Sstevel@tonic-gate lcval = (lcval<<4) + digit; 3860Sstevel@tonic-gate digitseen++; 3870Sstevel@tonic-gate continue; 3880Sstevel@tonic-gate } 3890Sstevel@tonic-gate break; 3900Sstevel@tonic-gate } 3910Sstevel@tonic-gate 3920Sstevel@tonic-gate 3930Sstevel@tonic-gate if (stow && digitseen) 3940Sstevel@tonic-gate { 3950Sstevel@tonic-gate /* suppress possible overflow on 2's-comp negation */ 3960Sstevel@tonic-gate if (negflg && lcval != HIBITL) 3970Sstevel@tonic-gate lcval = -lcval; 3980Sstevel@tonic-gate if (size == 'l') 3990Sstevel@tonic-gate *va_arg(*listp, long *) = lcval; 4000Sstevel@tonic-gate else if (size == 'h') 4010Sstevel@tonic-gate *va_arg(*listp, short *) = (short)lcval; 4020Sstevel@tonic-gate else 4030Sstevel@tonic-gate *va_arg(*listp, int *) = (int)lcval; 4040Sstevel@tonic-gate } 4050Sstevel@tonic-gate if (c == EOF) { 4060Sstevel@tonic-gate chcount--; 4070Sstevel@tonic-gate flag_eof=1; 4080Sstevel@tonic-gate } else if (locungetc(c) == EOF) 4090Sstevel@tonic-gate flag_eof=1; 4100Sstevel@tonic-gate return (digitseen); /* successful match if non-zero */ 4110Sstevel@tonic-gate } 4120Sstevel@tonic-gate 4130Sstevel@tonic-gate static int 414*722Smuffin string(int stow, int type, int len, char *tab, FILE *iop, va_list *listp) 4150Sstevel@tonic-gate { 416*722Smuffin int ch; 417*722Smuffin char *ptr; 4180Sstevel@tonic-gate char *start; 4190Sstevel@tonic-gate 4200Sstevel@tonic-gate start = ptr = stow ? va_arg(*listp, char *) : NULL; 4210Sstevel@tonic-gate if (type == 's') 4220Sstevel@tonic-gate { 4230Sstevel@tonic-gate if (!flag_eof) 4240Sstevel@tonic-gate { 4250Sstevel@tonic-gate while (isws(ch = locgetc())) 4260Sstevel@tonic-gate ; 4270Sstevel@tonic-gate } 4280Sstevel@tonic-gate else 4290Sstevel@tonic-gate ch = locgetc(); 4300Sstevel@tonic-gate if (ch == EOF) 4310Sstevel@tonic-gate return(-1); /* EOF before match */ 4320Sstevel@tonic-gate while (ch != EOF && !isws(ch)) 4330Sstevel@tonic-gate { 4340Sstevel@tonic-gate if (stow) 4350Sstevel@tonic-gate *ptr = ch; 4360Sstevel@tonic-gate ptr++; 4370Sstevel@tonic-gate if (--len <= 0) 4380Sstevel@tonic-gate break; 4390Sstevel@tonic-gate ch = locgetc(); 4400Sstevel@tonic-gate } 4410Sstevel@tonic-gate } else if (type == 'c') { 4420Sstevel@tonic-gate if (len == MAXINT) 4430Sstevel@tonic-gate len = 1; 4440Sstevel@tonic-gate while ( (ch = locgetc()) != EOF) 4450Sstevel@tonic-gate { 4460Sstevel@tonic-gate if (stow) 4470Sstevel@tonic-gate *ptr = ch; 4480Sstevel@tonic-gate ptr++; 4490Sstevel@tonic-gate if (--len <= 0) 4500Sstevel@tonic-gate break; 4510Sstevel@tonic-gate } 4520Sstevel@tonic-gate } else { /* type == '[' */ 4530Sstevel@tonic-gate while ( (ch = locgetc()) != EOF && !tab[ch]) 4540Sstevel@tonic-gate { 4550Sstevel@tonic-gate if (stow) 4560Sstevel@tonic-gate *ptr = ch; 4570Sstevel@tonic-gate ptr++; 4580Sstevel@tonic-gate if (--len <= 0) 4590Sstevel@tonic-gate break; 4600Sstevel@tonic-gate } 4610Sstevel@tonic-gate } 4620Sstevel@tonic-gate if (ch == EOF ) 4630Sstevel@tonic-gate { 4640Sstevel@tonic-gate chcount-=1; 4650Sstevel@tonic-gate flag_eof = 1; 4660Sstevel@tonic-gate } 4670Sstevel@tonic-gate else if (len > 0 && locungetc(ch) == EOF) 4680Sstevel@tonic-gate flag_eof = 1; 4690Sstevel@tonic-gate if (ptr == start) 4700Sstevel@tonic-gate return(0); /* no match */ 4710Sstevel@tonic-gate if (stow && type != 'c') 4720Sstevel@tonic-gate *ptr = '\0'; 4730Sstevel@tonic-gate return (1); /* successful match */ 4740Sstevel@tonic-gate } 4750Sstevel@tonic-gate 4760Sstevel@tonic-gate static unsigned char * 477*722Smuffin setup(unsigned char *fmt, char *tab) 4780Sstevel@tonic-gate { 479*722Smuffin int b, c, d, t = 0; 4800Sstevel@tonic-gate 4810Sstevel@tonic-gate if (*fmt == '^') 4820Sstevel@tonic-gate { 4830Sstevel@tonic-gate t++; 4840Sstevel@tonic-gate fmt++; 4850Sstevel@tonic-gate } 4860Sstevel@tonic-gate (void) memset(tab, !t, NCHARS); 4870Sstevel@tonic-gate if ( (c = *fmt) == ']' || c == '-') /* first char is special */ 4880Sstevel@tonic-gate { 4890Sstevel@tonic-gate tab[c] = t; 4900Sstevel@tonic-gate fmt++; 4910Sstevel@tonic-gate } 4920Sstevel@tonic-gate while ( (c = *fmt++) != ']') 4930Sstevel@tonic-gate { 4940Sstevel@tonic-gate if (c == '\0') 4950Sstevel@tonic-gate return(NULL); /* unexpected end of format */ 4960Sstevel@tonic-gate if (c == '-' && (d = *fmt) != ']' && (b = fmt[-2]) < d) 4970Sstevel@tonic-gate { 4980Sstevel@tonic-gate (void) memset(&tab[b], t, d - b + 1); 4990Sstevel@tonic-gate fmt++; 5000Sstevel@tonic-gate } 5010Sstevel@tonic-gate else 5020Sstevel@tonic-gate tab[c] = t; 5030Sstevel@tonic-gate } 5040Sstevel@tonic-gate return (fmt); 5050Sstevel@tonic-gate } 506