#!/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 :