aboutsummaryrefslogtreecommitdiff
path: root/Source/DOH/Doh/fio.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DOH/Doh/fio.c')
-rw-r--r--Source/DOH/Doh/fio.c385
1 files changed, 385 insertions, 0 deletions
diff --git a/Source/DOH/Doh/fio.c b/Source/DOH/Doh/fio.c
new file mode 100644
index 000000000..809147da9
--- /dev/null
+++ b/Source/DOH/Doh/fio.c
@@ -0,0 +1,385 @@
+/****************************************************************************
+ * DOH (Dynamic Object Hack)
+ *
+ * Author : David Beazley
+ *
+ * Department of Computer Science
+ * University of Chicago
+ * 1100 E 58th Street
+ * Chicago, IL 60637
+ * beazley@cs.uchicago.edu
+ *
+ * Please read the file LICENSE for the copyright and terms by which SWIG
+ * can be used and distributed.
+ ****************************************************************************/
+
+#include "doh.h"
+
+/* -----------------------------------------------------------------------------
+ * fio.c
+ *
+ * Support for formatted I/O via fprintf, fscanf.
+ * ----------------------------------------------------------------------------- */
+
+/* -----------------------------------------------------------------------------
+ * DohvPrintf(DOH *so, char *format, va_list ap)
+ *
+ * printf
+ * ----------------------------------------------------------------------------- */
+
+int
+DohvPrintf(DOH *so, char *format, va_list ap)
+{
+ static char *fmt_codes = "dioxXucsSfeEgGpnbB";
+ int state = 0;
+ char *p = format;
+ char newformat[256];
+ char *fmt;
+ char temp[64];
+ int widthval = 0;
+ int precval = 0;
+ int maxwidth;
+ char *w, *prec;
+ int ivalue;
+ int dvalue;
+
+ while (*p) {
+ switch(state) {
+ case 0: /* Ordinary text */
+ if (*p != '%') {
+ Putc(*p,so);
+ } else{
+ fmt = newformat;
+ widthval = 0;
+ precval = 0;
+ *(fmt++) = *p;
+ state = 10;
+ }
+ break;
+ case 10: /* Look for a width and precision */
+ if (isdigit(*p) && (*p != '0')) {
+ w = temp;
+ *(w++) = *p;
+ *(fmt++) = *p;
+ state = 20;
+ } else if (strchr(fmt_codes,*p)) {
+ /* Got one of the formatting codes */
+ p--;
+ state = 100;
+ } else if (*p == '*') {
+ /* Width field is specified in the format list */
+ widthval = va_arg(ap,int);
+ sprintf(temp,"%d",widthval);
+ for (w = temp; *w; w++) {
+ *(fmt++) = *w;
+ }
+ state = 30;
+ } else if (*p == '%') {
+ Putc(*p,so);
+ fmt = newformat;
+ state = 0;
+ } else {
+ *(fmt++) = *p;
+ }
+ break;
+
+ case 20: /* Hmmm. At the start of a width field */
+ if (isdigit(*p)) {
+ *(w++) = *p;
+ *(fmt++) = *p;
+ } else if (strchr(fmt_codes,*p)) {
+ /* Got one of the formatting codes */
+ /* Figure out width */
+ *w = 0;
+ widthval = atoi(temp);
+ p--;
+ state = 100;
+ } else if (*p == '.') {
+ *w = 0;
+ widthval = atoi(temp);
+ w = temp;
+ *(fmt++) = *p;
+ state = 40;
+ } else {
+ /* ??? */
+ *w = 0;
+ widthval = atoi(temp);
+ state = 50;
+ }
+ break;
+
+ case 30: /* Parsed a width from an argument. Look for a . */
+ if (*p == '.') {
+ w = temp;
+ *(fmt++) = *p;
+ state = 40;
+ } else if (strchr(fmt_codes,*p)) {
+ /* Got one of the formatting codes */
+ /* Figure out width */
+ p--;
+ state = 100;
+ } else {
+ /* hmmm. Something else. */
+ state = 50;
+ }
+ break;
+
+ case 40:
+ /* Start of precision expected */
+ if (isdigit(*p) && (*p != '0')) {
+ *(fmt++) = *p;
+ *(w++) = *p;
+ state = 41;
+ } else if (*p == '*') {
+ /* Precision field is specified in the format list */
+ precval = va_arg(ap,int);
+ sprintf(temp,"%d",precval);
+ for (w = temp; *w; w++) {
+ *(fmt++) = *w;
+ }
+ state = 50;
+ } else if (strchr(fmt_codes,*p)) {
+ p--;
+ state = 100;
+ } else {
+ *(fmt++) = *p;
+ state = 50;
+ }
+ break;
+ case 41:
+ if (isdigit(*p)) {
+ *(fmt++) = *p;
+ *(w++) = *p;
+ } else if (strchr(fmt_codes,*p)) {
+ /* Got one of the formatting codes */
+ /* Figure out width */
+ *w = 0;
+ precval = atoi(temp);
+ p--;
+ state = 100;
+ } else {
+ *w = 0;
+ precval = atoi(temp);
+ *(fmt++) = *p;
+ state = 50;
+ }
+ break;
+ /* Hang out, wait for format specifier */
+ case 50:
+ if (strchr(fmt_codes,*p)) {
+ p--;
+ state = 100;
+ } else {
+ *(fmt++) = *p;
+ }
+ break;
+ case 100:
+ /* Got a formatting code */
+ if (widthval < precval) maxwidth = precval;
+ else maxwidth = widthval;
+ if ((*p == 's') || (*p == 'S')) { /* Null-Terminated string */
+ DOH *doh;
+ DOH *Sval;
+ char *temps;
+ doh = va_arg(ap, DOH *);
+ if (DohCheck(doh)) {
+ /* Is an object at least */
+ if (String_check(doh)) {
+ Sval = doh;
+ } else {
+ Sval = Str(doh);
+ }
+ maxwidth = maxwidth+strlen(newformat)+Len(Sval);
+ *(fmt++) = 's';
+ *fmt = 0;
+ temps = (char *) malloc(maxwidth+1);
+ sprintf(temps,newformat,Data(Sval));
+ Write(so,temps,strlen(temps));
+ if ((DOH *) Sval != doh) {
+ Delete(Sval);
+ }
+ if (*p == 'S') {
+ Delete(doh);
+ }
+ free(temps);
+ } else {
+ maxwidth = maxwidth+strlen(newformat)+strlen((char *) doh);
+ *(fmt++) = 's';
+ *fmt = 0;
+ temps = (char *) malloc(maxwidth+1);
+ sprintf(temps,newformat,doh);
+ free(temps);
+ }
+ } else {
+ int ivalue;
+ double dvalue;
+ void *pvalue;
+ char *stemp;
+ *(fmt++) = *p;
+ *fmt = 0;
+ maxwidth = maxwidth+strlen(newformat)+64;
+ stemp = (char *) malloc(maxwidth+1);
+ switch(*p) {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'c':
+ ivalue = va_arg(ap,int);
+ sprintf(stemp,newformat,ivalue);
+ break;
+ case 'f':
+ case 'g':
+ case 'e':
+ case 'E':
+ case 'G':
+ dvalue = va_arg(ap,double);
+ sprintf(stemp,newformat,dvalue);
+ break;
+ case 'p':
+ pvalue = va_arg(ap,void *);
+ sprintf(stemp,newformat,pvalue);
+ break;
+ default:
+ break;
+ }
+ Write(so,stemp,strlen(stemp));
+ free(stemp);
+ }
+ state = 0;
+ break;
+ }
+ p++;
+ }
+ if (state) {
+ *fmt = 0;
+ Write(so,fmt,strlen(fmt));
+ }
+ return 1;
+}
+
+/* Printf */
+int DohPrintf(DOH *obj, char *format, ...) {
+ va_list ap;
+ int ret;
+ va_start(ap,format);
+ ret = DohvPrintf(obj,format,ap);
+ va_end(ap);
+ return ret;
+}
+
+#ifdef OLD
+
+/* ----------------------------------------------------------------------
+ * int String_scanfv(DOH *doh, char *format, va_list ap)
+ *
+ * Do a string scanf. Somewhat broken compared to C scanf.
+ * ---------------------------------------------------------------------- */
+
+int String_scanfv(DOH *doh, char *format, va_list ap) {
+ static char *fmt_chars = "diouxcsefgp";
+ String *s;
+ char newformat[256];
+ char *fmt;
+ char *p;
+ int state;
+ void *ptr;
+ int total = 0;
+ int i;
+
+ s = (String *) doh;
+ state = 0;
+ p = format;
+ while (*p) {
+ switch(state) {
+ case 0:
+ if (*p == '%') {
+ fmt = newformat;
+ *(fmt++) = *p;
+ state = 10;
+ }
+ break;
+ case 10:
+ if (strchr(fmt_chars,*p)) {
+ int len;
+ *(fmt++) = *p;
+ *fmt = 0;
+ ptr = va_arg(ap, void *);
+ len = sscanf(s->str+s->sp,newformat,ptr);
+ for (i = 0; i < len; i++) {
+ while (s->sp < s->len) {
+ if (!isspace(s->str[s->sp])) break;
+ s->sp++;
+ }
+ while (s->sp < s->len) {
+ if (isspace(s->str[s->sp])) break;
+ s->sp++;
+ }
+ }
+ total += len;
+ state = 0;
+ fmt = newformat;
+ } else {
+ *(fmt++) = *p;
+ }
+ break;
+ }
+ p++;
+ }
+ return total;
+}
+
+/* vPrintf */
+int DohvPrintf(DOH *obj, char *format, va_list ap) {
+ int ret;
+ DohBase *b = (DohBase *) obj;
+ if (DohIsFile(obj)) {
+ if (b->objinfo->doh_file->doh_printf) {
+ return (b->objinfo->doh_file->doh_printf)(obj,format,ap);
+ }
+ printf("No printf method defined for type '%s'\n", b->objinfo->objname);
+ } else {
+ if (!DohCheck(obj)) {
+ DOH *str;
+ str = NewString("");
+ DohvAppendf(str,format,ap);
+ ret = fprintf((FILE *) obj, "%s", Data(str));
+ Delete(str);
+ return ret;
+ }
+ }
+ return -1;
+}
+
+/* Printf */
+int DohScanf(DOH *obj, char *format, ...) {
+ va_list ap;
+ int ret;
+ DohBase *b = (DohBase *) obj;
+ if (DohIsFile(obj)) {
+ if (b->objinfo->doh_file->doh_scanf) {
+ va_start(ap,format);
+ ret = (b->objinfo->doh_file->doh_scanf)(obj,format,ap);
+ va_end(ap);
+ return ret;
+ }
+ printf("No scanf method defined for type '%s'\n", b->objinfo->objname);
+ }
+ return -1;
+}
+
+/* vPrintf */
+int DohvScanf(DOH *obj, char *format, va_list ap) {
+ DohBase *b = (DohBase *) obj;
+ if (DohIsFile(obj)) {
+ if (b->objinfo->doh_file->doh_scanf) {
+ return (b->objinfo->doh_file->doh_scanf)(obj,format,ap);
+ }
+ printf("No scanf method defined for type '%s'\n", b->objinfo->objname);
+ }
+ return -1;
+}
+
+#endif