/*      Copyright (C) 2002, 2003, 2004 Stijn van Dongen
 *
 * This file is part of MCL.  You can redistribute and/or modify MCL under the
 * terms of the GNU General Public License; either version 2 of the License or
 * (at your option) any later version.  You should have received a copy of the
 * GPL along with MCL, in the file COPYING.
*/

#ifndef util_opt_h
#define util_opt_h


/*  **************************************************************************
 * *
 **            Implementation notes (a few).
 *
 *    This interface munges and parses text presented to it, and creates
 *    hashes and linked lists from them. It does so by simply storing
 *    pointers to the data presented to it, and does not copy anything at all.
 *
 *    It is the callers job to make sure that the data scrutinized by this
 *    interface stays constant during interface usage.
 *
 * TODO:
 *    fix ugly mcxOptParse__ interface to mcxOptParse and mcxOptExhaust.  
 *    mcxOptParse will not care if more than suffix args remain (and
 *    does not report back the count of parsed args).
*/

#define     MCX_OPT_HASARG    1

#define     MCX_OPT_OK        0
#define     MCX_OPT_NOARG     1
#define     MCX_OPT_UNKNOWN   2


#include "types.h"
#include "ting.h"
#include "hash.h"


/*
 * the routines in here only use bit 1 currently, MCX_OPT_NOARG. The interface
 * is not yet frozen.
*/

typedef struct mcxOptAnchor
{  char*          tag         /* e.g. '-foo' or '--expand-only' etc */
;  int            flags
;  int            id          /* numerical ID */
;
}  mcxOptAnchor   ;


typedef struct mcxOptList
{  struct mcxOptList* next
;  char*          tag         /* e.g. -f, -foo, --foo */
;  char*          val         /* e.g. bar or baf */
;
}  mcxOptList     ;


typedef struct mcxArgs
{  const char**   argv
;  int            argc
;
}  mcxArgs        ;


/*
 * Creates a hash where the tag string is key, and the mcxOptAnchor is value.
*/ 

mcxHash* mcxOptHash
(  mcxOptAnchor*  opts
,  mcxHash*       hash
)  ;

void mcxOptHashFree
(  mcxHash**   hashpp
)  ;


/*    This tries to find as many arguments as it can, and reports the
 *    number of array elements it skipped.
*/

mcxOptList* mcxOptExhaust
(  mcxHash*       opthash
,  char**         argv
,  int            argc
,  int            prefix   /* skip these */
,  int*           n_elems_read
,  mcxstatus*     status
)  ;


/*    This will never read past the last arguments (suffix of them).
 *    It does currently not enforce that the number of arguments left
 *    is exactly equal to suffix (fixme?).
*/

mcxOptList* mcxOptParse
(  mcxHash*       opthash
,  char**         argv
,  int            argc
,  int            prefix   /* skip these */
,  int            suffix   /* skip those too */
,  mcxstatus*     status
)  ;


mcxOptAnchor* mcxOptFind
(  char*    tag
,  mcxHash*       hopts  
)  ;

void mcxOptListFree
(  mcxOptList** listpp
)  ;

void mcxUsage
(  FILE* fp
,  const char*  caller
,  const char** lines
)  ;



extern int mcxOptPrintDigits;

mcxbool mcxOptCheckBounds
(  const char*    caller
,  const char*    flag
,  char           type
,  void*          var
,  int            (*lftRlt) (const void*, const void*)
,  void*          lftBound
,  int            (*rgtRlt) (const void*, const void*)
,  void*          rgtBound
)  ;


#endif


