static int icvt_s(FILE *f, va_list *args, int store, int width, int type){ #pragma ref type int c, nn; register char *s; if(store) s=va_arg(*args, char *); do c=ngetc(f); while(isspace(c)); if(width--==0){ nungetc(c, f); goto Done; } nn=0; while(!isspace(c)){ if(c==EOF){ if(nn==0) return 0; else goto Done; } nn++; if(store) *s++=c; wgetc(c, f, Done); } nungetc(c, f); Done: if(store) *s='\0'; return 1; }
static int icvt_f(FILE *f, va_list *args, int store, int width, int type){ char buf[NBUF+1]; char *s=buf; int c, ndig=0, ndpt=0, nexp=1; if(width<0 || NBUF<width) width=NBUF; /* bug -- no limit specified in ansi */ do c=ngetc(f); while(isspace(c)); if(width--==0){ nungetc(c, f); goto Done; } if(c=='+' || c=='-'){ *s++=c; wgetc(c, f, Done); } while('0'<=c && c<='9' || ndpt==0 && c=='.'){ if(c=='.') ndpt++; else ndig++; *s++=c; wgetc(c, f, Done); } if(c=='e' || c=='E'){ *s++=c; nexp=0; wgetc(c, f, Done); if(c=='+' || c=='-'){ *s++=c; wgetc(c, f, Done); } while('0'<=c && c<='9'){ *s++=c; nexp++; wgetc(c, f, Done); } } nungetc(c, f); Done: if(ndig==0 || nexp==0) return 0; *s='\0'; if(store) switch(type){ case 'h': case 'n': *va_arg(*args, float *)=atof(buf); break; case 'L': /* bug -- should store in a long double */ case 'l': *va_arg(*args, double *)=atof(buf); break; } return 1; }
static int icvt_sq(FILE *f, va_list *args, int store, int width, int type){ #pragma ref type int c, nn; register char *s; register const char *pat; pat=++fmtp; if(*fmtp=='^') fmtp++; if(*fmtp!='\0') fmtp++; while(*fmtp!='\0' && *fmtp!=']') fmtp++; if(store) s=va_arg(*args, char *); nn=0; for(;;){ wgetc(c, f, Done); if(c==EOF){ if(nn==0) return 0; else goto Done; } if(!match(c, pat)) break; if(store) *s++=c; nn++; } nungetc(c, f); Done: if(store) *s='\0'; return 1; }
int vfscanf(FILE *f, const char *s, va_list args){ int c, width, type, store; nread=0; ncvt=0; fmtp=s; for(;*fmtp;fmtp++) switch(*fmtp){ default: if(isspace(*fmtp)){ do c=ngetc(f); while(isspace(c)); if(c==EOF) return ncvt?ncvt:EOF; nungetc(c, f); break; } NonSpecial: c=ngetc(f); if(c==EOF) return ncvt?ncvt:EOF; if(c!=*fmtp){ nungetc(c, f); return ncvt; } break; case '%': fmtp++; if(*fmtp!='*') store=1; else{ store=0; fmtp++; } if('0'<=*fmtp && *fmtp<='9'){ width=0; while('0'<=*fmtp && *fmtp<='9') width=width*10 + *fmtp++ - '0'; } else width=-1; type=*fmtp=='h' || *fmtp=='l' || *fmtp=='L'?*fmtp++:'n'; if(!icvt[*fmtp]) goto NonSpecial; if(!(*icvt[*fmtp])(f, &args, store, width, type)) return ncvt?ncvt:EOF; if(*fmtp=='\0') break; if(store) ncvt++; } return ncvt; }
/* When called with c==-1, it just creates the prompt */ static int itype(W *w, int c, void *obj, int *notify) { IREC *i; int omid; BW *bw; struct isrch *isrch = (struct isrch *)obj; WIND_BW(bw,w); if (isrch->quote) { goto in; } if (c == 8 || c == 127) { /* Backup */ if ((i = isrch->irecs.link.prev) != &isrch->irecs) { pgoto(bw->cursor, i->disp); if (globalsrch) globalsrch->wrap_flag = i->wrap_flag; omid = opt_mid; opt_mid = 1; dofollows(); opt_mid = omid; isrch->pattern = vstrunc(isrch->pattern, sLEN(isrch->pattern) - i->what); frirec(deque_f(IREC, link, i)); } else { if(joe_beep) ttputc(7); } } else if (c == 'Q' - '@' /* || c == '`' */) { isrch->quote = 1; } else if (c == 'S' - '@' || c == '\\' - '@' || c == 'L' - '@' || c == 'R' - '@') { /* Repeat */ if (c == 'R' - '@') { isrch->dir = 1; } else { isrch->dir = 0; } if (qempty(IREC, link, &isrch->irecs)) { if (lastpat && lastpat[0]) { iappend(bw, isrch, sv(lastpat)); } } else { SRCH *srch; i = alirec(); i->disp = i->start = bw->cursor->byte; i->what = 0; if (!globalsrch) srch = mksrch(NULL,NULL,opt_icase,isrch->dir,-1,0,0,0,0); else { srch = globalsrch; globalsrch = 0; } srch->addr = bw->cursor->byte; if (!srch->wrap_p || srch->wrap_p->b!=bw->b) { prm(srch->wrap_p); srch->wrap_p = pdup(bw->cursor, "itype"); srch->wrap_p->owner = &srch->wrap_p; srch->wrap_flag = 0; } i->wrap_flag = srch->wrap_flag; setpat(srch, vsncpy(NULL, 0, isrch->pattern, sLen(isrch->pattern))); srch->backwards = isrch->dir; if (dopfnext(bw, srch, NULL)) { if(joe_beep) ttputc(7); frirec(i); } else { enqueb(IREC, link, &isrch->irecs, i); } } } else if (c >= 0 && c < 32) { /* Done when a control character is received */ nungetc(c); if (notify) { *notify = 1; } smode = 2; if (lastisrch) { lastpat = vstrunc(lastpat, 0); lastpat = vsncpy(lastpat, 0, lastisrch->pattern, sLen(lastisrch->pattern)); rmisrch(lastisrch); } lastisrch = isrch; return 0; } else if (c != -1) { char buf[16]; ptrdiff_t buf_len; /* Search */ in: if (bw->b->o.charmap->type) { buf_len = utf8_encode(buf, c); } else { buf[0] = TO_CHAR_OK(from_uni(bw->b->o.charmap, c)); buf_len = 1; } isrch->quote = 0; iappend(bw, isrch, buf, buf_len); } omid = opt_mid; opt_mid = 1; bw->cursor->xcol = piscol(bw->cursor); dofollows(); opt_mid = omid; isrch->prompt = vstrunc(isrch->prompt, isrch->ofst); if (locale_map->type && !bw->b->o.charmap->type) { /* Translate bytes to utf-8 */ char buf[16]; int x; for (x=0; x!=sLEN(isrch->pattern); ++x) { int tc = to_uni(bw->b->o.charmap, isrch->pattern[x]); utf8_encode(buf, tc); isrch->prompt = vsncpy(sv(isrch->prompt),sz(buf)); } } else if (!locale_map->type && bw->b->o.charmap->type) { /* Translate utf-8 to bytes */ const char *p = isrch->pattern; ptrdiff_t len = sLEN(isrch->pattern); while (len) { int tc = utf8_decode_fwrd(&p, &len); if (tc >= 0) { tc = from_uni(locale_map, tc); isrch->prompt = vsadd(isrch->prompt, TO_CHAR_OK(tc)); } } } else { /* FIXME: translate when charmaps do not match */ isrch->prompt = vsncpy(sv(isrch->prompt),sv(isrch->pattern)); } if (mkqwnsr(bw->parent, sv(isrch->prompt), itype, iabrt, isrch, notify)) { return 0; } else { rmisrch(isrch); return -1; } }
/* * Generic fixed-point conversion * f is the input FILE *; * args is the va_list * into which to store the number; * store is a flag to enable storing; * width is the maximum field width; * type is 'h' 'l' or 'L', the scanf type modifier; * unsgned is SIGNED, UNSIGNED or POINTER, giving part of the type to store in; * base is the number base -- if 0, C number syntax is used. */ static int icvt_fixed(FILE *f, va_list *args, int store, int width, int type, int unsgned, int base){ unsigned long int num=0; int sign=1, ndig=0, dig; int c; do c=ngetc(f); while(isspace(c)); if(width--==0){ nungetc(c, f); goto Done; } if(c=='+'){ wgetc(c, f, Done); } else if(c=='-'){ sign=-1; wgetc(c, f, Done); } switch(base){ case 0: if(c=='0'){ wgetc(c, f, Done); if(c=='x' || c=='X'){ wgetc(c, f, Done); base=16; } else{ ndig=1; base=8; } } else base=10; break; case 16: if(c=='0'){ wgetc(c, f, Done); if(c=='x' || c=='X'){ wgetc(c, f, Done); } else ndig=1; } break; } while('0'<=c && c<='9' || 'a'<=c && c<='f' || 'A'<=c && c<='F'){ dig='0'<=c && c<='9'?c-'0':'a'<=c && c<='f'?c-'a'+10:c-'A'+10; if(dig>=base) break; ndig++; num=num*base+dig; wgetc(c, f, Done); } nungetc(c, f); Done: if(ndig==0) return 0; if(store){ switch(unsgned){ case SIGNED: switch(type){ case 'h': *va_arg(*args, short *)=num*sign; break; case 'n': *va_arg(*args, int *)=num*sign; break; case 'l': case 'L': *va_arg(*args, long *)=num*sign; break; } break; case UNSIGNED: switch(type){ case 'h': *va_arg(*args, unsigned short *)=num*sign; break; case 'n': *va_arg(*args, unsigned int *)=num*sign; break; case 'l': case 'L': *va_arg(*args, unsigned long *)=num*sign; break; } break; case POINTER: *va_arg(*args, void **)=(void *)(num*sign); break; } } return 1; }