Category : C Source Code
Archive   : CSRC2.ZIP
Filename : DOSCAN.C

 
Output of file : DOSCAN.C contained in archive : CSRC2.ZIP
/*
* d o s c a n . c
*/

/*)LIBRARY
*/

#ifdef DOCUMENTATION

title c_doscan Formatted Input Processor
index Formatted input processor

synopsis
.s.nf
int
c_doscan(iop, fmt, args)
FILE *iov; /* File descriptor */
char *fmt; /* Format string */
int *arg[]; /* Arg vector */
.s.f
Description

c_doscan() does parsing for scanf(), etc. See the description
of scanf() for more details.

c_doscan() returns the number of items matched.

Bugs

Character classes and float/double are not supported.

#endif

#include
#include

#define FALSE 0
#define TRUE 1
#define EOS 0
#define HUGE 32767 /* Infinite width field */

typedef char * POINTER;

int
c_doscan(fd, format, args)
FILE *fd;
register char *format;
POINTER *args;
{
register int c; /* Current character */
int nmatch; /* Nbr. formats matched */
int len; /* Field size */
register POINTER store_ptr; /* -> result storage */
int fileended; /* TRUE at eof */
extern int convert();

nmatch = 0;
fileended = FALSE;
for (;;) {
switch (c = *format++) {
case EOS: /* End of format */
return (nmatch);

case '%': /* Format starts */
if ((c = *format++) == '%') /* But, "%%" is a char */
goto any_char;
if (c == '*') { /* '*' means don't */
store_ptr = NULL; /* store a result. */
c = *format++;
}
else {
store_ptr = *args++;
}
len = 0; /* Get field lenth */
while (isdigit(c)) {
len = len*10 + (c - '0');
c = *format++;
}
if (len == 0)
len = HUGE; /* Big field */
if (c == 'l' || c == 'L') { /* Long? */
c = *format++;
if (islower(c))
c = toupper(c);
}
if (c == EOS) /* Format stopped in */
return (-2); /* mid-stream, so die */
if (convert(store_ptr, c, len, fd, &fileended) != FALSE
&& store_ptr != NULL)
nmatch++; /* Count a conversion */
if (fileended)
return ((nmatch) ? nmatch : -1);
break;

case ' ':
case '\n':
case '\t':
break; /* Ignore whitespace */

default: /* Random text must */
any_char: /* Match input stream */
if (c != (len = getc(fd))) {
return((len == EOF) ? -1 : nmatch);
}
break;
}
}
}


static int
convert(store_ptr, type, len, fd, eofptr)
POINTER store_ptr; /* Result pointer (or NULL) */
int type; /* Conversion type (character) */
int len; /* Field length */
FILE *fd; /* Input file */
int *eofptr; /* Set TRUE on eof */
/*
* Do the actual conversion.
*/
{
register char *np;
register int c;
register int base; /* -1/0/+1 for 8/10/16 */
int negative;
long value;
int ndigit;
int size; /* TRUE if long */
extern int getstring();

/*
* first decide whether it's a string or numeric type
*/
if (type=='c' || type=='s') {
return (getstring(store_ptr, type, len, fd, eofptr));
}
/*
* else, process a number
*/
value = 0;
ndigit = 0;
size = FALSE;
if (isupper(type)) {
size++;
type += ('a' - 'A');
}
base = 0;
if (type == 'o')
--base;
else if (type == 'x')
++base;
negative = FALSE;
while ((c = getc(fd)), isspace(c))
;
if (c == '-') {
negative++;
c = getc(fd);
len--;
}
else if (c == '+') {
len--;
c = getc(fd);
}
while (--len >= 0 && (isdigit(c) || (base > 0 && isxdigit(c)))) {
switch (base) {
case -1: /* Octal */
value <<= 3;
break;

case 0: /* Decimal */
value *= 10;
break;

case 1: /* Hex */
value <<= 4;
break;
}
c -= (isdigit(c)) ? '0'
: (islower(c)) ? ('a' - 10)
: ('A' - 10);
value += c;
c = getc(fd);
ndigit++;
}
if (negative)
value = (-value);
if (c != EOF) {
ungetc(c, fd);
*eofptr = FALSE;
}
else {
*eofptr = TRUE;
}
if (store_ptr != NULL && ndigit > 0) {
if (size)
*((long *) store_ptr) = value;
else
*((int *) store_ptr) = value;
return (TRUE);
}
else
return (FALSE);
}

static int
getstring(store_ptr, type, len, fd, eofptr)
register char *store_ptr; /* Result pointer (or NULL) */
int type; /* Conversion type (character) */
int len; /* Field length */
FILE *fd; /* Input file */
int *eofptr; /* Set TRUE on eof */
{
register int c;
char *store_start;

*eofptr = FALSE;
store_start = store_ptr;
if (type == 'c' && len == HUGE)
len = 1;
if (type == 'c')
c = getc(fd);
else {
/*
* Skip leading whitespace in a string
*/
while ((c = getc(fd)) != EOF && isspace(c))
;
}
while (--len >= 0 && c != EOF) {
if (store_ptr != NULL) {
*store_ptr++ = c;
}
c = getc(fd);
}
if (c != EOF) {
ungetc(c, fd);
*eofptr = FALSE;
}
else {
*eofptr = TRUE;
}
if (store_ptr != NULL && store_ptr != store_start) {
if (type != 'c')
*store_ptr = EOS;
return(TRUE);
}
return (FALSE);
}


  3 Responses to “Category : C Source Code
Archive   : CSRC2.ZIP
Filename : DOSCAN.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/