X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f Date: Mon, 5 Jan 2004 13:39:45 +0200 (EET) From: Esa A E Peuha Sender: peuha AT sirppi DOT helsinki DOT fi To: djgpp-workers AT delorie DOT com Subject: Use of FILE in sprintf/sscanf Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Reply-To: djgpp-workers AT delorie DOT com The sprintf and sscanf funcion families use FILE objects to point to strings. However, there is no reason why these functions should know what is inside FILE; the act of "opening" a string as file can be abstracted as follows: Index: include/libc/file.h =================================================================== RCS file: /cvs/djgpp/djgpp/include/libc/file.h,v retrieving revision 1.11 diff -c -r1.11 file.h *** include/libc/file.h 4 Feb 2003 20:24:58 -0000 1.11 --- include/libc/file.h 5 Jan 2004 11:34:05 -0000 *************** *** 104,109 **** --- 104,132 ---- return __putc_raw(x,p); } + static __inline__ void __sopenw(FILE *p, char *str, int len) + { + p->_flag = _IOWRT | _IOSTRG | _IONTERM; + p->_ptr = str; + p->_cnt = len; + } + + static __inline__ void __sopenr(FILE *p, const char *str) + { + union { + char *s; + const char *cs; + } u; + + u.cs = str; + p->_flag = _IOREAD | _IOSTRG | _IONTERM; + p->_ptr = p->_base = u.s; + p->_cnt = 0; + while (*str++) + p->_cnt++; + p->_bufsiz = p->_cnt; + } + #undef fileno #define fileno(f) (f->_file) #undef feof Index: src/libc/ansi/stdio/sprintf.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/sprintf.c,v retrieving revision 1.4 diff -c -r1.4 sprintf.c *** src/libc/ansi/stdio/sprintf.c 8 Jun 2002 10:14:23 -0000 1.4 --- src/libc/ansi/stdio/sprintf.c 5 Jan 2004 11:34:05 -0000 *************** *** 13,26 **** FILE _strbuf; int len; ! _strbuf._flag = _IOWRT|_IOSTRG|_IONTERM; ! _strbuf._ptr = str; ! _strbuf._cnt = INT_MAX; ! va_start(args, fmt); len = _doprnt(fmt, args, &_strbuf); va_end(args); ! ! *_strbuf._ptr = 0; return len; } --- 13,22 ---- FILE _strbuf; int len; ! __sopenw(&_strbuf, str, INT_MAX); va_start(args, fmt); len = _doprnt(fmt, args, &_strbuf); va_end(args); ! str[len] = '\0'; return len; } Index: src/libc/ansi/stdio/sscanf.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/sscanf.c,v retrieving revision 1.3 diff -c -r1.3 sscanf.c *** src/libc/ansi/stdio/sscanf.c 4 Aug 1999 19:58:22 -0000 1.3 --- src/libc/ansi/stdio/sscanf.c 5 Jan 2004 11:34:05 -0000 *************** *** 3,9 **** #include #include #include - #include int sscanf(const char *str, const char *fmt, ...) --- 3,8 ---- *************** *** 13,25 **** FILE _strbuf; va_start(a, fmt); ! ! _strbuf._flag = _IOREAD|_IOSTRG|_IONTERM; ! _strbuf._ptr = _strbuf._base = unconst(str, char *); ! _strbuf._cnt = 0; ! while (*str++) ! _strbuf._cnt++; ! _strbuf._bufsiz = _strbuf._cnt; r = _doscan(&_strbuf, fmt, a); va_end(a); return r; --- 12,18 ---- FILE _strbuf; va_start(a, fmt); ! __sopenr(&_strbuf, str); r = _doscan(&_strbuf, fmt, a); va_end(a); return r; Index: src/libc/ansi/stdio/vsnprntf.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/vsnprntf.c,v retrieving revision 1.2 diff -c -r1.2 vsnprntf.c *** src/libc/ansi/stdio/vsnprntf.c 8 Jun 2001 17:49:37 -0000 1.2 --- src/libc/ansi/stdio/vsnprntf.c 5 Jan 2004 11:34:05 -0000 *************** *** 21,45 **** } memset(&_strbuf, 0, sizeof(_strbuf)); - _strbuf._flag = _IOWRT | _IOSTRG | _IONTERM; /* If n == 0, just querying how much space is needed. */ if (n > 0) ! { ! _strbuf._cnt = n - 1; ! _strbuf._ptr = str; ! } else ! { ! _strbuf._cnt = 0; ! _strbuf._ptr = NULL; ! } len = _doprnt(fmt, ap, &_strbuf); /* Ensure nul termination */ if (n > 0) ! *_strbuf._ptr = 0; return len; } --- 21,38 ---- } memset(&_strbuf, 0, sizeof(_strbuf)); /* If n == 0, just querying how much space is needed. */ if (n > 0) ! __sopenw(&_strbuf, str, n - 1); else ! __sopenw(&_strbuf, NULL, 0); len = _doprnt(fmt, ap, &_strbuf); /* Ensure nul termination */ if (n > 0) ! str[len] = '\0'; return len; } Index: src/libc/ansi/stdio/vsprintf.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/vsprintf.c,v retrieving revision 1.3 diff -c -r1.3 vsprintf.c *** src/libc/ansi/stdio/vsprintf.c 4 Aug 1999 19:58:22 -0000 1.3 --- src/libc/ansi/stdio/vsprintf.c 5 Jan 2004 11:34:05 -0000 *************** *** 11,20 **** FILE f; int len; ! f._flag = _IOWRT|_IOSTRG|_IONTERM; ! f._ptr = str; ! f._cnt = INT_MAX; len = _doprnt(fmt, ap, &f); ! *f._ptr = 0; return len; } --- 11,18 ---- FILE f; int len; ! __sopenw(&f, str, INT_MAX); len = _doprnt(fmt, ap, &f); ! str[len] = '\0'; return len; } Index: src/libc/compat/stdio/vsscanf.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/compat/stdio/vsscanf.c,v retrieving revision 1.3 diff -c -r1.3 vsscanf.c *** src/libc/compat/stdio/vsscanf.c 4 Aug 1999 19:58:22 -0000 1.3 --- src/libc/compat/stdio/vsscanf.c 5 Jan 2004 11:34:05 -0000 *************** *** 3,20 **** #include #include #include - #include int vsscanf(const char *str, const char *fmt, va_list ap) { FILE _strbuf; ! _strbuf._flag = _IOREAD|_IOSTRG|_IONTERM; ! _strbuf._ptr = _strbuf._base = unconst(str, char *); ! _strbuf._cnt = 0; ! while (*str++) ! _strbuf._cnt++; ! _strbuf._bufsiz = _strbuf._cnt; return _doscan(&_strbuf, fmt, ap); } --- 3,14 ---- #include #include #include int vsscanf(const char *str, const char *fmt, va_list ap) { FILE _strbuf; ! __sopenr(&_strbuf, str); return _doscan(&_strbuf, fmt, ap); } -- Esa Peuha student of mathematics at the University of Helsinki http://www.helsinki.fi/~peuha/