area_compute 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 area_compute * * Mike Dixon, RAP, NCAR, Boulder, CO, USA, 80307-3000 * * Sept 1998 */ /* * area_compute 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 = "./area_compute.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;
area_compute -print_params > file
/********************************************************************** * TDRP params for area_compute **********************************************************************/ ///////////// 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 = "./area_compute.out";
#include#include #include "_tdrp.h" /* * function prototypes */ extern void parse_args(int argc, char **argv, char *prog_name, tdrp_override_t *override); extern int write_result(_tdrp_struct *params, double area);
#include "area_compute.h" int main(int argc, char **argv) { /* * basic declarations */ char *prog_name; char *params_file_path = NULL; tdrp_override_t override; _tdrp_struct params; /* parameter struct */ double area; /* * set program name */ prog_name = strrchr(argv[0], '/'); if (prog_name == NULL) { prog_name = argv[0]; } /* * initialize the override list */ TDRP_init_override(&override); /* * parse command line arguments */ parse_args(argc, argv, prog_name, &override); /* * load up parameters */ if (_tdrp_load_from_args(argc, argv, ¶ms, override.list, ¶ms_file_path)) { fprintf(stderr, "ERROR - %s:main\n", prog_name); if (params_file_path) { fprintf(stderr, "Problems with params file '%s'\n", params_file_path); } exit(-1); } /* * free up override list */ TDRP_free_override(&override); /* * 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 */ write_result(¶ms, area); /* * Free up */ _tdrp_free_all(); return(0); }
#include "area_compute.h" static void 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); } void parse_args(int argc, char **argv, char *prog_name, tdrp_override_t *override) { int error_flag = 0; int i; char tmp_str[BUFSIZ]; /* * look for command options */ for (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 { error_flag = TRUE; } } else if (!strcmp(argv[i], "-shape")) { if (i < argc - 1) { sprintf(tmp_str, "shape = %s;", argv[++i]); TDRP_add_override(override, tmp_str); } else { error_flag = TRUE; } } 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 { error_flag = TRUE; } } /* if */ } /* i */ /* * print message if error flag set */ if(error_flag) { usage(prog_name, stderr); exit(-1); } return; }
#include "area_compute.h" int write_result(_tdrp_struct *params, double area) { 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); }
PROGNAME = area_compute CC = gcc RM = /bin/rm -f INCLUDES = -I../include CFLAGS = -g LDFLAGS = -L.. -ltdrp SRCS = \ _tdrp.c \ write_result.c \ parse_args.c \ area_compute.c OBJS = $(SRCS:.c=.o) # link $(PROGNAME): $(OBJS) $(CC) -o $(PROGNAME) $(OBJS) $(LDFLAGS) # tdrp _tdrp.c: paramdef.$(PROGNAME) tdrp_gen -f paramdef.$(PROGNAME) -prog $(PROGNAME) clean_tdrp: $(RM) _tdrp.h _tdrp.c clean: $(RM) core a.out $(RM) *.i *.o *.ln *~ clean_bin: $(RM) $(PROGNAME) clean_all: clean clean_bin clean_tdrp # suffix rules .SUFFIXES: .c .o .c.o: $(CC) -c $(CFLAGS) $(INCLUDES) $<
/******************************************* * _tdrp.h * * TDRP header file. * * Code for program area_compute * * This header file has been automatically * generated by TDRP, do not modify. * *******************************************/ #ifndef __tdrp_h #define __tdrp_h #ifdef __cplusplus extern "C" { #endif #include/* * typedefs */ typedef enum { SQUARE = 0, CIRCLE = 1, EQ_TRIANGLE = 2 } _shape_t; /* * typedef for main struct - _tdrp_struct */ typedef struct { size_t struct_size; /***** debug *****/ tdrp_bool_t debug; /***** shape *****/ _shape_t shape; /***** size *****/ float size; /***** output_path *****/ char* output_path; } _tdrp_struct; /* * function prototypes */ extern int _tdrp_load_from_args(int argc, char **argv, _tdrp_struct *params, char **override_list, char **params_path_p); extern int _tdrp_load(char *param_file_path, _tdrp_struct *params, char **override_list, int expand_env, int debug); extern int _tdrp_load_defaults(_tdrp_struct *params, int expand_env); extern void _tdrp_sync(void); extern void _tdrp_print(FILE *out, tdrp_print_mode_t mode); extern void _tdrp_free_all(void); extern int _tdrp_check_all_set(FILE *out); extern int _tdrp_array_realloc(char *param_name, int new_array_n); extern int _tdrp_array2D_realloc(char *param_name, int new_array_n1, int new_array_n2); extern TDRPtable *_tdrp_table(void); extern TDRPtable *_tdrp_init(_tdrp_struct *params); #ifdef __cplusplus } #endif #endif
/******************************************* * _tdrp.c * * TDRP C code file. * * Code for program area_compute * * This file has been automatically * generated by TDRP, do not modify. * *******************************************/ #include "_tdrp.h" #include/* * file scope variables */ static TDRPtable Table[5]; static _tdrp_struct *Params; static char *Module = ""; /************************************************************* * _tdrp_load_from_args() * * Loads up TDRP using the command line args. * * Check TDRP_usage() for command line actions associated with * this function. * * argc, argv: command line args * * _tdrp_struct *params: loads up this struct * * 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 _tdrp_load_from_args(int argc, char **argv, _tdrp_struct *params, char **override_list, char **params_path_p) { Params = params; _tdrp_init(Params); if (tdrpLoadFromArgs(argc, argv, Table, Params, override_list, params_path_p)) { return (-1); } else { return (0); } } /************************************************************* * _tdrp_load() * * Loads up TDRP for a given module. * * This version of load gives the programmer the option to load * up more than one module for a single application. It is a * lower-level routine than _tdrp_load_from_args, * and hence more flexible, but the programmer must do more work. * * char *param_file_path: the parameter file to be read in. * * _tdrp_struct *params: loads up this struct * * 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 _tdrp_load(char *param_file_path, _tdrp_struct *params, char **override_list, int expand_env, int debug) { Params = params; _tdrp_init(Params); if (tdrpLoad(param_file_path, Table, params, override_list, expand_env, debug)) { return (-1); } else { return (0); } } /************************************************************* * _tdrp_load_defaults() * * Loads up defaults for a given module. * * See _tdrp_load() for more details. * * Returns 0 on success, -1 on failure. */ int _tdrp_load_defaults(_tdrp_struct *params, int expand_env) { Params = params; _tdrp_init(Params); if (tdrpLoad(NULL, Table, params, NULL, expand_env, FALSE)) { return (-1); } else { return (0); } } /************************************************************* * _tdrp_sync() * * Syncs the user struct data back into the parameter table, * in preparation for printing. */ void _tdrp_sync(void) { tdrpUser2Table(Table, Params); } /************************************************************* * _tdrp_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 _tdrp_print(FILE *out, tdrp_print_mode_t mode) { tdrpPrint(out, Table, Module, mode); } /************************************************************* * _tdrp_check_all_set() * * 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 _tdrp_check_all_set(FILE *out) { return (tdrpCheckAllSet(out, Table, Params)); } /************************************************************* * _tdrp_free_all() * * Frees up all TDRP dynamic memory. */ void _tdrp_free_all(void) { tdrpFreeAll(Table, Params); } /************************************************************* * _tdrp_array_realloc() * * 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 _tdrp_array_realloc(char *param_name, int new_array_n) { if (tdrpArrayRealloc(Table, Params, param_name, new_array_n)) { return (-1); } else { return (0); } } /************************************************************* * _tdrp_array2D_realloc() * * 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 _tdrp_array2D_realloc(char *param_name, int new_array_n1, int new_array_n2) { if (tdrpArray2DRealloc(Table, Params, param_name, new_array_n1, new_array_n2)) { return (-1); } else { return (0); } } /************************************************************* * _tdrp_table() * * Returns pointer to static Table for this module. */ TDRPtable *_tdrp_table(void) { return (Table); } /************************************************************* * _tdrp_init() * * Module table initialization function. * * * Returns pointer to static Table for this module. */ TDRPtable *_tdrp_init(_tdrp_struct *params) { TDRPtable *tt = Table; _tdrp_struct pp; /* for computing byte_offsets */ /* zero out struct, and store size */ memset(params, 0, sizeof(_tdrp_struct)); params->struct_size = sizeof(_tdrp_struct); /* 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 *) &(pp.debug) - (char *) &pp; 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 *) &(pp.shape) - (char *) &pp; 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 *) &(pp.size) - (char *) &pp; 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 *) &(pp.output_path) - (char *) &pp; tt->single_val.s = tdrpStrDup("./area_compute.out"); tt++; /* trailing entry has param_name set to NULL */ tt->param_name = NULL; return (Table); }