static char *SccsId = "@(#)dmdoget.c 3.12 (TU-Delft) 04/28/93";
/**********************************************************

Name/Version      : The Design Data Management Project

Language          : C
Operating system  : UNIX SYSTEM V
Host machine      : HP9000/S500

Author(s)         : S. de Graaf
                    A. van der Hoeven
                    T.G.R. van Leuken
                    N. van der Meijs
		    T. Vogel
		    P. van der Wolf
Creation date     : 04-Dec-1986
Modified by       : S. de Graaf
Modification date : 26-May-1987
Modification date : 26-Apr-1988


        Delft University of Technology
        Department of Electrical Engineering
        Network Theory Section
        Mekelweg 4 - P.O.Box 5031
        2600 GA DELFT
        The Netherlands

        Phone : 015 - 786234

        COPYRIGHT (C) 1985-1988, All rights reserved
**********************************************************/
#include <dmstd.h>
#  ifdef __STDC__
# include <stdarg.h>
#  else				/* not __STDC__ */
# include <varargs.h>
#  endif			/* else not __STDC__ */
#ifdef hpux
#include <values.h>
#else
/* int with highest bit turned on, assume 8 bits per byte */
#define HIBITI	(1 << (8*sizeof(int) - 1))
#endif

# define EOS    '\0'
# define BASE   10

/*
** Own version of isdigit and isspace, for 30% speed up of _dmDoget.
** '\t', '\n' and ' ' are considered space 
*/

# undef isspace
# undef isdigit

# define isspace(c) space[c]	/* watch out for c==EOF */
# define isdigit(c) ((c) >= '0' && (c) <= '9')

static char space[256] =
{
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 1, 1, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 1
};

#define UNGETC(c,iop) ungetc(c,iop)
/* [ps]
#if defined (__STDC__) && !defined(MSDOS)
# define UNGETC(iop) ((iop)->__ptr=(--_ptr), (iop)->__cnt=(++_cnt))

# undef getc
# define getc(p)     (--_cnt < 0 \
    ? (p)->__ptr=_ptr, (p)->__cnt=_cnt, \
      ch = __filbuf(p), \
      _cnt = (p)->__cnt, _ptr = (p)->__ptr, ch \
    : (int) *_ptr++)

#  else
# define UNGETC(iop) ((iop)->_ptr=(--_ptr), (iop)->_cnt=(++_cnt))

# undef getc
# define getc(p)     (--_cnt < 0 \
    ? (p)->_ptr=_ptr, (p)->_cnt=_cnt, \
      ch = _filbuf(p), \
      _cnt = (p)->_cnt, _ptr = (p)->_ptr, ch \
    : (int) *_ptr++)
#  endif
*/

#  ifdef __STDC__
int     _dmDoget (FILE * iop, char *fmt,...)
# else				/* not __STDC__ */
int     _dmDoget (iop, fmt, va_alist)
        FILE * iop;
