Like Tree1Likes
  • 1 Post By grumpy

Please explain me about Options.c

This is a discussion on Please explain me about Options.c within the Windows Programming forums, part of the Platform Specific Boards category; Option.c ?? please explain me this one. I need only the while portion of it. /* Utility function to extract ...

  1. #1
    Registered User
    Join Date
    Oct 2011
    Posts
    48

    Please explain me about Options.c

    Option.c ?? please explain me this one. I need only the while portion of it.
    /* Utility function to extract option flags from the command line. */

    Code:
    //Option.c
    #include "Everything.h"
    #include <stdarg.h>
    
    DWORD Options (int argc, LPCTSTR argv [], LPCTSTR OptStr, ...)
    
    /* argv is the command line.
        The options, if any, start with a '-' in argv[1], argv[2], ...
        OptStr is a text string containing all possible options,
        in one-to-one correspondence with the addresses of Boolean variables
        in the variable argument list (...).
        These flags are set if and only if the corresponding option
        character occurs in argv [1], argv [2], ...
        The return value is the argv index of the first argument beyond the options. */
    
    {
        va_list pFlagList;
        LPBOOL pFlag;
        int iFlag = 0, iArg;
    
        va_start (pFlagList, OptStr);
    
        while ((pFlag = va_arg (pFlagList, LPBOOL)) != NULL
                    && iFlag < (int)_tcslen (OptStr)) {
            *pFlag = FALSE;
            for (iArg = 1; !(*pFlag) && iArg < argc && argv [iArg] [0] == _T('-'); iArg++)
                *pFlag = _memtchr (argv [iArg], OptStr [iFlag],
                        _tcslen (argv [iArg])) != NULL;
            iFlag++;
        }
    
        va_end (pFlagList);
    
        for (iArg = 1; iArg < argc && argv [iArg] [0] == _T('-'); iArg++);
    
        return iArg;
    }
    cat.c // I understood this one. Just to show how Options.c is implemented
    Code:
    /* cat [options] [files]
        Only the -s option is used. Others are ignored.
        -s suppresses error report when a file does not exist */
    
    #include "Everything.h"
    
    #define BUF_SIZE 0x200
    
    static VOID CatFile (HANDLE, HANDLE);
    int _tmain (int argc, LPTSTR argv [])
    {
        HANDLE hInFile, hStdIn = GetStdHandle (STD_INPUT_HANDLE);
        HANDLE hStdOut = GetStdHandle (STD_OUTPUT_HANDLE);
        BOOL dashS;
        int iArg, iFirstFile;
    
        /*    dashS will be set only if "-s" is on the command line. */
        /*    iFirstFile is the argv [] index of the first input file. */
        iFirstFile = Options (argc, argv, _T("s"), &dashS, NULL);
    
        if (iFirstFile == argc) { /* No files in arg list. */
            CatFile (hStdIn, hStdOut);
            return 0;
        } 
        
        /* Process the input files. */
        for (iArg = iFirstFile; iArg < argc; iArg++) {
            hInFile = CreateFile (argv [iArg], GENERIC_READ,
                    0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
            if (hInFile == INVALID_HANDLE_VALUE) {
                if (!dashS) ReportError (_T ("Cat Error: File does not exist."), 0, TRUE);
            } else {
                CatFile (hInFile, hStdOut);
                if (GetLastError() != 0 && !dashS) {
                    ReportError (_T ("Cat Error: Could not process file completely."), 0, TRUE);
                }
                CloseHandle (hInFile);
            }
        }
        return 0;
    }
    
    static VOID CatFile (HANDLE hInFile, HANDLE hOutFile)
    {
        DWORD nIn, nOut;
        BYTE buffer [BUF_SIZE];
    
        while (ReadFile (hInFile, buffer, BUF_SIZE, &nIn, NULL) && (nIn != 0)
                && WriteFile (hOutFile, buffer, nIn, &nOut, NULL));
    
        return;
    }

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,434
    Can you narrow it down to some specific point?

    The whole while loop is pretty much as the comment reads.

    When in doubt, create a really simple main() to just call that function with a range of arguments and then single-step the code in the debugger, printing the variables as you go.


    You can't just roll up to the forum, dump a mess of code and say "explain this" without showing us that you've made some effort yourself.
    Like for example explaining the bits you DO understand, and making a bit of a guess at some parts you think you understand.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    Registered User
    Join Date
    Oct 2011
    Posts
    48
    Code:
    (pFlag = va_arg (pFlagList, LPBOOL)) != NULL
    // this is used to check whether we have reached end of the list or not.

    Code:
    iFlag < (int)_tcslen (OptStr)
    // I didn't get it. Why this is used.


    Code:
    *pFlag = FALSE;    // I did get it too.
    Code:
        for (iArg = 1; !(*pFlag) && iArg < argc && argv [iArg] [0] == _T('-'); iArg++)
    It will run till iArg = 1 to argc && if (first char of argv is '-')
    Code:
                *pFlag = _memtchr (argv [iArg], OptStr [iFlag],
                        _tcslen (argv [iArg])) != NULL;
    *pFlag will be set to true in while loop when it encounters '-' on its first run i.e till iFlag is zero, after it I don't understand.


    In summary I didn't get why iFlag is used and why it is needed to set pFlag to false .

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,198
    Quote Originally Posted by freiza View Post
    Code:
    (pFlag = va_arg (pFlagList, LPBOOL)) != NULL
    // this is used to check whether we have reached end of the list or not.
    It also sets the value of pFlag to be the result produced by the va_arg() macro. va_arg() is being used to step through the arguments the caller supplies after argc, argv, and OpStr. Every time around the loop, it retrieves the next argument. Since all of the arguments after OpStr should be pointers to BOOL, it tests if those pointers are non-NULL. Later on, the code writes to those pointers .... and writing to a NULL pointer is an invalid operation.

    Quote Originally Posted by freiza View Post
    In summary I didn't get why iFlag is used and why it is needed to set pFlag to false .
    iFlag is being used to track the number of options processed. The loop body should not be invoked if the option being processed is after the last one. The options are supplied in a character string, and iFlag is used in the loop to retrieve a character in that string. So iFlag needs to be less than the length of the string.

    pFlag is a pointer (supplied by the caller as part of the variable argument lst after OpStr) to a bool that needs to be set or not, depending on the corresponding content of argc, argv, and OpStr. The loop body sets *pFlag to false initially, and then searches for evidence that *pFlag needs to be set to true.
    freiza likes this.
    Right 98% of the time, and don't care about the other 3%.

  5. #5
    Registered User
    Join Date
    Oct 2011
    Posts
    48
    Let us assume the arv be
    cat -s -m filename1 filename2


    iFlag < (int)_tcslen (OptStr) // Initially IFlag is 0 so condition is true. But,
    *pFlag = _memtchr (argv [iArg], OptStr [iFlag], _tcslen (argv [iArg])) != NULL; //here since iFlag is 0, OptStr should be pointing to '-' and not 's'
    iFlag++; // But here iFlag is increamented by 1
    and also iArg is incremented by 1

    Now again at

    *pFlag = _memtchr (argv [iArg], OptStr [iFlag], _tcslen (argv [iArg])) != NULL; //after iFlag is incremented i.e iFlag=1, OptStr should be pointing to 'm' and not '-'

    What I was thinking that iFlag is pointing to characters in the string of argv[] and iArg is pointing to argv[0], argv[1], argv[2] etc. Am I wrong?



    And ,
    and writing to a NULL pointer is an invalid operation. Is this statement true?

    For example,
    int *p=NULL;
    int a=6;
    p=&a;

    this is not an error.

    Thank you very much.
    Last edited by freiza; 02-28-2012 at 02:43 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. 3 of 8 options
    By apolochaves in forum C Programming
    Replies: 5
    Last Post: 08-01-2010, 05:41 PM
  2. Is there really a better of the two options I have?
    By Shamino in forum C++ Programming
    Replies: 5
    Last Post: 12-26-2007, 07:37 AM
  3. Options Dialog
    By Morgul in forum Game Programming
    Replies: 3
    Last Post: 11-15-2005, 11:15 PM
  4. 2 options.... which way should I go?
    By CodeMonkey in forum Game Programming
    Replies: 9
    Last Post: 03-18-2002, 08:20 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21