summaryrefslogblamecommitdiffstats
path: root/c/src/lib/libbsp/i960/rxgen960/startup/frmstr.c
blob: 682890e57b2373c71c6d7354bfb1790ced252c20 (plain) (tree)
1
2
3
4
5
6
7
8



                                         



        































































































                                                                  
                       







                            
 






                                    
 












                                        
 





                                        
 





                                
 
















                                  
 
                  
 



                                
 






























                                                    
     






























































                                                             
   




































                                           
                       




























                                                                         
 


                                    
              
                      
             





































                                                           
              





                                                            
 
        
 








                       
                  

         
 
















                                                                        
       




















































































































































                                                                          
 












































                                           
/*-------------------------------------*/
/* frmstr.c                            */
/* Last change : 14.10.94              */
/*-------------------------------------*/
/*
 *  $Id$
 */

#include "frmstr.h"
/*-------------------------------------*/
  /* How to treat the rest.
   */
#define FOR_CONSOLE	1
#define DO_LONG         1

  /* To Store a byte.
   */
#ifdef _STORE_BYTE
#  define	STORE_BYTE(a, b)	(store_byte(a, b))
   long	store_byte(void);
#else
#  define 	STORE_BYTE(a, b)	(* (a) = (b))
#endif
  /* Some decalrations.
   */
static void geta(ArgType *, int);
static const char * gnum(const char *, ArgType * );
static char * i_compute(unsigned val, int, char *);
#ifdef DO_LONG
static char * l_compute(long, int, char *);
#endif
static ArgType * nextarg;
  /* And macros.
   */
#define wsize(par) 	((sizeof par) / sizeof(ArgType))
#define signbit(par) 	(1L<<(sizeof par * 8 - 1))

