/* -*- related-file-name: "../../liblcdf/clp.c" -*- */
#ifndef LCDF_CLP_H
#define LCDF_CLP_H
#ifdef __cplusplus
extern "C" {
#endif

/* clp.h - Public interface to CLP.
 * This file is part of CLP, the command line parser package.
 *
 * Copyright (c) 1997-2005 Eddie Kohler, kohler@icir.org
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, subject to the conditions
 * listed in the Click LICENSE file, which is available in full at
 * http://www.pdos.lcs.mit.edu/click/license.html. The conditions include: you
 * must preserve this copyright notice, and you cannot mention the copyright
 * holders in advertising related to the Software without their permission.
 * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
 * notice is a summary of the Click LICENSE file; the license in that file is
 * legally binding. */


/* Argument types */
#define Clp_NoArg		0
#define Clp_ArgString		1
#define Clp_ArgStringNotOption	2
#define Clp_ArgBool		3
#define Clp_ArgInt		4
#define Clp_ArgUnsigned		5
#define Clp_ArgDouble		6

#define Clp_FirstUserType	10

/* Flags for individual Clp_Options */
#define Clp_Mandatory		(1<<0)	/* Has mandatory argument */
#define Clp_Optional		(1<<1)	/* Has optional argument */
#define Clp_Negate		(1<<2)	/* Allow --no-OPT */
#define Clp_OnlyNegated		(1<<3)	/* Allow --no-OPT, but not --OPT */
#define Clp_PreferredMatch	(1<<4)	/* Prefer --OPT to --OPTwhatever */
					/* when matching option prefixes */

struct Clp_Option {
    const char *long_name;	/* e.g. "version" */
    int short_name;		/* e.g. 'v' */
    int option_id;		/* number returned by Clp_Next */
    int arg_type;		/* e.g. Clp_ArgBool */
    int flags;			/* e.g. Clp_Optional | Clp_Negate */
};


/* Sizes of clp->val */
#define Clp_ValSize		40
#define Clp_ValIntSize		10

typedef struct Clp_Option Clp_Option;
typedef struct Clp_Parser Clp_Parser;
typedef struct Clp_Internal Clp_Internal;
typedef struct Clp_ParserState Clp_ParserState;
typedef struct Clp_Argv Clp_Argv;

typedef int (*Clp_ArgParseFunc)(Clp_Parser *, const char *, int, void *);
typedef void (*Clp_ErrorHandler)(const char *);

struct Clp_Parser {
  
    int negated;
  
    int have_arg;
    const char *arg;
  
    union {
	int i;
	unsigned u;
	double d;
	const char *s;
	void *pv;
#ifdef HAVE_INT64_TYPES
	int64_t i64;
	uint64_t u64;
#endif
	char cs[Clp_ValSize];
	unsigned char ucs[Clp_ValSize];
	int is[Clp_ValIntSize];
	unsigned us[Clp_ValIntSize];
    } val;
  
    Clp_Internal *internal;
  
};


Clp_Parser *	Clp_NewParser(int argc, const char * const *argv,
			      int nopt, Clp_Option *opt);
void		Clp_DeleteParser(Clp_Parser *);

Clp_ErrorHandler Clp_SetErrorHandler(Clp_Parser *, Clp_ErrorHandler);

const char *	Clp_ProgramName(Clp_Parser *);
void		Clp_SetProgramName(Clp_Parser *, const char *);


struct Clp_Argv {
    int argc;
    char **argv;
    char *argv_buf;
};

Clp_Argv *	Clp_NewArgv(const char *args, int len);
void		Clp_DeleteArgv(Clp_Argv *);


/* Option types for Clp_SetOptionChar */
/*		Clp_NotOption		0 */
#define 	Clp_Short		(1<<0)
#define 	Clp_Long		(1<<1)
#define 	Clp_ShortNegated	(1<<2)
#define 	Clp_LongNegated		(1<<3)
#define 	Clp_LongImplicit	(1<<4)

int		Clp_SetOptionChar(Clp_Parser *, int c, int option_type);


/* Argument type flags for Clp_AddType */
#define 	Clp_DisallowOptions	(1<<0)	/* No option-looking args */

int		Clp_AddType
			(Clp_Parser *, int type_id, int flags,
			 Clp_ArgParseFunc func, void *user_data);


/* Flags for Clp_AddStringListType */
#define 	Clp_AllowNumbers	(1<<0)	/* Number args OK */

int		Clp_AddStringListType
			(Clp_Parser *, int type_id, int flags, ...);
int		Clp_AddStringListTypeVec
			(Clp_Parser *, int type_id, int flags,
			 int n, char **str, int *val);


/* Return values from Clp_Next */
#define		Clp_NotOption		0
#define		Clp_Done		-1
#define		Clp_BadOption		-2
#define		Clp_Error		-3

int		Clp_Next(Clp_Parser *);


const char *	Clp_Shift(Clp_Parser *, int allow_dashes);
int		Clp_SetOptionProcessing(Clp_Parser *, int option_processing);

Clp_ParserState *Clp_NewParserState(void);
void		Clp_DeleteParserState(Clp_ParserState *);
void		Clp_SaveParser(Clp_Parser *, Clp_ParserState *);
void		Clp_RestoreParser(Clp_Parser *, Clp_ParserState *);

int		Clp_OptionError(Clp_Parser *, const char *, ...);
int		Clp_CurOptionNameBuf(Clp_Parser *, char *buf, int buflen);
const char *	Clp_CurOptionName(Clp_Parser *); /* uses static memory */

#ifdef __cplusplus
}
#endif
#endif
