/* * Copyright (C) 2008 Red Hat, Inc. * Copyright (C) 2018 Tomasz Miąsko * * 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 2 * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * * The idea here is that we want to compare offset information two ways: * * 1) As generated by the compiler * 2) As found in the typelib * * So we write the field offsets using G_STRUCT_OFFSET() to one file and the * field offsets using the typelib to the another file. We can then diff the * two files to see if they are the same. */ #include #include #include #include #include #include #include "offsets.h" static GIRepository *repository; static const char *namespace = "Offsets"; static const char *version = "1.0"; static void introspected_struct (FILE *outfile, const gchar *name) { gint i, n_fields; GIStructInfo *struct_info; struct_info = g_irepository_find_by_name(repository, namespace, name); if (!struct_info) g_error ("Can't find GIStructInfo for '%s'", name); g_fprintf (outfile, "%s%s: size=%" G_GSIZE_FORMAT ", alignment=%" G_GSIZE_FORMAT "\n", namespace, name, g_struct_info_get_size (struct_info), g_struct_info_get_alignment (struct_info)); n_fields = g_struct_info_get_n_fields (struct_info); for (i = 0; i != n_fields; ++i) { GIFieldInfo *field_info; field_info = g_struct_info_get_field (struct_info, i); g_fprintf (outfile, "%s %d\n", g_base_info_get_name ((GIBaseInfo *) field_info), g_field_info_get_offset (field_info)); g_base_info_unref ((GIBaseInfo *)field_info); } g_fprintf (outfile, "\n"); g_base_info_unref ((GIBaseInfo *)struct_info); } static void compiled (FILE *outfile) { #define ALIGNOF(type) G_STRUCT_OFFSET(struct {char a; type b;}, b) #define PRINT_TYPE(type) g_fprintf (outfile, \ "%s: size=%" G_GSIZE_FORMAT ", alignment=%ld\n", \ #type, sizeof (type), ALIGNOF (type)) #define PRINT_MEMBER(type, member) g_fprintf (outfile, \ "%s %ld\n", \ #member, G_STRUCT_OFFSET(type, member)) PRINT_TYPE (OffsetsArray); PRINT_MEMBER (OffsetsArray, some_ints); PRINT_MEMBER (OffsetsArray, some_int8s); PRINT_MEMBER (OffsetsArray, some_doubles); PRINT_MEMBER (OffsetsArray, some_enum); PRINT_MEMBER (OffsetsArray, some_ptrs); g_fprintf (outfile, "\n"); PRINT_TYPE (OffsetsMultiDimArray); PRINT_MEMBER (OffsetsMultiDimArray, ints); PRINT_MEMBER (OffsetsMultiDimArray, chars); PRINT_MEMBER (OffsetsMultiDimArray, floats); PRINT_MEMBER (OffsetsMultiDimArray, pointers1); PRINT_MEMBER (OffsetsMultiDimArray, pointers2); PRINT_MEMBER (OffsetsMultiDimArray, pointers3); PRINT_MEMBER (OffsetsMultiDimArray, dummy); fprintf (outfile, "\n"); PRINT_TYPE (OffsetsBasic); PRINT_MEMBER (OffsetsBasic, dummy1); PRINT_MEMBER (OffsetsBasic, field_int8); PRINT_MEMBER (OffsetsBasic, dummy2); PRINT_MEMBER (OffsetsBasic, field_int16); PRINT_MEMBER (OffsetsBasic, dummy3); PRINT_MEMBER (OffsetsBasic, field_int32); PRINT_MEMBER (OffsetsBasic, dummy4); PRINT_MEMBER (OffsetsBasic, field_int64); PRINT_MEMBER (OffsetsBasic, dummy5); PRINT_MEMBER (OffsetsBasic, field_pointer); PRINT_MEMBER (OffsetsBasic, dummy6); PRINT_MEMBER (OffsetsBasic, field_float); PRINT_MEMBER (OffsetsBasic, dummy7); PRINT_MEMBER (OffsetsBasic, field_double); PRINT_MEMBER (OffsetsBasic, dummy8); PRINT_MEMBER (OffsetsBasic, field_size); PRINT_MEMBER (OffsetsBasic, dummy9); PRINT_MEMBER (OffsetsBasic, field_uchar1); PRINT_MEMBER (OffsetsBasic, dummy10); PRINT_MEMBER (OffsetsBasic, field_uchar2); PRINT_MEMBER (OffsetsBasic, dummy11); g_fprintf (outfile, "\n"); PRINT_TYPE (OffsetsEnum); PRINT_MEMBER (OffsetsEnum, enum1); PRINT_MEMBER (OffsetsEnum, dummy1); PRINT_MEMBER (OffsetsEnum, enum2); PRINT_MEMBER (OffsetsEnum, dummy2); PRINT_MEMBER (OffsetsEnum, enum3); PRINT_MEMBER (OffsetsEnum, dummy3); PRINT_MEMBER (OffsetsEnum, enum4); PRINT_MEMBER (OffsetsEnum, dummy4); PRINT_MEMBER (OffsetsEnum, enum5); PRINT_MEMBER (OffsetsEnum, dummy5); PRINT_MEMBER (OffsetsEnum, enum6); PRINT_MEMBER (OffsetsEnum, dummy6); g_fprintf (outfile, "\n"); PRINT_TYPE (OffsetsNested); PRINT_MEMBER (OffsetsNested, dummy1); PRINT_MEMBER (OffsetsNested, nestee); PRINT_MEMBER (OffsetsNested, dummy2); PRINT_MEMBER (OffsetsNested, nestee_union); PRINT_MEMBER (OffsetsNested, dummy3); g_fprintf (outfile, "\n"); PRINT_TYPE (OffsetsNestee); PRINT_MEMBER (OffsetsNestee, field1); PRINT_MEMBER (OffsetsNestee, field2); PRINT_MEMBER (OffsetsNestee, field3); g_fprintf (outfile, "\n"); PRINT_TYPE (OffsetsObj); PRINT_MEMBER (OffsetsObj, parent_instance); PRINT_MEMBER (OffsetsObj, other); g_fprintf (outfile, "\n"); PRINT_TYPE (OffsetsObjClass); PRINT_MEMBER (OffsetsObjClass, parent_class); g_fprintf (outfile, "\n"); #undef ALIGNOF #undef PRINT_TYPE #undef PRINT_MEMBER } int main(int argc, char **argv) { GError *error = NULL; FILE *outfile; if (argc != 3) g_error ("Usage: gitestoffsets COMPILED_OFFSETS_FILE INTROSPECTED_OFFSETS_FILE"); repository = g_irepository_get_default (); if (!g_irepository_require (repository, namespace, version, 0, &error)) g_error ("Failed to load %s-%s.typelib: %s", namespace, version, error->message); outfile = fopen (argv[1], "w"); if (!outfile) g_error ("Cannot open '%s': %s'", argv[1], g_strerror(errno)); compiled (outfile); fclose (outfile); outfile = fopen (argv[2], "w"); if (!outfile) g_error ("Cannot open '%s': %s'", argv[1], g_strerror(errno)); introspected_struct (outfile, "Array"); introspected_struct (outfile, "MultiDimArray"); introspected_struct (outfile, "Basic"); introspected_struct (outfile, "Enum"); introspected_struct (outfile, "Nested"); introspected_struct (outfile, "Nestee"); introspected_struct (outfile, "Obj"); introspected_struct (outfile, "ObjClass"); fclose (outfile); return 0; }