int format_string(const char * fmt, ArgType * args, char * buffer)
{
  char * s;
# ifdef DO_LONG
  long l;
  int lflag;
# else
# define lflag 0
# endif
# ifdef DO_FLOAT
  double dbl;
# endif
  ArgType inte;
  ArgType_U uint;
  ArgType width, ndigit;
  int i, j, c, rjust, ndfnd, zfill;
  const char * oldfmt;
  char * s1, buf[64];

  nextarg = args;
  while (c = * fmt ++) {
    if (c != '%') {
#     ifdef FOR_CONSOLE
      if (c == '\n') STORE_BYTE(buffer ++, '\r');
#     endif
      STORE_BYTE(buffer ++, c);
      continue;
    }
#   ifdef DO_LONG
    lflag = 0 ;
#   endif
    j = 10 ;
    rjust = 0;
    if (* fmt == '-') {
      fmt ++;
      rjust ++;
    }
    zfill = ' ';
    if (* fmt == '0') {
      fmt ++;
      zfill = '0';
    }
    fmt = gnum(fmt, & width);
    ndigit = 0; ndfnd = 0;
    if (* fmt == '.') {
      fmt ++; oldfmt = fmt;
      fmt = gnum(fmt, & ndigit);
      ndfnd = (int)(fmt != oldfmt);
    }
    s = s1 = buf;
#   ifdef DO_LONG
    if (* fmt == 'l' || * fmt == 'L') {
      fmt ++; lflag ++;
    }
#   endif
    switch (c = * fmt ++) {
      default:
#       ifdef FOR_CONSOLE
        if (c == '\n') STORE_BYTE(buffer ++, '\r');
#       endif
        STORE_BYTE(buffer ++, c);
        continue;
      case 's':
        geta((ArgType *) & s1, wsize(s1));
        s = s1;
        do {
	  if (s == 0) break;
	  if (* s == 0)
	    break;
	  s ++;
        } while (-- ndigit);
        break;
      case 'b':
        j = 2;
      case 'u':
        getu:

        if (! lflag) {
	  geta(& inte, wsize(inte));
	  goto i_unsignd;
        }
#     ifdef DO_LONG
      case 'U':
        getlu:

        geta((ArgType *) & l, wsize(l));
        goto l_unsignd;
      case 'B':
        j = 2 ;
        goto getlu;
      case 'X':
        j = 16;
        goto getlu;
      case 'O':
        j = 8;
        goto getlu ;
      case 'D':
        l_signed:

        geta((ArgType *) & l, wsize(l));
        if (l < 0) {
          STORE_BYTE(s ++, '-');
          l = -l;
        }
        goto do_l;

        l_unsignd:

        if (l && ndigit)
	  STORE_BYTE(s ++, '0');

        do_l:

        s = l_compute(l, j, s);
        break;
#     endif
      case 'x':
        j = 16;
        goto getu;
      case 'o':
        j = 8;
        goto getu;
      case 'd':
        if (lflag) goto l_signed;
        geta(& inte, wsize(inte));
        if (inte < 0) {
	  STORE_BYTE(s ++, '-');
	  inte = - inte;
        }
        goto do_i;

        i_unsignd:

        if (inte && ndigit)
	  STORE_BYTE(s ++, '0');

        do_i:

	s = i_compute(inte, j, s);
        break;
      case 'c':
	geta ((ArgType *) & uint, wsize(uint));
	for (i = sizeof uint - 1; i >= 0; i --) {
	  if (STORE_BYTE(s, uint % 256)) s ++;
	  uint /= 256 ;
	}
	break;
#     ifdef DO_FLOAT
      case 'e':
        geta((ArgType *) & dbl, wsize(dbl));
        s = _pscien(dbl, s, ndigit, ndfnd);
        break;
      case 'f':
        geta((ArgType *) &dbl,wsize(dbl));
        s = _pfloat(dbl, s, ndigit, ndfnd);
        break;
#     endif
      case 'r':
        geta((ArgType *) & nextarg, wsize(nextarg));
        geta((ArgType *) & oldfmt, wsize(fmt));
        fmt = oldfmt;
        continue;
    }
    j = s - s1;
    if ((c = width - j) > 0)  {
      if (rjust == 0)  {
	do STORE_BYTE(buffer ++, zfill);
	while (-- c);
      }
    }
    while (-- j >= 0)
      STORE_BYTE(buffer ++, * s1 ++);
    while (-- c >= 0)
      STORE_BYTE(buffer ++, zfill);
  }
  STORE_BYTE(buffer, 0);
  return 0;
}
static void geta(ArgType * p, int size)
{
  if ((ArgType *) & p - (ArgType *) & size > 0)  {
    p += size;
    while (size --)  {
	* -- p = * nextarg --;
    }
  }
  else  {
    while (size --)  {
      * p ++ = * nextarg ++ ;
    }
  }
}
static const char * gnum(const char * f, ArgType * ip)
{
  ArgType i;
  int c;

  if (* f == '*')  {
    geta(ip, wsize(i)) ;
    f ++;
  }
  else  {
    i = 0;
    while ((c = * f - '0') >= 0 && c <= 9) {
      i = i * 10 + c;
      f ++;
    }
    * ip = i;
  }
  return f;
}
static char * i_compute(unsigned int val, int base, char * s)
{
  int c;

  c = val % base;
  val /= base;
  if (val)
    s = i_compute(val, base, s);
  STORE_BYTE(s ++, c>9 ? c-10+'a' : c+'0');
  return s;
}
#ifdef DO_LONG
static char *l_compute(long l1,int d, char * s)
{
  int c;
  long l2;

  if (l1 < 0)  {
    c = l1 & 1;
    l2 = ((l1>>1) & ~signbit(l1));
    l1 = l2 / (d>>1);
    c += (l2%(d>>1))<<1;
  }
  else  {
    c = l1 % d;
    l1 = l1 / d;
  }
  if (l1)
    s = l_compute(l1, d, s);
  STORE_BYTE(s ++, c>9 ? c-10+'A' : c+'0');
  return s;
}
#endif
#ifdef _STORE_BYTE
long store_byte(char * cp, long c)
{
  long shift, reg, * ptr;

  shift = ((long) cp & 3) * 8;
  ptr = (long *) ((long) cp & ~3);
  reg = * ptr;
  reg &= ~(0xff << shift);
  reg |= c << shift;
  * ptr = reg;

  return c;
}
#endif

