patch-2.4.10 linux/lib/vsprintf.c
Next file: linux/mm/bootmem.c
Previous file: linux/lib/rbtree.c
Back to the patch index
Back to the overall index
- Lines: 199
- Date:
Sun Sep 16 11:26:10 2001
- Orig file:
v2.4.9/linux/lib/vsprintf.c
- Orig date:
Sun Aug 12 13:28:01 2001
diff -u --recursive --new-file v2.4.9/linux/lib/vsprintf.c linux/lib/vsprintf.c
@@ -308,6 +308,10 @@
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
qualifier = *fmt;
++fmt;
+ if (qualifier == 'l' && *fmt == 'l') {
+ qualifier = 'L';
+ ++fmt;
+ }
}
/* default base */
@@ -502,3 +506,187 @@
return i;
}
+/**
+ * vsscanf - Unformat a buffer into a list of arguments
+ * @buf: input buffer
+ * @fmt: format of buffer
+ * @args: arguments
+ */
+int vsscanf(const char * buf, const char * fmt, va_list args)
+{
+ const char *str = buf;
+ char *next;
+ int num = 0;
+ int qualifier;
+ int base;
+ unsigned int field_width;
+ int is_sign = 0;
+
+ for (; *fmt; fmt++) {
+ /* skip any white space in format */
+ if (isspace(*fmt)) {
+ continue;
+ }
+
+ /* anything that is not a conversion must match exactly */
+ if (*fmt != '%') {
+ if (*fmt++ != *str++)
+ return num;
+ continue;
+ }
+ ++fmt;
+
+ /* skip this conversion.
+ * advance both strings to next white space
+ */
+ if (*fmt == '*') {
+ while (!isspace(*fmt))
+ fmt++;
+ while(!isspace(*str))
+ str++;
+ continue;
+ }
+
+ /* get field width */
+ field_width = 0xffffffffUL;
+ if (isdigit(*fmt))
+ field_width = skip_atoi(&fmt);
+
+ /* get conversion qualifier */
+ qualifier = -1;
+ if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'Z') {
+ qualifier = *fmt;
+ fmt++;
+ }
+ base = 10;
+ is_sign = 0;
+
+ switch(*fmt) {
+ case 'c':
+ {
+ char *s = (char *) va_arg(args,char*);
+ do {
+ *s++ = *str++;
+ } while(field_width-- > 0);
+ num++;
+ }
+ continue;
+ case 's':
+ {
+ char *s = (char *) va_arg(args, char *);
+ /* first, skip leading white space in buffer */
+ while (isspace(*str))
+ str++;
+
+ /* now copy until next white space */
+ while (!isspace(*str) && field_width--) {
+ *s++ = *str++;
+ }
+ *s = '\0';
+ num++;
+ }
+ continue;
+ case 'n':
+ /* return number of characters read so far */
+ {
+ int *i = (int *)va_arg(args,int*);
+ *i = str - buf;
+ }
+ continue;
+ case 'o':
+ base = 8;
+ break;
+ case 'x':
+ case 'X':
+ base = 16;
+ break;
+ case 'd':
+ case 'i':
+ is_sign = 1;
+ case 'u':
+ break;
+ case '%':
+ /* looking for '%' in str */
+ if (*str++ != '%')
+ return num;
+ continue;
+ default:
+ /* invalid format; stop here */
+ return num;
+ }
+
+ /* have some sort of integer conversion.
+ * first, skip white space in buffer.
+ */
+ while (isspace(*str))
+ str++;
+
+ switch(qualifier) {
+ case 'h':
+ if (is_sign) {
+ short *s = (short *) va_arg(args,short *);
+ *s = (short) simple_strtol(str,&next,base);
+ } else {
+ unsigned short *s = (unsigned short *) va_arg(args, unsigned short *);
+ *s = (unsigned short) simple_strtoul(str, &next, base);
+ }
+ break;
+ case 'l':
+ if (is_sign) {
+ long *l = (long *) va_arg(args,long *);
+ *l = simple_strtol(str,&next,base);
+ } else {
+ unsigned long *l = (unsigned long*) va_arg(args,unsigned long*);
+ *l = simple_strtoul(str,&next,base);
+ }
+ break;
+ case 'L':
+ if (is_sign) {
+ long long *l = (long long*) va_arg(args,long long *);
+ *l = simple_strtoll(str,&next,base);
+ } else {
+ unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*);
+ *l = simple_strtoull(str,&next,base);
+ }
+ break;
+ case 'Z':
+ {
+ size_t *s = (size_t*) va_arg(args,size_t*);
+ *s = (size_t) simple_strtoul(str,&next,base);
+ }
+ break;
+ default:
+ if (is_sign) {
+ int *i = (int *) va_arg(args, int*);
+ *i = (int) simple_strtol(str,&next,base);
+ } else {
+ unsigned int *i = (unsigned int*) va_arg(args, unsigned int*);
+ *i = (unsigned int) simple_strtoul(str,&next,base);
+ }
+ break;
+ }
+ num++;
+
+ if (!next)
+ break;
+ str = next;
+ }
+ return num;
+}
+
+/**
+ * sscanf - Unformat a buffer into a list of arguments
+ * @buf: input buffer
+ * @fmt: formatting of buffer
+ * @...: resulting arguments
+ */
+int sscanf(const char * buf, const char * fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args,fmt);
+ i = vsscanf(buf,fmt,args);
+ va_end(args);
+ return i;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)