-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdat1_show_ndr.c
374 lines (340 loc) · 17 KB
/
dat1_show_ndr.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include "hds1.h" /* Global definitions for HDS */
#include "rec1.h" /* Internal rec_ definitions */
#include "dat1.h" /* Internal dat_ definitions */
#include "dat_err.h" /* DAT__ error code definitions */
void dat1_show_ndr( int *status )
{
/*+ */
/* Name: */
/* dat1_show_ndr */
/* Purpose: */
/* Display native data representation information for the host machine. */
/* Invocation: */
/* dat1_show_ndr( status ) */
/* Description: */
/* This function formats and displays the contents of the global native */
/* data representation structure which holds information about the way */
/* primitive values are stored on the current host machine. The results */
/* are written to the standard output. This routine is provided as an */
/* implementation aid only; the output format is liable to change */
/* without notice. */
/* Parameters: */
/* int *status */
/* The inherited global status. */
/* Returned Value: */
/* void */
/* Notes: */
/* This routine makes much use of macros because it must apply similar */
/* processing to a range of arithmetic data types whose characteristics */
/* are not known directly (typically they are themselves parameterised */
/* via the HDS primitive type macros). The macros used here appear, and */
/* are commented, as if they formed part of the normal executable code. */
/* Copyright: */
/* Copyright (C) 1992 Science & Engineering Research Council */
/* Authors: */
/* RFWS: R.F. Warren-Smith (STARLINK) */
/* TIMJ: Tim Jenness (JAC, Hawaii) */
/* {@enter_new_authors_here@} */
/* History: */
/* 4-SEP-1992 (RFWS): */
/* Original version. */
/* 5-OCT-1992 (RFWS): */
/* Changed to display and use decimal digits of precision value. */
/* 20-APR-2012 (TIMJ): */
/* Add _INT64 support. */
/* {@enter_further_changes_here@} */
/* Bugs: */
/* {@note_any_bugs_here@} */
/*- */
/* Local Variables: */
char hexbuf[ 101 ]; /* Buffer for formatting hex values */
const char *txt; /* Pointer to text for output */
int i; /* Loop counter for data types */
/*. */
/* Check the inherited global status. */
if ( !_ok( *status ) ) return;
/* Define macros. */
/* ============= */
/* Note that these macros execute in the context of the main display loop */
/* (below). Any variables not declared within the macro itself take their */
/* values from variables used within that loop. */
/* Define a macro to determine if an integer data type is signed or not, */
/* returning 0 or 1. */
#define _signed( dtype ) ( ( (dtype) -1 ) < ( (dtype) 0 ) )
/* Define a macro to format a value (given by the value argument) in */
/* hexadecimal format, where the bytes are stored in a specified order */
/* (given by the order argument with value DAT__LSB or DAT__MSB). The */
/* null-terminated result string is written to the char buffer hexbuf. */
#define _hexfmt( value, order )\
{\
int j; /* Byte counter for formatting hex values */\
int k; /* Character count for hex values */\
unsigned char *ptr; /* Pointer to byte sequence for formatting */\
\
/* Obtain a pointer to the byte sequence to be formatted. Loop through */\
/* these bytes looking at the most significant first. */\
ptr = (unsigned char *) &(value);\
if ( (order) == DAT__MSB )\
{\
for ( j = 0, k = 0; j < sizeof( value ); j++, k += 2 )\
{\
\
/* Write the hexadecimal equivalent of each byte into hexbuf (we assume */\
/* 8-bit bytes here). */\
(void) sprintf( hexbuf + k, "%02X", (unsigned int) ptr[ j ] );\
}\
}\
\
/* Handle the reverse byte order if necessary. */\
else if ( (order) == DAT__LSB )\
{\
for ( j = sizeof( value ) - 1, k = 0; j >= 0; j--, k += 2 )\
{\
(void) sprintf( hexbuf + k, "%02X", (unsigned int) ptr[ j ] );\
}\
}\
}
/* Define a macro for displaying values for the _CHAR data type. This is a */
/* special case; display the bad data value only using character format */
/* (and hexadecimal). */
#define _showc( dtype, t )\
{\
_hexfmt( dat_gl_ndr[ i ].bad.t, dat_gl_ndr[ i ].order )\
(void) printf( " Bad data value: \'%c\' (hex %s)\n",\
(int) dat_gl_ndr[ i ].bad.t, hexbuf );\
}
/* Define a macro for displaying _LOGICAL values. This is also a special */
/* case; display the bad data value only, but use integer format taking */
/* account of whether it is a signed data type or not. */
#define _showl( dtype, t )\
{\
_hexfmt( dat_gl_ndr[ i ].bad.t, dat_gl_ndr[ i ].order )\
\
/* If the data type is signed, then cast to long int for display. */\
if ( _signed( dtype ) )\
{\
(void) printf( " Bad data value: %-ld (hex %s)\n",\
(long int) dat_gl_ndr[ i ].bad.t, hexbuf );\
}\
\
/* If it is unsigned, then cast to unsigned long int. */\
else\
{\
(void) printf( " Bad data value: %-lu (hex %s)\n",\
(unsigned long int) dat_gl_ndr[ i ].bad.t, hexbuf );\
}\
}
/* Define a macro for displaying integer values. Display the minimum, */
/* maximum and bad data values, taking account of whether the data type is */
/* signed or not. */
#define _showi( dtype, t )\
{\
\
/* Display each value right justified within a field width given by its */\
/* txtsize value. Follow it by its value in hexadecimal. Cast values to */\
/* 64-bit int type for display if they are signed. */\
if ( _signed( dtype ) )\
{\
_hexfmt( dat_gl_ndr[ i ].min.t, dat_gl_ndr[ i ].order )\
(void) printf( " Minimum value: %*"INT_BIG_S" (hex %s)\n",\
(int) dat_gl_ndr[ i ].txtsize,\
(INT_BIG) dat_gl_ndr[ i ].min.t, hexbuf );\
_hexfmt( dat_gl_ndr[ i ].max.t, dat_gl_ndr[ i ].order )\
(void) printf( " Maximum value: %*"INT_BIG_S" (hex %s)\n",\
(int) dat_gl_ndr[ i ].txtsize,\
(INT_BIG) dat_gl_ndr[ i ].max.t, hexbuf );\
_hexfmt( dat_gl_ndr[ i ].bad.t, dat_gl_ndr[ i ].order )\
(void) printf( " Bad data value: %*"INT_BIG_S" (hex %s)\n",\
(int) dat_gl_ndr[ i ].txtsize,\
(INT_BIG) dat_gl_ndr[ i ].bad.t, hexbuf );\
}\
else\
{\
\
/* Cast unsigned values to unsigned 64-bit int for display. */\
_hexfmt( dat_gl_ndr[ i ].min.t, dat_gl_ndr[ i ].order )\
(void) printf( " Minimum value: %*"INT_BIG_U" (hex %s)\n",\
(int) dat_gl_ndr[ i ].txtsize,\
(UINT_BIG) dat_gl_ndr[ i ].min.t,\
hexbuf );\
_hexfmt( dat_gl_ndr[ i ].max.t, dat_gl_ndr[ i ].order )\
(void) printf( " Maximum value: %*"INT_BIG_U" (hex %s)\n",\
(int) dat_gl_ndr[ i ].txtsize,\
(UINT_BIG) dat_gl_ndr[ i ].max.t,\
hexbuf );\
_hexfmt( dat_gl_ndr[ i ].bad.t, dat_gl_ndr[ i ].order )\
(void) printf( " Bad data value: %*"INT_BIG_U" (hex %s)\n",\
(int) dat_gl_ndr[ i ].txtsize,\
(UINT_BIG) dat_gl_ndr[ i ].bad.t,\
hexbuf );\
}\
}
/* Define a macro for displaying floating-point values. Display the */
/* precision and the minimum, maximum and bad data values. There is no */
/* clear way of deciding how to format the hexadecimal representation here */
/* so that it will be meaningful (it depends on the byte order), so use the */
/* _INTEGER byte order as the best guess. */
#if ( __STDC__ == 1 ) && defined( _longd )
#define _showf( dtype, t )\
{\
\
/* Display the precision. */\
(void) printf( " Decimal digits of precision: %d\n",\
(int) dat_gl_ndr[ i ].digits );\
\
/* Cast values to long double for display. */\
_hexfmt( dat_gl_ndr[ i ].min.t, dat_gl_ndr[ DAT__I ].order )\
(void) printf( " Minimum value: %*.*LE (hex %s)\n",\
(int) dat_gl_ndr[ i ].txtsize,\
(int) ( dat_gl_ndr[ i ].digits - 1 ),\
(long double) dat_gl_ndr[ i ].min.t, hexbuf );\
_hexfmt( dat_gl_ndr[ i ].max.t, dat_gl_ndr[ DAT__I ].order )\
(void) printf( " Maximum value: %*.*LE (hex %s)\n",\
(int) dat_gl_ndr[ i ].txtsize,\
(int) ( dat_gl_ndr[ i ].digits - 1 ),\
(long double) dat_gl_ndr[ i ].max.t, hexbuf );\
_hexfmt( dat_gl_ndr[ i ].bad.t, dat_gl_ndr[ DAT__I ].order )\
(void) printf( " Bad data value: %*.*LE (hex %s)\n",\
(int) dat_gl_ndr[ i ].txtsize,\
(int) ( dat_gl_ndr[ i ].digits - 1 ),\
(long double) dat_gl_ndr[ i ].bad.t, hexbuf );\
}
#else
/* Don't use long double if it is not supported by the compiler. Use double */
/* instead. */
#define _showf( dtype, t )\
{\
(void) printf( " Decimal digits of precision: %d\n",\
(int) dat_gl_ndr[ i ].digits );\
_hexfmt( dat_gl_ndr[ i ].min.t, dat_gl_ndr[ DAT__I ].order )\
(void) printf( " Minimum value: %*.*E (hex %s)\n",\
(int) dat_gl_ndr[ i ].txtsize,\
(int) ( dat_gl_ndr[ i ].digits - 1 ),\
(double) dat_gl_ndr[ i ].min.t, hexbuf );\
_hexfmt( dat_gl_ndr[ i ].max.t, dat_gl_ndr[ DAT__I ].order )\
(void) printf( " Maximum value: %*.*E (hex %s)\n",\
(int) dat_gl_ndr[ i ].txtsize,\
(int) ( dat_gl_ndr[ i ].digits - 1 ),\
(double) dat_gl_ndr[ i ].max.t, hexbuf );\
_hexfmt( dat_gl_ndr[ i ].bad.t, dat_gl_ndr[ DAT__I ].order )\
(void) printf( " Bad data value: %*.*E (hex %s)\n",\
(int) dat_gl_ndr[ i ].txtsize,\
(int) ( dat_gl_ndr[ i ].digits - 1 ),\
(double) dat_gl_ndr[ i ].bad.t, hexbuf );\
}
#endif
/* Display information. */
/* =================== */
/* Loop to display information about each primitive type in turn. */
for ( i = 0; i < DAT__MXPRM; i++ )
{
/* Display a heading with the data type name. */
(void) printf( "\n" );
(void) printf( " %s data type:\n", dat_gl_ndr[ i ].name );
/* Show the data element size and the number of characters required for */
/* formatting. */
(void) printf( " Unformatted size in bytes: %d\n",
(int) dat_gl_ndr[ i ].length );
(void) printf( " Formatted size in characters: %d\n",
(int) dat_gl_ndr[ i ].txtsize );
/* Invoke the appropriate macro to display value information. */
switch ( i )
{
case DAT__C: _showc( _CHAR, C ) break;
case DAT__L: _showl( _LOGICAL, L ) break;
case DAT__B: _showi( _BYTE, B ) break;
case DAT__UB: _showi( _UBYTE, UB ) break;
case DAT__W: _showi( _WORD, W ) break;
case DAT__UW: _showi( _UWORD, UW ) break;
case DAT__I: _showi( _INTEGER, I ) break;
case DAT__K: _showi( _INT64, K ) break;
case DAT__R: _showf( _REAL, R ) break;
case DAT__D: _showf( _DOUBLE, D ) break;
}
/* Obtain a textual representation of the data format code. */
switch ( dat_gl_ndr[ i ].format )
{
case DAT__ASCII:
{
txt = "ASCII characters (\'ASCII\')";
break;
}
case DAT__BIT0:
{
txt = "Bit zero; 0 ==> FALSE, 1 ==> TRUE (\'BIT0\')";
break;
}
case DAT__NZ:
{
txt = "Zero ==> FALSE, non-zero ==> TRUE (\'NZ\')";
break;
}
case DAT__BINARY:
{
txt = "Binary integer (\'BINARY\')";
break;
}
case DAT__2COMP:
{
txt = "2\'s complement integer (\'2COMP\')";
break;
}
case DAT__VAXF:
{
txt = "VAX F-floating (\'VAXF\')";
break;
}
case DAT__VAXD:
{
txt = "VAX D-floating (\'VAXD\')";
break;
}
case DAT__IEEE_S:
{
txt = "IEEE single precision (\'IEEE_S\')";
break;
}
case DAT__IEEE_D:
{
txt = "IEEE double precision (\'IEEE_D\')";
break;
}
default:
{
txt = "?";
break;
}
}
/* Display the data format. */
(void) printf( " Data format: %s\n", txt );
/* Obtain a textual representation of the storage order. */
switch ( dat_gl_ndr[ i ].order )
{
case DAT__MSB:
{
txt = "Most significant byte first (\'MSB\')";
break;
}
case DAT__LSB:
{
txt = "Least significant byte first (\'LSB\')";
break;
}
default:
{
txt = "?";
break;
}
}
/* Display the storage order. */
(void) printf( " Storage order: %s\n", txt );
}
/* Add a final blank output line. */
(void) printf( "\n" );
/* Exit the routine. */
return;
}