13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier * pANS stdio -- vfscanf
33e12c5d1SDavid du Colombier */
43e12c5d1SDavid du Colombier #include "iolib.h"
53e12c5d1SDavid du Colombier #include <stdarg.h>
63e12c5d1SDavid du Colombier #include <math.h>
73e12c5d1SDavid du Colombier #include <stdlib.h>
83e12c5d1SDavid du Colombier #include <ctype.h>
93e12c5d1SDavid du Colombier static int icvt_f(FILE *f, va_list *args, int store, int width, int type);
103e12c5d1SDavid du Colombier static int icvt_x(FILE *f, va_list *args, int store, int width, int type);
113e12c5d1SDavid du Colombier static int icvt_sq(FILE *f, va_list *args, int store, int width, int type);
123e12c5d1SDavid du Colombier static int icvt_c(FILE *f, va_list *args, int store, int width, int type);
133e12c5d1SDavid du Colombier static int icvt_d(FILE *f, va_list *args, int store, int width, int type);
143e12c5d1SDavid du Colombier static int icvt_i(FILE *f, va_list *args, int store, int width, int type);
153e12c5d1SDavid du Colombier static int icvt_n(FILE *f, va_list *args, int store, int width, int type);
163e12c5d1SDavid du Colombier static int icvt_o(FILE *f, va_list *args, int store, int width, int type);
173e12c5d1SDavid du Colombier static int icvt_p(FILE *f, va_list *args, int store, int width, int type);
183e12c5d1SDavid du Colombier static int icvt_s(FILE *f, va_list *args, int store, int width, int type);
193e12c5d1SDavid du Colombier static int icvt_u(FILE *f, va_list *args, int store, int width, int type);
203e12c5d1SDavid du Colombier static int (*icvt[])(FILE *, va_list *, int, int, int)={
213e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0, /* ^@ ^A ^B ^C ^D ^E ^F ^G */
223e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0, /* ^H ^I ^J ^K ^L ^M ^N ^O */
233e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0, /* ^P ^Q ^R ^S ^T ^U ^V ^W */
243e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0, /* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */
253e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0, /* sp ! " # $ % & ' */
263e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0, /* ( ) * + , - . / */
273e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0, /* 0 1 2 3 4 5 6 7 */
283e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0, /* 8 9 : ; < = > ? */
293e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, icvt_f, 0, icvt_f, /* @ A B C D E F G */
303e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0, /* H I J K L M N O */
313e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0, /* P Q R S T U V W */
323e12c5d1SDavid du Colombier icvt_x, 0, 0, icvt_sq,0, 0, 0, 0, /* X Y Z [ \ ] ^ _ */
333e12c5d1SDavid du Colombier 0, 0, 0, icvt_c, icvt_d, icvt_f, icvt_f, icvt_f, /* ` a b c d e f g */
343e12c5d1SDavid du Colombier 0, icvt_i, 0, 0, 0, 0, icvt_n, icvt_o, /* h i j k l m n o */
353e12c5d1SDavid du Colombier icvt_p, 0, 0, icvt_s, 0, icvt_u, 0, 0, /* p q r s t u v w */
363e12c5d1SDavid du Colombier icvt_x, 0, 0, 0, 0, 0, 0, 0, /* x y z { | } ~ ^? */
373e12c5d1SDavid du Colombier
383e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
393e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
403e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
413e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
423e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
433e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
443e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
453e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
463e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
473e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
483e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
493e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
503e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
513e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
523e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
533e12c5d1SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0,
543e12c5d1SDavid du Colombier
553e12c5d1SDavid du Colombier };
563e12c5d1SDavid du Colombier #define ngetc(f) (nread++, getc(f))
573e12c5d1SDavid du Colombier #define nungetc(c, f) (--nread, ungetc((c), f))
583e12c5d1SDavid du Colombier #define wgetc(c, f, out) if(width--==0) goto out; (c)=ngetc(f)
593e12c5d1SDavid du Colombier #define wungetc(c, f) (++width, nungetc(c, f))
603e12c5d1SDavid du Colombier static int nread, ncvt;
613e12c5d1SDavid du Colombier static const char *fmtp;
623e12c5d1SDavid du Colombier
vfscanf(FILE * f,const char * s,va_list args)633e12c5d1SDavid du Colombier int vfscanf(FILE *f, const char *s, va_list args){
643e12c5d1SDavid du Colombier int c, width, type, store;
653e12c5d1SDavid du Colombier nread=0;
663e12c5d1SDavid du Colombier ncvt=0;
673e12c5d1SDavid du Colombier fmtp=s;
683e12c5d1SDavid du Colombier for(;*fmtp;fmtp++) switch(*fmtp){
693e12c5d1SDavid du Colombier default:
703e12c5d1SDavid du Colombier if(isspace(*fmtp)){
713e12c5d1SDavid du Colombier do
723e12c5d1SDavid du Colombier c=ngetc(f);
733e12c5d1SDavid du Colombier while(isspace(c));
743e12c5d1SDavid du Colombier if(c==EOF) return ncvt?ncvt:EOF;
753e12c5d1SDavid du Colombier nungetc(c, f);
763e12c5d1SDavid du Colombier break;
773e12c5d1SDavid du Colombier }
783e12c5d1SDavid du Colombier NonSpecial:
793e12c5d1SDavid du Colombier c=ngetc(f);
803e12c5d1SDavid du Colombier if(c==EOF) return ncvt?ncvt:EOF;
813e12c5d1SDavid du Colombier if(c!=*fmtp){
823e12c5d1SDavid du Colombier nungetc(c, f);
833e12c5d1SDavid du Colombier return ncvt;
843e12c5d1SDavid du Colombier }
853e12c5d1SDavid du Colombier break;
863e12c5d1SDavid du Colombier case '%':
873e12c5d1SDavid du Colombier fmtp++;
883e12c5d1SDavid du Colombier if(*fmtp!='*') store=1;
893e12c5d1SDavid du Colombier else{
903e12c5d1SDavid du Colombier store=0;
913e12c5d1SDavid du Colombier fmtp++;
923e12c5d1SDavid du Colombier }
933e12c5d1SDavid du Colombier if('0'<=*fmtp && *fmtp<='9'){
943e12c5d1SDavid du Colombier width=0;
953e12c5d1SDavid du Colombier while('0'<=*fmtp && *fmtp<='9') width=width*10 + *fmtp++ - '0';
963e12c5d1SDavid du Colombier }
973e12c5d1SDavid du Colombier else
983e12c5d1SDavid du Colombier width=-1;
993e12c5d1SDavid du Colombier type=*fmtp=='h' || *fmtp=='l' || *fmtp=='L'?*fmtp++:'n';
1003e12c5d1SDavid du Colombier if(!icvt[*fmtp]) goto NonSpecial;
1013e12c5d1SDavid du Colombier if(!(*icvt[*fmtp])(f, &args, store, width, type))
1023e12c5d1SDavid du Colombier return ncvt?ncvt:EOF;
1033e12c5d1SDavid du Colombier if(*fmtp=='\0') break;
1043e12c5d1SDavid du Colombier if(store) ncvt++;
1053e12c5d1SDavid du Colombier }
1063e12c5d1SDavid du Colombier return ncvt;
1073e12c5d1SDavid du Colombier }
icvt_n(FILE * f,va_list * args,int store,int width,int type)1083e12c5d1SDavid du Colombier static int icvt_n(FILE *f, va_list *args, int store, int width, int type){
1093e12c5d1SDavid du Colombier #pragma ref f
1103e12c5d1SDavid du Colombier #pragma ref width
1113e12c5d1SDavid du Colombier if(store){
1123e12c5d1SDavid du Colombier --ncvt; /* this assignment doesn't count! */
1133e12c5d1SDavid du Colombier switch(type){
1143e12c5d1SDavid du Colombier case 'h': *va_arg(*args, short *)=nread; break;
1153e12c5d1SDavid du Colombier case 'n': *va_arg(*args, int *)=nread; break;
1163e12c5d1SDavid du Colombier case 'l':
1173e12c5d1SDavid du Colombier case 'L': *va_arg(*args, long *)=nread; break;
1183e12c5d1SDavid du Colombier }
1193e12c5d1SDavid du Colombier }
1203e12c5d1SDavid du Colombier return 1;
1213e12c5d1SDavid du Colombier }
1223e12c5d1SDavid du Colombier #define SIGNED 1
1233e12c5d1SDavid du Colombier #define UNSIGNED 2
1243e12c5d1SDavid du Colombier #define POINTER 3
1253e12c5d1SDavid du Colombier /*
1263e12c5d1SDavid du Colombier * Generic fixed-point conversion
1273e12c5d1SDavid du Colombier * f is the input FILE *;
1283e12c5d1SDavid du Colombier * args is the va_list * into which to store the number;
1293e12c5d1SDavid du Colombier * store is a flag to enable storing;
1303e12c5d1SDavid du Colombier * width is the maximum field width;
1313e12c5d1SDavid du Colombier * type is 'h' 'l' or 'L', the scanf type modifier;
1323e12c5d1SDavid du Colombier * unsgned is SIGNED, UNSIGNED or POINTER, giving part of the type to store in;
1333e12c5d1SDavid du Colombier * base is the number base -- if 0, C number syntax is used.
1343e12c5d1SDavid du Colombier */
icvt_fixed(FILE * f,va_list * args,int store,int width,int type,int unsgned,int base)1353e12c5d1SDavid du Colombier static int icvt_fixed(FILE *f, va_list *args,
1363e12c5d1SDavid du Colombier int store, int width, int type, int unsgned, int base){
1373e12c5d1SDavid du Colombier unsigned long int num=0;
1383e12c5d1SDavid du Colombier int sign=1, ndig=0, dig;
1393e12c5d1SDavid du Colombier int c;
1403e12c5d1SDavid du Colombier do
1413e12c5d1SDavid du Colombier c=ngetc(f);
1423e12c5d1SDavid du Colombier while(isspace(c));
1433e12c5d1SDavid du Colombier if(width--==0){
1443e12c5d1SDavid du Colombier nungetc(c, f);
1453e12c5d1SDavid du Colombier goto Done;
1463e12c5d1SDavid du Colombier }
1473e12c5d1SDavid du Colombier if(c=='+'){
1483e12c5d1SDavid du Colombier wgetc(c, f, Done);
1493e12c5d1SDavid du Colombier }
1503e12c5d1SDavid du Colombier else if(c=='-'){
1513e12c5d1SDavid du Colombier sign=-1;
1523e12c5d1SDavid du Colombier wgetc(c, f, Done);
1533e12c5d1SDavid du Colombier }
1543e12c5d1SDavid du Colombier switch(base){
1553e12c5d1SDavid du Colombier case 0:
1563e12c5d1SDavid du Colombier if(c=='0'){
1573e12c5d1SDavid du Colombier wgetc(c, f, Done);
1583e12c5d1SDavid du Colombier if(c=='x' || c=='X'){
1593e12c5d1SDavid du Colombier wgetc(c, f, Done);
1603e12c5d1SDavid du Colombier base=16;
1613e12c5d1SDavid du Colombier }
1623e12c5d1SDavid du Colombier else{
1633e12c5d1SDavid du Colombier ndig=1;
1643e12c5d1SDavid du Colombier base=8;
1653e12c5d1SDavid du Colombier }
1663e12c5d1SDavid du Colombier }
1673e12c5d1SDavid du Colombier else
1683e12c5d1SDavid du Colombier base=10;
1693e12c5d1SDavid du Colombier break;
1703e12c5d1SDavid du Colombier case 16:
1713e12c5d1SDavid du Colombier if(c=='0'){
1723e12c5d1SDavid du Colombier wgetc(c, f, Done);
1733e12c5d1SDavid du Colombier if(c=='x' || c=='X'){
1743e12c5d1SDavid du Colombier wgetc(c, f, Done);
1753e12c5d1SDavid du Colombier }
1763e12c5d1SDavid du Colombier else ndig=1;
1773e12c5d1SDavid du Colombier }
1783e12c5d1SDavid du Colombier break;
1793e12c5d1SDavid du Colombier }
1803e12c5d1SDavid du Colombier while('0'<=c && c<='9' || 'a'<=c && c<='f' || 'A'<=c && c<='F'){
1813e12c5d1SDavid du Colombier dig='0'<=c && c<='9'?c-'0':'a'<=c && c<='f'?c-'a'+10:c-'A'+10;
1823e12c5d1SDavid du Colombier if(dig>=base) break;
1833e12c5d1SDavid du Colombier ndig++;
1843e12c5d1SDavid du Colombier num=num*base+dig;
1853e12c5d1SDavid du Colombier wgetc(c, f, Done);
1863e12c5d1SDavid du Colombier }
1873e12c5d1SDavid du Colombier nungetc(c, f);
1883e12c5d1SDavid du Colombier Done:
1893e12c5d1SDavid du Colombier if(ndig==0) return 0;
1903e12c5d1SDavid du Colombier if(store){
1913e12c5d1SDavid du Colombier switch(unsgned){
1923e12c5d1SDavid du Colombier case SIGNED:
1933e12c5d1SDavid du Colombier switch(type){
1943e12c5d1SDavid du Colombier case 'h': *va_arg(*args, short *)=num*sign; break;
1953e12c5d1SDavid du Colombier case 'n': *va_arg(*args, int *)=num*sign; break;
1963e12c5d1SDavid du Colombier case 'l':
1973e12c5d1SDavid du Colombier case 'L': *va_arg(*args, long *)=num*sign; break;
1983e12c5d1SDavid du Colombier }
1993e12c5d1SDavid du Colombier break;
2003e12c5d1SDavid du Colombier case UNSIGNED:
2013e12c5d1SDavid du Colombier switch(type){
2023e12c5d1SDavid du Colombier case 'h': *va_arg(*args, unsigned short *)=num*sign; break;
2033e12c5d1SDavid du Colombier case 'n': *va_arg(*args, unsigned int *)=num*sign; break;
2043e12c5d1SDavid du Colombier case 'l':
2053e12c5d1SDavid du Colombier case 'L': *va_arg(*args, unsigned long *)=num*sign; break;
2063e12c5d1SDavid du Colombier }
2073e12c5d1SDavid du Colombier break;
2083e12c5d1SDavid du Colombier case POINTER:
2093e12c5d1SDavid du Colombier *va_arg(*args, void **)=(void *)(num*sign); break;
2103e12c5d1SDavid du Colombier }
2113e12c5d1SDavid du Colombier }
2123e12c5d1SDavid du Colombier return 1;
2133e12c5d1SDavid du Colombier }
icvt_d(FILE * f,va_list * args,int store,int width,int type)2143e12c5d1SDavid du Colombier static int icvt_d(FILE *f, va_list *args, int store, int width, int type){
2153e12c5d1SDavid du Colombier return icvt_fixed(f, args, store, width, type, SIGNED, 10);
2163e12c5d1SDavid du Colombier }
icvt_x(FILE * f,va_list * args,int store,int width,int type)2173e12c5d1SDavid du Colombier static int icvt_x(FILE *f, va_list *args, int store, int width, int type){
2183e12c5d1SDavid du Colombier return icvt_fixed(f, args, store, width, type, UNSIGNED, 16);
2193e12c5d1SDavid du Colombier }
icvt_o(FILE * f,va_list * args,int store,int width,int type)2203e12c5d1SDavid du Colombier static int icvt_o(FILE *f, va_list *args, int store, int width, int type){
2213e12c5d1SDavid du Colombier return icvt_fixed(f, args, store, width, type, UNSIGNED, 8);
2223e12c5d1SDavid du Colombier }
icvt_i(FILE * f,va_list * args,int store,int width,int type)2233e12c5d1SDavid du Colombier static int icvt_i(FILE *f, va_list *args, int store, int width, int type){
2243e12c5d1SDavid du Colombier return icvt_fixed(f, args, store, width, type, SIGNED, 0);
2253e12c5d1SDavid du Colombier }
icvt_u(FILE * f,va_list * args,int store,int width,int type)2263e12c5d1SDavid du Colombier static int icvt_u(FILE *f, va_list *args, int store, int width, int type){
2273e12c5d1SDavid du Colombier return icvt_fixed(f, args, store, width, type, UNSIGNED, 10);
2283e12c5d1SDavid du Colombier }
icvt_p(FILE * f,va_list * args,int store,int width,int type)2293e12c5d1SDavid du Colombier static int icvt_p(FILE *f, va_list *args, int store, int width, int type){
2303e12c5d1SDavid du Colombier return icvt_fixed(f, args, store, width, type, POINTER, 16);
2313e12c5d1SDavid du Colombier }
2323e12c5d1SDavid du Colombier #define NBUF 509
icvt_f(FILE * f,va_list * args,int store,int width,int type)2333e12c5d1SDavid du Colombier static int icvt_f(FILE *f, va_list *args, int store, int width, int type){
2343e12c5d1SDavid du Colombier char buf[NBUF+1];
2353e12c5d1SDavid du Colombier char *s=buf;
2363e12c5d1SDavid du Colombier int c, ndig=0, ndpt=0, nexp=1;
2373e12c5d1SDavid du Colombier if(width<0 || NBUF<width) width=NBUF; /* bug -- no limit specified in ansi */
2383e12c5d1SDavid du Colombier do
2393e12c5d1SDavid du Colombier c=ngetc(f);
2403e12c5d1SDavid du Colombier while(isspace(c));
2413e12c5d1SDavid du Colombier if(width--==0){
2423e12c5d1SDavid du Colombier nungetc(c, f);
2433e12c5d1SDavid du Colombier goto Done;
2443e12c5d1SDavid du Colombier }
2453e12c5d1SDavid du Colombier if(c=='+' || c=='-'){
2463e12c5d1SDavid du Colombier *s++=c;
2473e12c5d1SDavid du Colombier wgetc(c, f, Done);
2483e12c5d1SDavid du Colombier }
2493e12c5d1SDavid du Colombier while('0'<=c && c<='9' || ndpt==0 && c=='.'){
2503e12c5d1SDavid du Colombier if(c=='.') ndpt++;
2513e12c5d1SDavid du Colombier else ndig++;
2523e12c5d1SDavid du Colombier *s++=c;
2533e12c5d1SDavid du Colombier wgetc(c, f, Done);
2543e12c5d1SDavid du Colombier }
2553e12c5d1SDavid du Colombier if(c=='e' || c=='E'){
2563e12c5d1SDavid du Colombier *s++=c;
2573e12c5d1SDavid du Colombier nexp=0;
2583e12c5d1SDavid du Colombier wgetc(c, f, Done);
2593e12c5d1SDavid du Colombier if(c=='+' || c=='-'){
2603e12c5d1SDavid du Colombier *s++=c;
2613e12c5d1SDavid du Colombier wgetc(c, f, Done);
2623e12c5d1SDavid du Colombier }
2633e12c5d1SDavid du Colombier while('0'<=c && c<='9'){
2643e12c5d1SDavid du Colombier *s++=c;
2653e12c5d1SDavid du Colombier nexp++;
2663e12c5d1SDavid du Colombier wgetc(c, f, Done);
2673e12c5d1SDavid du Colombier }
2683e12c5d1SDavid du Colombier }
2693e12c5d1SDavid du Colombier nungetc(c, f);
2703e12c5d1SDavid du Colombier Done:
2713e12c5d1SDavid du Colombier if(ndig==0 || nexp==0) return 0;
2723e12c5d1SDavid du Colombier *s='\0';
2733e12c5d1SDavid du Colombier if(store) switch(type){
2743e12c5d1SDavid du Colombier case 'h':
2753e12c5d1SDavid du Colombier case 'n': *va_arg(*args, float *)=atof(buf); break;
2763e12c5d1SDavid du Colombier case 'L': /* bug -- should store in a long double */
2773e12c5d1SDavid du Colombier case 'l': *va_arg(*args, double *)=atof(buf); break;
2783e12c5d1SDavid du Colombier }
2793e12c5d1SDavid du Colombier return 1;
2803e12c5d1SDavid du Colombier }
icvt_s(FILE * f,va_list * args,int store,int width,int type)2813e12c5d1SDavid du Colombier static int icvt_s(FILE *f, va_list *args, int store, int width, int type){
2823e12c5d1SDavid du Colombier #pragma ref type
2833e12c5d1SDavid du Colombier int c, nn;
2843e12c5d1SDavid du Colombier register char *s;
2853e12c5d1SDavid du Colombier if(store) s=va_arg(*args, char *);
2863e12c5d1SDavid du Colombier do
2873e12c5d1SDavid du Colombier c=ngetc(f);
2883e12c5d1SDavid du Colombier while(isspace(c));
2893e12c5d1SDavid du Colombier if(width--==0){
2903e12c5d1SDavid du Colombier nungetc(c, f);
2913e12c5d1SDavid du Colombier goto Done;
2923e12c5d1SDavid du Colombier }
2933e12c5d1SDavid du Colombier nn=0;
2943e12c5d1SDavid du Colombier while(!isspace(c)){
2953e12c5d1SDavid du Colombier if(c==EOF){
296*43751f27SDavid du Colombier nread--;
2973e12c5d1SDavid du Colombier if(nn==0) return 0;
2983e12c5d1SDavid du Colombier else goto Done;
2993e12c5d1SDavid du Colombier }
3003e12c5d1SDavid du Colombier nn++;
3013e12c5d1SDavid du Colombier if(store) *s++=c;
3023e12c5d1SDavid du Colombier wgetc(c, f, Done);
3033e12c5d1SDavid du Colombier }
3043e12c5d1SDavid du Colombier nungetc(c, f);
3053e12c5d1SDavid du Colombier Done:
3063e12c5d1SDavid du Colombier if(store) *s='\0';
3073e12c5d1SDavid du Colombier return 1;
3083e12c5d1SDavid du Colombier }
icvt_c(FILE * f,va_list * args,int store,int width,int type)3093e12c5d1SDavid du Colombier static int icvt_c(FILE *f, va_list *args, int store, int width, int type){
3103e12c5d1SDavid du Colombier #pragma ref type
3113e12c5d1SDavid du Colombier int c;
3123e12c5d1SDavid du Colombier register char *s;
3133e12c5d1SDavid du Colombier if(store) s=va_arg(*args, char *);
3143e12c5d1SDavid du Colombier if(width<0) width=1;
3153e12c5d1SDavid du Colombier for(;;){
3163e12c5d1SDavid du Colombier wgetc(c, f, Done);
3173e12c5d1SDavid du Colombier if(c==EOF) return 0;
3183e12c5d1SDavid du Colombier if(store) *s++=c;
3193e12c5d1SDavid du Colombier }
3203e12c5d1SDavid du Colombier Done:
3213e12c5d1SDavid du Colombier return 1;
3223e12c5d1SDavid du Colombier }
match(int c,const char * pat)3233e12c5d1SDavid du Colombier static int match(int c, const char *pat){
3243e12c5d1SDavid du Colombier int ok=1;
3253e12c5d1SDavid du Colombier if(*pat=='^'){
3263e12c5d1SDavid du Colombier ok=!ok;
3273e12c5d1SDavid du Colombier pat++;
3283e12c5d1SDavid du Colombier }
3293e12c5d1SDavid du Colombier while(pat!=fmtp){
3303e12c5d1SDavid du Colombier if(pat+2<fmtp && pat[1]=='-'){
3313e12c5d1SDavid du Colombier if(pat[0]<=c && c<=pat[2]
3323e12c5d1SDavid du Colombier || pat[2]<=c && c<=pat[0])
3333e12c5d1SDavid du Colombier return ok;
3343e12c5d1SDavid du Colombier pat+=2;
3353e12c5d1SDavid du Colombier }
3363e12c5d1SDavid du Colombier else if(c==*pat) return ok;
3373e12c5d1SDavid du Colombier pat++;
3383e12c5d1SDavid du Colombier }
3393e12c5d1SDavid du Colombier return !ok;
3403e12c5d1SDavid du Colombier }
icvt_sq(FILE * f,va_list * args,int store,int width,int type)3413e12c5d1SDavid du Colombier static int icvt_sq(FILE *f, va_list *args, int store, int width, int type){
3423e12c5d1SDavid du Colombier #pragma ref type
3433e12c5d1SDavid du Colombier int c, nn;
3443e12c5d1SDavid du Colombier register char *s;
3453e12c5d1SDavid du Colombier register const char *pat;
3463e12c5d1SDavid du Colombier pat=++fmtp;
3473e12c5d1SDavid du Colombier if(*fmtp=='^') fmtp++;
3483e12c5d1SDavid du Colombier if(*fmtp!='\0') fmtp++;
3493e12c5d1SDavid du Colombier while(*fmtp!='\0' && *fmtp!=']') fmtp++;
3503e12c5d1SDavid du Colombier if(store) s=va_arg(*args, char *);
3513e12c5d1SDavid du Colombier nn=0;
3523e12c5d1SDavid du Colombier for(;;){
3533e12c5d1SDavid du Colombier wgetc(c, f, Done);
3543e12c5d1SDavid du Colombier if(c==EOF){
355*43751f27SDavid du Colombier nread--;
3563e12c5d1SDavid du Colombier if(nn==0) return 0;
3573e12c5d1SDavid du Colombier else goto Done;
3583e12c5d1SDavid du Colombier }
3593e12c5d1SDavid du Colombier if(!match(c, pat)) break;
3603e12c5d1SDavid du Colombier if(store) *s++=c;
3613e12c5d1SDavid du Colombier nn++;
3623e12c5d1SDavid du Colombier }
3633e12c5d1SDavid du Colombier nungetc(c, f);
3643e12c5d1SDavid du Colombier Done:
3653e12c5d1SDavid du Colombier if(store) *s='\0';
3663e12c5d1SDavid du Colombier return 1;
3673e12c5d1SDavid du Colombier }
368