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

This is stdio_fprintf.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_fprintf.c
 */

#include "stdio_internal.h"


/*
 * If format string looks like "%d %f" this will
 * temporily change the format string to look like "%d".
 * Then call fprintf().  Then change the format string to
 * look like " %f".
 */
#ifdef PCN_FPRINTF_HACK
#define print_arg(c_type, pcn_type, cPtr, fp, fmt, arg, status) \
{ \
    char __ch = *(++cPtr); \
    *cPtr = '\0'; \
    status = fprintf(fp, fmt, (c_type) *((pcn_type *)(arg))); \
    status = 1; \
    *cPtr = __ch; \
    fmt = cPtr; \
}
#else  /* PCN_FPRINTF_HACK */
#define print_arg(c_type, pcn_type, cPtr, fp, fmt, arg, status) \
{ \
    char __ch = *(++cPtr); \
    *cPtr = '\0'; \
    status = fprintf(fp, fmt, (c_type) *((pcn_type *)(arg))); \
    *cPtr = __ch; \
    fmt = cPtr; \
}
#endif /* PCN_FPRINTF_HACK */


/*
 * _p_stdio_fprint_arg()
 *
 * Look for the '%' and the conversion character after it, in the 'fmt' 
 * If it is the same as the C then call fprintf().  Then change the
 * format string to the location after the conversion character
 */
void _p_stdio_fprint_arg(fp, fmt, arg, arg_type, status, depth, chars_printed)
FILE **fp;
struct s_fmt *fmt;
char_t *arg;
int_t *arg_type;
int_t *status;
int_t *depth, *chars_printed;	/* Used for term printing */
{
    int is_long = 0;
    int printed;
    char *fmt_ptr = fmt->string + fmt->findex;
    char *cPtr;
    
    *depth = 0;
    
    if ((cPtr = strchr(fmt_ptr, '%')) != NULL)
    {
	is_long = 0;
	printed = 0;
	while (!printed)
	{
	    switch (*(++cPtr))
	    {
	    case '%': 
		if ((cPtr = strchr(++cPtr, '%')) == NULL)
		    printed++;
	    case 'l': 
		is_long = 1;
		break;
	    case 'd':
	    case 'i':
	    {
		int_t dummy_i;
		if (*arg_type == ARG_TYPE_CHAR)
		    dummy_i = (int_t) *((char_t *) arg);
		else
		    dummy_i = *((int_t *) arg);
		
		if (is_long)
		    print_arg(long, int_t, cPtr, *fp, fmt_ptr,
			      &dummy_i, *status)
		else
		    print_arg(int, int_t, cPtr, *fp, fmt_ptr,
			      &dummy_i, *status);
		printed++;
		break;
	    }
	    case 'o':
	    case 'u':
	    case 'x':
	    case 'X':
	    {
		int_t dummy_i;
		if (*arg_type == ARG_TYPE_CHAR)
		    dummy_i = (int_t) *((char_t *) arg);
		else
		    dummy_i = *((int_t *) arg);
		
		if (is_long)
		    print_arg(unsigned long, u_int_t, cPtr, *fp, fmt_ptr,
			      &dummy_i, *status)
		else
		    print_arg(unsigned int, u_int_t, cPtr, *fp, fmt_ptr,
			      &dummy_i, *status);
		printed++;
		break;
	    }
	    case 'f':
	    case 'e':
	    case 'E':
	    case 'g':
	    case 'G':
		print_arg(double, double_t, cPtr, *fp, fmt_ptr, arg, *status);
		printed++;
		break;
	    case 'c':
	    {
		char_t dummy_c;
		if (*arg_type == ARG_TYPE_CHAR)
		    dummy_c = *((char_t *) arg);
		else
		    dummy_c = (char_t) *((int_t *) arg);
		print_arg(int, char_t, cPtr, *fp, fmt_ptr, &dummy_c, *status);
		printed++;
		break;
	    }
	    case 's':
		print_arg(char *, char_t *, cPtr, *fp, fmt_ptr, &arg, *status);
		printed++;
		break;
	    case 't':
	    {
		char *cPtr1 = cPtr - 1;
		
		/* Null out the % */
		while (*cPtr1 != '%') cPtr1--;
		*cPtr1 = '\0'; 
		
		*chars_printed = *status = fprintf(*fp, fmt_ptr);
#ifdef PCN_FPRINTF_HACK
		*chars_printed = *status = 1;
#endif /* PCN_FPRINTF_HACK */
		if (*status != EOF)
		    *status = is_long ? PRINT_LTERM : PRINT_TERM;
		fmt_ptr = cPtr+1;
		printed++;
		break;
	    }
	    case '0':
	    case '1':
	    case '2':
	    case '3':
	    case '4':
	    case '5':
	    case '6':
	    case '7':
	    case '8':
	    case '9':
		*depth *= 10;
		*depth += *cPtr - '0';
		break;
	    default:
		break;
	    }
	}
	fmt->findex = fmt_ptr - fmt->string;
    }
} /* _p_stdio_fprint_arg() */


void _p_stdio_dump_fmt(fp, fmt, status)
FILE **fp;
struct s_fmt *fmt;
int_t *status;
{
    *status = fprintf(*fp, fmt->string + fmt->findex);
#ifdef PCN_FPRINTF_HACK
    *status = 1;
#endif /* PCN_FPRINTF_HACK */
}

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