From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 474 invoked by alias); 12 Oct 2007 21:18:32 -0000 Received: (qmail 465 invoked by uid 22791); 12 Oct 2007 21:18:30 -0000 X-Spam-Status: No, hits=-1.5 required=5.0 tests=AWL,BAYES_20,DK_POLICY_SIGNSOME,SPF_HELO_PASS,SPF_PASS,TW_DW X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 12 Oct 2007 21:18:23 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.1) with ESMTP id l9CLILhV007288 for ; Fri, 12 Oct 2007 17:18:21 -0400 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [10.11.255.20]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l9CLILNK008759 for ; Fri, 12 Oct 2007 17:18:21 -0400 Received: from [172.16.57.153] (multics.rdu.redhat.com [172.16.57.153]) by pobox.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l9CLIKM2003529 for ; Fri, 12 Oct 2007 17:18:20 -0400 Subject: generating type tests From: Stan Cox To: Frysk List Content-Type: multipart/mixed; boundary="=-OrwhaHDrOBZ3SLcgrGpw" Date: Fri, 12 Oct 2007 21:18:00 -0000 Message-Id: <1192223570.2947.145.camel@multics.rdu.redhat.com> Mime-Version: 1.0 X-Mailer: Evolution 2.10.3 (2.10.3-2.fc7) X-Virus-Checked: Checked by ClamAV on sourceware.org X-IsSubscribed: yes Mailing-List: contact frysk-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: frysk-owner@sourceware.org X-SW-Source: 2007-q4/txt/msg00045.txt.bz2 --=-OrwhaHDrOBZ3SLcgrGpw Content-Type: text/plain Content-Transfer-Encoding: 7bit Content-length: 1299 Here is gen-typetests.py which can be used to generate a C type test program and the associated java tester. When invoked as 'python gen-typetests.py -type' it will generate: funit-type-entry.c and TestTypeEntryType.java. The tests this generates all pass with the patches outlined below. Checking values via 'python gen-typetests.py -value' is in progress. Suggestions are encouraged, including a good way to graft this onto the make machinery. TypeEntry.java: -Add getUnionType -case DwTag.UNION_TYPE_ invoke getUnionType -case DwTag.STRUCTURE_TYPE_ remove classType.setTypedefFIXME -case DwTag.VOLATILE_TYPE_: new -case DwTag.CONST_TYPE_: new ArrayType.java: -Add public void toPrint(String s, PrintWriter writer) This is to support the odd C syntax for pointer to array where the pointer designation is embedded: int (* x) [2]. Using 1.5's String.format would be nicer PointerType.java: -Add public void toPrint(String s, PrintWriter writer) Similar to above to handle pointer to array TypeDecorator.java -special case PointerType so 'const int * x' and 'int * const x' are handled properly CompositeType.java: -Add public void toPrint(int indentation, PrintWriter writer) -if member is a CompositeType invoke toPrint with indentation+2 -special case pointer to array case --=-OrwhaHDrOBZ3SLcgrGpw Content-Disposition: attachment; filename=gen-typetests.py Content-Type: text/x-python; name=gen-typetests.py; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-length: 21955 #!/usr/bin/python import os,posix,sys from subprocess import * from os.path import * ######################################################################## # Manage creation of the java file ######################################################################## class j: def open(self,name): self.j_file = open("TestTypeEntry" + name.capitalize() + ".java", 'w') self.name = "TestTypeEntry" + name.capitalize() def write(self,str): self.j_file.write(str) def prologue(self,): self.j_file.write('''// Generated by gen-typetests.py package frysk.debuginfo; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import lib.dwfl.DwarfDie; import lib.dwfl.Dwfl; import lib.dwfl.DwflDieBias; import frysk.dwfl.DwflCache; import frysk.proc.Task; import frysk.testbed.TestLib; import frysk.value.Type; public class %s extends TestLib { private class ExpectTest { DebugInfoFrame frame; DwarfDie die; DwarfDie[] allDies; TypeEntry typeEntry; ExpectTest(String executable) { Task task = StoppedTestTaskFactory.getStoppedTaskFromExecDir(executable); frame = DebugInfoStackFactory.createVirtualStackTrace(task); Dwfl dwfl; long pc = frame.getAdjustedAddress(); dwfl = DwflCache.getDwfl(frame.getTask()); DwflDieBias bias = dwfl.getDie(pc); die = bias.die; allDies = die.getScopes(pc - bias.bias); typeEntry = new TypeEntry(frame.getTask().getIsa()); } void compareEqual(Expect[] expect, String myName) { Type varType; for (int i = 0; i < expect.length; i++) { DwarfDie varDie = die.getScopeVar(allDies, expect[i].symbol); if (varDie == null) System.out.println("Error: Cannot find " + expect[i].symbol); assertNotNull(varDie); varType = typeEntry.getType(varDie.getType()); System.out.println("Expect: " + expect[i].symbol + "\\n'" + expect[i].output + "'\\nGot:\\n'" + varType.toPrint() + "'"); assertNotNull(varType); assertEquals(myName + expect[i].symbol, expect[i].output, varType.toPrint()); } } void compareRegex(Expect[] expect, String myName) { Type varType; for (int i = 0; i < expect.length; i++) { DwarfDie varDie = die.getScopeVar(allDies, expect[i].symbol); if (varDie == null) varDie = DwarfDie.getDeclCU(allDies, expect[i].symbol); if (varDie == null) { continue; } varType = typeEntry.getType(varDie.getType()); Pattern p = Pattern.compile(expect[i].output, Pattern.DOTALL); Matcher m = p.matcher(varType.toPrint()); assertTrue(myName + expect[i].symbol, m.matches()); } } } private class Expect { String symbol; String output; Expect (String symbol, String expect) { this.symbol = symbol; this.output = expect; } } Logger logger = Logger.getLogger("frysk"); ''' % self.name) def start_test(self,name): self.j_file.write(''' public void test%s () { Expect [] expect = { ''' % (name)) def add_test(self,tool,name,type,long,decl,value): self.j_file.write('\t new Expect("%s",' % name) if (tool == "type"): self.j_file.write('"%s"' % type) elif (tool == "value"): self.j_file.write('"%s"' % value) self.j_file.write("),\n") def end_test(self): self.j_file.write(''' }; ExpectTest expectTest = new ExpectTest("funit-scalar"); expectTest.compareEqual(expect, "testScalar "); } ''') def epilogue(self,debug): self.j_file.write(''' } ''') ######################################################################## # Manage creation of the C file ######################################################################## class c: def open(self,name): self.c_file = open("funit-type-entry" + ".c", 'w') def write(self,str): str = str.replace("\\n","\n") self.c_file.write(str) def add_decl(self,str): self.c_file.write("static " + str) def prologue(self,): self.c_file.write('''// Generated by gen-typetests.py #include #include #define unused __attribute__((unused)) static void crash () { char *a = 0; a[0] = 0; } // Naming convention examples: // ptr_const_char_var - Pointer to a const char // char_ptr_const_var - Const pointer to a char // arr_ptr_arr_arr_char - Array of pointers to 2 dimension arrays of char // struct_arr_arr_int_var - Struct of 2 dimension arrays of int ''') def epilogue(self,debug): self.c_file.write("\n") if (debug): self.c_file.write("volatile int x = 1;\n") self.c_file.write("int\n") self.c_file.write("main (int argc, char **argv) {\n") if (debug): self.c_file.write("while (x);\n") self.c_file.write(" crash ();\n return 0;\n}\n") ######################################################################## # Coordinate creation of the source files ######################################################################## class s: def open(self,tool): self.tool = tool self.c_file = c() self.c_file.open(tool) self.c_file.prologue() self.j_file = j() self.j_file.open(tool) self.j_file.prologue() def c_write(self,str): self.c_file.write(str) def j_write(self,str): self.j_file.write(str) def start_test(self,str): self.j_file.start_test(str) def add_test(self, name, short, long, decl, value): self.j_file.add_test(self.tool, name, short, long, decl, value) def end_test(self): # self.c_file.end_test() self.j_file.end_test() def add(self, type, var, type_arr, initial): if (type_arr == ""): var_suffix = "_var" else: var_suffix = "" source.c_file.write("static " + type + " " + var + var_suffix + type_arr) source.c_file.write(" unused") if initial != "": source.c_file.write(" = " + initial) source.c_file.write(";\n") if (type_arr.startswith("[")): jtype = type + " " + type_arr else: jtype = type + type_arr jtype = jtype.rstrip() source.j_file.add_test(self.tool, var + var_suffix, jtype, jtype, jtype, initial) # like add but allows expected type to be given separately def addexpected(self, type, etype, var, type_arr, initial): if (type_arr == ""): var_suffix = "_var" else: var_suffix = "" source.c_file.write("static " + type + " " + var + var_suffix + type_arr) source.c_file.write(" unused") if initial != "": source.c_file.write(" = " + initial) source.c_file.write(";\n") source.j_file.add_test(self.tool, var + var_suffix, etype, etype, etype, initial) def add_decl(self,str): self.c_file.write("static " + str) # self.j_file.write("static " + str) def epilogue(self): self.c_file.epilogue(debug) self.j_file.epilogue(debug) ######################################################################## # main ######################################################################## def usage (): print "Usage " + sys.argv[0] + " -value OR -type" sys.exit(1) if (len (sys.argv) == 1): usage() debug=0 for t in sys.argv: if (t == "-value"): tool="value" elif (t == "-type"): tool="type" elif (t == "-debug"): debug=1 elif (t.startswith("-")): usage() host='x86' # Used for variable initialization limits={'char' : {'min' : {'x86' : '41', 'x86_64' : '41'}, 'max' : {'x86' : '176', 'x86_64' : '176'}}, 'uchar' : {'min' : {'x86' : '0', 'x86_64' : '0'}, 'max' : {'x86' : '255', 'x86_64' : '255'}}, 'short int' : {'min' : {'x86' : '-32767-1', 'x86_64' : '-32768'}, 'max' : {'x86' : '32767', 'x86_64' : '32767'}}, 'ushort' : {'min' : {'x86' : '65535', 'x86_64' : '65535'}, 'max' : {'x86' : '65535', 'x86_64' : '65535'}}, 'int' : {'min' : {'x86' : '-2147483647-1', 'x86_64' : '-2147483648'}, 'max' : {'x86' : '2147483647', 'x86_64' : '2147483647'}}, 'uint' : {'min' : {'x86' : '4294967295', 'x86_64' : '4294967295'}, 'max' : {'x86' : '4294967295', 'x86_64' : '4294967295'}}, 'long int' : {'min' : {'x86' : '-2147483647L-1', 'x86_64' : '-9223372036854775807L-1'}, 'max' : {'x86' : '2147483647L', 'x86_64' : '9223372036854775807L'}}, 'ulong' : {'min' : {'x86' : '4294967295UL', 'x86_64' : '18446744073709551615UL'}, 'max' : {'x86' : '4294967295UL', 'x86_64' : '18446744073709551615UL'}}, 'long long int' : {'min' : {'x86' : '-9223372036854775807LL-1', 'x86_64' : '-9223372036854775807LL-1'}, 'max' : {'x86' : '9223372036854775807LL', 'x86_64' : '9223372036854775807LL'}}, 'ulong long' : {'min' : {'x86' : '18446744073709551615ULL', 'x86_64' : '18446744073709551615ULL'}, 'max' : {'x86' : '18446744073709551615ULL', 'x86_64' : '18446744073709551615ULL'}}, 'float' : {'min' : {'x86' : '1.175494E-38', 'x86_64' : '1.175494E-38'}, 'max' : {'x86' : '3.402823E+38', 'x86_64' : '3.402823E+38'}}, 'double' : {'min' : {'x86' : '2.225074E-308', 'x86_64' : '2.225074E-308'}, 'max' : {'x86' : '1.797693E+308', 'x86_64' : '1.797693E+308'}}, } # base types we generate variables for. used to index into limits map base_types=('char','short int','int','long int','long long int','float','double') type_modifiers=('const','volatile') source = s() source.open(tool) tm = te = tme = tms = "" for m in type_modifiers: tm = tm + m + " " te = " " + te + m # gcc puts multiple types in the opposite order of source so ignore these tm = tm.rstrip() te = te.lstrip() tms = tm.rstrip().replace(" ","_") source.start_test("Scalar") ######################################## for t in base_types: try: ts = t.replace(" ","_") source.c_write("// %s\n" % t); min = limits[t]['min'][host] max = limits[t]['max'][host] source.add(t, ts, "", max) for m in type_modifiers: source.add("%s %s" % (m,t), "%s_%s" % (m,ts), "", min) # source.addexpected("%s %s" % (tm,t), "%s %s" % (te,t), "%s_%s" % (tms,ts), "", max) source.add("%s *" % t, "ptr_" + ts, "", "&%s_var" % ts) for m in type_modifiers: source.add("%s %s *" % (m,t), "ptr_%s_%s" % (m,ts), "", "&%s_var" % ts) source.add("%s * %s" % (t,m), "%s_ptr_%s" % (ts,m), "", "&%s_var" % ts) # source.add("%s %s *" % (tm,t), "ptr_%s_%s" % (tms,ts), "", # "&%s_var" % ts) # source.add("%s * %s" % (t,tm), "%s_ptr_%s" % (ts,tms), "", # "&%s_var" % ts) # if (t != "float" and t != "double"): # source.addexpected("unsigned %s" % t, "unsigned %s" % t, "unsigned_%s" % ts, "", max) except KeyError: continue source.end_test() source.start_test("Array") ######################################## source.c_write("\n"); for t in base_types: source.c_write("// array of %s\n" % (t)) ts = t.replace(" ","_") min = limits[t]['min'][host] max = limits[t]['max'][host] source.add(t, "arr_%s" % ts, "[2]", "{%s,%s}" % (min,max)) source.add(t, "arr_arr_%s" % ts, "[2][2]", "{{%s,%s},{%s,%s}}" % (min,max,min,max)) source.add(t, "arr_arr_arr_%s" % ts, "[2][2][2]", "{{{%s,%s},{%s,%s}},{{%s,%s},{%s,%s}}}" % (min,max,min,max,min,max,min,max)) source.add("%s *" % t, "arr_ptr_arr_arr_%s" % ts, "[2]", "{arr_arr_%s[0],arr_arr_%s[1]}" % (ts,ts)) source.add("%s (*" % t, "ptr_arr_%s" % ts, ")[2]", "&arr_%s" % ts) # we modify \\n so c source has actual new lines and java has a \n escape source.c_write("\\nstatic int one = 1, two = 2, three = 3, four = 4;\n") source.add("struct {\\n int int_var;\\n}", "arr_struct", "[2]","{{1},{2}}") source.add("union {\\n int int_var;\\n float float_var;\\n}", "arr_union", "[2]", "{{1},{2}}") source.add("struct {\\n int int_var;\\n}", "arr_arr_struct", "[2][2]", "{{{1},{2}},{{3},{4}}}") source.add("union {\\n int int_var;\\n float float_var;\\n}", "arr_arr_union", "[2][2]", "{{{1},{2}},{{3},{4}}}") source.add("int *", "arr_arr_ptr", "[2][2]", "{{&one,&two},{&three,&four}}") source.add("struct {\\n int arr_int[2];\\n}", "arr_struct_arr_int", "[2]", "{{{1, 2}}, {{3, 4}}}") source.add("struct {\\n struct {\\n int int_var;\\n } struct_a;\\n}", "arr_struct_struct", "[2]", "{{{1}},{{2}}}") source.add("struct {\\n union {\\n int int_var;\\n float float_var;\\n } struct_a;\\n}", "arr_struct_union", "[2]", "{{{1}},{{2}}}") source.add("struct {\\n int * ptr;\\n}", "arr_struct_ptr", "[2]", "{{&one},{&two}}") source.add("union {\\n int arr_int[2];\\n float arr_float[2];\\n}", "arr_union_arr_int", "[2]", "{{{1, 2}}, {{3, 4}}}") source.add("union {\\n struct {\\n int int_var;\\n } struct_a;\\n}", "arr_union_struct", "[2]", "{{{1}}, {{2}}}") source.add("union {\\n union {\\n int int_var;\\n } union_a;\\n}", "arr_union_union", "[2]", "{{{1}}, {{2}}}") source.add("union {\\n int * ptr;\\n}", "arr_union_ptr", "[2]", "{{&one}, {&two}}") # ??? fails # source.add("int (*", "arr_ptr_arr", "[2])[2]", "{&arr_int, &arr_int}") source.add("struct {\\n int int_var;\\n} *", "arr_ptr_struct", "[2]", "") source.add("union {\\n int int_var;\\n float float_var;\\n} *", "arr_ptr_union", "[2]", "") source.add("int * *", "arr_ptr_ptr", "[2]", "") source.add("struct {\\n int int_var;\\n} (*", "ptr_arr_struct", ")[2]","") source.add("union {\\n int int_var;\\n} (*", "ptr_arr_union", ")[2]", "") source.add("int * (*", "ptr_arr_ptr", ")[2]", "") source.end_test() source.start_test("Struct") ######################################## source.c_write('''typedef struct { char char_var; short short_var; int int_var; long long_var; float float_var; double double_var; char arr_char[4]; } type_struct; typedef struct { type_struct type_struct_min; type_struct type_struct_max; } type_type_struct; type_type_struct type_minmax_struct = {{%s, %s, %s, %s, %s, %s, %s}, {%s, %s, %s, %s, %s, %s, %s} };\n''' % (limits['char']['min'][host],limits['short int']['min'][host],limits['int']['min'][host],limits['long int']['min'][host],limits['float']['min'][host],limits['double']['min'][host],'"ABC"',limits['char']['max'][host],limits['short int']['max'][host],limits['int']['max'][host],limits['long int']['max'][host],limits['float']['max'][host],limits['double']['max'][host],'"XYZ"')) source.add('''struct {\\n unsigned int bit1_0:1;\\n unsigned int bit1_1:1;\\n char char_2;\\n unsigned int bit1_6:1;\\n unsigned int bit1_7:1;\\n char char_8;\\n unsigned int bit1_9:1;\\n unsigned int bit1_10:1;\\n}''', "bitfields_small", "", "{1, 0, 0x7f, 1, 0, 0x7f, 1, 0}") source.add('''struct {\\n unsigned char char_0;\\n int bit1_4:1;\\n unsigned int bit1_5:1;\\n int bit2_6:2;\\n unsigned int bit2_8:2;\\n int bit3_10:3;\\n unsigned int bit3_13:3;\\n int bit9_16:9;\\n unsigned int bit9_25:9;\\n char char_34;\\n}''', "bitfields_bit", "", "{0x7f, 1, 1, 1, 3, 3, 7, UINT8_MAX, 511, 0x7f}") source.add('''struct {\\n short int arr_short[2];\\n}''', "struct_arr_short", "", "{{1, 2}}") source.add('''struct {\\n struct {\\n int int_var;\\n } struct_a;\\n}''', "struct_struct", "", "{{1}}") source.add("struct {\\n union {\\n int int_var;\\n } union_a;\\n}", "struct_union", "", "{{1}}") source.add('''struct {\\n int * ptr_int;\\n}''', "struct_ptr", "", "{&one}") source.add('''union {\\n int arr_int[4];\\n float arr_float[4];\\n}''', "union_arr", "", "{{1, 2, 3, 4}}") source.add('''union {\\n struct {\\n int int_var;\\n } struct_a;\\n}''', "union_struct", "", "{{1}}") source.add('''union {\\n union {\\n int int_var;\\n float float_var;\\n } union_a;\\n}''', "union_union", "", "{{1}}") source.add('''union {\\n int * ptr_int;\\n}''', "union_ptr", "", "{&one}") source.add('''struct {\\n int int_var;\\n} *''', "ptr_struct", "", "") source.add('''union {\\n int int_var;\\n} *''', "ptr_union", "", "") source.add('''struct {\\n int arr_arr_int[2][2];\\n}''', "struct_arr_arr_int", "", "{{{1, 2}, {3, 4}}}") # ??? improve indentation source.add('''struct {\\n struct {\\n int int_var;\\n} arr_struct[2];\\n}''', "struct_arr_struct", "", "{{{1}, {2}}}") source.add('''struct {\\n union {\\n int int_var;\\n} arr_union[4];\\n}''', "struct_arr_union", "", "{{{1}, {2}}}") source.add('''struct {\\n int * arr_ptr[2];\\n}''', "struct_arr_ptr", "", "{{&one, &two}}") source.add('''struct {\\n struct {\\n int arr_int[2];\\n } struct_arr;\\n}''', "struct_struct_arr_int", "", "{{{1, 2}}}") source.add('''struct {\\n struct {\\n struct {\\n int int_var;\\n } struct_a;\\n } struct_struct;\\n}''', "struct_struct_struct", "", "{{{1}}}") source.add('''struct {\\n struct {\\n union {\\n char int_var;\\n } union_a;\\n } struct_union;\\n}''', "struct_struct_union", "", "{{{1}}}") source.add('''struct {\\n struct {\\n int * ptr_int;\\n } sp;\\n}''', "struct_struct_ptr", "", "{{&three}}") source.add('''struct {\\n union {\\n int arr_int[4];\\n } union_arr_int;\\n}''', "struct_union_arr", "", "{{{1, 2, 3, 4}}}") source.add('''struct {\\n union {\\n struct {\\n int int_var;\\n } struct_a;\\n } union_struct;\\n}''', "struct_union_struct", "", "{{{1}}}") source.add('''struct {\\n union {\\n union {\\n long int int_var;\\n float float_var;\\n } union_a;\\n } union_union;\\n}''', "struct_union_union", "", "{{{1.0}}}") source.add('''struct {\\n union {\\n int * ptr_int;\\n } union_ptr;\\n}''', "struct_union_ptr", "", "{{&four}}") source.add('''struct {\\n int (* ptr_arr)[4];\\n}''', "struct_ptr_arr", "", "") # ??? improve indentation source.add('''struct {\\n struct {\\n int int_var;\\n} * ptr_struct;\\n}''', "struct_ptr_struct", "", "") source.add('''struct {\\n union {\\n int int_var;\\n} * ptr_union;\\n}''', "struct_ptr_union", "", "") source.add('''struct {\\n int * * ptr_ptr;\\n}''', "struct_ptr_ptr", "", "") source.add('''union {\\n int arr_int[2][2];\\n float arr_float[2][2];\\n}''', "union_arr_int", "", "{{{1, 2}, {3, 4}}}") # ??? improve indentation source.add('''union {\\n struct {\\n int int_var;\\n} arr_struct[2];\\n}''', "union_arr_struct", "", "{{{1}}}") source.add('''union {\\n union {\\n int int_var;\\n float float_var;\\n} arr_union[2];\\n}''', "union_arr_union", "", "{{{1.1}}}") source.add('''union {\\n int * arr_ptr[4];\\n}''', "union_arr_ptr", "", "{{&one}}") source.add('''union {\\n struct {\\n int arr_int[4];\\n } struct_arr;\\n}''', "union_struct_arr_int", "", "{{{1, 2, 3, 4}}}") source.add('''union {\\n struct {\\n struct {\\n int int_var;\\n } struct_a;\\n } struct_b;\\n}''', "union_struct_struct", "", "{{{1}}}") source.add('''union {\\n struct {\\n union {\\n int int_var;\\n float float_var;\\n } union_a;\\n } struct_a;\\n}''', "union_struct_union", "", "{{{1.1}}}") source.add('''union {\\n struct {\\n int * ptr_int;\\n } struct_ptr;\\n}''', "union_struct_ptr", "", "{{&one}}") source.add('''union {\\n union {\\n long long int arr_int[4];\\n } union_arr;\\n}''', "union_union_arr_int", "", "{{{1, 2, 3, 4}}}") source.add('''union {\\n union {\\n struct {\\n long long int int_var;\\n } struct_a;\\n } union_a;\\n}''', "union_union_struct", "", "{{{1}}}") source.add('''union {\\n union {\\n union {\\n int int_var;\\n float float_var;\\n } union_a;\\n } union_b;\\n}''', "union_union_union", "", "{{{1.1}}}") source.add('''union {\\n union {\\n int * ptr_int;\\n float * ptr_float;\\n } union_ptr;\\n}''', "union_union_ptr", "", "{{&one}}") source.add('''union {\\n int (* ptr_arr)[4];\\n}''', "union_ptr_arr", "", "") source.add('''union {\\n struct {\\n int int_var;\\n} * ptr_struct;\\n}''', "union_ptr_struct", "", "") source.add('''union {\\n union {\\n int int_var;\\n} * ptr_union;\\n}''', "union_ptr_union", "", "") source.add('''union {\\n int * * ptr_ptr;\\n}''', "union_ptr_ptr", "", "") source.add('''struct {\\n int arr_int[4];\\n} *''', "ptr_struct_arr_int", "", "") source.add('''struct {\\n struct {\\n int int_var;\\n } struct_a;\\n} *''', "ptr_struct_struct", "", "") source.add('''struct {\\n union {\\n int int_var;\\n } union_a;\\n} *''', "ptr_struct_union", "", "") source.add('''struct {\\n int * ptr_int;\\n} *''', "ptr_struct_ptr", "", "") source.add('''union {\\n int arr_int[4];\\n} *''',"ptr_union_arr_int", "", "") source.add('''union {\\n struct {\\n int int_var;\\n } struct_a;\\n} *''',"ptr_union_struct", "", "") source.add('''union {\\n union {\\n int int_var;\\n } union_a;\\n} *''', "ptr_union_union", "", "") source.add('''union {\\n int * ptr_int;\\n} *''', "ptr_union_ptr", "", "") source.add('''struct {\\n int int_var;\\n} * *''', "ptr_ptr_struct", "", "") source.add('''union {\\n int int_var;\\n} * *''', "ptr_ptr_union", "", "") source.end_test() source.start_test("Enum") ######################################## source.add('''enum {\\n red = 0,\\n green = 1,\\n blue = 2\\n}''', "primary_colors", "", "") source.add('''enum colors {\\n orange = 0,\\n yellow = 1,\\n violet = 2,\\n indigo = 3\\n}''', "rainbow_colors", "", "") source.add('''enum {\\n chevy = 33,\\n dodge = 44,\\n ford = 55\\n}''', "usa_cars", "", "") source.add('''enum cars {\\n bmw = 0,\\n mercedes = 1,\\n porsche = 2\\n}''', "european_cars", "", "") source.end_test() source.epilogue() --=-OrwhaHDrOBZ3SLcgrGpw--