git @ Cat's Eye Technologies OpenZz / master src / printz.c
master

Tree @master (Download .tar.gz)

printz.c @masterraw · history · blame

/* 
    Zz Dynamic Parser Library
    Copyright (C) 1989 - I.N.F.N - S.Cabasino, P.S.Paolucci, G.M.Todesco

    The Zz Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    The Zz Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/*

	FILE: PRINTZ.C

@	int fprintz (FILE *file_ptr, const char *format_spec, ...);
	int printz  (const char *format_spec, ...);
	int sprintz (char *str, const char *format_spec, ...);
	int printz_aux(FILE *chan);
	int printz_code(char code,int (*fprint_proc),int (*sprint_proc));
	
@       fprintz(),printz(),sprintz() funzionano come fprintf(),...
        
@	fprintz_aux(chan); abilita la scrittura su un file ausiliario da parte
	di fprintz() 

@	printz_aux(chan); abilita la scrittura su un file ausiliario da parte
	di printz() 
	
@	printz_code('z',fprint_z,sprint_z); aggiunge la gestione del
	formato 'z'; le procedure fprint_z e sprint_z devono avere i
	seguenti parametri:

	fprint_z(FILE *chanout, void *argument, char* fmt)
	sprint_z(char *stringout, void *argument, char* fmt)

	fmt contiene gli eventuali modificatori di formato presenti 
	(es.: "%10.3lz")

*/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define PRINTZ
#include "printz.h"

#ifdef PRINTZ_USE_STDARG
#include <stdarg.h>
#else
#include <varargs.h>
#endif

/*----------------------------------------------------------------------------*/
static FILE *printz_aux_chan=0,*fprintz_aux_chan=0;

#define T_LONG 		1
#define T_DOUBLE 	2
#define T_POINTER 	3

#define MAX_PRINTZ_TYPE 100

static struct {
  char code,type;
  int (*fprint_routine)(FILE *chan, ...);
  int (*sprint_routine)(char buffer[], ...);
}
printz_table[MAX_PRINTZ_TYPE+1];
static int printz_table_n=0;


#ifdef PRINTZ_USE_PROTOTYPES
int do_printz(FILE *chanout,FILE *chanout_1,
              char *stringout,char *fmt,va_list *ap);
#else
int do_printz();
#endif


/*---------------------------------------------------------------------------*/


int printz_code(int code,int (*fprint_routine)(FILE *chan,...),int (*sprint_routine)(char buffer[], ...))
{
  int i;
  if(printz_table_n<MAX_PRINTZ_TYPE)
    {
      i=printz_table_n++;
      printz_table[i].code = code;
      printz_table[i].type = T_POINTER;
      printz_table[i].fprint_routine = fprint_routine;
      printz_table[i].sprint_routine = sprint_routine;
      return 1;
    }
  else
    {
      fprintf(stderr,"add printz type: too many printz type\n");
      return 0;
    }
}


/*---------------------------------------------------------------------------*/


int printz_aux(chan)
     FILE *chan;
{
  printz_aux_chan = chan;
  return 1;
}


/*---------------------------------------------------------------------------*/


int fprintz_aux(chan)
     FILE *chan;
{
  fprintz_aux_chan = chan;
  return 1;
}


/*---------------------------------------------------------------------------*/
#ifdef PRINTZ_USE_STDARG
/*---------------------------------------------------------------------------*/


int sprintz(char *out, char *fmt, ...)
{
  int ret=0;
  va_list ap;
  va_start(ap,fmt);
  if(out && fmt) ret=do_printz(0,0,out,fmt,&ap);   
  va_end(ap);
  return ret;
}


/*---------------------------------------------------------------------------*/


int fprintz(FILE *chan, char *fmt, ...)
{
  FILE *chan_1;
  int ret=0;
  va_list ap;
  va_start(ap,fmt);
  chan_1 = chan==stdout?printz_aux_chan:fprintz_aux_chan;
  if(chan && fmt) ret=do_printz(chan,chan_1,0, fmt,&ap);   
  va_end(ap);
  fflush(chan);
  if(chan_1) fflush(chan_1);
  return ret;
}


/*---------------------------------------------------------------------------*/


int printz(char *fmt,...)
{
  int ret=0;
  va_list ap;
  FILE *chan;
  va_start(ap,fmt);
  chan = stdout;
  if(fmt)ret=do_printz(chan,printz_aux_chan,0, fmt,&ap);   
  va_end(ap);
  return ret;
}


/*---------------------------------------------------------------------------*/
#else
/*---------------------------------------------------------------------------*/


int sprintz(va_alist)
     va_dcl
{
  char *out,*fmt;
  int ret=0;
  va_list ap;
  va_start(ap);
  out = va_arg(ap,char*);
  fmt = va_arg(ap,char*);
  if(out && fmt)ret=do_printz(0,0,out,fmt,&ap);   
  va_end(ap);
  return ret;
}

/*---------------------------------------------------------------------------*/


