AreaCompute computes the area of a shape of a given size. The size is set in the parameter file. The user may choose one of three shapes, a square, circle or equilateral triangle. The area is computed and the result is written to a file. The file path is also set in the parameter file.
All of the parameters may be overridden by command line arguments.
/********************************************************* * parameter definitions for AreaCompute * * Mike Dixon, RAP, NCAR, Boulder, CO, USA, 80307-3000 * * Sept 1998 */ /* * AreaCompute is a small TDRP demonstration program. * * The program allows the user to compute the area of * a geometric shape of a given size. * * The result is printed to a file. */ ////////////////////////////////////////////////////////// paramdef boolean { p_default = FALSE; p_descr = "Option to print debugging messages"; } debug; typedef enum { SQUARE, CIRCLE, EQ_TRIANGLE } shape_t ; paramdef enum shape_t { p_default = SQUARE; p_descr = "Shape type."; p_help = "The program will compute the area of a square," "circle or equilateral triangle."; } shape; paramdef float { p_default = 1.0; p_min = 0.0; p_descr = "Size of the shape."; } size; paramdef string { p_default = "./AreaCompute.out"; p_descr = "The path of the file to which the output is written."; p_help = "The directory which contains this path must exist."; } output_path;
AreaCompute -print_params > file
/********************************************************************** * TDRP params for AreaCompute **********************************************************************/ ///////////// debug /////////////////////////////////// // // Option to print debugging messages. // Type: boolean // debug = FALSE; ///////////// shape /////////////////////////////////// // // Shape type. // The program will compute the area of a square, circle or equilateral // triangle. // // Type: enum // Options: // SQUARE, CIRCLE, EQ_TRIANGLE // // shape = SQUARE; ///////////// size //////////////////////////////////// // // Size of the shape. // Minimum val: 0 // Type: float // size = 1; ///////////// output_path ///////////////////////////// // // The path of the file to which the output is written. // The directory which contains this path must exist. // Type: string // output_path = "./AreaCompute.out";
#include "AreaCompute.hh" // file scope static void tidy_and_exit (int sig); static AreaCompute *Prog; // main int main(int argc, char **argv) { // create program object AreaCompute *Prog; Prog = new AreaCompute(argc, argv); if (!Prog->OK) { return(-1); } // run it int iret = Prog->Run(); // clean up tidy_and_exit(iret); return (iret); } // tidy up on exit static void tidy_and_exit (int sig) { delete(Prog); exit(sig); }
#include#include "Args.hh" #include "Params.hh" class AreaCompute { public: // constructor AreaCompute (int argc, char **argv); // destructor ~AreaCompute(); // run int Run(); // data members int OK; protected: private: char *_progName; char *_paramsPath; Args *_args; Params *_params; double _area; int AreaCompute::_writeResults(); };
#include "AreaCompute.hh" #include#include // Constructor AreaCompute::AreaCompute(int argc, char **argv) { OK = TRUE; // set programe name _progName = strdup("AreaCompute"); // get command line args _args = new Args(argc, argv, _progName); if (!_args->OK) { fprintf(stderr, "ERROR: %s\n", _progName); fprintf(stderr, "Problem with command line args\n"); OK = FALSE; return; } // get TDRP params _params = new Params(); _paramsPath = "unknown"; if (_params->loadFromArgs(argc, argv, _args->override.list, &_paramsPath)) { fprintf(stderr, "ERROR: %s\n", _progName); fprintf(stderr, "Problem with TDRP parameters\n"); OK = FALSE; return; } return; } // destructor AreaCompute::~AreaCompute() { // free up delete(_params); delete(_args); free(_progName); } ////////////////////////////////////////////////// // Run int AreaCompute::Run() { // compute area switch (_params->shape) { case SQUARE: _area = _params->size * _params->size; break; case CIRCLE: _area = _params->size * _params->size * (3.14159 / 4.0); break; case EQ_TRIANGLE: _area = _params->size * _params->size * (0.866 / 2.0); break; } // switch // debug message if (_params->debug) { fprintf(stderr, "Size is: %g\n", _params->size); switch (_params->shape) { case SQUARE: fprintf(stderr, "Shape is SQUARE\n"); break; case CIRCLE: fprintf(stderr, "Shape is CIRCLE\n"); break; case EQ_TRIANGLE: fprintf(stderr, "Shape is EQ_TRIANGLE\n"); break; } /* switch */ fprintf(stderr, "Area is: %g\n", _area); } // write out the result _writeResults(); return (0); } ////////////////////////////////////////////////// // writeResults int AreaCompute::_writeResults() { FILE *out; if ((out = fopen(_params->output_path, "w")) == NULL) { perror(_params->output_path); return (-1); } fprintf(out, "Size is: %g\n", _params->size); switch (_params->shape) { case SQUARE: fprintf(out, "Shape is SQUARE\n"); break; case CIRCLE: fprintf(out, "Shape is CIRCLE\n"); break; case EQ_TRIANGLE: fprintf(out, "Shape is EQ_TRIANGLE\n"); break; } /* switch */ fprintf(out, "Area is: %g\n", _area); fclose(out); return (0); }
#include#include class Args { public: // constructor Args (int argc, char **argv, char *prog_name); // Destructor ~Args(); // public data int OK; tdrp_override_t override; protected: private: void _usage(char *prog_name, FILE *out); };
#include "Args.hh" #include// Constructor Args::Args (int argc, char **argv, char *prog_name) { char tmp_str[BUFSIZ]; // intialize OK = TRUE; TDRP_init_override(&override); // loop through args for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "-h")) { _usage(prog_name, stdout); exit(0); } else if (!strcmp(argv[i], "-debug")) { sprintf(tmp_str, "debug = TRUE;"); TDRP_add_override(&override, tmp_str); } else if (!strcmp(argv[i], "-size")) { if (i < argc - 1) { sprintf(tmp_str, "size = %s;", argv[++i]); TDRP_add_override(&override, tmp_str); } else { OK = FALSE; } } else if (!strcmp(argv[i], "-shape")) { if (i < argc - 1) { sprintf(tmp_str, "shape = %s;", argv[++i]); TDRP_add_override(&override, tmp_str); } else { OK = FALSE; } } else if (!strcmp(argv[i], "-output")) { if (i < argc - 1) { sprintf(tmp_str, "output_path = %s;", argv[++i]); TDRP_add_override(&override, tmp_str); } else { OK = FALSE; } } // if } // i if (!OK) { _usage(prog_name, stderr); } } // Destructor Args::~Args () { TDRP_free_override(&override); } void Args::_usage(char *prog_name, FILE *out) { fprintf(out, "%s%s%s%s", "Usage: ", prog_name, " [options as below]\n", " [ -h] produce this list.\n" " [ -debug ] print debug messages\n" " [ -output ?] set output_path\n" " [ -size ?] set shape size\n" " [ -shape ?] set shape type\n" " options are SQUARE, CIRCLE and EQ_TRIANGLE\n"); TDRP_usage(out); }
PROGNAME = AreaCompute CPPC = g++ RM = /bin/rm -f INCLUDES = -I../include CFLAGS = -g LDFLAGS = -L.. -ltdrp SRCS = \ Params.cc \ AreaCompute.cc \ Args.cc \ Main.cc OBJS = $(SRCS:.cc=.o) # link $(PROGNAME): $(OBJS) $(CPPC) -o $(PROGNAME) $(OBJS) $(LDFLAGS) # tdrp Params.cc: paramdef.$(PROGNAME) tdrp_gen -f paramdef.$(PROGNAME) -c++ -prog $(PROGNAME) clean_tdrp: $(RM) Params.hh Params.cc clean: $(RM) core a.out $(RM) *.i *.o *.ln *~ clean_bin: $(RM) $(PROGNAME) clean_all: clean clean_bin # suffix rules .SUFFIXES: .c .o .cc.o: $(CPPC) -c $(CFLAGS) $(INCLUDES) $<
#include#include // typedefs // Class definition class Params { public: // enum typedefs typedef enum { SQUARE = 0, CIRCLE = 1, EQ_TRIANGLE = 2 } shape_t; // Member functions Params() { _init(); } ~Params() { freeAll(); } int loadFromArgs(int argc, char **argv, char **override_list, char **params_path_p); int load(char *param_file_path, char **override_list, int expand_env, int debug); int loadDefaults(int expand_env); void sync(); void print(FILE *out, tdrp_print_mode_t mode); int checkAllSet(FILE *out); int arrayRealloc(char *param_name, int new_array_n); int array2DRealloc(char *param_name, int new_array_n1, int new_array_n2); void freeAll(void); // Data members char _start_; // start of data region // needed for zeroing out data // and computing offsets tdrp_bool_t debug; shape_t shape; float size; char* output_path; char _end_; // end of data region // needed for zeroing out data private: void _init(); TDRPtable _table[5]; char *_className; };
#include "Params.hh" #include////////////////////////////////////////////////////////////// // loadFromArgs() // // Loads up TDRP using the command line args. // // Check TDRP_usage() for command line actions associated with // this function. // // argc, argv: command line args // // char **override_list: A null-terminated list of overrides // to the parameter file. // An override string has exactly the format of an entry // in the parameter file itself. // // char **params_path_p: if non-NULL, this is set to point to // the path of the params file used. // // Returns 0 on success, -1 on failure. // int Params::loadFromArgs(int argc, char **argv, char **override_list, char **params_path_p) { if (tdrpLoadFromArgs(argc, argv, _table, &_start_, override_list, params_path_p)) { return (-1); } else { return (0); } } ////////////////////////////////////////////////////////////// // load() // // Loads up TDRP for a given class. // // This version of load gives the programmer the option to load // up more than one class for a single application. It is a // lower-level routine than loadFromArgs, // and hence more flexible, but the programmer must do more work. // // char *param_file_path: the parameter file to be read in. // // char **override_list: A null-terminated list of overrides // to the parameter file. // An override string has exactly the format of an entry // in the parameter file itself. // // expand_env: flag to control environment variable // expansion during tokenization. // If TRUE, environment expansion is set on. // If FALSE, environment expansion is set off. // // Returns 0 on success, -1 on failure. // int Params::load(char *param_file_path, char **override_list, int expand_env, int debug) { if (tdrpLoad(param_file_path, _table, &_start_, override_list, expand_env, debug)) { return (-1); } else { return (0); } } ////////////////////////////////////////////////////////////// // loadDefaults() // // Loads up default params for a given class. // // See load() for more detailed info. // // Returns 0 on success, -1 on failure. // int Params::loadDefaults(int expand_env) { if (tdrpLoad(NULL, _table, &_start_, NULL, expand_env, FALSE)) { return (-1); } else { return (0); } } ////////////////////////////////////////////////////////////// // sync() // // Syncs the user struct data back into the parameter table, // in preparation for printing. // void Params::sync(void) { tdrpUser2Table(_table, &_start_); } ////////////////////////////////////////////////////////////// // print() // // Print params file // // The modes supported are: // // PRINT_SHORT: main comments only, no help or descriptions // structs and arrays on a single line // PRINT_NORM: short + descriptions and help // PRINT_LONG: norm + arrays and structs expanded // PRINT_VERBOSE: long + private params included // void Params::print(FILE *out, tdrp_print_mode_t mode) { tdrpPrint(out, _table, _className, mode); } ////////////////////////////////////////////////////////////// // checkAllSet() // // Return TRUE if all set, FALSE if not. // // If out is non-NULL, prints out warning messages for those // parameters which are not set. // int Params::checkAllSet(FILE *out) { return (tdrpCheckAllSet(out, _table, &_start_)); } ////////////////////////////////////////////////////////////// // freeAll() // // Frees up all TDRP dynamic memory. // void Params::freeAll(void) { tdrpFreeAll(_table, &_start_); } ////////////////////////////////////////////////////////////// // arrayRealloc() // // Realloc 1D array. // // If size is increased, the values from the last array entry is // copied into the new space. // // Returns 0 on success, -1 on error. // int Params::arrayRealloc(char *param_name, int new_array_n) { if (tdrpArrayRealloc(_table, &_start_, param_name, new_array_n)) { return (-1); } else { return (0); } } ////////////////////////////////////////////////////////////// // array2DRealloc() // // Realloc 2D array. // // If size is increased, the values from the last array entry is // copied into the new space. // // Returns 0 on success, -1 on error. // int Params::array2DRealloc(char *param_name, int new_array_n1, int new_array_n2) { if (tdrpArray2DRealloc(_table, &_start_, param_name, new_array_n1, new_array_n2)) { return (-1); } else { return (0); } } ////////////////////////////////////////////////////////////// // _init() // // Class table initialization function. // // void Params::_init() { TDRPtable *tt = _table; // zero out table memset(_table, 0, sizeof(_table)); // zero out members memset(&_start_, 0, &_end_ - &_start_); _className = "Params"; // Parameter 'debug' // ctype is 'tdrp_bool_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = BOOL_TYPE; tt->param_name = tdrpStrDup("debug"); tt->descr = tdrpStrDup("Option to print debugging messages"); tt->help = tdrpStrDup(""); tt->val_offset = (char *) &debug - &_start_; tt->single_val.b = pFALSE; tt++; // Parameter 'shape' // ctype is '_shape_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = ENUM_TYPE; tt->param_name = tdrpStrDup("shape"); tt->descr = tdrpStrDup("Shape type."); tt->help = tdrpStrDup("The program will compute the area of a square, circle or equilateral triangle."); tt->val_offset = (char *) &shape - &_start_; tt->enum_def.name = tdrpStrDup("shape_t"); tt->enum_def.nfields = 3; tt->enum_def.fields = (enum_field_t *) tdrpMalloc(tt->enum_def.nfields * sizeof(enum_field_t)); tt->enum_def.fields[0].name = tdrpStrDup("SQUARE"); tt->enum_def.fields[0].val = SQUARE; tt->enum_def.fields[1].name = tdrpStrDup("CIRCLE"); tt->enum_def.fields[1].val = CIRCLE; tt->enum_def.fields[2].name = tdrpStrDup("EQ_TRIANGLE"); tt->enum_def.fields[2].val = EQ_TRIANGLE; tt->single_val.e = SQUARE; tt++; // Parameter 'size' // ctype is 'float' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = FLOAT_TYPE; tt->param_name = tdrpStrDup("size"); tt->descr = tdrpStrDup("Size of the shape."); tt->help = tdrpStrDup(""); tt->val_offset = (char *) &size - &_start_; tt->has_min = TRUE; tt->min_val.f = 0; tt->max_val.f = 1e+33; tt->single_val.f = 1; tt++; // Parameter 'output_path' // ctype is 'string' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = STRING_TYPE; tt->param_name = tdrpStrDup("output_path"); tt->descr = tdrpStrDup("The path of the file to which the output is written."); tt->help = tdrpStrDup("The directory which contains this path must exist."); tt->val_offset = (char *) &output_path - &_start_; tt->single_val.s = tdrpStrDup("./AreaCompute.out"); tt++; // trailing entry has param_name set to NULL tt->param_name = NULL; return; }