static char *SccsId = "@(#)dmdoput.c 3.7 (TU-Delft) 03/26/91";
/**********************************************************

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       : 
Modification date : 


        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-1987 , All rights reserved
**********************************************************/
#include "dmstd.h"
#  ifdef __STDC__
# include <stdarg.h>
#  else				/* not __STDC__ */
# include <varargs.h>
#  endif			/* else not __STDC__ */

# define MAXCHAR 100
# define PUT(x) putc((int)x, fp)

static char *tab[] = {
    "00", "01", "02", "03", "04", "05", "06", "07", "08", "09",
    "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
    "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
    "30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
    "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
    "50", "51", "52", "53", "54", "55", "56", "57", "58", "59",
    "60", "61", "62", "63", "64", "65", "66", "67", "68", "69",
    "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
    "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
    "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"
};

/*
** This is an efficient routine for writing the records to the files.
** On the Sel/Gould, we gain about a factor 4
*/

/* VARARGS2 */
#  ifdef __STDC__
_dmDoput (FILE * fp, char *fmt,...)
# else				/* not __STDC__ */
_dmDoput (fp, fmt, va_alist)
FILE * fp;
register char  *fmt;
va_dcl
#  endif			/* else not __STDC__ */
{
    register long   n;
    register long  *np;
    register char  *s;
    double  d;

    long    buf[12];
    long    n1;
    long    w;

    va_list ap;
#  ifdef __STDC__
    va_start (ap, fmt);
#  else				/* not __STDC__ */
    va_start (ap);
#  endif			/* else not __STDC__ */

    fmt--;
loop: 
    switch (*++fmt) {
	default: 		/* ordinary char, usually space */
	    PUT (*fmt);
	    goto loop;

	case 'F': 		/* double to be written as scaled int */
	    d = va_arg (ap, double);
	    n = (d == 0.0 ? 0 : (long) (1000.0 * d + (d > 0 ? 0.5 : -0.5)));
	    goto caseD;

	case 'W': 		/* fieldwith 16 */
	case 'D': 		/* integer argument */
	    n = va_arg (ap, long);
	    if (*fmt == 'W') {
	    /* 
	     ** could make this more efficient,
	     ** but the format W is not used very often
	     ** and will probably become obsolete soon
	     */
		w = ((n1 = n) < 0) ? 15 : 16;
		while (n1 /= 10)
		    w--;
		while (--w > 0)
		    PUT (' ');
	    }

    caseD: 
	    if (n < 0) {
		PUT ('-');
		n = (unsigned) (-n);
	    }

	    np = buf;
	    while (n > 99) {
		*np++ = n % 100;
		n /= 100;
	    };
	    if (n < 10)
		PUT ('0' + n);	/* ASCII */
	    else {
		PUT (tab[n][0]);
		PUT (tab[n][1]);
	    }
	    while (np > buf) {
		PUT (tab[*--np][0]);
		PUT (tab[*np][1]);
	    }
	    goto loop;

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

	/* This format is mainly used for attribute strings * of the form
	   "name=value; name=value". */

	    s = va_arg (ap, char *);

	/* put first the length of the string */
	    n = s ? (long) strlen (s) : 0;
	    np = buf;
	    while (n > 99) {
		*np++ = n % 100;
		n /= 100;
	    };
	    if (n < 10)
		PUT ('0' + n);	/* ASCII */
	    else {
		PUT (tab[n][0]);
		PUT (tab[n][1]);
	    }
	    while (np > buf) {
		PUT (tab[*--np][0]);
		PUT (tab[*np][1]);
	    }

	/* Now put a space to delimit the number from * the string. */
	    PUT (' ');

	/* Now the string itself, we do not need something * special for
	   the empty string, since we know its length. */
	    if (s != NULL)
		while (*s)
		    PUT (*(s++));

	    goto loop;

	case 'S': 		/* string argument */
	    s = va_arg (ap, char *);
	    if (s != NULL && *s != NULL) {
		while (*s)
		    PUT (*(s++));
	    }
	    else {
		PUT ('~');	/* special, denotes empty string */
	    }
	    goto loop;

	case 'C': 		/* character argument */
	    n = va_arg (ap, int);/* C converts char to int before pushing
				   it on the stack, so pop an int */
	    PUT (n);
	    goto loop;

	case '\0': 		/* format exhausted */
	    return (ferror (fp) ? -1 : 0);
    };
}

#ifdef DRIVER

main (argc, argv)
int     argc;
char   *argv[];
{
    int     r,
            i1,
            i2;
    char    c;
    char    s1[100];
    char    s2[100];

    r = _dmDoput (stdout, "C D W S A F\n", 'x', 123, 456, "abc", "de fg", 1.1115);
    if (r < 0)
	fprintf (stderr, "error");
    r = _dmDoput (stdout, "C D W S A F\n", 'x', 123, 456, "abc", "", 1.1114);
    if (r < 0)
	fprintf (stderr, "error");
    r = _dmDoput (stdout, "C D W S A F\n", 'x', 123, 456, "abc", "a", -1.2);
    if (r < 0)
	fprintf (stderr, "error");
}
#endif				/* DRIVER */