int fprintz(va_alist)
     va_dcl
{
  FILE *chan,*chan_1;
  char *fmt;
  int ret=0;
  va_list ap;
  va_start(ap);
  chan = va_arg(ap,FILE*);
  fmt = va_arg(ap,char*);
  chan_1 = chan==stdout?printz_aux_chan:fprintz_aux_chan;
  if(chan && fmt) ret=do_printz(chan,chan_1,0, fmt,&ap);   
  va_end(ap);
  fflush(chan);
  if(chan_1) fflush(chan_1);
  return ret;
}


/*---------------------------------------------------------------------------*/


int printz(va_alist)
     va_dcl
{
  char *fmt;
  int ret=0;
  va_list ap;
  FILE *chan;
  va_start(ap);
  fmt = va_arg(ap,char*);
  chan = stdout;
  if(fmt)ret=do_printz(chan,printz_aux_chan,0, fmt,&ap);   
  va_end(ap);
  return ret;
}


/*---------------------------------------------------------------------------*/
#endif
/*---------------------------------------------------------------------------*/



#define MAX_S_FMT 40
#define MAX_BUFFER 1024
#define OUTPUT(S)\
   if(stringout)\
     {\
      strcpy(stringout,(S));\
      stringout+=strlen(S);\
     }\
   else\
     {\
      fwrite((S),sizeof(char),strlen(S),chanout); \
      if(chanout_1)\
        fwrite((S),sizeof(char),strlen(S),chanout_1);    \
     }
	

/*---------------------------------------------------------------------------*/


int do_printz(FILE *chanout,FILE *chanout_1,char *stringout,char *fmt,va_list *ap)
{
  char sf,*s;
  char buffer[MAX_BUFFER+1],tmp[MAX_S_FMT+1];
  int i,j;
  void *argp;
  while(*fmt)
    { 
      i=0;
      while(*fmt && i<MAX_BUFFER && *fmt!='%')
	{
	  if(*fmt=='\\')
	    {
	      fmt++;
	      if(*fmt>='0' && *fmt<='9')
		{
		  j=0;do {tmp[j++]= *fmt++;} while(j<3 && *fmt>='0' && *fmt<='9');
		  tmp[j]='\0';
		  buffer[i++] = atoi(tmp);
		}
	      else
		{
		  switch(*fmt)
		    {
		    case '\0':break;
		    case 'n':buffer[i++]='\n';break;
		    case 't':buffer[i++]='\t';break;
		    default:buffer[i++]= *fmt;
		    }
		  fmt++;
		}
	    }
	  else
	    {
	      buffer[i++] = *fmt++;
	    }
	}
      buffer[i]='\0';
      OUTPUT(buffer)

	if(*fmt=='%')
	  {
	    tmp[0]= *fmt++;
	    i=1;
	    sf = 0;
	    if(i<MAX_S_FMT  && *fmt=='-') tmp[i++] = *fmt++;
	    while(i<MAX_S_FMT && *fmt>='0' && *fmt<='9') tmp[i++] = *fmt++;
	    if(i<MAX_S_FMT  && *fmt=='.') tmp[i++] = *fmt++;
	    while(i<MAX_S_FMT  && *fmt>='0' && *fmt<='9') tmp[i++] = *fmt++;
	    if(i<MAX_S_FMT  && (*fmt=='l' || *fmt=='L')) tmp[i++] = *fmt++;
	    if(i<MAX_S_FMT  && *fmt) tmp[i++] = sf = *fmt++;
	    tmp[i]='\0';
	    if(sf>='A' && sf<='Z') sf+='a'-'A';
	    switch(sf)
	      {
	      case 's':
		s = va_arg(*ap,char*);
		sprintf(buffer,tmp,s?s:"<nil>");
		OUTPUT(buffer)
		  break;
	      case 'd':
	      case 'o':
	      case 'x':
	      case 'c':
	      case 'u':
		sprintf(buffer,tmp,va_arg(*ap,long));
		OUTPUT(buffer)
		  break;
	      case 'e':
	      case 'f':
	      case 'g':
		sprintf(buffer,tmp,va_arg(*ap,double));
		OUTPUT(buffer)
		  break;
	      case '%':
		OUTPUT("%")
		  break;
	      default:
		for(i=printz_table_n-1;i>=0 && printz_table[i].code!=sf;i--);
		if(i>=0) argp = va_arg(*ap,void*);
		if(stringout)
		  {              
		    if(i<0 || !printz_table[i].sprint_routine)
		      {
			strcpy(stringout,tmp);
			stringout+=strlen(tmp);
		      }
		    else
		      {
			(*printz_table[i].sprint_routine)(stringout,argp,tmp);
			while(*stringout)stringout++;
		      }                 
		  }
		else
		  {
		    if(i<0 || !printz_table[i].fprint_routine)
		      {
			fwrite(tmp,sizeof(char),strlen(tmp),chanout);
			if(chanout_1)
			  fwrite(tmp,sizeof(char),strlen(tmp),chanout_1);
		      }
		    else
		      {
			(*printz_table[i].fprint_routine)(chanout,argp,tmp);
			if(chanout_1)
			  (*printz_table[i].fprint_routine)(chanout_1,argp,tmp);
		      }                               
		  }
	      }
	  }
    }
  return 1;
}

 
static char rcsid[] = "$Id: printz.c,v 1.2 2002/01/11 11:52:02 brooks Exp $";