1: scanf (p1, p2, p3, p4) 2: int p1, p2, p3, p4; 3: { 4: /* first arg can be a control string, a file id, or -1 */ 5: int ptrs[10], j, ip, flp, k; 6: char *np; 7: /* extern int cin;*/ 8: extern (*_Igetc)(), (*_Iungc)(), cgetc(), ungetc(), _Igstr(), _Iungs(); 9: extern char *_Iinpt; 10: ip = 0; 11: if (p1 == -1) 12: {k = 1; _Iinpt = p2;} 13: else if (p1 >= 0 && p1 < 10) 14: k = 0; 15: else 16: k = -1; 17: if (k <= 0) 18: {_Igetc = cgetc; _Iungc = ungetc;} 19: else 20: {_Igetc = _Igstr; _Iungc = _Iungs;} 21: j = 0; 22: for (np = (&p2)[k]; *np; np++) 23: if (*np == '%' && *(np+1) != '%' && *(np+1) != '*') 24: ptrs[ip++] = (&p3)[(j++)+k]; 25: return (_Iscan ((k==0 ? p1 : 0), (&p2)[k], ptrs)); 26: } 27: 28: _Iscan (fileid, format, listp) 29: char *format; 30: int *listp; 31: { 32: char ch, _Inxch(); 33: int nmatch; 34: extern int _Isfil; 35: _Isfil = fileid; 36: nmatch = 0; 37: while (1) switch (ch= *format++) 38: { 39: case '\0': return (nmatch); 40: case '%': switch (_Isfrm(&format, *listp++)) 41: { 42: case 0: listp--; break; 43: case -1: return (nmatch > 0 ? nmatch : -1); 44: default: nmatch++; 45: } 46: case ' ': 47: case '\n': 48: case '\t': break; 49: default: if (ch != _Inxch()) 50: return(nmatch); 51: } 52: } 53: 54: int _Isfil 0; 55: 56: _Ichar (cptr) 57: char *cptr; 58: { 59: char ch, _Inxch(); 60: 61: if ((ch = _Inxch()) < 0) 62: return (-1); 63: if (cptr == 0) 64: return (0); 65: *cptr = ch; 66: return (1); 67: } 68: 69: _Iflot (fptr, length) 70: float *fptr; 71: int length; 72: { 73: char temp[75]; 74: int _Inodg(); 75: float x; 76: double atof(); 77: 78: if (_Isstr(temp, length, _Inodg) < 0) 79: return (-1); 80: x = atof(temp); 81: if (fptr == 0) 82: return (0); 83: *fptr = x; 84: return (1); 85: } 86: 87: _Inodg (ch) 88: char ch; 89: { 90: if (_Idigt(ch,10) >= 0) return (0); 91: switch (ch) 92: { 93: case 'E': 94: case 'e': 95: case '.': case '+': case '-': 96: return (0); 97: } 98: return (1); 99: } 100: 101: _Isfrm (spec, pointer) 102: char **spec; 103: int pointer; 104: { 105: int length, lflag, _Iestr(), _Ispnd(); 106: char ch; 107: length = lflag = 0; 108: while (1) switch (ch = *((*spec)++)) 109: { 110: case '*': pointer=0; break; 111: case '0': case '1': case '2': case '3': case '4': 112: case '5': case '6': case '7': case '8': case '9': 113: length = length*10 + ch - '0' ; 114: lflag++; 115: break; 116: case 'o': /* octal */ 117: return(_Iint(pointer, lflag ? length : 100, 8)); 118: case 'x': /* hex */ 119: return(_Iint(pointer, lflag ? length : 100, 16)); 120: case 'd': /* decimal */ 121: return (_Iint(pointer, lflag ? length : 100, 10)); 122: case 'c': /* character */ 123: return (_Ichar(pointer)); 124: case 's': /* string */ 125: return (_Isstr(pointer, lflag ? length : 100, _Iestr)); 126: case 'f': 127: case 'e': /* float */ 128: return (_Iflot(pointer, lflag ? length : 100)); 129: case 'l': /* (long) double or int */ 130: switch(*(*spec)++) 131: { 132: case 'f': case 'F': 133: case 'e': case 'E': 134: return (_Ilong (pointer, lflag ? length : 100)); 135: default: printf(2, "long not yet implemented\n"); 136: return(0); 137: } 138: case '[': /* special strings */ 139: _Imtab(spec); 140: return (_Isstr (pointer, lflag ? length : 100, _Ispnd)); 141: case '%': 142: if (_Inxch() != '%') 143: return (-1); 144: return(0); 145: case '\0': 146: _Ierr("scanf: bad format termination\n"); 147: default: _Ierr ("scanf: format character %c", ch); 148: } 149: }