register char  *fmt;
va_dcl
#  endif			/* else not __STDC__ */
{
    va_list ap;

    register int    ch;
#if defined (hpux) || defined (sun) || defined (cadmus) || defined (apollo) || defined (__STDC__)
    register unsigned char *_ptr;
#else				/*   */
    register char  *_ptr;
#endif 
/*     register int    _cnt;   [ps] */
    register long   val;
    register char  *ptr;
    int     nmatch = 0;
    int     negflg;

/* [ps]
#if defined (__STDC__) && !defined(MSDOS)
#  else
    _cnt = iop -> _cnt;
    _ptr = iop -> _ptr;
#  endif
*/

#  ifdef __STDC__
    va_start (ap, fmt);
#  else				/* not __STDC__ */
    va_start (ap);
#  endif			/* else not __STDC__ */
    ch = getc (iop);

    fmt--;
loop: 
    switch (*++fmt) {
	case 'F': 		/* double that was written as scaled int 
				*/
	case 'D': 
	case 'W': 
	    negflg = 0;
	    while (ch != EOF && isspace (ch))
		ch = getc (iop);

	    if (ch == '-') {
		negflg++;
		ch = getc (iop);
	    }
	    else
		if (ch == '+')
		    ch = getc (iop);

	    if (isdigit (ch)) {
		val = ch - '0';
		for (ch = getc (iop); isdigit (ch); ch = getc (iop))
		    val = BASE * val +ch - '0';

		if (negflg && val !=HIBITI)
		    val = -val;	/* should suppress possible overflow on
				   2's-comp negation */

		if (*fmt == 'F') {
		    *va_arg (ap, double *) = (double) val /1000.0;
		}
		else {
		    *va_arg (ap, long *) = val;
		}
		nmatch++;
		goto loop;
	    }
	    break;		/* no match */

	case 'A': 		/* string with white space */

	    while (ch != EOF && isspace (ch))
		ch = getc (iop);

	    if (!isdigit (ch))
		break;		/* error */

	    val = ch - '0';
	    for (ch = getc (iop); isdigit (ch); ch = getc (iop))
		val = BASE * val +ch - '0';

	    ptr = va_arg (ap, char *);

	/* skip current ch, it should be a space */

#ifdef BACKWARD_COMPAT
	/* This is for backward compatibility: previously * empty strings
	   where coded with length 1 and a ~. * This is only necessary for
	   unpacked databases that * where written with older versions
	   that did not support * or use (dmPutDesignData) the 'A' fmt
	   specifier. */
	    if (val == 1) {
		if ((ch = getc (iop)) != '~') {
		    if (ch == EOF) {/* premature */
			*ptr = EOS;
			break;
		    }
		    *ptr++ = (char) (ch & 0xff);
		}

		*ptr = EOS;
		ch = getc (iop);/* read ahead next character */
		nmatch++;
		goto loop;
	    }
#endif				/* BACKWARD_COMPAT */

	/* read 'val' characters */
	    while (val --> 0) {
		if ((ch = getc (iop)) == EOF) {
				/* premature end-of-file */
		    *ptr = EOS;
		    break;
		}
		*ptr++ = (char) (ch & 0xff);
	    }
	    ch = getc (iop);	/* read ahead next character */

	    *ptr = EOS;
	    nmatch++;
	    goto loop;

	case 'S': 
	    while (ch != EOF && isspace (ch))
		ch = getc (iop);

	    if (ch != EOF) {
		ptr = va_arg (ap, char *);
		do {
		    *ptr++ = (char) (ch & 0xff);
		} while ((ch = getc (iop)) != EOF && !isspace (ch));
		*ptr = EOS;

		nmatch++;
		goto loop;
	    }
	    break;		/* no match */

	case 'C': 
	    if (ch != EOF) {
		nmatch++;
		*va_arg (ap, char *) = (char) (ch & 0xff);
		ch = getc (iop);
		goto loop;
	    }
	    break;		/* end of input, no match */

	case EOS: 
	    UNGETC (*fmt,iop);
	    return (nmatch);	/* end of format */

	case ' ': 
	case '\t': 
	case '\n': 
	    while (ch != EOF && isspace (ch))
		ch = getc (iop);
	    goto loop;

	default: 
	    UNGETC (*fmt,iop);
	    return (nmatch);	/* failed to match input */
    }

    if (ch == EOF)
	return (EOF);		/* end of input */
    else {
	UNGETC (ch,iop);
	return (nmatch);	/* failed to match input */
    }
}

#ifdef DRIVER

main (argc, argv)
int     argc;
char   *argv[];
{
    int     r,
            i1,
            i2;
    double  d;
    char    c;
    char    s1[100];
    char    s2[100];
    for (;;) {
	r = _dmDoget (stdin, "CDWSAF\n", &c, &i1, &i2, s1, s2, &d);
	if (r == EOF)
	    break;
	fprintf (stdout, "%c %d %d %s \"%s\" %f result: %d\n",
		c, i1, i2, s1, s2, d, r);
    }
}
#endif				/* DRIVER */
