ftp.nice.ch/pub/next/unix/developer/pcn.2.0.s.tar.gz#/src/stdio/stdio_sscanf.c

This is stdio_sscanf.c in view mode; [Download] [Up]

/*
 * PCN System
 * Author:      Steve Tuecke
 *              Argonne National Laboratory
 *
 * Please see the DISCLAIMER file in the top level directory of the
 * distribution regarding the provisions under which this software
 * is distributed.
 *
 * stdio_sscanf.c
 */

#include "stdio_internal.h"


/*
 * macro used by _p_stdio_get_sscan_arg
 *
 * Prepare format 'fmt_ptr' to read 'str'.  If 'fmt_ptr' is "%d %f" then
 * the format string seen by sscanf() will be "%d%[^\1]".  Then
 * 'fmt_ptr' will be " %f" and 'str' will be the result of the second
 * argument.  In other words the rest of the string after reading 
 * (in this case) an integer.
 * line 2:  make "%d %f", "%d" 
 * line 3: format = "%d[^\1]" 
 * line 6: make "124 2.50", " 2.50"
 *
 * This assumes we will never hit an ascii 1 (SOH) in the input string.
 */
#define FMT_TAIL "%[^\1]"
#define sscan_arg(ARG) \
{ \
    char __ch = *(++cPtr); \
    *cPtr = '\0'; \
    sprintf(scratch_fmt, "%s%s", fmt_ptr, FMT_TAIL); \
    *eof = sscanf(str, scratch_fmt, (ARG), scratch_str); \
    *cPtr = __ch; \
    strcpy (str, scratch_str); \
    fmt_ptr = cPtr; \
}

/*
 * _p_stdio_get_sscan_arg()
 *
 * Get one argument for scanf().  'str' and 'fmt' will be modified by
 * this call.
 */
void _p_stdio_get_sscan_arg(str, scratch_str, fmt, scratch_fmt, type, i, f,
			    sbuf, eof)
char_t *str, *scratch_str;
struct s_fmt *fmt;
char_t *scratch_fmt;
int_t *type, *i;
double_t *f;
char_t *sbuf;
int_t *eof;
{
    int is_long = 0;
    int printed;
    
    char *cPtr;
    char *fmt_ptr = fmt->string + fmt->findex;
    
    *eof = 0;
    if ((cPtr = strchr(fmt_ptr, '%')) != NULL)
    {
	is_long = 0;
	printed = 0;
	while (!printed)
	{
	    switch (*(++cPtr))
	    {
	    case '%':
		if ((cPtr = strchr(++cPtr, '%')) == NULL)
		{
		    *eof = EOF;
		    printed++;
		}
		break;
	    case '*':
		if ((cPtr = strchr(++cPtr, '%')) == NULL)
		{
		    *eof = EOF;
		    printed++;
		}
		break;
	    case 'l':
		is_long = 1;
		break;
	    case 'd':
	    case 'i':
	    case 'o':
	    case 'u':
	    case 'x':
	    case 'X':
		if (is_long)
		{
		    long tmp_l;
		    sscan_arg(&tmp_l);
		    *i = (int_t) tmp_l;
		}
		else
		{
		    int tmp_i;
		    sscan_arg(&tmp_i);
		    *i = (int_t) tmp_i;
		}
		printed++;
		*type = SCAN_INT;
		break;
	    case 'f':
	    case 'e':
	    case 'E':
	    case 'g':
	    case 'G':
		if (is_long)
		{
		    double tmp_d;
		    sscan_arg(&tmp_d);
		    *f = (double_t) tmp_d;
		}
		else
		{
		    float tmp_f;
		    sscan_arg(&tmp_f);
		    *f = (double_t) tmp_f;
		}
		printed++;
		*type = SCAN_FLOAT;
		break;
	    case 'c':
	    {
		char c;
		sscan_arg(&c);
		*i = (int_t) c;
		printed++;
		*type = SCAN_CHAR;
		break;
	    }
	    case 's':
		
		sscan_arg(sbuf);
		*i = strlen(sbuf) + 1;
		*type = SCAN_STRING;
		printed++;
		break;
		
	    default:
		break;
		
	    }
	}
	fmt->findex = fmt_ptr - fmt->string;
    }
    else
    {
	*eof = sscanf(str, fmt_ptr, NULL);
    }
} /* _p_stdio_get_sscan_arg() */

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.