desc short_params callback default single_code_line
%type type
%%
/*
* Rules section
*/
all: globals entries usages
| globals usages
;
globals: /* empty */
| globals global
| global
;
global: include
| mandatory
| exit_value
| break_lines
| export_long_options
| no_struct
| global_callback
;
include: INCLUDE LT FILENAME GT
{
my_params->add_include ((string)"<" + $3 + ">");
mylog.write ((string) "adding include file: <" + $3 + ">");
free ($3);
}
| INCLUDE DOUBLEQUOTE FILENAME DOUBLEQUOTE
{
my_params->add_include ((string)"\"" + $3 + "\"");
mylog.write ((string) "adding include file: \"" + $3 + "\"");
free ($3);
}
;
mandatory: MANDATORY C_VAR
{
my_params->add_mandatory ($2);
mylog.write ((string) "adding mandatory: " + $2);
free ($2);
}
;
exit_value: EXIT_VALUE C_VAR
{
my_params->set_exit_value ($2);
mylog.write ((string) "adding exit value: " + $2);
free ($2);
}
| EXIT_VALUE ALNUM
{
my_params->set_exit_value ($2);
mylog.write ((string) "adding exit value: " + $2);
free ($2);
}
;
break_lines: BREAK_LINES ALNUM
{
my_params->set_break_lines ($2);
mylog.write ((string) "breaking lines to a width of: " + $2);
free ($2);
}
;
export_long_options: EXPORT_LONG_OPTIONS
{
my_params->set_export_long_options (true);
mylog.write ((string) "exporting long options struct");
}
;
no_struct: NO_STRUCT
{
my_params->set_no_struct (true);
mylog.write ((string) "do not auto generate a struct / class for parsing results");
}
;
global_callback: callback
{
my_params->set_global_callback ($1);
mylog.write ((string) "setting global callback: " + $1);
}
;
entries: entries entry
| entry
;
entry:
{
param = new Clparam; mylog.write ("reading parameter...");
}
new_entry
{
add_param_to_list ();
}
| gp_include
;
new_entry: param type options
{
param->set_type ($2);
dump_param_type ($2);
}
;
options: /* empty */
| options option
| option
;
option: default
{
param->set_default_value ($1);
mylog.write ((string) " default value: " + $1);
free ($1);
}
| range
| callback
{
param->set_callback ($1);
mylog.write ((string) " callback: " + $1);
}
| descs
| STORE_LONGINDEX
{
param->set_store_longindex (true);
mylog.write ((string) " longindex for this parameter must be stored");
}
| err_msg
| ADD_FLAG
{
param->set_add_flag (true);
mylog.write ((string) " this parameter also gets a flag");
}
| DO_NOT_DOCUMENT
{
param->set_do_not_document (true);
mylog.write ((string) " do not document this parameter");
}
| comment
| code_lines
;
descs: descs desc
| desc
;
err_msg: ERR_MSG OPEN_ROUND_BRACE err_msg_arg CLOSE_ROUND_BRACE
;
err_msg_arg: ALNUM
{
param->set_err_msg ($1);
mylog.write ((string) " conversion error message: " + $1);
free ($1);
}
|
QUOTED
{
param->set_err_msg (string("\"") + $1 + '\"');
mylog.write ((string) " conversion error message: \"" + $1 + '\"');
free ($1);
}
|
ALNUM COLON C_VAR
{
param->set_err_msg ($1);
mylog.write ((string) " conversion error message: " + $1);
param->set_err_msg_conv ($3);
mylog.write ((string) " conversion function for erraneous argument: " + $3);
free ($1);
free ($3);
}
|
QUOTED COLON C_VAR
{
param->set_err_msg (string("\"") + $1 + '\"');
mylog.write ((string) " conversion error message: \"" + $1 + '\"');
param->set_err_msg_conv ($3);
mylog.write ((string) " conversion function for erraneous argument: " + $3);
free ($1);
free ($3);
}
;
comment: COMMENT OPEN_ROUND_BRACE COMMENT_STR CLOSE_ROUND_BRACE
{
param->set_comment ($3);
mylog.write ((string) " comment: " + $3);
free ($3);
}
gp_include: GP_INCLUDE FILENAME
{
mylog.write ((string) "including genparse file" + $2);
free ($2);
}
;
param: short_params
{
param->set_short_reps ($1);
dump_short_reps ($1);
free ($1);
}
| NONE SLASH long_param
{
param->set_longopt_value (longopt_value.get ());
param->set_long_only (true);
}
| short_params SLASH long_param
{
param->set_short_reps ($1);
dump_short_reps ($1);
free ($1);
}
;
short_params: FIRST_STR
| FIRST_STR ASTERISK
{
param->set_short_has_arg (optional_argument);
}
| FIRST_STR EXCLAMATIONMARK
{
param->set_short_has_arg (no_argument);
}
;
long_param: multi_long_option
| multi_long_option mandatory_opt_name
| multi_long_option optional_opt_name
;
mandatory_opt_name: EQUAL C_VAR
{
param->set_opt_name ($2);
free ($2);
}
| EQUAL OPT_NAME
{
param->set_opt_name ($2);
free ($2);
}
;
optional_opt_name: OPEN_SQUARE_BRACE mandatory_opt_name CLOSE_SQUARE_BRACE
{
param->set_opt_name_in_square_braces (true);
}
;
multi_long_option: long_option {}
| long_option ASTERISK
{
param->set_long_has_arg (optional_argument);
}
| long_option EXCLAMATIONMARK
{
param->set_long_has_arg (no_argument);
}
;
long_option: ALNUM
{
param->set_long_rep ($1);
mylog.write ((string) " long representation: " + $1);
free ($1);
}
| C_VAR
{
param->set_long_rep ($1);
mylog.write ((string) " long representation: " + $1);
free ($1);
}
;
type: INT { $$ = int_type; }
| LONG
{
if (my_params->get_use_gnulib ())
$$ = long_type;
else
yyerror ("type long only supported if GNU Portability Library is used "
"(option --gnulib enables it)");
}
| ULONG
{
if (my_params->get_use_gnulib ())
$$ = ulong_type;
else
yyerror ("type ulong only supported if GNU Portability Library is used "
"(option --gnulib enables it)");
}
| INTMAX
{
if (my_params->get_use_gnulib ())
$$ = intmax_type;
else
yyerror ("type intmax_t only supported if GNU Portability Library is used "
"(option --gnulib enables it)");
}
| UINTMAX
{
if (my_params->get_use_gnulib ())
$$ = uintmax_type;
else
yyerror ("type uintmax_t only supported if GNU Portability Library is used "
"(option --gnulib enables it)");
}
| FLOAT { $$ = float_type; }
| DOUBLE
{
if (my_params->get_use_gnulib ())
$$ = double_type;
else
yyerror ("type double only supported if GNU Portability Library is used "
"(option --gnulib enables it)");
}
| STRING { $$ = string_type; }
| CHAR { $$ = char_type; }
| FLAG { $$ = flag_type; }
;
default: ALNUM
| CHAR_VAL
| OPEN_BRACE QUOTED CLOSE_BRACE { $$ = $2; }
;
range: OPEN_SQUARE_BRACE contiguous_range CLOSE_SQUARE_BRACE
;
contiguous_range: ALNUM range_spec more_range
{
param->set_low_range ($1);
mylog.write ((string)" parameter range: " + $1 + "..");
free ($1);
}
| range_spec more_range
;
/* both are needed because of lexing ambiguity */
more_range: ALNUM
{
param->set_high_range ($1);
mylog.write ((string)" parameter range: .." + $1);
free ($1);
}
| C_VAR
{
param->set_high_range ($1);
mylog.write ((string)" parameter range: .." + $1);
free ($1);
}
|
;
range_spec: RANGE_SPEC1
| RANGE_SPEC2
;
callback: FUNCTION FUNC_SPEC { $$ = $1; }
;
desc: QUOTED
{
param->add_description ($1, false);
mylog.write ((string) " description: " + $1);
free ($1);
}
| FIRST_QUOTED
{
param->add_description ($1, true);
mylog.write ((string) " description starting in 1st column: " + $1);
free ($1);
}
;
usages: /* empty */
| usages usage
| usage
;
usage: USAGE_LINE
{
my_params->append_usage_line ($1);
mylog.write ((string)" usage string:" + $1);
free ($1);
}
;
code_lines: code_lines code_line
| code_line
;
code_line: single_code_line CODE_END
{
param->add_code_line ($1);
mylog.write ((string)" code string:" + $1);
free ($1);
}
| CODE_END
{
param->add_code_line ("");
mylog.write ((string)" code string:");
}
;
single_code_line: CODE_LINE
{
}
| OPEN_ROUND_BRACE
{
$$ = strdup ((string ("(")).c_str ());
}
| CLOSE_ROUND_BRACE
{
$$ = strdup ((string (")")).c_str ());
}
| single_code_line single_code_line
{
$$ = strdup ((string ($1) + $2).c_str ());
free ($1);
free ($2);
}
;
%%
int yyerror (char *s)
{
cerr << s << " in " << yyfilename << ": " << yylineno << endl;
return 1;
}
void dump_short_reps (char *s)
{
mylog.write (LOG_OPTION_NO_CR, " short representation: ");
mylog.write (LOG_OPTION_NO_TS, s);
}
void add_param_to_list ()
{
mylog.write ("done reading parameter...adding to list");
my_params->add (*param);
delete param;
}
void dump_param_type (param_type p)
{
mylog.write (LOG_OPTION_NO_CR, " parameter type: ");
switch (p)
{
case int_type:
mylog.write (LOG_OPTION_NO_TS, "int");
break;
case long_type:
mylog.write (LOG_OPTION_NO_TS, "long int");
break;
case ulong_type:
mylog.write (LOG_OPTION_NO_TS, "unsigned long int");
break;
case intmax_type:
mylog.write (LOG_OPTION_NO_TS, "intmax_t");
break;
case uintmax_type:
mylog.write (LOG_OPTION_NO_TS, "uintmax_t");
break;
case float_type:
mylog.write (LOG_OPTION_NO_TS, "float");
break;
case double_type:
mylog.write (LOG_OPTION_NO_TS, "double");
break;
case string_type:
mylog.write (LOG_OPTION_NO_TS, "string");
break;
case char_type:
mylog.write (LOG_OPTION_NO_TS, "char");
break;
case flag_type:
mylog.write (LOG_OPTION_NO_TS, "flag");
break;
default:
break;
}
}
genparse-0.9.1/src/clparam_list_factory.cc 0000644 0000766 0000144 00000003206 11716257231 015555 0000000 0000000 /** @file clparam_list_factory.cc
\brief Methods for the command line parameter list factory class */
/*
* Copyright (C) 2006 - 2012
* Michael Geng
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "clparam_list_factory.h"
#include "c_clparam_list.h"
#include "cpp_clparam_list.h"
#include "java_clparam_list.h"
/** Creates the Clparam_list sub class using new which is able to generate language code
@param language must be "c" or "C" in order to generate C code, "c++" or "cpp" or "cc" or "cxx"
in order to generate C++ code and "java" or "Java" in order to generate Java code.
*/
Clparam_list *Clparam_list_factory::Create_Clparam_list (const string &language) const throw (EH)
{
if (language == "c" || language == "C")
return new C_Clparam_list;
else if (language == "c++" || language == "cpp" || language == "cc" || language == "cxx")
return new CPP_Clparam_list;
else if (language == "java" || language == "Java")
return new Java_Clparam_list;
else
throw EH ("invalid parameter " + language);
}
genparse-0.9.1/src/genparse_util.cc 0000644 0000766 0000144 00000004112 11716257231 014212 0000000 0000000 /** @file genparse_util.cc
\brief Utilities used within the genparse project */
/*
* Copyright (C) 2000, 2006 - 2012
* Michael S. Borella and
* Michael Geng
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include "genparse_util.h"
namespace genparse_util
{
/** Convert a string to upper case */
string str2upper (string s)
{
/* toupper is ambiguous, so use a cast in order to choose the right one */
transform (s.begin (), s.end (), s.begin (), (int (*)(int))toupper);
return s;
}
/** Given a string, return it in C comment form in a new string */
string C_comment (string s)
{
return "/* " + s + " */";
}
/** combine directory and filename to a complete path. */
string full_path (const string directory, const string filename)
{
if (directory.length () > 0)
{
return (directory + '/' + filename);
}
else
{
return (filename);
}
}
/** Converts '-' to '_' */
char minus_to_underscore (const char c)
{
if (c == '-')
return '_';
else
return c;
}
/** Convert a string to C style. Converts every '-' to '_' and prepend and underscore ('_') to
every single digit name */
string str2C (string s)
{
if (s.length () == 1)
{
if (isdigit (s[0]))
return ('_' + s);
}
else
transform (s.begin (), s.end (), s.begin (), (int (*)(int))minus_to_underscore);
return s;
}
}
genparse-0.9.1/src/systime.cc 0000644 0000766 0000144 00000007775 11716257231 013070 0000000 0000000 /** @file systime.cc
\brief Methods for the system time class */
/*
* Copyright (C) 2000, 2006 - 2012
* Michael S. Borella and
* Michael Geng
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include "systime.h"
#define TIMESTR_LEN 64
//---------------------------------------------------------------------------
//
// Systime::Systime ()
//
// Constructor method. Call the function that does the work.
//
//---------------------------------------------------------------------------
Systime::Systime ()
{
refresh ();
}
//---------------------------------------------------------------------------
//
// Systime::operator=()
//
// Assignment operator overload
//
//---------------------------------------------------------------------------
Systime& Systime::operator=(const Systime& rhs)
{
// guard against self-assignment
if (this != &rhs)
{
_tv = rhs._tv;
_tp = localtime ((time_t *) &_tv.tv_sec);
}
return *this;
}
//---------------------------------------------------------------------------
//
// Systime::operator-()
//
// Assignment operator overload
//
//---------------------------------------------------------------------------
Systime Systime::operator-(const Systime st)
{
Systime temp;
temp._tv.tv_sec = _tv.tv_sec - st._tv.tv_sec;
temp._tv.tv_usec = _tv.tv_usec - st._tv.tv_usec;
temp._tp = localtime ((time_t *) &_tv.tv_sec);
return temp;
}
//---------------------------------------------------------------------------
//
// Systime::refresh ()
//
// Update the time. Read the clock again.
//
//---------------------------------------------------------------------------
void Systime::refresh () throw (EH_system)
{
// Get the time from the system clock
if (gettimeofday (&_tv, (struct timezone *) 0) == -1)
{
EH_system e ("can't get system time");
throw e;
}
// Convert them, assign to our structures
_tp = localtime ((time_t *) &_tv.tv_sec);
}
//---------------------------------------------------------------------------
//
// Systime::hms ()
//
// Return HH:MM:SS
//
//---------------------------------------------------------------------------
string Systime::hms ()
{
char timestr[TIMESTR_LEN];
strftime (timestr, TIMESTR_LEN, "%T", _tp);
string s = timestr;
return s;
}
//---------------------------------------------------------------------------
//
// Systime::month ()
//
// Return the month in a string
//
//---------------------------------------------------------------------------
string Systime::month ()
{
char timestr[TIMESTR_LEN];
strftime (timestr, TIMESTR_LEN, "%B", _tp);
string s = timestr;
return s;
}
//---------------------------------------------------------------------------
//
// Systime::day ()
//
// Return the day (e.g., "monday") in a string
//
//---------------------------------------------------------------------------
string Systime::day ()
{
char timestr[TIMESTR_LEN];
strftime (timestr, TIMESTR_LEN, "%A", _tp);
string s = timestr;
return s;
}
//---------------------------------------------------------------------------
//
// Systime::unix_ctime ()
//
// Return time in UNIX ctime () format
//
//---------------------------------------------------------------------------
string Systime::unix_ctime ()
{
time_t tmp;
string s;
// Convert the time
tmp = mktime (_tp);
s = ctime (&tmp);
return s;
}
genparse-0.9.1/src/lexer.ll 0000644 0000766 0000144 00000027207 11347173775 012536 0000000 0000000 /*
* $Id: lexer.ll,v 1.24 2010/03/14 14:51:17 mgeng Exp $
*
* Copyright (C) 2000, 2006, 2007, 2008
* Michael S. Borella and
* Michael Geng
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
%option yylineno
%option noyywrap
%{
/*
* Definitions section
*/
#include
#include
#include "clparam.h"
#include "parser.h"
#include "genparse.h"
/*
* Help with debugging
*/
#ifdef DEBUG
#define return_token(x) { fprintf (stderr,"LEX: Token %s: '%s'\n",#x,yytext); return x; }
#else
#define return_token(x) { return (x); }
#endif
#define MAX_INCLUDE_DEPTH 10
YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
int include_stack_ptr = 0;
int old_start_condition;
int brace_level;
%}
/*
* More definitions
*/
range1 ".."
range2 "..."
char [A-Za-z]
first_str ^[A-Za-z0-9]+
digit [0-9]
alnum [\-a-zA-Z_0-9]+(\.[0-9]+)?
c_var [a-zA-Z_][a-zA-Z_0-9]*
file [a-zA-Z_][a-zA-Z_0-9/\-]*[\.a-zA-Z_0-9/\-]*
opt_name [a-zA-Z_0-9|{}]+
whitespace [ \t\n]
doublequote [\"]
any .
empty_line ^\n
any_line .*
code_line [^()\n]*
comment_str [^()\n]*
func_spec "()"
space [ \t]
%x usage include include_doublequote gp_include comment __code__
%s before_type after_type
%%
{whitespace}* ; /* do nothing on whitespace */
"/*" { /* Ignore C comments */
int c1 = 0;
int c2 = yyinput ();
for (;;)
{
if (c2 == EOF) break;
if (c1 == '*' && c2 == '/') break;
c1 = c2;
c2 = yyinput ();
}
}
"NONE" {
BEGIN (before_type);
return_token (NONE);
}
{first_str} {
BEGIN (before_type);
yylval.str = strdup (yytext);
return_token (FIRST_STR);
}
"{" return_token (OPEN_BRACE);
"}" return_token (CLOSE_BRACE);
"[" return_token (OPEN_SQUARE_BRACE);
"]" return_token (CLOSE_SQUARE_BRACE);
"(" return_token (OPEN_ROUND_BRACE);
")" return_token (CLOSE_ROUND_BRACE);
"/" return_token (SLASH);
"int" {
BEGIN (after_type);
return_token (INT);
}
"long" {
BEGIN (after_type);
return_token (LONG);
}
"ulong" {
BEGIN (after_type);
return_token (ULONG);
}
"intmax" {
BEGIN (after_type);
return_token (INTMAX);
}
"uintmax" {
BEGIN (after_type);
return_token (UINTMAX);
}
"float" {
BEGIN (after_type);
return_token (FLOAT);
}
"double" {
BEGIN (after_type);
return_token (DOUBLE);
}
"char" {
BEGIN (after_type);
return_token (CHAR);
}
"string" {
BEGIN (after_type);
return_token (STRING);
}
"flag" {
BEGIN (after_type);
return_token (FLAG);
}
"#include" {
old_start_condition = YY_START;
BEGIN (include);
return_token (INCLUDE);
}
"<" return_token (LT);
">" return_token (GT);
{doublequote} return_token (DOUBLEQUOTE);
"<" return_token (LT);
">" {
BEGIN (old_start_condition);
return_token (GT);
}
{doublequote} {
BEGIN (include_doublequote);
return_token (DOUBLEQUOTE);
}
{doublequote} {
BEGIN (old_start_condition);
return_token (DOUBLEQUOTE);
}
"=" return_token (EQUAL);
"*" return_token (ASTERISK);
"!" return_token (EXCLAMATIONMARK);
"," return_token (COLON);
"#mandatory" return_token (MANDATORY);
"#exit_value" return_token (EXIT_VALUE);
"#break_lines" return_token (BREAK_LINES);
"#export_long_options" return_token (EXPORT_LONG_OPTIONS);
"#no_struct" return_token (NO_STRUCT);
"__ERR_MSG__" return_token (ERR_MSG);
"__DO_NOT_DOCUMENT__" return_token (DO_NOT_DOCUMENT);
"__ADD_FLAG__" return_token (ADD_FLAG);
"__COMMENT__" {
old_start_condition = YY_START;
BEGIN (comment);
return_token (COMMENT);
}
"(" return_token (OPEN_ROUND_BRACE);
")" {
BEGIN (old_start_condition);
return_token (CLOSE_ROUND_BRACE);
}
{comment_str} {
yylval.str = strdup (yytext);
return_token (COMMENT_STR);
}
"__STORE_LONGINDEX__" return_token (STORE_LONGINDEX);
"#usage_begin" BEGIN (usage);
"#usage_end" BEGIN (0);
"__CODE__" {
old_start_condition = YY_START;
brace_level = 0;
BEGIN (__code__);
}
<__code__>"(" {
brace_level++;
if (brace_level > 1)
return (OPEN_ROUND_BRACE);
}
<__code__>")" {
brace_level--;
if (brace_level < 0)
throw EH ("unexpected ) at " + string(yytext));
if (brace_level > 0)
{
return (CLOSE_ROUND_BRACE);
}
else
{
BEGIN (old_start_condition);
return (CODE_END);
}
}
<__code__>{code_line} {
if (brace_level <= 0)
throw EH ("missing opening ( at " + string(yytext));
yylval.str = strdup (yytext);
return_token (CODE_LINE);
}
<__code__>\n {
return_token (CODE_END);
}
{c_var} {
yylval.str = strdup (yytext);
return_token (C_VAR);
}
{func_spec} return_token (FUNC_SPEC);
{c_var}/{space}*{func_spec} {
yylval.str = strdup (yytext);
return_token (FUNCTION);
}
{file} {
yylval.str = strdup (yytext);
return_token (FILENAME);
}
{opt_name} {
yylval.str = strdup (yytext);
return_token (OPT_NAME);
}
{alnum} {
yylval.str = strdup (yytext);
return_token (ALNUM);
}
{range1} return_token (RANGE_SPEC1);
{range2} return_token (RANGE_SPEC2);
^"\""[^\"]*"\"" {
yylval.str = strdup (yytext+1);
yylval.str[strlen (yylval.str)-1]='\0';
return_token (FIRST_QUOTED);
}
"\""[^\"]*"\"" {
yylval.str = strdup (yytext+1);
yylval.str[strlen (yylval.str)-1]='\0';
return_token (QUOTED);
}
"\'"[^\'\n]*"\'" {
yylval.str = strdup (yytext);
return_token (CHAR_VAL);
}
{any} { /* error */
fprintf (stderr,"parser error in line %d ('%s') \n",yylineno,yytext);
exit (1);
}
{any_line} {
yylval.str = strdup (yytext);
return_token (USAGE_LINE);
}
{empty_line} {
yylval.str = strdup ("");
return_token (USAGE_LINE);
}
<*>.|\n /* Don't print unmatched characters in start conditions */
"#gp_include" {
old_start_condition = YY_START;
BEGIN (gp_include);
return_token (GP_INCLUDE);
}
{whitespace}*; /* do nothing on whitespace */
{file} { /* include file name */
if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
throw EH ("gp_includes nested too deeply");
include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
yyin = fopen (yytext, "r");
if (!yyin)
throw EH ("failed to open gp_include file " + string(yytext));
yy_switch_to_buffer (yy_create_buffer (yyin, YY_BUF_SIZE));
BEGIN (old_start_condition);
yylval.str = strdup (yytext);
return_token (FILENAME);
}
<> {
if (--include_stack_ptr < 0)
{
yyterminate ();
}
else
{
yy_delete_buffer (YY_CURRENT_BUFFER);
yy_switch_to_buffer (include_stack[include_stack_ptr]);
}
}
%%
genparse-0.9.1/src/clparam.h 0000644 0000766 0000144 00000013657 11716257231 012650 0000000 0000000 /** @file clparam.h
\brief Class definition for a single command line parameter */
/*
* Copyright (C) 2000, 2006 - 2012
* Michael S. Borella and
* Michael Geng
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef CLPARAM_H
#define CLPARAM_H
#include
#include
#include "cldesc.h"
#include "logfile.h"
// valid types of parameters
enum param_type
{
null_type = 0, int_type, long_type, ulong_type, intmax_type, uintmax_type,
float_type, double_type, char_type, string_type, flag_type
};
enum has_arg_type
{
no_argument = 0, required_argument, optional_argument, argument_undefined
};
/** \brief Contains information for 1 command line parameter. */
class Clparam
{
private:
string _short_reps; // single letter representation
string _long_rep; // string representation
string _opt_name; // e.g. SIZE in --block-size=SIZE, only used on help screen
bool _opt_name_in_square_braces; // e.g. in --block*[=SIZE]
param_type _type;
string _default_value;
string _low_range;
string _high_range;
string _callback;
string _err_msg;
string _err_msg_conv;
string _comment;
list _descriptions;
list _code_lines;
int _longopt_value;
bool _long_only;
bool _store_longindex;
bool _do_not_document;
bool _add_flag;
has_arg_type _short_has_arg;
has_arg_type _long_has_arg;
public:
// Constructor, destructor and copy constructor
Clparam ();
~Clparam () {}
Clparam& operator=(const Clparam &);
// functions to set the values
void set_short_reps (const string &s) { _short_reps = s; }
void set_long_rep (const string &s) { _long_rep = s; }
void set_opt_name (const string &s) { _opt_name = s; }
void set_opt_name_in_square_braces (bool b) { _opt_name_in_square_braces = b; }
void set_type (param_type t) { _type = t; }
void set_default_value (const string &s) { _default_value = s; }
void set_low_range (const string &s) { _low_range = s; }
void set_high_range (const string &s) { _high_range = s; }
void set_callback (const string &s) { _callback = s; }
void set_err_msg (const string &s) { _err_msg = s; }
void set_err_msg_conv (const string &s) { _err_msg_conv = s; }
void set_comment (const string &s) { _comment = s; }
void add_description (const string &description, bool start_1st_col = false);
void set_longopt_value (int i) { _longopt_value = i; }
void set_long_only (bool b) { _long_only = b; }
void set_store_longindex (bool b) { _store_longindex = b; }
void set_do_not_document (bool b) { _do_not_document = b; }
void set_add_flag (bool b) { _add_flag = b; }
void set_short_has_arg (has_arg_type x) { _short_has_arg = x; }
void set_long_has_arg (has_arg_type x) { _long_has_arg = x; }
void add_code_line (const string & s) { _code_lines.push_back (s); }
// functions to retrieve the values
bool requires_additional_flag_arg (void) const;
char get_short_rep (unsigned int i) const;
const string get_short_reps (void) const { return _short_reps; }
unsigned int get_num_short_reps (void) const { return _short_reps.length (); }
bool contains (char c) const;
const string &get_long_rep (void) const { return _long_rep; }
const string &get_opt_name (void) const { return _opt_name; }
bool get_opt_name_in_square_braces (void) const { return _opt_name_in_square_braces; }
param_type get_type (void) const { return _type; }
const string &get_default_value (void) const { return _default_value; }
const string &get_low_range (void) const { return _low_range; }
const string &get_high_range (void) const { return _high_range; }
const string &get_callback (void) const { return _callback; }
const string &get_err_msg (void) const { return _err_msg; }
const string &get_err_msg_conv (void) const { return _err_msg_conv; }
const string &get_comment (void) const { return _comment; }
int get_longopt_value (void) const { return _longopt_value; }
bool get_long_only (void) const { return _long_only; }
bool get_store_longindex (void) const { return _store_longindex; }
bool get_do_not_document (void) const { return _do_not_document; }
bool get_add_flag (void) const { return _add_flag; }
has_arg_type get_short_has_arg (void) const { return _short_has_arg; }
has_arg_type get_long_has_arg (void) const { return _long_has_arg; }
list get_description (unsigned int indentation,
unsigned int additional_indentation_following_lines, int break_lines) const;
const list &get_code_lines (void) const { return _code_lines; }
void normalize_code_lines_indentation (void);
bool has_callback (void) const { return !_callback.empty (); }
void logdump (Logfile&) const;
};
#endif // CLPARAM_H
genparse-0.9.1/src/genparse.cc 0000644 0000766 0000144 00000013512 11716257231 013161 0000000 0000000 /** @file genparse.cc
\brief main () function of the command-line parser generator */
/*
* Copyright (C) 2000, 2006 - 2012
* Michael S. Borella and
* Michael Geng
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include
#include "genparse.h"
#include "logfile.h"
#include "clparam_list.h"
#include "clparam_list_factory.h"
#include "parse_cl.h"
#include "unique_int.h"
// Characters are 0-255, so this the first safe value
const int FIRST_LONGOPT_VALUE = 256;
char *yyfilename;
extern FILE *yyin;
extern int yyparse ();
extern int yydebug;
// This is the cat's pajamas - the main object
Clparam_list *my_params = NULL;
// Declare the logfile object globally so that we can access if from
// everywhere
Logfile mylog;
// The object that will give us longopt numbers
Unique_Int longopt_value (FIRST_LONGOPT_VALUE);
/*---------------------------------------------------------------------------
*
* add_extra_params ()
*
* Add -h, -v
*-------------------------------------------------------------------------*/
void add_extra_params (void)
{
Clparam *p;
// if any of the extra parameters are not already set, add them now
// start with help
mylog.write ("Adding -h / --help parameter");
if (!my_params->contains ("help"))
{
p = new Clparam ();
if (!my_params->contains ('h'))
p->set_short_reps (string ("h"));
else
p->set_long_only (true);
p->set_long_rep ("help");
p->set_type (flag_type);
p->add_description ("Display this help and exit.");
my_params->add (*p);
delete p;
}
// version
mylog.write ("Adding -v / --version parameter");
if (!my_params->contains ("version"))
{
p = new Clparam ();
if (!my_params->contains ('v'))
p->set_short_reps (string ("v"));
else
p->set_long_only (true);
p->set_long_rep ("version");
p->set_type (flag_type);
p->add_description ("Output version information and exit.");
my_params->add (*p);
delete p;
}
}
/*---------------------------------------------------------------------------
*
* main ()
*
*-------------------------------------------------------------------------*/
int main (int argc, char *argv[])
{
// Parse my command line parameters
// Here's the lowdown:
// d = debug (logging) flag
// f = filename of log file
// o = filename of output file
Cmdline cl (argc, argv);
// if the user just wants help or the version, do that now then quit
if (cl.v ())
{
cout << PACKAGE << " v" << VERSION << endl;
exit (0);
}
if (cl.h ())
cl.usage (0);
Clparam_list_factory factory;
my_params = factory.Create_Clparam_list (cl.l ());
// set quiet mode if specified
if (cl.q ())
my_params->set_quiet ();
// for debugging purposes, it is useful to traverse the list and make sure
// it really has everything that we gave it
my_params->logdump (mylog);
// set the parsing function / class
my_params->set_parsefunc (cl.p ());
// set the directory for output files
my_params->set_directory (cl.D ());
// set the c++ extension
my_params->set_cppext (cl.c ());
// set longmembers flag (use of long member names in parser class)
my_params->set_longmembers (cl.m ());
// set internationalization flag (put internationalization macro _() arount help text)
my_params->set_internationalization (cl.i ());
// set --static-headers flag (don't add creation date, user name, kernel version etc.)
my_params->set_static_headers (cl.s ());
// set flag if Gnu Portability Library (Gnulib) shall be used
my_params->set_use_gnulib (cl.g ());
/** set flag specifying if every command line parameter shall be output in a separate print
command */
my_params->set_many_prints (cl.P ());
// make sure that we've got a file to parse
if (cl.next_param () >= argc)
throw EH ("Must include a genparse file on the command line.");
// Start the log file if debugging mode is turned on
if (cl.d ())
{
mylog.open (cl.f ());
yydebug= 1;
}
// Open the .gp file for parsing in C style so that the yacc code works
FILE *fp = fopen (argv[cl.next_param ()], "r");
if (fp == NULL)
throw EH ("can't open input genparse file: " + (string) argv[cl.next_param ()]);
yyin = fp;
mylog.write ("opened input file: " + (string) argv[cl.next_param ()]);
// set the filename and run the parser on the .gp file
yyfilename = argv[cl.next_param ()];
if (yyparse ())
exit (1);
// add --help and --version params if not already defined
add_extra_params ();
// required after parsing
my_params->post_parser_adjust ();
if (!my_params->has_usage ())
{
/* No usage function defined in the Genparse file => set default */
my_params->append_usage_line ("usage: __PROGRAM_NAME__ __OPTIONS_SHORT__ __MANDATORIES__");
my_params->append_usage_line ("__GLOSSARY__");
}
// if we got here, it parsed successfully, now we clean up a little
fclose (fp);
mylog.write ("done reading input file");
mylog.write_separator ();
// Now we write the output files
my_params->output (cl.o ());
// Close the log file before we leave
mylog.close ();
// quit, and do it nicely!
exit (0);
}
genparse-0.9.1/src/java_clparam_list.h 0000644 0000766 0000144 00000004660 11716257231 014676 0000000 0000000 /** @file java_clparam_list.h
\brief C++ implementation of the command line parser */
/*
* Copyright (C) 2006 - 2012
* Michael Geng
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef JAVA_CLPARAM_LIST_H
#define JAVA_CLPARAM_LIST_H
#include
#include "clparam_list.h"
/**
\brief Java implementation of class Clparam_list
Generates Java output files for parsing a command line.
3 Files can be generated:
- a Java source file with the class definition
- a Java source file containing the parser class implementation
- a Java source file containing callback functions
*/
class Java_Clparam_list: public Clparam_list
{
private:
void output_print_command (ofstream& o, const string &text) const;
void check_parameters (void) const;
void output_comments_object (ofstream& o, string classname, string comment,
string objectname) const;
const string string_type_str (void) const { return "String"; }
const string boolean_type_str (void) const { return "boolean"; }
/** get the class name of the interface for the parser class */
const string get_interface_name (void) const { return get_parsefunc () + "Interface"; }
/** get the class name of the exception class thrown by the parser class */
const string get_exception_class_name (void) const { return get_parsefunc () + "Ex"; }
// output Java code
void output_exception_class ( void) const throw (EH);
void output_interface ( string filename_without_extension) const throw (EH);
void output_implementation (string filename_without_extension) const throw (EH);
void output_callbacks ( string filename_without_extension) const throw (EH);
public:
Java_Clparam_list () { set_exit_value ("-1"); }
~Java_Clparam_list () {}
void set_use_gnulib (bool b) throw (EH);
};
#endif // JAVA_CLPARAM_LIST_H
genparse-0.9.1/src/Makefile.am 0000644 0000766 0000144 00000001250 10733746160 013100 0000000 0000000 AM_CXXFLAGS = -Wall
YACC = bison -y -d
bin_PROGRAMS = genparse
dist-hook: genparse
genparse_SOURCES = getopt.cc getopt.h eh.cc eh.h eh_system.cc eh_system.h systime.cc systime.h \
userinfo.cc userinfo.h sysinfo.cc sysinfo.h logfile.cc logfile.h unique_int.cc unique_int.h \
clparam.cc clparam.h clparam_list.cc clparam_list.h parse_cl.cc parse_cl.h genparse.cc \
genparse.h parser.yy parser.h lexer.ll c_clparam_list.cc c_clparam_list.h cpp_clparam_list.cc \
cpp_clparam_list.h clparam_list_factory.h clparam_list_factory.cc genparse_util.cc \
genparse_util.h java_clparam_list.h java_clparam_list.cc cldesc.cc cldesc.h
genparse_LDADD =
CLEANFILES = genparse.log *~
genparse-0.9.1/src/clparam_list.h 0000644 0000766 0000144 00000017565 11716257231 013705 0000000 0000000 /** @file clparam_list.h
\brief Definition of the class which generates the command line parser */
/*
* Copyright (C) 2000, 2006 - 2012
* Michael S. Borella and
* Michael Geng
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef CLPARAM_LIST_H
#define CLPARAM_LIST_H
#include
#include
#include
#include "clparam.h"
#include "eh.h"
/** \brief Gererates the source files which form the command line parser. */
class Clparam_list
{
private:
list _params;
string _global_callback;
list _include_list;
list _mandatory_list;
string _parsefunc;
string _directory;
string _cppext;
string _exit_value;
bool _quiet;
bool _longmembers;
bool _internationalization;
bool _static_headers;
bool _export_long_options;
bool _use_gnulib;
bool _many_prints;
bool _no_struct;
int _break_lines;
list _usage_list;
bool parameters_have_callbacks (void) const;
bool long_only (void) const;
string get_options_string (void) const;
list get_glossary (void) const;
list get_glossary_gnu (unsigned int indentation = 24) const;
string get_mandatories_string (void) const;
/** Check if the combination of parameters fit together */
virtual void check_parameters (void) const {};
// Language specific methods which must be defined in sub classes in order to let output () work
virtual void output_interface ( const string filename_without_extension) const throw (EH) {}
virtual void output_implementation (const string filename_without_extension) const throw (EH) {}
virtual void output_callbacks ( const string filename_without_extension) const throw (EH) {}
protected:
bool have_callbacks (void) const;
const string type2str (const param_type t) const;
bool contains (const Clparam &p) const;
const list &get_params (void) const;
/** get name of global callback function */
const string &get_global_callback (void) const { return _global_callback; }
string const get_parameter_name (const Clparam ¶m) const;
virtual const string string_type_str (void) const { return "char *"; }
virtual const string boolean_type_str (void) const { return "bool"; }
string::size_type parse_macro (string::size_type &arg_start_pos, string::size_type &arg_end_pos,
string::size_type &closing_bracket_pos, const string ¯o, const string &line) const;
list get_usage (void) const;
// These are for any language
void output_comments_header (ofstream& o, const string &filename, const string &purpose) const;
void output_function_comment (ofstream& o, const string &function_name,
const string &comment) const;
void output_includes (ofstream& o) const;
public:
// Constructor, destructor and copy constructor
Clparam_list ();
virtual ~Clparam_list () {}
Clparam_list& operator= (const Clparam_list &);
void add (const Clparam &p) throw (EH);
/** Add an include file */
void add_include (const string &s) { _include_list.push_back (s); }
/** Add a mandatory */
void add_mandatory (const string &s) { _mandatory_list.push_back (s); }
/** Set name of global callback function */
void set_global_callback (const string &s) { _global_callback = s; }
/** set the parsing function / class name */
void set_parsefunc (const string s) { _parsefunc = s; }
/** set the directory for output files */
void set_directory (const string s) { _directory = s; }
/** get the parsing function / class name */
const string &get_parsefunc (void) const { return _parsefunc; }
/** get the directory for output files */
const string &get_directory (void) const { return _directory; }
/** set the c++ extension */
void set_cppext (const string s) { _cppext = s; }
/** set the exit value for the case of a failure exit */
void set_exit_value (const string s) { _exit_value = s; }
/** get the c++ extension */
const string &get_cppext (void) const { return _cppext; }
/** get the exit value for the case of a failure exit */
const string &get_exit_value (void) const { return _exit_value; }
/** set longmembers flag (use of long member names in parser class) */
void set_longmembers (bool b) { _longmembers = b; }
/** get longmembers flag (use of long member names in parser class) */
bool get_longmembers (void) const { return _longmembers; }
/** set internationalization flag (put internationalization macro _() arount help text) */
void set_internationalization (bool b) { _internationalization = b; }
/** get internationalization flag (put internationalization macro _() arount help text) */
bool get_internationalization (void) const { return _internationalization; }
/** set --static-headers flag (don't add creation date, user name, kernel version etc.) */
void set_static_headers (bool b) { _static_headers = b; }
/** get --static-headers flag (don't add creation date, user name, kernel version etc.) */
bool get_static_headers (void) const { return _static_headers; }
/** Set width of help scren. Longer lines will be broken. -1 means: don't break lines
automatically. */
void set_break_lines (const char *width) { _break_lines = atoi (width); }
/** get width of help scren. */
int get_break_lines (void) const { return _break_lines; }
/** add a function get_long_options () which exports the long_options array used by getopt_long */
void set_export_long_options (bool b) { _export_long_options = b; }
/** get flag for adding a function get_long_options () which exports the long_options array
used by getopt_long */
bool get_export_long_options (void) const { return _export_long_options; }
/** set flag if Gnu Portability Library (Gnulib) shall be used */
virtual void set_use_gnulib (bool b) { _use_gnulib = b; }
/** get flag if Gnu Portability Library (Gnulib) shall be used */
bool get_use_gnulib (void) const { return _use_gnulib; }
/** set flag which specifies if every command line parameter shall be output in a separate print
command */
virtual void set_many_prints (bool b) { _many_prints = b; }
/** get flag which specifies if every command line parameter shall be output in a separate print
command */
bool get_many_prints (void) const { return _many_prints; }
/** get flag which specifies if no struct / class for parsing results shall be generated */
bool get_no_struct (void) const { return _no_struct; }
/** set flag which specifies if no struct / class for parsing results shall be generated */
void set_no_struct (bool b) { _no_struct = b; }
/** set quiet mode */
void set_quiet (void) { _quiet = true; }
/** get quiet mode */
bool get_quiet (void) const { return _quiet; }
/** Appends a line to the explanation of the usage of the generated program */
void append_usage_line (string s) { _usage_list.push_back (s); }
/** Return true is a usage text is defined */
bool has_usage (void) const { return !_usage_list.empty (); }
bool contains (const char c) const;
bool contains (const string s) const;
void logdump (Logfile&) const;
void post_parser_adjust (void);
void output (const string filename_without_extension) const;
};
#endif // CLPARAM_LIST_H
genparse-0.9.1/src/c_clparam_list.cc 0000644 0000766 0000144 00000106743 11716257231 014342 0000000 0000000 /** @file c_clparam_list.cc
\brief Methods for the C implementation of the command line parser */
/*
* Copyright (C) 2000, 2006 - 2012
* Michael S. Borella and
* Michael Geng
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include
#include "c_clparam_list.h"
#include "sysinfo.h"
#include "systime.h"
#include "userinfo.h"
#include "genparse_util.h"
using genparse_util::full_path;
using genparse_util::str2C;
/** Helper function for output_usage (). Output one print command. Uses the "print" command
if there are arguments (args not empty), "puts" otherwise. */
void C_Clparam_list::output_print_command (
/** open stream where to print */
ofstream& o,
/** body of the message */
const string &text,
/** list of arguments with colons between them, e.g. ", x, y" */
const string &args) const
{
string usage_string;
usage_string = "\"\\\n";
o << " ";
/* puts () always prints trailing newline "\n", so it can only be used if the string which
has to be printed ends with a newline. */
if (args.empty () && (text.length () >= 2) && (text.substr (text.length () - 2, 2) == "\\n"))
{
o << "puts";
/* Do not print the trailing "\n" if the command is puts. */
usage_string += text.substr (0, text.length () - 2);
}
else
{
o << "printf";
usage_string += text;
}
usage_string += '\"';
o << " (";
if (get_internationalization ())
o << add_i18n_macro (usage_string);
else
o << usage_string;
o << args << ");" << endl;
}
/** Output the usage function */
void C_Clparam_list::output_usage (ofstream& o) const
{
list::const_iterator iter;
ostringstream usage_stream, arg_stream;
// comments
output_function_comment (o, "usage", "Print out usage information, then exit");
// declaration
o << endl;
o << "void usage (int status, char *program_name)" << endl;
o << "{" << endl;
o << " if (status != EXIT_SUCCESS)" << endl;
o << " fprintf (stderr, ";
string s ("\"Try `%s --help' for more information.\\n\"");
if (get_internationalization ())
o << add_i18n_macro (s);
else
o << s;
o << ',' << endl;
o << " program_name);" << endl;
o << " else" << endl;
o << " {" << endl;
list usage_list = get_usage ();
for (iter = usage_list.begin (); iter != usage_list.end (); iter++)
{
string::size_type macro_pos, arg_start_pos, arg_end_pos, closing_bracket_pos;
bool line_manipulated;
string line = *iter;
do
{
if ((macro_pos = line.find (string ("__PROGRAM_NAME__"))) != string::npos)
{
line.replace (macro_pos, 16, string ("%s"));
arg_stream << ", program_name";
}
else if ((macro_pos = parse_macro (arg_start_pos, arg_end_pos, closing_bracket_pos,
"__STRING__", line)) != string::npos)
{
arg_stream << ", " << string (line, arg_start_pos, arg_end_pos - arg_start_pos + 1);
line.replace (macro_pos, closing_bracket_pos - macro_pos + 1, string ("%s"));
}
else if ((macro_pos = parse_macro (arg_start_pos, arg_end_pos, closing_bracket_pos,
"__INT__", line)) != string::npos)
{
arg_stream << ", " << string (line, arg_start_pos, arg_end_pos - arg_start_pos + 1);
line.replace (macro_pos, closing_bracket_pos - macro_pos + 1, string ("%d"));
}
}
while (macro_pos != string::npos);
if (line.find ("__DO_NOT_DOCUMENT__") == string::npos)
{
line_manipulated = false;
do
{
if ((macro_pos = line.find (string ("__NEW_PRINT__"))) != string::npos)
{
if (macro_pos > 0)
{
if (!usage_stream.str ().empty ())
usage_stream << "\\" << endl;
usage_stream << string (line, 0, macro_pos);
usage_stream << "\\n";
}
if (!usage_stream.str ().empty ())
output_print_command (o, usage_stream.str (), arg_stream.str ());
usage_stream.str ("");
arg_stream.str ("");
/* Remove __NEW_PRINT__ and any characters before */
line.erase (0, macro_pos + 13);
line_manipulated = true;
}
else if ((macro_pos = parse_macro (arg_start_pos, arg_end_pos, closing_bracket_pos,
"__CODE__", line)) != string::npos)
{
if (macro_pos > 0)
{
if (!usage_stream.str ().empty ())
usage_stream << "\\" << endl;
usage_stream << string (line, 0, macro_pos);
usage_stream << "\\n";
}
if (!usage_stream.str ().empty ())
output_print_command (o, usage_stream.str (), arg_stream.str ());
o << " "
<< line.substr (arg_start_pos, closing_bracket_pos - arg_start_pos) << endl;
usage_stream.str ("");
arg_stream.str ("");
/* Remove __CODE__() and any characters before */
line.erase (0, closing_bracket_pos + 1);
line_manipulated = true;
}
else if ((macro_pos = parse_macro (arg_start_pos, arg_end_pos, closing_bracket_pos,
"__COMMENT__", line)) != string::npos)
{
if (macro_pos > 0)
{
if (!usage_stream.str ().empty ())
usage_stream << "\\" << endl;
usage_stream << string (line, 0, macro_pos);
usage_stream << "\\n";
}
if (!usage_stream.str ().empty ())
output_print_command (o, usage_stream.str (), arg_stream.str ());
usage_stream.str ("");
arg_stream.str ("");
o << " /* "
<< line.substr (arg_start_pos, closing_bracket_pos - arg_start_pos)
<< " */" << endl;
/* Remove __COMMENT__() and any characters before */
line.erase (0, closing_bracket_pos + 1);
line_manipulated = true;
}
}
while (macro_pos != string::npos);
if (!line_manipulated || !line.empty ())
{
if (!usage_stream.str ().empty ())
usage_stream << "\\" << endl;
usage_stream << line << "\\n";
}
}
}
if (!usage_stream.str ().empty ())
output_print_command (o, usage_stream.str (), arg_stream.str ());
// back matter
o << " }" << endl;
o << " exit (status);" << endl;
o << "}" << endl;
}
/** Output the get_long_options function */
void C_Clparam_list::output_get_long_options (ofstream& o) const
{
// comments
output_function_comment (o, "get_long_options", "Return long_options struct");
o << endl;
o << "struct option const *get_long_options (void)" << endl;
o << "{" << endl;
o << " return long_options;" << endl;
o << "}" << endl;
}
/** Returns true if the parser interface (include file) requires xstrtol.h */
bool C_Clparam_list::interface_requires_xstrtol_h (void) const
{
list params = get_params ();
list::const_iterator iter;
for (iter = params.begin (); iter != params.end (); iter++)
{
if ((iter->get_type () == intmax_type) || (iter->get_type () == uintmax_type))
return true;
}
return false;
}
/** Returns true if the parser implementation (.c file) requires error.h */
bool C_Clparam_list::implementation_requires_error_h (void) const
{
list params = get_params ();
list::const_iterator iter;
for (iter = params.begin (); iter != params.end (); iter++)
{
if ((iter->get_type () == long_type) || (iter->get_type () == ulong_type)
|| (iter->get_type () == intmax_type) || (iter->get_type () == uintmax_type)
|| (iter->get_type () == double_type))
return true;
}
return false;
}
/** Returns true if the parser implementation (.c file) requires xstrtol.h */
bool C_Clparam_list::implementation_requires_xstrtol_h (void) const
{
list params = get_params ();
list::const_iterator iter;
for (iter = params.begin (); iter != params.end (); iter++)
{
if ((iter->get_type () == long_type) || (iter->get_type () == ulong_type)
|| (iter->get_type () == intmax_type) || (iter->get_type () == uintmax_type))
return true;
}
return false;
}
/** Returns true if the parser implementation (.c file) requires xstrtod.h */
bool C_Clparam_list::implementation_requires_xstrtod_h (void) const
{
list params = get_params ();
list::const_iterator iter;
for (iter = params.begin (); iter != params.end (); iter++)
{
if (iter->get_type () == double_type)
return true;
}
return false;
}
/** Returns true if the parser implementation (.c file) requires strtod.h */
bool C_Clparam_list::implementation_requires_strtod_h (void) const
{
return implementation_requires_xstrtod_h ();
}
/** Output the C header file containing the interface of the parser class */
void C_Clparam_list::output_interface (const string filename_without_extension) const throw (EH)
{
// make file .h extension
const string filename = filename_without_extension + ".h";
const string path = full_path (get_directory (), filename);
list params = get_params ();
list::const_iterator iter;
// tell the user what we're doing
if (!get_quiet ())
cout << "creating " << path << "...";
// open the header file
ofstream o;
o.open (path.c_str ());
if (!o)
throw EH ("can't open file: " + path);
// print a nice friendly comment banner at the beginning of the file
output_comments_header (o, filename, "Header file for command line parser");
// print the includes
o << "#include " << endl;
if (interface_requires_xstrtol_h())
o << "#include \"xstrtol.h\"" << endl;
// add include files specified in the genparse (.gp) file
output_includes (o);
// add a bool type for C
o << "#ifndef bool" << endl;
o << "typedef enum bool_t" << endl;
o << "{" << endl;
o << " false = 0, true" << endl;
o << "} bool;" << endl;
o << "#endif" << endl
<< endl;
if (!get_no_struct ())
{
o << "/* customized structure for command line parameters */" << endl;
o << "struct arg_t" << endl;
o << "{" << endl;
for (iter = params.begin (); iter != params.end (); iter++)
{
o << " " << type2str (iter->get_type ()) << ' '
<< get_parameter_name (*iter) << ';' << endl;
if (iter->requires_additional_flag_arg ())
o << " " << type2str (flag_type) << ' '
<< get_parameter_name (*iter) << "_flag;" << endl;
if (iter->get_store_longindex ())
o << " " << type2str (int_type) << ' '
<< get_parameter_name (*iter) << "_li;" << endl;
}
o << " int optind;" << endl;
o << "};" << endl
<< endl;
}
// function prototypes
o << "/* function prototypes */" << endl;
o << "void " << get_parsefunc () << " (";
if (!get_no_struct ())
o << "struct arg_t *my_args, ";
o << "int argc, char *argv[]);" << endl;
o << "void usage (int status, char *program_name);" << endl;
if (get_export_long_options ())
o << "struct option const *get_long_options (void);" << endl;
// more prototypes, for the callbacks, global and local
if (have_callbacks ())
{
list param_callback_list;
o << endl;
o << "/* callback functions */" << endl;
/* global callback function */
if (!get_global_callback ().empty ())
o << "int " << get_global_callback ()
<< " (struct arg_t *);" << endl
<< endl;
/* parameter related callbacks */
for (iter = params.begin (); iter != params.end (); iter++)
{
if (!iter->get_callback ().empty ())
/* Print every callback function only once, no matter how many parameters use it. */
if (find (param_callback_list.begin (), param_callback_list.end (),
iter->get_callback ()) == param_callback_list.end ())
{
o << "int " << iter->get_callback () << " (" << type2str (iter->get_type ())
<< ");" << endl;
param_callback_list.push_back (iter->get_callback ());
}
}
}
if (!o)
throw EH ("can't write to file: " + path);
// close the header file
o.close ();
if (!o)
throw EH ("can't close file: " + path);
// tell the user what we're doing
if (!get_quiet ())
cout << "done" << endl;
}
/** Output the C source file containing the implementation of the parser struct */
void C_Clparam_list::output_implementation (const string filename_without_extension)
const throw (EH)
{
list params = get_params ();
list::const_iterator iter;
// make file .c extension
const string filename = filename_without_extension + ".c";
const string path = full_path (get_directory (), filename);
// tell the user what we're doing
if (!get_quiet ())
cout << "creating " << path << "...";
// open the c file
ofstream o;
o.open (path.c_str ());
if (!o)
throw EH ("can't open file: " + path);
// print a nice friendly comment banner at the beginning of the file
output_comments_header (o, filename, "C file for command line parser");
// print the includes
o << "#include " << endl;
o << "#include " << endl;
o << "#include " << endl;
if (implementation_requires_error_h ())
o << "#include \"error.h\"" << endl;
if (implementation_requires_xstrtol_h ())
o << "#include \"xstrtol.h\"" << endl;
if (implementation_requires_xstrtod_h ())
o << "#include \"xstrtod.h\"" << endl;
if (implementation_requires_strtod_h ())
{
if (get_internationalization ())
o << "#include \"c-strtod.h\"" << endl;
else
o << "#include \"xstrtod.h\"" << endl;
}
o << "#include \"" << filename_without_extension + ".h" << "\"" << endl
<< endl;
// write the options structure
o << "static struct option const long_options[] =" << endl;
o << "{" << endl;
for (iter = params.begin (); iter != params.end (); iter++)
{
if (iter->get_long_rep ().length () > 0)
{
o << " {\"" << iter->get_long_rep () << "\", ";
switch (iter->get_long_has_arg ())
{
case no_argument:
o << "no_argument";
break;
case optional_argument:
o << "optional_argument";
break;
case required_argument:
o << "required_argument";
break;
default:
break;
}
o << ", NULL, ";
if (iter->get_long_only ())
o << iter->get_longopt_value ();
else
o << '\'' << iter->get_short_rep (0) << '\'';
o << "}," << endl;
}
}
o << " {NULL, 0, NULL, 0}" << endl;
o << "};" << endl
<< endl;
// comments
output_function_comment (o, get_parsefunc (),
"Parse the argv array of command line parameters");
// declaration and local vars
o << endl;
o << "void " << get_parsefunc () << " (";
if (!get_no_struct ())
o << "struct arg_t *my_args, ";
o << "int argc, char *argv[])" << endl;
o << "{" << endl;
o << " extern char *optarg;" << endl;
o << " extern int optind;" << endl;
o << " int c;" << endl;
o << " int errflg = 0;" << endl
<< endl;
if (!get_no_struct ())
{
// write initialisations
for (iter = params.begin (); iter != params.end (); iter++)
{
switch (iter->get_type ())
{
case flag_type: // all flags default to off
o << " my_args->" << get_parameter_name (*iter)
<< " = false;" << endl;
break;
case string_type: // copy default if there, NULL otherwise
if (!iter->get_default_value ().empty ())
o << " my_args->" << get_parameter_name (*iter)
<< " = \"" << iter->get_default_value () << "\";" << endl;
else
o << " my_args->" << get_parameter_name (*iter)
<< " = NULL;" << endl;
break;
default: // all else - copy default if there
if (!iter->get_default_value ().empty ())
o << " my_args->" << get_parameter_name (*iter)
<< " = " << iter->get_default_value () << ";" << endl;
}
if (iter->requires_additional_flag_arg ())
o << " my_args->" << get_parameter_name (*iter)
<< "_flag = false;" << endl;
if (iter->get_store_longindex ())
o << " my_args->" << get_parameter_name (*iter)
<< "_li = 0;" << endl;
}
o << endl;
}
// reset global optind variable, otherwise it would not be possible to instantiate the parser
// class multiple times in the same program
o << " optind = 0;" << endl;
// Make the getopt_long () call
o << " while ((c = getopt_long (argc, argv, \"";
for (iter = params.begin (); iter != params.end (); iter++)
{
if (!iter->get_long_only ())
{
o << iter->get_short_reps ();
if (iter->get_short_has_arg () == required_argument)
o << ':';
else if (iter->get_short_has_arg () == optional_argument)
o << "::";
}
}
o << "\", long_options, &optind)) != - 1)" << endl;
// do the switch statement
o << " {" << endl;
o << " switch (c)" << endl;
o << " {" << endl;
for (iter = params.begin (); iter != params.end (); iter++)
{
unsigned int indent_width;
#define INDENT string (indent_width, ' ')
if (iter->get_long_only ())
o << " case " << iter->get_longopt_value () << ":" << endl;
else
{
for (unsigned int i = 0; i < iter->get_num_short_reps ();i++)
o << " case '" << iter->get_short_rep (i) << "':" << endl;
}
indent_width = 10;
if (!get_no_struct ())
{
if (iter->requires_additional_flag_arg ())
{
o << INDENT << "my_args->" << get_parameter_name (*iter)
<< "_flag = true;" << endl;
o << INDENT << "if (optarg != NULL)" << endl;
indent_width += 2;
}
if (get_use_gnulib ()
&& ((iter->get_type () == long_type) || (iter->get_type () == ulong_type)
|| (iter->get_type () == intmax_type) || (iter->get_type () == uintmax_type)
|| (iter->get_type () == double_type)))
{
string err_msg;
o << INDENT << "if (";
switch (iter->get_type ())
{
case long_type:
o << "xstrtol";
break;
case ulong_type:
o << "xstrtoul";
break;
case intmax_type:
o << "xstrtoimax";
break;
case uintmax_type:
o << "xstrtoumax";
break;
case double_type:
o << "! xstrtod";
break;
default:
break;
}
o << " (optarg, NULL";
if (iter->get_type () != double_type)
o << ", 10";
o << ", &my_args->" << get_parameter_name (*iter) << ", ";
if (iter->get_type () == double_type)
if (get_internationalization ())
o << "c_strtod)";
else
o << "strtod)";
else
o << "NULL) != LONGINT_OK";
if (!iter->get_err_msg ().empty ())
{
if (!iter->get_low_range ().empty ())
{
o << endl;
o << INDENT << " || my_args->" << get_parameter_name (*iter)
<< " < " << iter->get_low_range ();
}
if (!iter->get_high_range ().empty ())
{
o << endl;
o << INDENT << " || my_args->" << get_parameter_name (*iter)
<< " > " << iter->get_high_range ();
}
}
o << ')' << endl;
indent_width += 2;
o << INDENT << "error (" << get_exit_value () << ", 0, ";
if (!iter->get_err_msg ().empty ())
err_msg = iter->get_err_msg ();
else
err_msg = string ("\"could not convert %s to " + type2str (iter->get_type ()) + '\"');
if (get_internationalization ())
o << add_i18n_macro (err_msg);
else
o << err_msg;
o << ", ";
if (!iter->get_err_msg_conv ().empty ())
o << iter->get_err_msg_conv () << " (";
o << "optarg";
if (!iter->get_err_msg_conv ().empty ())
o << ')';
o << ");" << endl;
indent_width -= 2;
}
else
{
o << INDENT << "my_args->" << get_parameter_name (*iter);
switch (iter->get_type ())
{
case string_type:
o << " = optarg;" << endl;
break;
case int_type:
o << " = atoi (optarg);" << endl;
break;
case float_type:
o << " = atof (optarg);" << endl;
break;
case char_type:
o << " = *optarg;" << endl;
break;
case flag_type:
o << " = true;" << endl;
if (iter->get_long_rep () == "help")
o << INDENT << "usage (EXIT_SUCCESS, argv[0]);" << endl;
break;
default:
break;
}
}
if (iter->requires_additional_flag_arg ())
indent_width -= 2;
// store longindex (last argument to getopt_long) if requested
if (iter->get_store_longindex ())
{
o << INDENT << "my_args->" << get_parameter_name (*iter)
<< "_li = optind;" << endl;
}
}
// do low range checking
if ((iter->get_err_msg ().empty ()) && (!iter->get_low_range ().empty ()))
{
o << INDENT << "if (my_args->" << get_parameter_name (*iter)
<< " < " << iter->get_low_range () << ")" << endl;
indent_width += 2;
o << INDENT << "{" << endl;
indent_width += 2;
o << INDENT << "fprintf (stderr, ";
string s ("\"parameter range error: " +
get_parameter_name (*iter) + " must be >= " +
iter->get_low_range () + "\\n\"");
if (get_internationalization ())
o << add_i18n_macro (s);
else
o << s;
o << ");" << endl;
o << INDENT << "errflg++;" << endl;
indent_width -= 2;
o << INDENT << "}" << endl;
indent_width -= 2;
}
// do high range checking
if ((iter->get_err_msg ().empty ()) && (!iter->get_high_range ().empty ()))
{
o << INDENT << "if (my_args->" << get_parameter_name (*iter)
<< " > " << iter->get_high_range () << ")" << endl;
indent_width += 2;
o << INDENT << "{" << endl;
indent_width += 2;
o << INDENT << "fprintf (stderr, ";
string s ("\"parameter range error: " +
get_parameter_name (*iter) + " must be <= " +
iter->get_high_range () + "\\n\"");
if (get_internationalization ())
o << add_i18n_macro (s);
else
o << s;
o << ");" << endl;
o << INDENT << "errflg++;" << endl;
indent_width -= 2;
o << INDENT << "}" << endl;
indent_width -= 2;
}
// write user defined code for this parameter
list code_lines = iter->get_code_lines ();
list::const_iterator code_iter;
for (code_iter = code_lines.begin (); code_iter != code_lines.end (); code_iter++)
o << INDENT << *code_iter << endl;
// do callbacks
if (!iter->get_callback ().empty ())
{
o << INDENT << "if (!" << iter->get_callback ()
<< " (my_args->" << str2C (get_parameter_name (*iter))
<< "))" << endl;
indent_width += 2;
o << INDENT << "usage (" << get_exit_value () << ", argv[0]);" << endl;
indent_width -= 2;
}
// do break statement
o << INDENT << "break;" << endl
<< endl;
}
// print default action for unknown parameters
o << " default:" << endl;
o << " usage (" << get_exit_value () << ", argv[0]);" << endl
<< endl;
// print the end of the function, with global callback calls
o << " }" << endl;
o << " } /* while */" << endl
<< endl;
o << " if (errflg)" << endl;
o << " usage (" << get_exit_value () << ", argv[0]);" << endl;
if (!get_global_callback ().empty ())
{
o << endl;
o << " if (!" << get_global_callback () << " (my_args))" << endl;
o << " usage (" << get_exit_value () << ", argv[0]);" << endl;
}
if (!get_no_struct ())
{
o << endl;
o << " if (optind >= argc)" << endl;
o << " my_args->optind = 0;" << endl;
o << " else" << endl;
o << " my_args->optind = optind;" << endl;
}
o << "}" << endl
<< endl;
// dump the usage () function
output_usage (o);
// dump the get_long_options () function
if (get_export_long_options ())
{
o << endl;
output_get_long_options (o);
}
if (!o)
throw EH ("can't write to file: " + path);
// close the C file
o.close ();
if (!o)
throw EH ("can't close file: " + path);
// tell the user what we're doing
if (!get_quiet ())
cout << "done" << endl;
}
/** Output the C source file containing the default implementation of the callback functions */
void C_Clparam_list::output_callbacks (const string filename_without_extension) const throw (EH)
{
list params = get_params ();
list::iterator iter;
// first figure out if we have to do anything at all - no callbacks = no
// callback file
if (have_callbacks ())
{
// make the callback filename
const string filename = filename_without_extension + "_cb.c";
const string path = full_path (get_directory (), filename);
list param_callback_list;
// tell the user what we're doing
if (!get_quiet ())
cout << "creating " << path << "...";
// open the callback file
ofstream o;
o.open (path.c_str ());
if (!o)
throw EH ("can't open file: " + path);
// do the main comments
output_comments_header (o, filename, "Callback routines for command line parser");
// use the header filename for the includes
o << "#include " << endl;
o << "#include \"" << filename_without_extension + ".h" << "\"" << endl
<< endl;
// do the global callbacks first
if (!get_global_callback ().empty ())
{
output_function_comment (o, get_global_callback (), "User defined global callback.");
o << endl;
o << "int " << get_global_callback () << " (struct arg_t *a)" << endl;
o << "{" << endl;
o << " return 1;" << endl;
o << "}" << endl
<< endl;
}
// do the parameter callbacks
for (iter = params.begin (); iter != params.end (); iter++)
if (!iter->get_callback ().empty ())
if (find (param_callback_list.begin (), param_callback_list.end (),
iter->get_callback ()) == param_callback_list.end ())
{
output_function_comment (o, iter->get_callback (),
"User defined parameter callback.");
o << endl;
o << "int " << iter->get_callback () << " ("
<< type2str (iter->get_type ()) << " var)" << endl;
o << "{" << endl;
o << " return 1;" << endl;
o << "}" << endl
<< endl;
param_callback_list.push_back (iter->get_callback ());
}
if (!o)
throw EH ("can't write to file: " + path);
// close the callback file
o.close ();
if (!o)
throw EH ("can't close file: " + path);
// tell the user what we're doing
if (!get_quiet ())
cout << "done" << endl;
}
}
genparse-0.9.1/src/sysinfo.cc 0000644 0000766 0000144 00000003106 11716257231 013045 0000000 0000000 /** @file sysinfo.cc
\brief Methods for the system information class */
/*
* Copyright (C) 2000, 2006 - 2012
* Michael S. Borella and
* Michael Geng
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include
#include
#include "sysinfo.h"
//---------------------------------------------------------------------------
//
// Sysinfo::Sysinfo ()
//
// Constructor method. Does most of the work
//
//---------------------------------------------------------------------------
Sysinfo::Sysinfo () throw (EH_system)
{
struct utsname machine;
// Get the machine-specific info
if (uname (&machine) == -1)
{
EH_system e ("can't get system info");
throw e;
}
// store all of the items locally
_name = machine.sysname;
_release = machine.release;
_build = machine.version;
_hardware = machine.machine;
_domainname = machine.nodename;
}
genparse-0.9.1/src/java_clparam_list.cc 0000644 0000766 0000144 00000057265 11716257231 015045 0000000 0000000 /** @file java_clparam_list.cc
\brief Methods for the Java implementation of the command line parser */
/*
* Copyright (C) 2006 - 2012
* Michael Geng
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include
#include "java_clparam_list.h"
#include "sysinfo.h"
#include "systime.h"
#include "userinfo.h"
#include "genparse_util.h"
using genparse_util::C_comment;
using genparse_util::full_path;
/** Helper function for output_usage (). Output one print command. */
void Java_Clparam_list::output_print_command (
/** open stream where to print */
ofstream& o,
/** Text which must be printed. Must contain starting double quotes '"',
ending double quotes are appended in this function. */
const string &text) const
{
o << " System.out.println (" << endl;
o << text << "\");" << endl;
}
/** set flag if Gnu Portability Library (Gnulib) shall be used */
void Java_Clparam_list::set_use_gnulib (bool b) throw (EH)
{
if (b)
throw EH ("Use of GNU Portability library not supported for Java output");
}
void Java_Clparam_list::check_parameters (void) const
{
if (get_internationalization ())
cerr << "Warning: Internationalization not implemented for Java output" << endl;
}
/** Output a class comment banner */
void Java_Clparam_list::output_comments_object (ofstream& o, string classname, string comment,
string objectname) const
{
o << "/*----------------------------------------------------------------------------" << endl;
o << "**" << endl;
o << "** " << objectname << ' ' << classname << endl;
o << "**" << endl;
o << "** " << comment << endl;
o << "**" << endl;
o << "**--------------------------------------------------------------------------*/" << endl;
}
/** Output a file containing the java exception class thrown by the parser class. */
void Java_Clparam_list::output_exception_class (void) const throw (EH)
{
const string filename = get_exception_class_name () + ".java";
const string path = full_path (get_directory (), filename);
list params = get_params ();
// tell the user what we're doing
if (!get_quiet ())
cout << "creating " << path << "...";
// open the file
ofstream o;
o.open (path.c_str ());
if (!o)
throw EH ("can't open file: " + path);
// print a nice friendly comment banner at the beginning of the file
output_comments_header (o, filename, "Interface of the command line parser class");
// output the definition of the exception class
output_comments_object (o, get_exception_class_name (),
"Exception class thrown by the command line parser class", "class");
o << endl;
o << "public class " << get_parsefunc () << "Ex extends RuntimeException" << endl;
o << '{' << endl;
o << " public " << get_exception_class_name () << " (String text) { super (text); }" << endl;
o << '}' << endl;
if (!o)
throw EH ("can't write to file: " + path);
// close the file
o.close ();
if (!o)
throw EH ("can't close file: " + path);
// tell the user what we're doing
if (!get_quiet ())
cout << "done" << endl;
}
/** Output a file containing the java interface of the parser class + another file containing
the exception class. */
void Java_Clparam_list::output_interface (const string filename_without_extension) const throw (EH)
{
// make file Interface.java
const string filename = filename_without_extension + "Interface.java";
const string path = full_path (get_directory (), filename);
list params = get_params ();
list::const_iterator str_iter;
list::const_iterator iter;
if (get_no_struct ())
throw EH ("#no_struct not yet implemented for C++ output.");
// tell the user what we're doing
if (!get_quiet ())
cout << "creating " << path << "...";
// open the file
ofstream o;
o.open (path.c_str ());
if (!o)
throw EH ("can't open file: " + path);
// print a nice friendly comment banner at the beginning of the file
output_comments_header (o, filename, "Interface of the command line parser class");
// dump the class
output_comments_object (o, get_interface_name (),
"Interface of the command line parser class", "interface");
o << endl;
o << "public interface " << get_interface_name () << endl;
o << "{" << endl;
o << " " << C_comment ("usage function") << endl;
o << " void usage (int status, String program_name);" << endl;
o << endl;
o << " " << C_comment ("return next (non-option) parameter") << endl;
o << " int next_param ();" << endl;
o << endl;
if (have_callbacks ())
{
list param_callback_list;
o << " " << C_comment ("callback functions") << endl;
/* global callbacks */
if (!get_global_callback ().empty ())
o << " boolean " << get_global_callback () << " ();" << endl;
/* parameter related callbacks */
for (iter = params.begin (); iter != params.end (); iter++)
if (!(iter->get_callback ()).empty ())
/* Print every callback function only once, no matter how many parameters use it. */
if (find (param_callback_list.begin (), param_callback_list.end (),
iter->get_callback ()) == param_callback_list.end ())
{
o << " boolean " << iter->get_callback () << " ();" << endl;
param_callback_list.push_back (iter->get_callback ());
}
o << endl;
}
o << " " << C_comment ("getter functions for command line parameters") << endl;
for (iter = params.begin (); iter != params.end (); iter++)
{
o << " " << type2str (iter->get_type ()) << ' ' << get_parameter_name (*iter)
<< " ();" << endl;
if (iter->requires_additional_flag_arg ())
o << " " << type2str (flag_type) << ' ' << get_parameter_name (*iter)
<< "_flag ();" << endl;
if (iter->get_store_longindex ())
o << " " << type2str (int_type) << ' ' << get_parameter_name (*iter)
<< "_li ();" << endl;
}
// closing bracket for class definition
o << "};" << endl;
if (!o)
throw EH ("can't write to file: " + path);
// close the file
o.close ();
if (!o)
throw EH ("can't close file: " + path);
// tell the user what we're doing
if (!get_quiet ())
cout << "done" << endl;
output_exception_class ();
}
/** Output a java source file containing the implementation of the parser class */
void Java_Clparam_list::output_implementation (const string filename_without_extension)
const throw (EH)
{
// make file extension
const string filename = filename_without_extension + ".java";
const string path = full_path (get_directory (), filename);
list params = get_params ();
list::const_iterator str_iter;
list::const_iterator iter;
unsigned int i;
ostringstream usage_stream;
// tell the user what we're doing
if (!get_quiet ())
cout << "creating " << path << "...";
// open the file
ofstream o;
o.open (path.c_str ());
if (!o)
throw EH ("can't open file: " + path);
// print a nice friendly comment banner at the beginning of the file
output_comments_header (o, filename, "Definition of command line parser class");
// imports
o << "import gnu.getopt.LongOpt;" << endl;
o << "import gnu.getopt.Getopt;" << endl;
o << endl;
// comments for parser class
output_function_comment (o, "class " + get_parsefunc (), "Command line parser class.");
o << endl;
// dump the class
o << "public class " << get_parsefunc () << " implements " << get_interface_name () << endl;
o << "{" << endl;
o << " " << C_comment ("parameters") << endl;
for (iter = params.begin (); iter != params.end (); iter++)
{
o << " private " << type2str (iter->get_type ()) << " _"
<< get_parameter_name (*iter);
if (iter->get_type () == string_type)
o << " = \"\"";
o << ";" << endl;
if (iter->requires_additional_flag_arg ())
o << " private " << type2str (flag_type) << " _"
<< get_parameter_name (*iter) << "_flag;" << endl;
if (iter->get_store_longindex ())
o << " private " << type2str (int_type) << " _"
<< get_parameter_name (*iter) << "_li;" << endl;
}
o << endl;
o << " " << C_comment ("Name of the calling program") << endl;
o << " private String _executable;" << endl;
o << endl;
o << " " << C_comment ("next (non-option) parameter") << endl;
o << " private int _optind;" << endl;
o << endl;
// Constructor
o << " " << C_comment ("Must be constructed with parameters.") << endl;
o << " public " << get_parsefunc () << " (String[] argv) throws "
<< get_exception_class_name () << endl;
o << " {" << endl;
o << " " << C_comment ("character returned by optind ()") << endl;
o << " int c;" << endl;
o << endl;
// options structure
o << " LongOpt[] longopts = new LongOpt[" << params.size () << "];" << endl;
int param_no = 0;
for (iter = params.begin (); iter != params.end (); iter++)
{
if (iter->get_long_rep ().length () > 0)
{
o << " longopts[" << param_no << "] = new LongOpt (\"" << iter->get_long_rep ()
<< "\", LongOpt.";
switch (iter->get_long_has_arg ())
{
case no_argument:
o << "NO_ARGUMENT";
break;
case optional_argument:
o << "OPTIONAL_ARGUMENT";
break;
case required_argument:
o << "REQUIRED_ARGUMENT";
break;
default:
break;
}
o << ", null, ";
if (iter->get_long_only ())
o << iter->get_longopt_value ();
else
o << '\'' << iter->get_short_rep (0) << '\'';
o << ");" << endl;
param_no++;
}
}
o << endl;
o << " _executable = " << get_parsefunc () << ".class.getName ();" << endl;
o << endl;
// assign default values
o << " " << C_comment ("default values") << endl;
for (iter = params.begin (); iter != params.end (); iter++)
{
switch (iter->get_type ())
{
case flag_type: // all flags default to off
o << " _" << get_parameter_name (*iter) << " = false;" << endl;
break;
case string_type: // copy default if there, NULL otherwise
if (!iter->get_default_value ().empty ())
o << " _" << get_parameter_name (*iter)
<< " = \"" << iter->get_default_value () << "\";" << endl;
break;
default: // all else - copy default if there
if (!iter->get_default_value ().empty ())
{
o << " _" << get_parameter_name (*iter)
<< " = " << iter->get_default_value ();
if (iter->get_type () == float_type) o << "f";
o << ";" << endl;
}
}
if (iter->requires_additional_flag_arg ())
o << " _" << get_parameter_name (*iter) << "_flag = false;" << endl;
if (iter->get_store_longindex ())
o << " _" << get_parameter_name (*iter) << "_li = 0;" << endl;
}
o << endl;
// Make the Getopt () call
o << " Getopt g = new Getopt (_executable, argv, \"";
for (iter = params.begin (); iter != params.end (); iter++)
{
if (!iter->get_long_only ())
{
o << iter->get_short_reps ();
if (iter->get_short_has_arg () == required_argument)
o << ':';
else if (iter->get_short_has_arg () == optional_argument)
o << "::";
}
}
o << "\", longopts);" << endl;
o << " while ((c = g.getopt ()) != -1)" << endl;
o << " {" << endl;
// do the switch statement
o << " switch (c)" << endl;
o << " {" << endl;
for (iter = params.begin (); iter != params.end (); iter++)
{
unsigned int indent_width;
#define INDENT string (indent_width, ' ')
if (iter->get_long_only ())
o << " case " << iter->get_longopt_value () << ": " << endl;
else
{
for (i = 0; i < iter->get_num_short_reps ();i++)
o << " case '" << iter->get_short_rep (i) << "': " << endl;
}
indent_width = 10;
if (iter->requires_additional_flag_arg ())
{
o << INDENT << '_' << get_parameter_name (*iter) << "_flag = true;" << endl;
o << INDENT << "if (g.getOptarg () != null)" << endl;
indent_width += 2;
}
o << INDENT << '_' << get_parameter_name (*iter);
switch (iter->get_type ())
{
case string_type:
o << " = g.getOptarg ();" << endl;
break;
case int_type:
o << " = Integer.parseInt (g.getOptarg ());" << endl;
break;
case float_type:
o << " = Float.parseFloat (g.getOptarg ());" << endl;
break;
case char_type:
o << " = g.getOptarg ().charAt (0);" << endl;
break;
case flag_type:
o << " = true;" << endl;
if (iter->get_long_rep () == "help")
o << INDENT << "usage (0, _executable);" << endl;
break;
default:
break;
}
if (iter->get_store_longindex ())
o << INDENT << '_' << get_parameter_name (*iter) << "_li = g.getLongind ();" << endl;
// do low range checking
if (!iter->get_low_range ().empty ())
{
o << INDENT << "if (_" << get_parameter_name (*iter)
<< " < " << iter->get_low_range ();
indent_width += 2;
if (iter->get_type () == float_type) o << "f";
o << ")" << endl;
o << INDENT << "throw new " << get_exception_class_name ()
<< " (\"parameter range error: " << get_parameter_name (*iter)
<< " must be >= " << iter->get_low_range ();
if (iter->get_type () == float_type) o << "f";
o << "\");" << endl;
indent_width -= 2;
}
// do high range checking
if (!iter->get_high_range ().empty ())
{
o << INDENT << "if (_" << get_parameter_name (*iter)
<< " > " << iter->get_high_range ();
indent_width += 2;
if (iter->get_type () == float_type) o << "f";
o << ")" << endl;
o << INDENT << "throw new " << get_exception_class_name ()
<< " (\"parameter range error: " << get_parameter_name (*iter)
<< " must be <= " << iter->get_high_range ();
if (iter->get_type () == float_type) o << "f";
o << "\");" << endl;
indent_width -= 2;
}
// write user defined code for this parameter
list code_lines = iter->get_code_lines ();
list::const_iterator code_iter;
for (code_iter = code_lines.begin (); code_iter != code_lines.end (); code_iter++)
o << INDENT << *code_iter << endl;
// do callbacks
if (!iter->get_callback ().empty ())
{
o << INDENT << "if (!" << iter->get_callback () << " ())" << endl;
indent_width += 2;
o << INDENT << "usage (" << get_exit_value () << ", _executable);" << endl;
indent_width -= 2;
}
// do break statement
o << INDENT << "break;" << endl
<< endl;
}
// print default action for unknown parameters
o << " default:" << endl;
o << " usage (" << get_exit_value () << ", _executable);" << endl << endl;
o << " }" << endl;
o << " } /* while */" << endl << endl;
// save a pointer to the next argument
o << " _optind = g.getOptind ();" << endl;
// do global callbacks
if (!get_global_callback ().empty ())
{
o << " if (!" << get_global_callback () << " ())" << endl;
o << " usage (" << get_exit_value () << ", _executable);" << endl << endl;
}
o << " }" << endl;
o << endl;
// usage function
o << " public void " << "usage (int status, String program_name)" << endl;
o << " {" << endl;
o << " if (status != 0)" << endl;
o << " {" << endl;
o << " System.err.println (\"Try `\" + program_name + \" --help' for more information.\");"
<< endl;
o << " }" << endl;
o << " else" << endl;
o << " {" << endl;
list usage_list = get_usage ();
for (str_iter = usage_list.begin (); str_iter != usage_list.end (); str_iter++)
{
string::size_type macro_pos, arg_start_pos, arg_end_pos, closing_bracket_pos;
string macro_argument;
bool line_manipulated;
string line = *str_iter;
do
if ((macro_pos = line.find (string ("__PROGRAM_NAME__"))) != string::npos)
line.replace (macro_pos, 16, string ("\" + program_name + \""));
while (macro_pos != string::npos);
if (line.find ("__DO_NOT_DOCUMENT__") == string::npos)
{
line_manipulated = false;
do
{
if ((macro_pos = line.find (string ("__NEW_PRINT__"))) != string::npos)
{
if (macro_pos > 0)
{
if (!usage_stream.str ().empty ())
usage_stream << "\\n\" +" << endl;
usage_stream << '\"' << string (line, 0, macro_pos);
}
if (usage_stream.str ().length () > 0)
output_print_command (o, usage_stream.str ());
usage_stream.str ("");
/* Remove __NEW_PRINT__ and any characters before */
line.erase (0, macro_pos + 13);
line_manipulated = true;
}
else if ((macro_pos = parse_macro (arg_start_pos, arg_end_pos, closing_bracket_pos,
"__CODE__", line)) != string::npos)
{
if (macro_pos > 0)
{
if (!usage_stream.str ().empty ())
usage_stream << "\\n\" +" << endl;
usage_stream << '\"' << string (line, 0, macro_pos);
}
if (usage_stream.str ().length () > 0)
output_print_command (o, usage_stream.str ());
o << " "
<< line.substr (arg_start_pos, closing_bracket_pos - arg_start_pos) << endl;
usage_stream.str ("");
/* Remove __CODE__() and any characters before */
line.erase (0, closing_bracket_pos + 1);
line_manipulated = true;
}
else if ((macro_pos = parse_macro (arg_start_pos, arg_end_pos, closing_bracket_pos,
"__COMMENT__", line)) != string::npos)
{
if (macro_pos > 0)
{
if (!usage_stream.str ().empty ())
usage_stream << "\\n\" +" << endl;
usage_stream << '\"' << string (line, 0, macro_pos);
}
if (usage_stream.str ().length () > 0)
output_print_command (o, usage_stream.str ());
usage_stream.str ("");
o << " /* "
<< line.substr (arg_start_pos, closing_bracket_pos - arg_start_pos)
<< " */" << endl;
/* Remove __COMMENT__() and any characters before */
line.erase (0, closing_bracket_pos + 1);
line_manipulated = true;
}
}
while (macro_pos != string::npos);
if (!line_manipulated || !line.empty ())
{
if (!usage_stream.str ().empty ())
usage_stream << "\\n\" +" << endl;
usage_stream << '\"' << line;
}
}
}
if (usage_stream.str ().length () > 0)
output_print_command (o, usage_stream.str ());
o << " }" << endl;
o << " System.exit (status);" << endl;
o << " }" << endl;
o << endl;
o << " " << C_comment ("return next (non-option) parameter") << endl;
o << " public int next_param () { return _optind; }" << endl;
o << endl;
if (have_callbacks ())
{
list param_callback_list;
o << " " << C_comment ("Callback functions") << endl;
o << " " << C_comment ("Derive your own class and overwrite any of the callback ") << endl;
o << " " << C_comment ("functions if you need customized callbacks.") << endl;
/* global callbacks */
if (!get_global_callback ().empty ())
o << " public " << boolean_type_str () << ' ' << get_global_callback ()
<< " () { return true; }" << endl;
/* parameter related callbacks */
for (iter = params.begin (); iter != params.end (); iter++)
if (!(iter->get_callback ()).empty ())
if (find (param_callback_list.begin (), param_callback_list.end (),
iter->get_callback ()) == param_callback_list.end ())
{
o << " public " << boolean_type_str () << ' ' << iter->get_callback ()
<< " () { return true; }" << endl;
param_callback_list.push_back (iter->get_callback ());
}
o << endl;
}
o << " " << C_comment ("getter functions for command line parameters") << endl;
for (iter = params.begin (); iter != params.end (); iter++)
{
o << " public " << type2str (iter->get_type ()) << ' '
<< get_parameter_name (*iter) << " () { return _"
<< get_parameter_name (*iter) << "; }" << endl;
if (iter->requires_additional_flag_arg ())
o << " public " << type2str (flag_type) << ' '
<< get_parameter_name (*iter) << "_flag () { return _"
<< get_parameter_name (*iter) << "_flag; }" << endl;
if (iter->get_store_longindex ())
o << " public " << type2str (int_type) << ' '
<< get_parameter_name (*iter) << "_li () { return _"
<< get_parameter_name (*iter) << "_li; }" << endl;
}
// closing bracket for class definition
o << "}" << endl;
if (!o)
throw EH ("can't write to file: " + path);
// close the file
o.close ();
if (!o)
throw EH ("can't close file: " + path);
// tell the user what we're doing
if (!get_quiet ())
cout << "done" << endl;
}
/** Dummy. In Java no separate file is generated for callbacks. Derive your own class from the
command line class instead. */
void Java_Clparam_list::output_callbacks (const string filename_without_extension) const throw (EH)
{
}
genparse-0.9.1/src/clparam_list.cc 0000644 0000766 0000144 00000057231 11716257231 014035 0000000 0000000 /** @file clparam_list.cc
\brief Methods for the command line parameter list class */
/*
* Copyright (C) 2000, 2006 - 2012
* Michael S. Borella and
* Michael Geng
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include
#include
#include
#include
#include "clparam_list.h"
#include "sysinfo.h"
#include "systime.h"
#include "userinfo.h"
#include "genparse_util.h"
/** Constructor */
Clparam_list::Clparam_list ()
{
_cppext = "cc";
_exit_value = "EXIT_FAILURE";
_quiet = false;
_longmembers = false;
_internationalization = false;
_static_headers = false;
_export_long_options = false;
_use_gnulib = false;
_many_prints = false;
_no_struct = false;
_break_lines = - 1;
}
/** Copy constructor */
Clparam_list& Clparam_list::operator=(const Clparam_list &rhs)
{
// guard against self-assignment
if (this != &rhs)
{
_params = rhs._params;
_global_callback = rhs._global_callback;
_include_list = rhs._include_list;
_mandatory_list = rhs._mandatory_list;
_parsefunc = rhs._parsefunc;
_directory = rhs._directory;
_cppext = rhs._cppext;
_exit_value = rhs._exit_value;
_quiet = rhs._quiet;
_longmembers = rhs._longmembers;
_internationalization = rhs._internationalization;
_static_headers = rhs._static_headers;
_break_lines = rhs._break_lines;
_export_long_options = rhs._export_long_options;
_use_gnulib = rhs._use_gnulib;
_many_prints = rhs._many_prints;
_usage_list = rhs._usage_list;
}
return *this;
}
/** Return true if at least 1 parameter has a callback function. */
bool Clparam_list::parameters_have_callbacks (void) const
{
return (find_if (_params.begin (), _params.end (), mem_fun_ref (&Clparam::has_callback))
!= _params.end ());
}
/** Return true if there are any callback functions (global or related to a parameter). */
bool Clparam_list::have_callbacks (void) const
{
return (parameters_have_callbacks () || !_global_callback.empty ());
}
/** Add a parameter to the list, checking for duplicates. */
void Clparam_list::add (const Clparam &p) throw (EH)
{
if (this->contains (p))
{
throw EH ("duplicate parameter");
}
_params.push_back (p);
}
/** Does the list contain this parameter? Yes if either the short or long representation matches. */
bool Clparam_list::contains (const Clparam &p) const
{
list::const_iterator iter;
unsigned int i;
for (iter = _params.begin (); iter != _params.end (); iter++)
{
if (!iter->get_long_only () && (iter->get_short_rep (0) != 0))
for (i = 0; i < p.get_num_short_reps (); i++)
if (iter->contains (p.get_short_rep (i)))
return true;
if ((iter->get_long_rep ().length () > 0) && (iter->get_long_rep () == p.get_long_rep ()))
return true;
}
return false;
}
/** Does the list contain this parameter? Yes if short representation matches. */
bool Clparam_list::contains (const char c) const
{
list::const_iterator iter;
for (iter = _params.begin (); iter != _params.end (); iter++)
if (iter->contains (c))
return true;
return false;
}
/** Does the list contain this parameter? Yes if short representation matches. */
bool Clparam_list::contains (const string s) const
{
list::const_iterator iter;
for (iter = _params.begin (); iter != _params.end (); iter++)
if (iter->get_long_rep () == s)
return true;
return false;
}
/** Dump contents to a log file */
void Clparam_list::logdump (Logfile& l) const
{
// preface
l.write ("dumping parameter list...");
// do the global stuff here
list::const_iterator iter;
for (iter = _include_list.begin (); iter != _include_list.end (); iter++)
l.write (" include file: " + *iter);
for (iter = _mandatory_list.begin (); iter != _mandatory_list.end (); iter++)
l.write (" mandatory: " + *iter);
if (!get_global_callback ().empty ());
l.write (" global_callback: " + get_global_callback ());
// now do the parameters
list::const_iterator iter2;
for (iter2 = _params.begin (); iter2 != _params.end (); iter2++)
iter2->logdump (l);
// afterword
l.write ("finished dumping parameter list");
}
/** Given a parameter type, return that type in a string */
const string Clparam_list::type2str (param_type t) const
{
switch (t)
{
case flag_type:
return boolean_type_str ();
break;
case int_type:
return "int";
break;
case long_type:
return "long int";
break;
case ulong_type:
return "unsigned long int";
break;
case intmax_type:
return "intmax_t";
break;
case uintmax_type:
return "uintmax_t";
break;
case float_type:
return "float";
break;
case double_type:
return "double";
break;
case char_type:
return "char";
break;
case string_type:
return string_type_str ();
default:
throw EH ("unknown parameter type");
}
}
/** Returns true if all parameters have only parameters in the long form. */
bool Clparam_list::long_only (void) const
{
list