Simple vsscanf source code

R

Ray Mitchell

Hello,

I realize that the source code for vsscanf is available from several
sources, such as GNU. However, all such source code I've found so far is
filled with cryptic (to me) #ifdefs, system stuff, and basically all kinds
of
general things related to a particular implementation.

I'm looking for a simple concise generic C99 version that I can easily adapt
into my application without having to look all over the place for a
seemingly
unending litany of cryptic "helper" functions. I'm sure I could write my
own
version but I'd rather not go through the pain if I can avoid it.

Thanks,
Ray Mitchell
 
C

Charlie Gordon

Ray Mitchell said:
Hello,

I realize that the source code for vsscanf is available from several
sources, such as GNU. However, all such source code I've found so far is
filled with cryptic (to me) #ifdefs, system stuff, and basically all kinds
of
general things related to a particular implementation.

I'm looking for a simple concise generic C99 version that I can easily adapt
into my application without having to look all over the place for a
seemingly
unending litany of cryptic "helper" functions. I'm sure I could write my
own
version but I'd rather not go through the pain if I can avoid it.

Well no surprise! vsscanf() is one of the most complex functions you can find in
the C library.
Its semantics are contorted and extensive and there are a lot of small details
to take care of, especially with portability as a constraint.
What kind of extensions are you looking to add ?
What features are you willing to remove to get a simpler version ?
You can try to find Plauger's implementation from his book "The Standard C
Library". An older version would be a better start.

Chqrlie.
 
H

Hans-Bernhard Broeker

