+scanf (p1, p2, p3, p4)
+ int p1, p2, p3, p4;
+{
+/* first arg can be a control string, a file id, or -1 */
+ int ptrs[10], j, ip, flp, k;
+ char *np;
+/* extern int cin;*/
+extern (*_Igetc)(), (*_Iungc)(), cgetc(), ungetc(), _Igstr(), _Iungs();
+extern char *_Iinpt;
+ip = 0;
+if (p1 == -1)
+ {k = 1; _Iinpt = p2;}
+else if (p1 >= 0 && p1 < 10)
+ k = 0;
+else
+ k = -1;
+if (k <= 0)
+ {_Igetc = cgetc; _Iungc = ungetc;}
+else
+ {_Igetc = _Igstr; _Iungc = _Iungs;}
+j = 0;
+for (np = (&p2)[k]; *np; np++)
+ if (*np == '%' && *(np+1) != '%' && *(np+1) != '*')
+ ptrs[ip++] = (&p3)[(j++)+k];
+return (_Iscan ((k==0 ? p1 : 0), (&p2)[k], ptrs));
+}
+
+_Iscan (fileid, format, listp)
+ char *format;
+ int *listp;
+{
+ char ch, _Inxch();
+ int nmatch;
+ extern int _Isfil;
+ _Isfil = fileid;
+nmatch = 0;
+while (1) switch (ch= *format++)
+ {
+ case '\0': return (nmatch);
+ case '%': switch (_Isfrm(&format, *listp++))
+ {
+ case 0: listp--; break;
+ case -1: return (nmatch > 0 ? nmatch : -1);
+ default: nmatch++;
+ }
+ case ' ':
+ case '\n':
+ case '\t': break;
+ default: if (ch != _Inxch())
+ return(nmatch);
+ }
+}
+
+int _Isfil 0;
+
+_Ichar (cptr)
+ char *cptr;
+{
+ char ch, _Inxch();
+
+if ((ch = _Inxch()) < 0)
+ return (-1);
+if (cptr == 0)
+ return (0);
+*cptr = ch;
+return (1);
+}
+
+_Iflot (fptr, length)
+ float *fptr;
+ int length;
+{
+ char temp[75];
+ int _Inodg();
+ float x;
+ double atof();
+
+if (_Isstr(temp, length, _Inodg) < 0)
+ return (-1);
+x = atof(temp);
+if (fptr == 0)
+ return (0);
+*fptr = x;
+return (1);
+}
+
+_Inodg (ch)
+char ch;
+{
+if (_Idigt(ch,10) >= 0) return (0);
+switch (ch)
+ {
+ case 'E':
+ case 'e':
+ case '.': case '+': case '-':
+ return (0);
+ }
+return (1);
+}
+
+_Isfrm (spec, pointer)
+ char **spec;
+ int pointer;
+{
+ int length, lflag, _Iestr(), _Ispnd();
+ char ch;
+length = lflag = 0;
+while (1) switch (ch = *((*spec)++))
+ {
+ case '*': pointer=0; break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ length = length*10 + ch - '0' ;
+ lflag++;
+ break;
+ case 'o': /* octal */
+ return(_Iint(pointer, lflag ? length : 100, 8));
+ case 'x': /* hex */
+ return(_Iint(pointer, lflag ? length : 100, 16));
+ case 'd': /* decimal */
+ return (_Iint(pointer, lflag ? length : 100, 10));
+ case 'c': /* character */
+ return (_Ichar(pointer));
+ case 's': /* string */
+ return (_Isstr(pointer, lflag ? length : 100, _Iestr));
+ case 'f':
+ case 'e': /* float */
+ return (_Iflot(pointer, lflag ? length : 100));
+ case 'l': /* (long) double or int */
+ switch(*(*spec)++)
+ {
+ case 'f': case 'F':
+ case 'e': case 'E':
+ return (_Ilong (pointer, lflag ? length : 100));
+ default: printf(2, "long not yet implemented\n");
+ return(0);
+ }
+ case '[': /* special strings */
+ _Imtab(spec);
+ return (_Isstr (pointer, lflag ? length : 100, _Ispnd));
+ case '%':
+ if (_Inxch() != '%')
+ return (-1);
+ return(0);
+ case '\0':
+ _Ierr("scanf: bad format termination\n");
+ default: _Ierr ("scanf: format character %c", ch);
+ }
+}