#define	SPC	01
#define	STP	02

#define NULL 	0
#define EOF	0
#define	SHORT	0
#define	REGULAR	1
#define	LONG	2
#define	INT	0
#define	FLOAT	1

static int new_c(void);
static void unnew_c(char);
static int _innum(int ** ptr, int type, int len, int size, int * eofptr);
static int _instr(char * ptr, int type, int len, int * eofptr);
static const char * _getccl(const char *);
static int vme_isupper(char);
static int vme_tolower(char);
static int vme_isdigit(char);

static char _sctab[128] = {
	0,0,0,0,0,0,0,0,
	0,SPC,SPC,0,0,0,0,0,
	0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,
	SPC,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,
};
static const char * line;
static char * linep;

int unformat_string(const char * fmt, int ** argp, const char * buffer)
{
  int ch;
  int nmatch, len, ch1;
  int ** ptr, fileended, size;

  line = buffer;
  linep = (char*)line;

  nmatch = 0;
  fileended = 0;
  for (;;) switch (ch = * fmt ++)  {
    case '\0':
      return (nmatch);
    case '%':
      if ((ch = * fmt ++) == '%')
        goto def;
      ptr = 0;
      if (ch != '*')
	ptr = argp ++;
      else
	ch = * fmt ++;
      len = 0;
      size = REGULAR;
      while (vme_isdigit(ch))  {
	len = len*10 + ch - '0';
	ch = * fmt ++;
      }
      if (len == 0)
	len = 30000;
      if (ch == 'l')  {
	ch = * fmt ++;
	size = LONG;
      }
      else if (ch == 'h')  {
	size = SHORT;
	ch = * fmt ++;
      }
      else if (ch=='[')
	fmt = _getccl(fmt);
	if (vme_isupper(ch)) {
	  ch = vme_tolower(ch);
	  size = LONG;
	}
	if (ch == '\0')
	  return -1;
	if (_innum(ptr, ch, len, size, & fileended) && ptr)
	  nmatch ++;
	if (fileended)
	  return nmatch? nmatch: -1;
	break;
    case ' ':
    case '\n':
    case '\t':
      while ((ch1 = new_c())==' ' || ch1=='\t' || ch1=='\n')
	;
      if (ch1 != EOF)
	unnew_c(ch1);
      break;
    default:

    def:

      ch1 = new_c();
      if (ch1 != ch)  {
	if (ch1==EOF)
	  return -1 ;
	unnew_c(ch1);
	return nmatch;
      }
   }
}
static int new_c()
{
  char c;

  if (linep)  {
    c = * linep ++;
    return c;
  }
  else  {
    return 0;
  }
}
static void unnew_c(char ch)
{
  if (linep > line)
    * (-- linep) = ch;
}
static int _innum(int ** ptr, int type, int len, int size, int * eofptr)
{
# ifdef DO_FLOAT
  extern double atof();
# endif
  char * np;
  char numbuf[64];
  int c, base;
  int expseen, scale, negflg, c1, ndigit;
  long lcval;

  if (type=='c' || type=='s' || type=='[')
    return _instr(ptr? * (char **) ptr: (char *) NULL, type, len, eofptr);
  lcval = 0;
  ndigit = 0;
  scale = INT;
  if (type=='e'||type=='f')
    scale = FLOAT;
  base = 10;
  if (type=='o')
    base = 8;
  else if (type=='x')
    base = 16;
  np = numbuf;
  expseen = 0;
  negflg = 0;
  while ((c = new_c())==' ' || c=='\t' || c=='\n');
  if (c=='-') {
    negflg ++;
    * np ++ = c;
    c = new_c();
    len --;
  }
  else if (c=='+') {
    len --;
    c = new_c();
  }
  for ( ; -- len >= 0; * np ++ = c, c = new_c()) {
    if (vme_isdigit(c)
	|| base==16 && ('a'<=c && c<='f' || 'A'<=c && c<='F')) {
      ndigit ++;
      if (base==8)
	lcval <<=3;
      else if (base==10)
	lcval = ((lcval<<2) + lcval)<<1;
      else
	lcval <<= 4;
      c1 = c;
      if ('0'<=c && c<='9')
        c -= '0';
      else if ('a'<=c && c<='f')
	c -= 'a'-10;
      else
	c -= 'A'-10;
      lcval += c;
      c = c1;
      continue;
    }
    else if (c=='.')  {
      if (base!=10 || scale==INT)
	break;
      ndigit ++;
      continue;
    }
    else if ((c=='e'||c=='E') && expseen==0)  {
      if (base!=10 || scale==INT || ndigit==0)
	break;
      expseen ++;
      * np ++ = c;
      c = new_c();
      if (c!='+'&&c!='-'&&('0'>c||c>'9'))
	break;
    }
    else
      break;
  }
  if (negflg)
    lcval = -lcval;
  if (c != EOF) {
    unnew_c(c);
    * eofptr = 0;
  }
  else
    * eofptr = 1;
  if (ptr==NULL || np==numbuf)
    return 0;
  * np ++ = 0;
  switch ((scale<<4) | size)  {
#   ifdef DO_FLOAT

    case (FLOAT<<4) | SHORT:
    case (FLOAT<<4) | REGULAR:
      ** (float **) ptr = atof(numbuf);
      break;

    case (FLOAT<<4) | LONG:
      ** (double **) ptr = atof(numbuf);
      break;
#   endif
    case (INT<<4) | SHORT:
      ** (short **) ptr = lcval;
      break;

    case (INT<<4) | REGULAR:
      ** (int **) ptr = lcval;
      break;

    case (INT<<4) | LONG:
      ** (long **) ptr = lcval;
      break;
  }
  return 1;
}
static int _instr(char * ptr, int type, int len, int * eofptr)
{
  int ch;
  char * optr;
  int ignstp;

  * eofptr = 0;
  optr = ptr;
  if (type=='c' && len==30000)
    len = 1;
  ignstp = 0;
  if (type=='s')
    ignstp = SPC;
  while (_sctab[ch = new_c()] & ignstp)
    if (ch==EOF)
      break;
  ignstp = SPC;
  if (type=='c')
    ignstp = 0;
  else if (type=='[')
    ignstp = STP;
  while (ch!=EOF && (_sctab[ch]&ignstp)==0)  {
    if (ptr)
      * ptr ++ = ch;
    if (-- len <= 0)
      break;
    ch = new_c();
  }
  if (ch != EOF)  {
    if (len > 0)
      unnew_c(ch);
    * eofptr = 0;
  }
  else
    * eofptr = 1;
  if (ptr && ptr!=optr) {
    if (type!='c')
      * ptr ++ = '\0';
    return 1;
  }
  return 0;
}
static const char * _getccl(const char * s)
{
  int c, t;

  t = 0;
  if (* s == '^') {
    t ++;
    s ++;
  }
  for (c = 0; c < 128; c++)
    if (t)
      _sctab[c] &= ~STP;
    else
      _sctab[c] |= STP;
    while (((c = * s ++)&0177) != ']') {
    if (t)
      _sctab[c++] |= STP;
    else
      _sctab[c++] &= ~STP;
    if (c==0)
      return -- s;
  }
  return s;
}
static int vme_isupper(char ch)
{
  if( ch >= 'A' & ch <= 'Z')
    return 1;
  else
    return 0;
}
static int vme_tolower(char ch)
{
  return 'a' + 'A' - ch;
}
static vme_isdigit(char ch)
{
  if (ch >= '0' & ch <= '9')
    return 1;
  else
    return 0;
}
/*-------------*/
/* End of file */
/*-------------*/