[F'up2 cut down --- should have been done by OP!]

In comp.lang.c.moderated Ray Mitchell said:
I realize that the source code for vsscanf is available from several
sources, such as GNU. However, all such source code I've found so
far is filled with cryptic (to me) #ifdefs, system stuff, and
basically all kinds of general things related to a particular
implementation.

And you think the authors of those versions put all those
system-specifica and #if's in there for fun, or what?

Here's a clue: if a simple, portable implementation were possible,
odds are vsscanf() would never have become part of the standard
library to begin with. The primary reason for including a function in
the library, nowadays, is "the job can't be done (efficiently) in a
platform-independent way". I.e. it's in libc *because* you can't
write it yourself without becoming hugely platform-dependent.
I'm looking for a simple concise generic C99 version that I can
easily adapt into my application without having to look all over the
place for a seemingly unending litany of cryptic "helper" functions.

In C99 you can't possibly need such a thing --- the very fact that a
compiler toolchain supports C99 mandates that it already supplies you
with a vsscanf() implementation.
 
J

Jonathan Leffler

Ray said:
I realize that the source code for vsscanf is available from
several sources, such as GNU. However, all such source code I've
found so far is filled with cryptic (to me) #ifdefs, system stuff,
and basically all kinds of general things related to a particular
implementation.

I'm looking for a simple concise generic C99 version that I can
easily adapt into my application without having to look all over
the place for a seemingly unending litany of cryptic "helper"
functions. I'm sure I could write my own version but I'd rather not
go through the pain if I can avoid it.

If you can meet the licencing terms, consider Plauger's The Standard C
Library (where the standard in question is ISO 9899:1990).
 
M

MarcSmith

int vsscanf( char *buf, char *format, va_list argp )
{
char *fmtp;
char *bufp;
Bool suppress;
int mytype, width, n, k = 0;
char lastchar;

bufp = buf;

for (fmtp = format; *fmtp; fmtp++)
{ if (*fmtp == '%')
{ mytype = NORMAL_TYPE;
suppress = FALSE;
width = 0;
lastchar = ' ';
}
else if (*fmtp == '*')
suppress = TRUE;
else if (isspace(*fmtp));
else if (isdigit(*fmtp))
{ if (lastchar != '.')
{ width *= 10;
width += (*fmtp - '0');
}
}
else if (*fmtp == 'l' || *fmtp == 'L')
mytype = LONG;
else if (*fmtp == 'h')
mytype = SHORT;
else if (*fmtp == 'i' || *fmtp == 'd')
{ if (suppress)
bufp = Advance(bufp);
else if (mytype == SHORT)
{ k+=sscanf(bufp,"%hd%n",va_arg(argp,short*),&n);
bufp+=n;
}
else if (mytype == LONG)
{ k+=sscanf(bufp,"%ld%n",va_arg(argp,long*),&n);
bufp+=n;
}
else
{ k+=sscanf(bufp,"%d%n",va_arg(argp, int*),&n);
bufp+=n;
}
}
else if (*fmtp == 'f')
{ if (suppress)
bufp = Advance(bufp);
else if (mytype == LONG)
{ k+=sscanf(bufp,"%f%n",va_arg(argp, double*),&n);
bufp+=n;
}
else
{ k+=sscanf(bufp,"%f%n",va_arg(argp, float*),&n);
bufp+=n;
}
}
else if (*fmtp == 's')
{ if (suppress)
bufp = Advance(bufp);
else {
k+=sscanf(bufp,"%s%n",va_arg(argp, char*),&n);
bufp+=n;
}
}
else if (*fmtp == 'c')
{ if (!suppress)
{ k+=sscanf(bufp,"%c%n",va_arg(argp, char*),&n);
bufp+=n;
}
else bufp++;
}
else lastchar = *fmtp;
} /* for */
return k;
} /* vsscanf clone */

static char *Advance( char *bufp )
{
char *new_bufp = bufp;

/* Skip over nonwhite SPACE */
while ((*new_bufp != ' ') && (*new_bufp != '\t') &&
(*new_bufp != '\n') && (*new_bufp != '\0'))
new_bufp++;

/* Skip white SPACE */
while ((*new_bufp == ' ') || (*new_bufp == '\t') ||
(*new_bufp == '\n') || (*new_bufp == '\0'))
new_bufp++;

return new_bufp;
} /* Advance *


-
MarcSmit
 
?

=?ISO-8859-1?Q?Bj=F8rn_Augestad?=

MarcSmith wrote:
[snip]
int vsscanf( char *buf, char *format, va_list argp )

const char* buf, const char* format, if you want to clone vsscanf().
{
char *fmtp;
char *bufp;
Bool suppress;
int mytype, width, n, k = 0;
char lastchar;

bufp = buf;

for (fmtp = format; *fmtp; fmtp++)
{ if (*fmtp == '%')
{ mytype = NORMAL_TYPE;
suppress = FALSE;
width = 0;
lastchar = ' ';
}
else if (*fmtp == '*')
suppress = TRUE;
else if (isspace(*fmtp));
else if (isdigit(*fmtp))
{ if (lastchar != '.')
{ width *= 10;
width += (*fmtp - '0');
}
}
else if (*fmtp == 'l' || *fmtp == 'L')
mytype = LONG;
else if (*fmtp == 'h')
mytype = SHORT;
else if (*fmtp == 'i' || *fmtp == 'd')
{ if (suppress)
bufp = Advance(bufp);
else if (mytype == SHORT)
{ k+=sscanf(bufp,"%hd%n",va_arg(argp,short*),&n);
bufp+=n;
}
else if (mytype == LONG)
{ k+=sscanf(bufp,"%ld%n",va_arg(argp,long*),&n);
bufp+=n;
}
else
{ k+=sscanf(bufp,"%d%n",va_arg(argp, int*),&n);
bufp+=n;
}
}
else if (*fmtp == 'f')
{ if (suppress)
bufp = Advance(bufp);
else if (mytype == LONG)
{ k+=sscanf(bufp,"%f%n",va_arg(argp, double*),&n);
bufp+=n;
}
else
{ k+=sscanf(bufp,"%f%n",va_arg(argp, float*),&n);
bufp+=n;
}
}
else if (*fmtp == 's')
{ if (suppress)
bufp = Advance(bufp);
else {
k+=sscanf(bufp,"%s%n",va_arg(argp, char*),&n);
bufp+=n;
}
}
else if (*fmtp == 'c')
{ if (!suppress)
{ k+=sscanf(bufp,"%c%n",va_arg(argp, char*),&n);
bufp+=n;
}
else bufp++;
}
else lastchar = *fmtp;
} /* for */
return k;
} /* vsscanf clone */


static char *Advance( char *bufp )
{
char *new_bufp = bufp;

/* Skip over nonwhite SPACE */
while ((*new_bufp != ' ') && (*new_bufp != '\t') &&
(*new_bufp != '\n') && (*new_bufp != '\0'))
new_bufp++;

/* Skip white SPACE */
while ((*new_bufp == ' ') || (*new_bufp == '\t') ||
(*new_bufp == '\n') || (*new_bufp == '\0'))

a) BUG:-------------------*new_bufp != '\0'

b) How about using the isspace() macro instead?

c) I didn't spend much time on this and the code is barely readable, but
it looks to me that Advance() always skips to the end of bufp (assuming
that the bug is fixed)?
> new_bufp++;

return new_bufp;
} /* Advance */



Bjørn

PS: Should the faq contain some kind of formatting rules for code posted
here, and maybe include a sample indent.pro file or something?
 
C

Charlie Gordon

MarcSmith said:
int vsscanf( char *buf, char *format, va_list argp )
{
.... lots of very badly presented useless code

Wrong prototype, buggy code, useless post : implementing vsscanf in terms of
sscanf is a joke right ?

Chqrlie.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top