#!/bin/sh # # aegis - project change supervisor. # Copyright (C) 2008, 2011, 2012, 2014 Peter Miller # # 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 3 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 . # TEST_SUBJECT="fmtgen, included stuff" # load up standard prelude and test functions . test_funcs cat > blah.def << 'fubar' type t1 = boolean; type t2 = integer; type t3 = (one, two, three); type t4 = real; type t5 = string; type t6 = { y = integer; }; type t7 = time; fubar if test $? -ne 0 ; then no_result; fi cat > test.def << 'fubar' #include x1 = t1; x2 = t2; x3 = t3; x4 = t4; x5 = t5; x6 = t6; x7 = t7; fubar if test $? -ne 0 ; then no_result; fi cat > ok.cc << 'fubar' // // This file is generated by fmtgen. // #include #include #include #include #include #include void test_write(const output::pointer &fp, test_ty *this_thing) { if (!this_thing) return; trace(("test_write(this_thing = %p)\n{\n", this_thing)); assert(((test_ty *)this_thing)->reference_count > 0); trace(("rc = %ld;\n", ((test_ty *)this_thing)->reference_count)); boolean_write(fp, "x1", this_thing->x1, 1); integer_write(fp, "x2", this_thing->x2, 0); t3_write(fp, "x3", this_thing->x3, 1); real_write(fp, "x4", this_thing->x4, 0); string_write(fp, "x5", this_thing->x5); t6_write(fp, "x6", this_thing->x6); time_write(fp, "x7", this_thing->x7, 0); trace(("}\n")); } void test_write_xml(const output::pointer &fp, test_ty *this_thing) { if (!this_thing) return; trace(("test_write_xml(this_thing = %p)\n{\n", this_thing)); assert(((test_ty *)this_thing)->reference_count > 0); trace(("rc = %ld;\n", ((test_ty *)this_thing)->reference_count)); fp->fputs("\n"); boolean_write_xml(fp, "x1", this_thing->x1, 0); integer_write_xml(fp, "x2", this_thing->x2, 0); t3_write_xml(fp, "x3", this_thing->x3, 0); real_write_xml(fp, "x4", this_thing->x4, 0); string_write_xml(fp, "x5", this_thing->x5); t6_write_xml(fp, "x6", this_thing->x6); time_write_xml(fp, "x7", this_thing->x7, 0); fp->fputs("\n"); } #include #include static void * test_alloc(void) { test_ty *this_thing; trace(("test_alloc()\n{\n")); this_thing = (test_ty *)mem_alloc(sizeof(test_ty)); this_thing->reference_count = 1; this_thing->mask = 0; this_thing->errpos = lex_position().get_ref_copy(); this_thing->x1 = (bool)0; this_thing->x2 = (long)0; this_thing->x3 = (t3_ty)0; this_thing->x4 = (double)0; this_thing->x5 = (string_ty *)0; this_thing->x6 = (t6_ty *)0; this_thing->x7 = (time_t)0; trace(("return %p;\n", this_thing)); trace(("}\n")); return this_thing; } test_ty * test_copy(test_ty *this_thing) { trace(("test_copy()\n{\n")); this_thing->reference_count++; trace(("return %p;\n", this_thing)); trace(("}\n")); return this_thing; } test_ty * test_clone(test_ty *this_thing) { if (!this_thing) return 0; trace(("test_clone()\n{\n")); test_ty *result = (test_ty *)test_alloc(); result->x1 = this_thing->x1; result->x2 = this_thing->x2; result->x3 = this_thing->x3; result->x4 = this_thing->x4; result->x5 = str_copy(this_thing->x5); result->x6 = t6_clone(this_thing->x6); result->x7 = this_thing->x7; trace(("return %p;\n", result)); trace(("}\n")); return result; } #ifdef DEBUG void test_trace_real(const char *name, const test_ty *value) { if (name && *name) { trace_printf("%s = ", name); } if (!value) { trace_printf("NULL"); } else { trace_printf("{\n"); trace_bool_real("x1", value->x1); trace_long_real("x2", &value->x2); trace_printf("x3 = %s;\n", t3_ename(value->x3)); trace_double_real("x4", value->x4); trace_string_real("x5", value->x5); t6_trace_real("x6", value->x6); trace_time_real("x7", value->x7); trace_printf("}"); } trace_printf((name && *name) ? ";\n" : ",\n"); } #endif // DEBUG static void test_free(void *that) { test_ty *this_thing; this_thing = (test_ty *)that; if (!this_thing) return; this_thing->reference_count--; assert(this_thing->reference_count >= 0); if (this_thing->reference_count > 0) return; trace(("test_free(this_thing = %p)\n{\n", this_thing)); if (this_thing->errpos) { str_free(this_thing->errpos); this_thing->errpos = 0; } str_free(this_thing->x5); t6_type.free(this_thing->x6); mem_free(this_thing); trace(("}\n")); } static type_table_ty test_table[] = { { "x1", offsetof(test_ty, x1), &boolean_type, test_x1_mask, 0, // redefinition not ok 0, // fast_name }, { "x2", offsetof(test_ty, x2), &integer_type, test_x2_mask, 0, // redefinition not ok 0, // fast_name }, { "x3", offsetof(test_ty, x3), &t3_type, test_x3_mask, 0, // redefinition not ok 0, // fast_name }, { "x4", offsetof(test_ty, x4), &real_type, test_x4_mask, 0, // redefinition not ok 0, // fast_name }, { "x5", offsetof(test_ty, x5), &string_type, test_x5_mask, 0, // redefinition not ok 0, // fast_name }, { "x6", offsetof(test_ty, x6), &t6_type, test_x6_mask, 0, // redefinition not ok 0, // fast_name }, { "x7", offsetof(test_ty, x7), &time_type, test_x7_mask, 0, // redefinition not ok 0, // fast_name }, }; static void * test_parse(void *this_thing, string_ty *name, meta_type **type_pp, unsigned long *mask_p, int *redef_p) { void *addr; trace(("test_parse(this_thing = %p, name = %p, type_pp = %p)\n{\n", this_thing, name, type_pp)); assert(((test_ty *)this_thing)->reference_count > 0); addr = generic_struct_parse ( this_thing, name, type_pp, mask_p, redef_p, test_table, SIZEOF(test_table) ); trace(("return %p;\n}\n", addr)); return addr; } static string_ty * test_fuzzy(string_ty *name) { string_ty *result; trace(("test_fuzzy(name = %p)\n{\n", name)); result = generic_struct_fuzzy ( name, test_table, SIZEOF(test_table) ); trace(("return %p;\n", result)); trace(("}\n")); return result; } static rpt_value::pointer test_convert(void *this_thing) { trace(("test_convert(name = %p)\n{\n", this_thing)); assert(((test_ty *)this_thing)->reference_count > 0); rpt_value::pointer result = generic_struct_convert ( this_thing, test_table, SIZEOF(test_table) ); trace(("return %p;\n", result.get())); trace(("}\n")); return result; } meta_type test_type = { "test", test_alloc, test_free, 0, // enum_parse 0, // list_parse test_parse, test_fuzzy, test_convert, generic_struct_is_set, }; test_ty * test_read_file(const nstring &filename) { return test_read_file(filename.get_ref()); } #include #include test_ty * test_read_file(string_ty *filename) { test_ty *result; trace(("test_read_file(filename = \"%s\")\n{\n", (filename ? filename->str_text : ""))); os_become_must_be_active(); result = (test_ty *)parse(filename, &test_type); trace(("return %p;\n", result)); trace(("}\n")); return result; } void test_write_file(const nstring &filename, test_ty *value, bool comp) { test_write_file(filename.get_ref(), value, comp); } #include #include #include void test_write_file(string_ty *filename, test_ty *value, int needs_compression) { trace(("test_write_file(filename = \"%s\", value = %p)\n{\n", (filename ? filename->str_text : ""), value)); if (filename) os_become_must_be_active(); output::pointer fp; if (needs_compression) { fp = output_file::binary_open(filename); fp = output_filter_gzip::create(fp); } else { fp = output_file::text_open(filename); } fp = output_filter_indent::create(fp); io_comment_emit(fp); test_write(fp, value); type_enum_option_clear(); trace(("}\n")); } void test__rpt_init(void) { trace(("test__rpt_init()\n{\n")); t3__rpt_init(); trace(("}\n")); } fubar if test $? -ne 0 ; then no_result; fi cat > ok.h << 'fubar' // // This file is generated by fmtgen. // #ifndef TEST_H #define TEST_H #include #include #ifndef t3_DEF #define t3_DEF enum t3_ty { t3_one, t3_two, t3_three }; #define t3_max 3 #endif // t3_DEF extern meta_type t3_type; void t3_write(const output::pointer &fp, const char *name, t3_ty value, bool show); void t3_write_xml(const output::pointer &fp, const char *name, t3_ty value, bool show); const char *t3_ename(t3_ty); void t3__rpt_init(void); #include #ifndef t6_DEF #define t6_DEF #define t6_y_mask ((unsigned long)1 << 0) struct t6_ty { long reference_count; unsigned long mask; string_ty *errpos; long y; }; #endif // t6_DEF extern meta_type t6_type; void t6_write(const output::pointer &fp, const char *name, t6_ty *value); void t6_write_xml(const output::pointer &fp, const char *name, t6_ty *value); t6_ty *t6_copy(t6_ty *); t6_ty *t6_clone(t6_ty *); #include #ifndef t6_trace #ifdef DEBUG void t6_trace_real(const char *name, const t6_ty *value); #define t6_trace(x) ((void)(trace_pretest_ && (trace_where_, t6_trace_real(trace_stringize(x), x), 0))) #else #define t6_trace(x) #endif #endif #include #ifndef test_DEF #define test_DEF #define test_x1_mask ((unsigned long)1 << 0) #define test_x2_mask ((unsigned long)1 << 1) #define test_x3_mask ((unsigned long)1 << 2) #define test_x4_mask ((unsigned long)1 << 3) #define test_x5_mask ((unsigned long)0) #define test_x6_mask ((unsigned long)0) #define test_x7_mask ((unsigned long)1 << 4) struct test_ty { long reference_count; unsigned long mask; string_ty *errpos; bool x1; long x2; t3_ty x3; double x4; string_ty *x5; t6_ty *x6; time_t x7; }; #endif // test_DEF extern meta_type test_type; void test_write(const output::pointer &fp, test_ty *value); void test_write_xml(const output::pointer &fp, test_ty *value); test_ty *test_copy(test_ty *); test_ty *test_clone(test_ty *); #ifndef test_trace #ifdef DEBUG void test_trace_real(const char *name, const test_ty *value); #define test_trace(x) ((void)(trace_pretest_ && (trace_where_, test_trace_real(trace_stringize(x), x), 0))) #else #define test_trace(x) #endif #endif /** * The test_write_file function is used to * write test meta data to the named file. * * @param filename * The name of the file to be written. * @param value * The value of the meta-data to be written. * @param comp * true (non-zero) if data should be compressed. * @note * If any errors are encountered, this * function will not return. All errors * will print a fatal error message, and * exit with an exit status of 1. */ void test_write_file(string_ty *filename, test_ty *value, int comp); #include /** * The test_write_file function is used to * write test meta data to the named file. * * @param filnam * The name of the file to be written. * @param value * The value of the meta-data to be written. * @param comp * true if data should be compressed. * @note * If any errors are encountered, this * function will not return. All errors * will print a fatal error message, and * exit with an exit status of 1. */ void test_write_file(const nstring &filnam, test_ty *value, bool comp); /** * The test_read_file function is used to * read test meta data from the named file. * * @param filename * The name of the file to be read. * @returns * a pointer to a dynamically allocated * value read from the file. * @note * If any errors are encountered, this * function will not return. All errors * (including syntax errors) will print a * fatal error message, and exit with an * exit status of 1. */ test_ty *test_read_file(string_ty *filename); /** * The test_read_file function is used to * read test meta data from the named file. * * @param filename * The name of the file to be read. * @returns * a pointer to a dynamically allocated * value read from the file. * @note * If any errors are encountered, this * function will not return. All errors * (including syntax errors) will print a * fatal error message, and exit with an * exit status of 1. */ test_ty *test_read_file(const nstring &filename); void test__rpt_init(void); #endif // TEST_H fubar if test $? -ne 0 ; then no_result; fi # # test the functionality # activity="fmtgen vs include 570" fmtgen -tw=2 test.def -oc test.cc -oi test.h if test $? -ne 0 ; then fail; fi diff ok.cc test.cc if test $? -ne 0 ; then fail; fi diff ok.h test.h if test $? -ne 0 ; then fail; fi # # Only definite negatives are possible. # The functionality exercised by this test appears to work, # no other guarantees are made. # pass # vim: set ts=8 sw=4 et :