See what's going on with flipcode!




This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 

  vsscanf for Win32
  Submitted by



I don't how many times I've been irritated by the fact that Microsoft chose to implement all the v*printf family of routines, but for some odd reason decided to leave out all the v*scanf routines. It is all the more frustrating that the functionality is actually present inside their crt library (in a function called input, which is not exported). From there your choices are as follows:
  • Write your own vsscanf
  • Rip the source out of crt and graft it into your app.
  • Use a third party implementation (trio is a good one, btw).


  • All these solutions suck: if you choose to write your own, you'll soon discover how hard it is to write an ANSI conforming scanf, other than hacking together Frankenstein code that is half yours, and half calling the native system sscanf when things gets hard (float conversion springs to mind). If you choose a third party implementation (crt, trio, glibc, ...), there's the usual problems: it's usually much bulkier than you'd like, doesn't compile the way you have your tree setup, comes with hieroglyphic Makefiles, carries crual and unusual licensing agreements, and basically adds a maintenance burden to your already complicated work day. Given all this, and the fact that irritation always ends up breeding code, here's my solution to the problem: since sscanf is available in the system, I've implemented vsscanf by hacking together a fake stack before hoping into sscanf. Advantages:
  • It works
  • It is small
  • It has no strings attached
  • In time, it inherits all maintenance work done by MSFT on scanf
  • Disadvantages:
  • It adds a tiny overhead (browsing the fmt for % signs)
  • It is not portable (although the technique is)
  • But then again the rest of the universe *does* implement vsscanf, so who cares.


  • Enjoy,
    - mgix PS: This is written with Visual C++ inline assembly. If someone gets around to writing the equivalent in the weird gcc inline assembly linguo, please send it my way. Thanks.

    Download Associated File: vsscanf.txt (3,040 bytes)

    /*

    I don't how many time I've been irritated by the fact that Microsoft chose to implement all the v*printf family of routines, but for some odd reason decided to leave out all the v*scanf routines.

    It is all the more frustrating that the functionality is actually present inside their crt library (in a function called input, which is not exported).

    >From there your choices are as follows:

    - Write your own vsscanf - Rip the source out of crt and graft it into your app. - Use a third party implementation (trio is a good one, btw).

    All these solutions suck: if you choose to write your own, you'll soon discover how hard it is to write an ANSI conforming scanf, other than hacking together Frankenstein code that is half yours, and half calling the native system sscanf when things gets hard (float conversion springs to mind).

    If you choose a third party implementation (crt, trio, glibc, ...), there's the usual problems: it's usually much bulkier than you'd like, doesn't compile the way you have your tree setup, comes with hieroglyphic Makefiles, carries crual and unusual licensing agreements, and basically adds a maintenance burden to your already complicated work day. Given all this, and the fact that irritation always ends up breeding code, here's my solution to the problem: since sscanf is available in the system, I've implemented vsscanf by hacking together a fake stack before hoping into sscanf.

    Advantages: - It works - It is small - It has no strings attached - In time, it inherits all maintenance work done by MSFT on scanf

    Disadvantages: - It adds a tiny overhead (browsing the fmt for % signs) - It is not portable (although the technique is) - But then again the rest of the universe *does* implement vsscanf, so who cares.

    Enjoy,

    - mgix

    PS: This is written with Visual C++ inline assembly. If someone gets around to writing the equivalent in the weird gcc inline assembly linguo, please send it my way. Thanks.

    */


    /* * vsscanf for Win32 * * Written 5/2003 by <mgix@mgix.com> * * This code is in the Public Domain * */

    #include <stdio.h> #include <stdarg.h> #include <malloc.h> #include <string.h>

    int vsscanf( const char *buffer, const char *format, va_list argPtr ) { // Get an upper bound for the # of args size_t count = 0; const char *p = format; while(1) { char c = *(p++); if(c==0) break; if(c=='%' && (p[0]!='*' && p[0]!='%')) ++count; }

    // Make a local stack size_t stackSize = (2+count)*sizeof(void*); void **newStack = (void**)alloca(stackSize);

    // Fill local stack the way sscanf likes it newStack[0] = (void*)buffer; newStack[1] = (void*)format; memcpy(newStack+2, argPtr, count*sizeof(void*));

    // Warp into system sscanf with new stack int result; void *savedESP; _asm { mov savedESP, esp; mov esp, newStack; call sscanf; mov esp, savedESP; mov result, eax; } return result; }

    The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

     

    Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
    Please read our Terms, Conditions, and Privacy information.