1#!/bin/sh
2#
3# aegis - project change supervisor.
4# Copyright (C) 2008, 2011, 2012 Peter Miller
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 3 of the License, or (at
9# your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14# General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.
18#
19
20TEST_SUBJECT="fmtgen, time"
21
22# load up standard prelude and test functions
23. test_funcs
24
25#
26# test the functionality
27#
28activity="fmtgen, time, incl"
29cat > test.def << 'fubar'
30fred = time;
31fubar
32test $? -eq 0 || no_result
33
34cat > test.fmtgen.h.ok << 'fubar'
35//
36// This file is generated by fmtgen.
37//
38
39#ifndef TEST_FMTGEN_H
40#define TEST_FMTGEN_H
41#include <common/ac/time.h>
42#include <libaegis/introspector.h>
43#include <libaegis/output.h>
44
45#ifndef test_DEF
46#define test_DEF
47
48/**
49* The test class is used to represent ''test'' formatted Aegis meta-data.
50* See aetest(5) for more information.
51*/
52class test
53{
54public:
55    /**
56    * The pointer typedef is used to have a pointer type which may be used
57    * by clients of this API, allowing the pointer implementation to be
58    * changed without extensive code changes throughout the rest of the
59    * code base.
60    */
61    typedef aegis_shared_ptr<test> pointer;
62
63    /**
64    * The destructor.
65    */
66    virtual ~test();
67
68private:
69    /**
70    * The default constructor. It is private on purpose, use the #create
71    * class method instead.
72    */
73    test();
74
75public:
76    /**
77    * The create class method is used to create new dynamically allocated
78    * instances of this class.
79    */
80    static pointer create();
81
82private:
83    /**
84    * The copy constructor. It is private on purpose, use the #create class
85    * method instead.
86    *
87    * @param rhs
88    *     The right hand side of the initialization.
89    */
90    test(const test &rhs);
91
92public:
93    /**
94    * The create class method is used to create new dynamically allocated
95    * instances of this class.
96    *
97    * @param rhs
98    *     The right hand side of the initialization.
99    */
100    static pointer create(const test &rhs);
101
102    /**
103    * The assignment operator.
104    *
105    * @param rhs
106    *     The right hand side of the assignment.
107    */
108    test &operator=(const test &rhs);
109
110private:
111    /**
112    * The fred instance variable is used to remember the time fred.
113    */
114    time_t fred;
115
116public:
117    /**
118    * The fred_set method is used to set the #fred instance variable, and
119    * remember that it has been set.
120    *
121    * @param n
122    *     The new value.
123    */
124    void fred_set(time_t n);
125
126    /**
127    * The fred_get method is used to obtain the value of the #fred instance
128    * variable, or 0 if it has not been set.
129    */
130    time_t fred_get() const;
131
132    /**
133    * The fred_is_set method is used to determine whether or not the #fred
134    * instance variable is set.
135    */
136    bool fred_is_set() const;
137
138    /**
139    * The fred_clear method is used to clear the value of the #fred
140    * instance variable, and remember that it is no longer set.
141    */
142    void fred_clear();
143
144    /**
145    * The fred_introspector_factory method is used to obtain an
146    * introspector for the #fred instance variable.
147    */
148    introspector::pointer fred_introspector_factory();
149
150public:
151    /**
152    * The introspector_factory method is used to create an introspector for
153    * this class and instance, usually used with the meta-data parser when
154    * reading the contents of a meta-data file.
155    */
156    introspector::pointer introspector_factory();
157
158    /**
159    * The write method is used to write this structure's contents to the
160    * given output.
161    *
162    * @param fp
163    *     Where to write the output.
164    */
165    void write(const output::pointer &fp) const;
166
167    /**
168    * The write_xml method is used to write this structure's contents to
169    * the given output as XML.
170    *
171    * @param fp
172    *     Where to write the output.
173    */
174    void write_xml(const output::pointer &fp) const;
175
176    /**
177    * The trace_print method is used by the trace_test macro to print an
178    * object of this type.
179    *
180    * @param name
181    *     The name of the variable being printed.
182    */
183    void trace_print(const char *name) const;
184
185    /**
186    * The create_from_file class method is used to read the given file to
187    * create a new dynamically allocated instance of this class.
188    *
189    * @param filename
190    *     The name of the file to be read.
191    * @note
192    *     If any errors are encountered, this method will not return. All
193    *     errors will print a fatal error message, and exit with an exit
194    *     status of 1.
195    */
196    static pointer create_from_file(const nstring &filename);
197
198    /**
199    * The write_file method is used to write the data to the named file,
200    * via the #write method.
201    *
202    * @param filename
203    *     The name of the file to be written.
204    * @param compress
205    *     true if data should be compressed, false if not.
206    * @note
207    *     If any errors are encountered, this method will not return. All
208    *     errors will print a fatal error message, and exit with an exit
209    *     status of 1.
210    */
211    void write_file(const nstring &filename, bool compress) const;
212
213    /**
214    * The report_init class method is used to initialize the report
215    * generator with the names and values of enumerations used by this
216    * meta-data.
217    */
218    static void report_init();
219};
220
221/**
222* The test_trace macro is used to conditionally print a trace of a test
223* value, if the DEBUG macro is defined.
224*/
225#include <common/debug.h>
226#ifndef test_trace
227#ifdef DEBUG
228#define test_trace(x) ((void)(trace_pretest_ && (trace_where_, (x).trace_print(trace_stringize(x)), 0)))
229#else
230#define test_trace(x)
231#endif
232#endif
233
234#endif // test_DEF
235
236#endif // TEST_FMTGEN_H
237fubar
238test $? -eq 0 || no_result
239
240fmtgen -ii test.fmtgen.h test.def
241test $? -eq 0 || fail
242
243diff test.fmtgen.h.ok test.fmtgen.h
244test $? -eq 0 || fail
245
246activity="fmtgen, time, code"
247cat > test.fmtgen.cc.ok << 'fubar'
248//
249// This file is generated by fmtgen.
250//
251#include <test.fmtgen.h>
252#include <common/ac/assert.h>
253#include <common/trace.h>
254
255test::~test()
256{
257    trace(("%s\n", __PRETTY_FUNCTION__));
258}
259
260test::test() :
261    fred(0)
262{
263    trace(("%s\n", __PRETTY_FUNCTION__));
264}
265
266test::pointer
267test::create()
268{
269    trace(("%s\n", __PRETTY_FUNCTION__));
270    return pointer(new test());
271}
272
273test::test(const test &rhs) :
274    fred(rhs.fred)
275{
276    trace(("%s\n", __PRETTY_FUNCTION__));
277}
278
279test::pointer
280test::create(const test &rhs)
281{
282    trace(("%s\n", __PRETTY_FUNCTION__));
283    return pointer(new test(rhs));
284}
285
286test &
287test::operator=(const test &rhs)
288{
289    trace(("%s\n", __PRETTY_FUNCTION__));
290    if (this != &rhs)
291    {
292        fred = rhs.fred;
293    }
294    return *this;
295}
296
297time_t
298test::fred_get()
299    const
300{
301    return fred;
302}
303
304bool
305test::fred_is_set()
306    const
307{
308    return (fred != 0);
309}
310
311void
312test::fred_set(time_t x)
313{
314    fred = x;
315}
316
317void
318test::fred_clear()
319{
320    fred = 0;
321}
322#include <libaegis/introspector/time.h>
323
324introspector::pointer
325test::fred_introspector_factory()
326{
327    return introspector_time::create ( introspector_time::adapter_by_method
328        < test > ::create ( this, &test::fred_set, &test::fred_is_set));
329}
330#include <libaegis/introspector/structure.h>
331
332introspector::pointer
333test::introspector_factory()
334{
335    trace(("%s\n", __PRETTY_FUNCTION__));
336    introspector_structure::pointer ip =
337        introspector_structure::create("test");
338    ip->register_member ( "fred", introspector_structure::adapter_by_method
339        < test > ::create ( this, &test::fred_introspector_factory,
340            &test::fred_is_set));
341    return ip;
342};
343
344void
345test::write(const output::pointer &fp)
346    const
347{
348    trace(("%s\n{\n", __PRETTY_FUNCTION__));
349    introspector_time::write(fp, "fred", fred, false);
350    trace(("}\n"));
351}
352
353void
354test::write_xml(const output::pointer &fp)
355    const
356{
357    trace(("%s\n{\n", __PRETTY_FUNCTION__));
358    fp->fputs("<test>\n");
359    introspector_time::write_xml(fp, "fred", fred, false);
360    fp->fputs("</test>\n");
361    trace(("}\n"));
362}
363
364void
365test::trace_print(const char *name_)
366    const
367{
368    if (name_ && *name_)
369    {
370        trace_printf("%s = ", name_);
371    }
372    trace_printf("{\n");
373    trace_time_real("fred", fred_get());
374    trace_printf("}");
375    trace_printf((name_ && *name_) ? ";\n" : ",\n");
376}
377#include <libaegis/meta_context/introspector.h>
378#include <libaegis/os.h>
379
380test::pointer
381test::create_from_file(const nstring &filename)
382{
383    trace(("%s\n{\n", __PRETTY_FUNCTION__));
384    pointer p = create();
385    introspector::pointer ip = p->introspector_factory();
386    meta_context_introspector meta;
387    os_become_must_be_active();
388    meta.parse_file(filename, ip);
389    trace(("}\n"));
390    return p;
391}
392#include <libaegis/io.h>
393#include <libaegis/output/file.h>
394#include <libaegis/output/filter/gzip.h>
395#include <libaegis/output/filter/indent.h>
396
397void
398test::write_file(const nstring &filename, bool needs_compression)
399    const
400{
401    trace(("%s\n{\n", __PRETTY_FUNCTION__));
402    if (filename)
403        os_become_must_be_active();
404    output::pointer fp = (needs_compression ?
405        output_filter_gzip::create(output_file::binary_open(filename)) :
406        output_file::text_open(filename));
407    fp = output_filter_indent::create(fp);
408    io_comment_emit(fp);
409    write(fp);
410    type_enum_option_clear();
411    trace(("}\n"));
412}
413
414void
415test::report_init(void)
416{
417    trace(("%s\n{\n", __PRETTY_FUNCTION__));
418    trace(("}\n"));
419}
420fubar
421test $? -eq 0 || no_result
422
423fmtgen -ic test.fmtgen.cc test.def
424test $? -eq 0 || fail
425
426diff test.fmtgen.cc.ok test.fmtgen.cc
427test $? -eq 0 || fail
428
429#
430# Only definite negatives are possible.
431# The functionality exercised by this test appears to work,
432# no other guarantees are made.
433#
434pass
435
436
437// vim: set ts=8 sw=4 et :
438