1/*********************************************************************
2 *   Copyright 1993, UCAR/Unidata
3 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 *   $Header: /upc/share/CVS/netcdf-3/ncgen/offsets.c,v 1.1 2009/09/25 18:22:40 dmh Exp $
5 *********************************************************************/
6
7/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
8 * Copyright by The HDF Group.                                               *
9 * Copyright by the Board of Trustees of the University of Illinois.         *
10 * All rights reserved.                                                      *
11 *                                                                           *
12 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
13 * terms governing use, modification, and redistribution, is contained in    *
14 * the files COPYING and Copyright.html.  COPYING can be found at the root   *
15 * of the source code distribution tree; Copyright.html can be found at the  *
16 * root level of an installed copy of the electronic HDF5 document set and   *
17 * is linked from the top-level documents page.  It can also be found at     *
18 * http://hdfgroup.org/HDF5/doc/Copyright.html.  If you do not have          *
19 * access to either file, you may request a copy from help@hdfgroup.org.     *
20 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22/*
23This code is a variantion of the H5detect.c code from HDF5.
24Author: D. Heimbigner 10/7/2008
25*/
26
27#ifndef OFFSETTEST
28#include        "includes.h"
29#else
30#include        <stdlib.h>
31#include        <stdio.h>
32#include        <string.h>
33#include        <assert.h>
34#endif
35
36#ifdef OFFSETTEST
37
38static void* emalloc(size_t);
39
40typedef int nc_type;
41typedef struct nc_vlen_t {
42    size_t len;
43    void* p;
44nc_vlen_t;
45
46#define NC_NAT          0 /* NAT = 'Not A Type' (c.f. NaN) */
47#define NC_BYTE         1 /* signed 1 byte integer */
48#define NC_CHAR  2 /* ISO/ASCII character */
49#define NC_SHORT  3 /* signed 2 byte integer */
50#define NC_INT          4 /* signed 4 byte integer */
51#define NC_FLOAT  5 /* single precision floating point number */
52#define NC_DOUBLE  6 /* double precision floating point number */
53#define NC_UBYTE  7 /* unsigned 1 byte int */
54#define NC_USHORT  8 /* unsigned 2-byte int */
55#define NC_UINT  9 /* unsigned 4-byte int */
56#define NC_INT64  10 /* signed 8-byte int */
57#define NC_UINT64  11 /* unsigned 8-byte int */
58#define NC_STRING  12 /* string */
59#define NC_STRING  12 /* string */
60#define NC_VLEN  13
61#define NC_OPAQUE  14
62#define NC_ENUM  15
63#define NC_COMPOUND  16
64#endif
65
66#include        "offsets.h"
67
68
69/*
70The heart of this is the following macro,
71which computes the offset of a field x
72when preceded by a char field.
73The assumptions appear to be as follows:
741. the offset produced in this situation indicates
75   the alignment for x relative in such a way that it
76   depends only on the types that precede it in the struct.
772. the compiler does not reorder fields.
783. arrays are tightly packed.
794. nested structs are alignd according to their first member
80   (this actually follows from C language requirement that
81    a struct can legally be cast to an instance of its first member).
82Given the alignments for the various common primitive types,
83it is assumed that one can use them anywhere to construct
84the layout of a struct of such types.
85It seems to work for HDF5 for a wide variety of machines.
86Note that technically, this is compiler dependent, but in practice
87all compilers seem to mimic the gcc rules.
88*/
89
90#define COMP_ALIGNMENT(DST,TYPE)  {\
91    struct {char f1TYPE x;} tmp; \
92    DST.typename = #TYPE ;        \
93    DST.alignment = (size_t)((char*)(&(tmp.x)) - (char*)(&tmp));}
94
95char* ctypenames[NCTYPES] = {
96(char*)NULL,
97"char","unsigned char",
98"short","unsigned short",
99"int","unsigned int",
100"long long","unsigned long long",
101"float","double",
102"void*","nc_vlen_t"
103};
104
105static Typealignvec vec[NCTYPES];
106static Typealignset set;
107
108unsigned int
109nctypealignment(nc_type nctype)
110{
111    Alignmentalign = NULL;
112    int index = 0;
113    switch (nctype) {
114      case NC_BYTEindex = UCHARINDEX; break;
115      case NC_CHARindex = CHARINDEX; break;
116      case NC_SHORTindex = SHORTINDEX; break;
117      case NC_INTindex = INTINDEX; break;
118      case NC_FLOATindex = FLOATINDEX; break;
119      case NC_DOUBLEindex = DOUBLEINDEX; break;
120      case NC_UBYTEindex = UCHARINDEX; break;
121      case NC_USHORTindex = USHORTINDEX; break;
122      case NC_UINTindex = UINTINDEX; break;
123      case NC_INT64index = LONGLONGINDEX; break;
124      case NC_UINT64index = ULONGLONGINDEX; break;
125      case NC_STRINGindex = PTRINDEX; break;
126      case NC_VLENindex = NCVLENINDEX; break;
127      case NC_OPAQUEindex = UCHARINDEX; break;
128      default:
129 fprintf(stderr,"nctypealignment: bad type code: %d",nctype);
130 exit(1);
131    }
132    align = &vec[index];
133    return align->alignment;
134}
135
136
137void
138compute_alignments(void)
139{
140    /* Compute the alignments for all the common C data types*/
141    /* First for the struct*/
142    /* initialize*/
143    memset((void*)&set,0,sizeof(set));
144    memset((void*)vec,0,sizeof(vec));
145
146    COMP_ALIGNMENT(set.charalign,char);
147    COMP_ALIGNMENT(set.ucharalign,unsigned char);
148    COMP_ALIGNMENT(set.shortalign,short);
149    COMP_ALIGNMENT(set.ushortalign,unsigned short);
150    COMP_ALIGNMENT(set.intalign,int);
151    COMP_ALIGNMENT(set.uintalign,unsigned int);
152    COMP_ALIGNMENT(set.longlongalign,long long);
153    COMP_ALIGNMENT(set.ulonglongalign,unsigned long long);
154    COMP_ALIGNMENT(set.floatalign,float);
155    COMP_ALIGNMENT(set.doublealign,double);
156    COMP_ALIGNMENT(set.ptralign,void*);
157    COMP_ALIGNMENT(set.ncvlenalign,nc_vlen_t);
158
159    /* Then the vector*/
160    COMP_ALIGNMENT(vec[CHARINDEX],char);
161    COMP_ALIGNMENT(vec[UCHARINDEX],unsigned char);
162    COMP_ALIGNMENT(vec[SHORTINDEX],short);
163    COMP_ALIGNMENT(vec[USHORTINDEX],unsigned short);
164    COMP_ALIGNMENT(vec[INTINDEX],int);
165    COMP_ALIGNMENT(vec[UINTINDEX],unsigned int);
166    COMP_ALIGNMENT(vec[LONGLONGINDEX],long long);
167    COMP_ALIGNMENT(vec[ULONGLONGINDEX],unsigned long long);
168    COMP_ALIGNMENT(vec[FLOATINDEX],float);
169    COMP_ALIGNMENT(vec[DOUBLEINDEX],double);
170    COMP_ALIGNMENT(vec[PTRINDEX],void*);
171    COMP_ALIGNMENT(vec[NCVLENINDEX],nc_vlen_t);
172}
173
174#ifdef OFFSETTEST
175
176/* Compute the alignment of TYPE when it is preceded
177   by a field of type TYPE1
178*/
179#define COMP_ALIGNMENT1(DST,TYPE1,TYPE)  {\
180    struct {TYPE1 f1TYPE x;} tmp; \
181    DST.typename = #TYPE ;        \
182    DST.alignment = (size_t)((char*)(&(tmp.x)) - (char*)(&tmp));}
183
184/* Compute the alignment of TYPE when it is preceded
185   by a field of type TYPE1 and a field of type TYPE2
186*/
187#define COMP_ALIGNMENT2(DST,TYPE1,TYPE2,TYPE)  {\
188    struct {TYPE1 f1TYPE2 f2TYPE x;} tmp;   \
189    DST.typename = #TYPE ;                      \
190    DST.alignment = (size_t)((char*)(&(tmp.x)) - (char*)(&tmp));}
191
192/* Compute the alignment of TYPE when it is preceded
193   by a field of type TYPE1 and a field of type TYPE2
194*/
195#define COMP_SIZE0(DST,TYPE1,TYPE2)  {\
196    struct {TYPE1 cTYPE2 x;} tmp; \
197    DST = sizeof(tmp); }
198
199static char*
200padname(char* name)
201{
202#define MAX 20
203    if(name == NULLname = "null";
204    int len = strlen(name);
205    if(len > MAXlen = MAX;
206    char* s = (char*)emalloc(MAX+1);
207    memset(s,' ',MAX);
208    s[MAX+1] = '\0';
209    strncpy(s,name,len);
210    return s;
211}
212
213static void
214verify(Typealignvecvec)
215{
216    int i,j;
217    Typealignvecvec16;
218    Typealignvecvec32;
219    int* sizes8;
220    int* sizes16;
221    int* sizes32;
222
223    vec16 = (Typealignvec*)emalloc(sizeof(Typealignvec)*NCTYPES);
224    vec32 = (Typealignvec*)emalloc(sizeof(Typealignvec)*NCTYPES);
225    sizes8 = (int*)emalloc(sizeof(int)*NCTYPES);
226    sizes16 = (int*)emalloc(sizeof(int)*NCTYPES);
227    sizes32 = (int*)emalloc(sizeof(int)*NCTYPES);
228
229    COMP_SIZE0(sizes8[1],char,char);
230    COMP_SIZE0(sizes8[2],unsigned char,char);
231    COMP_SIZE0(sizes8[3],short,char);
232    COMP_SIZE0(sizes8[4],unsigned short,char);
233    COMP_SIZE0(sizes8[5],int,char);
234    COMP_SIZE0(sizes8[6],unsigned int,char);
235    COMP_SIZE0(sizes8[7],long long,char);
236    COMP_SIZE0(sizes8[8],unsigned long long,char);
237    COMP_SIZE0(sizes8[9],float,char);
238    COMP_SIZE0(sizes8[10],double,char) ;
239    COMP_SIZE0(sizes8[11],void*,char);
240    COMP_SIZE0(sizes8[12],nc_vlen_t,char);
241
242    COMP_SIZE0(sizes16[1],char,short);
243    COMP_SIZE0(sizes16[2],unsigned char,short);
244    COMP_SIZE0(sizes16[3],short,short);
245    COMP_SIZE0(sizes16[4],unsigned short,short);
246    COMP_SIZE0(sizes16[5],int,short);
247    COMP_SIZE0(sizes16[6],unsigned int,short);
248    COMP_SIZE0(sizes16[7],long long,short);
249    COMP_SIZE0(sizes16[8],unsigned long long,short);
250    COMP_SIZE0(sizes16[9],float,short);
251    COMP_SIZE0(sizes16[10],double,short) ;
252    COMP_SIZE0(sizes16[11],void*,short);
253    COMP_SIZE0(sizes16[12],nc_vlen_t*,short);
254
255    COMP_SIZE0(sizes32[1],char,int);
256    COMP_SIZE0(sizes32[2],unsigned char,int);
257    COMP_SIZE0(sizes32[3],short,int);
258    COMP_SIZE0(sizes32[4],unsigned short,int);
259    COMP_SIZE0(sizes32[5],int,int);
260    COMP_SIZE0(sizes32[6],unsigned int,int);
261    COMP_SIZE0(sizes32[7],long long,int);
262    COMP_SIZE0(sizes32[8],unsigned long long,int);
263    COMP_SIZE0(sizes32[9],float,int);
264    COMP_SIZE0(sizes32[10],double,int) ;
265    COMP_SIZE0(sizes32[11],void*,int);
266    COMP_SIZE0(sizes32[12],nc_vlen_t*,int);
267
268    COMP_ALIGNMENT1(vec16[1],char,short);
269    COMP_ALIGNMENT1(vec16[2],unsigned char,short);
270    COMP_ALIGNMENT1(vec16[3],short,short);
271    COMP_ALIGNMENT1(vec16[4],unsigned short,short);
272    COMP_ALIGNMENT1(vec16[5],int,short);
273    COMP_ALIGNMENT1(vec16[6],unsigned int,short);
274    COMP_ALIGNMENT1(vec32[7],long long,short);
275    COMP_ALIGNMENT1(vec32[8],unsigned long long,short);
276    COMP_ALIGNMENT1(vec16[9],float,short);
277    COMP_ALIGNMENT1(vec16[10],double,short);
278    COMP_ALIGNMENT1(vec16[11],void*,short);
279    COMP_ALIGNMENT1(vec16[12],nc_vlen_t*,short);
280
281    COMP_ALIGNMENT1(vec32[1],char,short);
282    COMP_ALIGNMENT1(vec32[2],unsigned char,short);
283    COMP_ALIGNMENT1(vec32[3],char,short);
284    COMP_ALIGNMENT1(vec32[4],unsigned short,short);
285    COMP_ALIGNMENT1(vec32[5],int,int);
286    COMP_ALIGNMENT1(vec32[6],unsigned int,int);
287    COMP_ALIGNMENT1(vec32[7],long long,int);
288    COMP_ALIGNMENT1(vec32[8],unsigned long long,int);
289    COMP_ALIGNMENT1(vec32[9],float,int);
290    COMP_ALIGNMENT1(vec32[10],double,int);
291    COMP_ALIGNMENT1(vec32[11],void*,int);
292    COMP_ALIGNMENT1(vec32[12],nc_vlen_t*,int);
293
294    for(i=0;i<NCTYPES;i++) {
295 printf("%s: size=%2d  alignment=%2d\n",
296 padname(vec[i].typename),sizes8[i],vec[i].alignment);
297    }
298    for(i=0;i<NCTYPES;i++) {
299 printf("short vs %s: size=%2d  alignment=%2d\n",
300 padname(vec[i].typename),sizes16[i],vec16[i].alignment);
301    }
302    for(i=0;i<NCTYPES;i++) {
303 printf("int vs %s: size=%2d  alignment=%2d\n",
304 padname(vec[i].typename),sizes32[i],vec32[i].alignment);
305    }
306
307}
308
309void *
310emalloc(size_t bytes) {
311    size_t *memory;
312    memory = malloc(bytes);
313    if(memory == 0) {
314 printf("malloc failed\n");
315 exit(2);
316    }
317    return memory;
318}
319
320int
321main(int argc, char** argv)
322{
323    int i;
324
325    compute_alignments();
326
327    verify(vec);
328
329/*
330    for(i=0;i<NCTYPES;i++) {
331 printf("%s:\talignment=%d\n",vec[i].typename,vec[i].alignment);
332    }
333*/
334    exit(0);
335}
336#endif /*OFFSETTEST*/


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed