Commit 9fd40746 authored by Thomas Jahns's avatar Thomas Jahns 🤸
Browse files

Use C99 literals in endianness detection.

* This way no static variables are needed,
  unless the source is compiled with C++.
parent 96c9fdb3
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# include "../src/config.h" # include "../src/config.h"
#endif #endif
#include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
...@@ -32,6 +33,14 @@ int vlistInqVarMissvalUsed(int vlistID, int varID); ...@@ -32,6 +33,14 @@ int vlistInqVarMissvalUsed(int vlistID, int varID);
# define IS_EQUAL(x,y) (!IS_NOT_EQUAL(x,y)) # define IS_EQUAL(x,y) (!IS_NOT_EQUAL(x,y))
#endif #endif
#ifndef HOST_ENDIANNESS
#ifdef __cplusplus
static const uint32_t HOST_ENDIANNESS_temp[1] = { UINT32_C(0x00030201) };
#define HOST_ENDIANNESS (((const unsigned char *)HOST_ENDIANNESS_temp)[0])
#else
#define HOST_ENDIANNESS (((const unsigned char *)&(const uint32_t[1]){UINT32_C(0x00030201)})[0])
#endif
#endif
#include "printinfo.h" #include "printinfo.h"
...@@ -499,14 +508,10 @@ void printShortinfo(int streamID, int vlistID, int vardis) ...@@ -499,14 +508,10 @@ void printShortinfo(int streamID, int vlistID, int vardis)
} }
#undef IsBigendian
#define IsBigendian() ( u_byteorder.c[sizeof(long) - 1] )
static static
void setDefaultDataType(char *datatypestr) void setDefaultDataType(char *datatypestr)
{ {
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
int nbits = -1; int nbits = -1;
enum {D_UINT, D_INT, D_FLT, D_CPX}; enum {D_UINT, D_INT, D_FLT, D_CPX};
int dtype = -1; int dtype = -1;
...@@ -609,12 +614,12 @@ void setDefaultDataType(char *datatypestr) ...@@ -609,12 +614,12 @@ void setDefaultDataType(char *datatypestr)
{ {
if ( *datatypestr == 'l' || *datatypestr == 'L' ) if ( *datatypestr == 'l' || *datatypestr == 'L' )
{ {
if ( IsBigendian() ) DefaultByteorder = CDI_LITTLEENDIAN; if ( HOST_ENDIANNESS == CDI_BIGENDIAN ) DefaultByteorder = CDI_LITTLEENDIAN;
datatypestr++; datatypestr++;
} }
else if ( *datatypestr == 'b' || *datatypestr == 'B' ) else if ( *datatypestr == 'b' || *datatypestr == 'B' )
{ {
if ( ! IsBigendian() ) DefaultByteorder = CDI_BIGENDIAN; if ( HOST_ENDIANNESS == CDI_LITTLEENDIAN ) DefaultByteorder = CDI_BIGENDIAN;
datatypestr++; datatypestr++;
} }
else else
......
...@@ -2,65 +2,76 @@ ...@@ -2,65 +2,76 @@
# include "config.h" # include "config.h"
#endif #endif
#include <inttypes.h>
#include "cdi.h"
#include "error.h" #include "error.h"
#include "file.h" #include "file.h"
#include "swap.h" #include "swap.h"
#include "binary.h" #include "binary.h"
#undef IsBigendian
#define IsBigendian() ( u_byteorder.c[sizeof(long) - 1] )
UINT32 get_UINT32(unsigned char *x) UINT32 get_UINT32(unsigned char *x)
{ {
/* IsBigendian returns 1 for big endian byte order */ switch (HOST_ENDIANNESS)
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1}; {
case CDI_BIGENDIAN:
if ( IsBigendian() ) return((UINT32)(((UINT32)x[0]<<24)+((UINT32)x[1]<<16)+((UINT32)x[2]<< 8)+ (UINT32)x[3]));
return((UINT32)(((UINT32)x[0]<<24)+((UINT32)x[1]<<16)+((UINT32)x[2]<< 8)+ (UINT32)x[3])); case CDI_LITTLEENDIAN:
else return ((UINT32)(((UINT32)x[3]<<24)+((UINT32)x[2]<<16)+((UINT32)x[1]<< 8)+ (UINT32)x[0]));
return((UINT32)(((UINT32)x[3]<<24)+((UINT32)x[2]<<16)+((UINT32)x[1]<< 8)+ (UINT32)x[0])); default:
Error("unhandled endianness %d", HOST_ENDIANNESS);
return UINT32_C(0xFFFFFFFF);
}
} }
UINT32 get_SUINT32(unsigned char *x) UINT32 get_SUINT32(unsigned char *x)
{ {
/* IsBigendian returns 1 for big endian byte order */ switch (HOST_ENDIANNESS)
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1}; {
case CDI_BIGENDIAN:
if ( IsBigendian() ) return((UINT32)(((UINT32)x[3]<<24)+((UINT32)x[2]<<16)+((UINT32)x[1]<< 8)+ (UINT32)x[0]));
return((UINT32)(((UINT32)x[3]<<24)+((UINT32)x[2]<<16)+((UINT32)x[1]<< 8)+ (UINT32)x[0])); case CDI_LITTLEENDIAN:
else return((UINT32)(((UINT32)x[0]<<24)+((UINT32)x[1]<<16)+((UINT32)x[2]<< 8)+ (UINT32)x[3]));
return((UINT32)(((UINT32)x[0]<<24)+((UINT32)x[1]<<16)+((UINT32)x[2]<< 8)+ (UINT32)x[3])); default:
Error("unhandled endianness %d", HOST_ENDIANNESS);
return UINT32_C(0xFFFFFFFF);
}
} }
UINT64 get_UINT64(unsigned char *x) UINT64 get_UINT64(unsigned char *x)
{ {
/* IsBigendian returns 1 for big endian byte order */ switch (HOST_ENDIANNESS)
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1}; {
case CDI_BIGENDIAN:
if ( IsBigendian() ) return((UINT64)(((UINT64)x[0]<<56)+((UINT64)x[1]<<48)+((UINT64)x[2]<<40)+((UINT64)x[3]<<32)+
return((UINT64)(((UINT64)x[0]<<56)+((UINT64)x[1]<<48)+((UINT64)x[2]<<40)+((UINT64)x[3]<<32)+ ((UINT64)x[4]<<24)+((UINT64)x[5]<<16)+((UINT64)x[6]<< 8)+ (UINT64)x[7]));
((UINT64)x[4]<<24)+((UINT64)x[5]<<16)+((UINT64)x[6]<< 8)+ (UINT64)x[7])); case CDI_LITTLEENDIAN:
else return((UINT64)(((UINT64)x[7]<<56)+((UINT64)x[6]<<48)+((UINT64)x[5]<<40)+((UINT64)x[4]<<32)+
return((UINT64)(((UINT64)x[7]<<56)+((UINT64)x[6]<<48)+((UINT64)x[5]<<40)+((UINT64)x[4]<<32)+ ((UINT64)x[3]<<24)+((UINT64)x[2]<<16)+((UINT64)x[1]<< 8)+ (UINT64)x[0]));
((UINT64)x[3]<<24)+((UINT64)x[2]<<16)+((UINT64)x[1]<< 8)+ (UINT64)x[0])); default:
Error("unhandled endianness %d", HOST_ENDIANNESS);
return UINT64_C(0xFFFFFFFFFFFFFFFF);
}
} }
UINT64 get_SUINT64(unsigned char *x) UINT64 get_SUINT64(unsigned char *x)
{ {
/* IsBigendian returns 1 for big endian byte order */ switch (HOST_ENDIANNESS)
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1}; {
case CDI_BIGENDIAN:
if ( IsBigendian() ) return((UINT64)(((UINT64)x[7]<<56)+((UINT64)x[6]<<48)+((UINT64)x[5]<<40)+((UINT64)x[4]<<32)+
return((UINT64)(((UINT64)x[7]<<56)+((UINT64)x[6]<<48)+((UINT64)x[5]<<40)+((UINT64)x[4]<<32)+ ((UINT64)x[3]<<24)+((UINT64)x[2]<<16)+((UINT64)x[1]<< 8)+ (UINT64)x[0]));
((UINT64)x[3]<<24)+((UINT64)x[2]<<16)+((UINT64)x[1]<< 8)+ (UINT64)x[0])); case CDI_LITTLEENDIAN:
else return((UINT64)(((UINT64)x[0]<<56)+((UINT64)x[1]<<48)+((UINT64)x[2]<<40)+((UINT64)x[3]<<32)+
return((UINT64)(((UINT64)x[0]<<56)+((UINT64)x[1]<<48)+((UINT64)x[2]<<40)+((UINT64)x[3]<<32)+ ((UINT64)x[4]<<24)+((UINT64)x[5]<<16)+((UINT64)x[6]<< 8)+ (UINT64)x[7]));
((UINT64)x[4]<<24)+((UINT64)x[5]<<16)+((UINT64)x[6]<< 8)+ (UINT64)x[7])); default:
Error("unhandled endianness %d", HOST_ENDIANNESS);
return UINT64_C(0xFFFFFFFFFFFFFFFF);
}
} }
...@@ -83,11 +94,11 @@ size_t binReadF77Block(int fileID, int byteswap) ...@@ -83,11 +94,11 @@ size_t binReadF77Block(int fileID, int byteswap)
void binWriteF77Block(int fileID, int byteswap, size_t blocksize) void binWriteF77Block(int fileID, int byteswap, size_t blocksize)
{ {
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
unsigned char f77block[4]; unsigned char f77block[4];
if ( IsBigendian() ) switch (HOST_ENDIANNESS)
{ {
case CDI_BIGENDIAN:
if ( byteswap ) if ( byteswap )
{ {
f77block[0] = (unsigned char) (blocksize); f77block[0] = (unsigned char) (blocksize);
...@@ -102,9 +113,8 @@ void binWriteF77Block(int fileID, int byteswap, size_t blocksize) ...@@ -102,9 +113,8 @@ void binWriteF77Block(int fileID, int byteswap, size_t blocksize)
f77block[1] = (unsigned char) (blocksize >> 16); f77block[1] = (unsigned char) (blocksize >> 16);
f77block[0] = (unsigned char) (blocksize >> 24); f77block[0] = (unsigned char) (blocksize >> 24);
} }
} break;
else case CDI_LITTLEENDIAN:
{
if ( byteswap ) if ( byteswap )
{ {
f77block[3] = (unsigned char) (blocksize); f77block[3] = (unsigned char) (blocksize);
...@@ -119,6 +129,9 @@ void binWriteF77Block(int fileID, int byteswap, size_t blocksize) ...@@ -119,6 +129,9 @@ void binWriteF77Block(int fileID, int byteswap, size_t blocksize)
f77block[2] = (unsigned char) (blocksize >> 16); f77block[2] = (unsigned char) (blocksize >> 16);
f77block[3] = (unsigned char) (blocksize >> 24); f77block[3] = (unsigned char) (blocksize >> 24);
} }
break;
default:
Error("unhandled endianness %d", HOST_ENDIANNESS);
} }
if ( fileWrite(fileID, f77block, 4) != 4 ) if ( fileWrite(fileID, f77block, 4) != 4 )
......
#ifndef _BINARY_H #ifndef _BINARY_H
#define _BINARY_H #define _BINARY_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#ifndef _DTYPES_H #ifndef _DTYPES_H
#include "dtypes.h" #include "dtypes.h"
#endif #endif
#ifndef HOST_ENDIANNESS
#ifdef __cplusplus
static const uint32_t HOST_ENDIANNESS_temp[1] = { UINT32_C(0x00030201) };
#define HOST_ENDIANNESS (((const unsigned char *)HOST_ENDIANNESS_temp)[0])
#else
#define HOST_ENDIANNESS (((const unsigned char *)&(const uint32_t[1]){UINT32_C(0x00030201)})[0])
#endif
#endif
UINT32 get_UINT32(unsigned char *x); UINT32 get_UINT32(unsigned char *x);
UINT32 get_SUINT32(unsigned char *x); UINT32 get_SUINT32(unsigned char *x);
......
...@@ -23,6 +23,7 @@ extern "C" { ...@@ -23,6 +23,7 @@ extern "C" {
#define CDI_BIGENDIAN 0 /* Byte order BIGENDIAN */ #define CDI_BIGENDIAN 0 /* Byte order BIGENDIAN */
#define CDI_LITTLEENDIAN 1 /* Byte order LITTLEENDIAN */ #define CDI_LITTLEENDIAN 1 /* Byte order LITTLEENDIAN */
#define CDI_PDPENDIAN 2
#define CDI_REAL 1 /* Real numbers */ #define CDI_REAL 1 /* Real numbers */
#define CDI_COMP 2 /* Complex numbers */ #define CDI_COMP 2 /* Complex numbers */
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
PARAMETER (CDI_BIGENDIAN = 0) PARAMETER (CDI_BIGENDIAN = 0)
INTEGER CDI_LITTLEENDIAN INTEGER CDI_LITTLEENDIAN
PARAMETER (CDI_LITTLEENDIAN = 1) PARAMETER (CDI_LITTLEENDIAN = 1)
INTEGER CDI_PDPENDIAN
PARAMETER (CDI_PDPENDIAN = 2)
INTEGER CDI_REAL INTEGER CDI_REAL
PARAMETER (CDI_REAL = 1) PARAMETER (CDI_REAL = 1)
INTEGER CDI_COMP INTEGER CDI_COMP
......
...@@ -98,7 +98,6 @@ char *strdup(const char *s); ...@@ -98,7 +98,6 @@ char *strdup(const char *s);
# define IS_EQUAL(x,y) (!IS_NOT_EQUAL(x,y)) # define IS_EQUAL(x,y) (!IS_NOT_EQUAL(x,y))
#endif #endif
#define FALSE 0 #define FALSE 0
#define TRUE 1 #define TRUE 1
......
...@@ -27,6 +27,7 @@ module mo_cdi ...@@ -27,6 +27,7 @@ module mo_cdi
integer(c_int), public, parameter :: CDI_GLOBAL = -1 integer(c_int), public, parameter :: CDI_GLOBAL = -1
integer(c_int), public, parameter :: CDI_BIGENDIAN = 0 integer(c_int), public, parameter :: CDI_BIGENDIAN = 0
integer(c_int), public, parameter :: CDI_LITTLEENDIAN = 1 integer(c_int), public, parameter :: CDI_LITTLEENDIAN = 1
integer(c_int), public, parameter :: CDI_PDPENDIAN = 2
integer(c_int), public, parameter :: CDI_REAL = 1 integer(c_int), public, parameter :: CDI_REAL = 1
integer(c_int), public, parameter :: CDI_COMP = 2 integer(c_int), public, parameter :: CDI_COMP = 2
integer(c_int), public, parameter :: CDI_BOTH = 3 integer(c_int), public, parameter :: CDI_BOTH = 3
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "binary.h"
#include "cdi.h" #include "cdi.h"
#include "cdi_int.h" #include "cdi_int.h"
#include "cdi_cksum.h" #include "cdi_cksum.h"
...@@ -56,29 +57,25 @@ const resOps streamOps = { ...@@ -56,29 +57,25 @@ const resOps streamOps = {
#undef IsBigendian
#define IsBigendian() ( u_byteorder.c[sizeof(long) - 1] )
static static
int getByteorder(int byteswap) int getByteorder(int byteswap)
{ {
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
int byteorder = -1; int byteorder = -1;
if ( IsBigendian() ) switch (HOST_ENDIANNESS)
{
if ( byteswap ) byteorder = CDI_LITTLEENDIAN;
else byteorder = CDI_BIGENDIAN;
}
else
{ {
if ( byteswap ) byteorder = CDI_BIGENDIAN; case CDI_BIGENDIAN:
else byteorder = CDI_LITTLEENDIAN; byteorder = byteswap ? CDI_LITTLEENDIAN : CDI_BIGENDIAN;
break;
case CDI_LITTLEENDIAN:
byteorder = byteswap ? CDI_BIGENDIAN : CDI_LITTLEENDIAN;
break;
/* FIXME: does not currently adjust for PDP endianness */
case CDI_PDPENDIAN:
default:
Error("unhandled endianness");
} }
return byteorder;
return (byteorder);
} }
// used also in CDO // used also in CDO
...@@ -206,16 +203,17 @@ int streamInqFiletype(int streamID) ...@@ -206,16 +203,17 @@ int streamInqFiletype(int streamID)
int getByteswap(int byteorder) int getByteswap(int byteorder)
{ {
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1}; int byteswap = -1;
int byteswap = 0;
if ( IsBigendian() ) switch (byteorder)
{ {
if ( byteorder == CDI_LITTLEENDIAN ) byteswap = TRUE; case CDI_BIGENDIAN:
} case CDI_LITTLEENDIAN:
else case CDI_PDPENDIAN:
{ byteswap = (HOST_ENDIANNESS != byteorder);
if ( byteorder == CDI_BIGENDIAN ) byteswap = TRUE; break;
default:
Error("unexpected byteorder %d query!", byteorder);
} }
return (byteswap); return (byteswap);
......
...@@ -18,45 +18,45 @@ ...@@ -18,45 +18,45 @@
#include "binary.h" #include "binary.h"
#undef IsBigendian
#define IsBigendian() ( u_byteorder.c[sizeof(long) - 1] )
void cdiPrintDatatypes(void) void cdiPrintDatatypes(void)
{ {
/* IsBigendian returns 1 for big endian byte order */
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
fprintf (stderr, "+-------------+-------+\n");
fprintf (stderr, "| types | bytes |\n");
fprintf (stderr, "+-------------+-------+\n");
fprintf (stderr, "| void * | %3d |\n", (int) sizeof(void *));
fprintf (stderr, "+-------------+-------+\n");
fprintf (stderr, "| char | %3d |\n", (int) sizeof(char));
fprintf (stderr, "+-------------+-------+\n");
fprintf (stderr, "| short | %3d |\n", (int) sizeof(short));
fprintf (stderr, "| int | %3d |\n", (int) sizeof(int));
fprintf (stderr, "| long | %3d |\n", (int) sizeof(long));
fprintf (stderr, "| long long | %3d |\n", (int) sizeof(long long));
fprintf (stderr, "| size_t | %3d |\n", (int) sizeof(size_t));
fprintf (stderr, "| off_t | %3d |\n", (int) sizeof(off_t));
fprintf (stderr, "+-------------+-------+\n");
fprintf (stderr, "| float | %3d |\n", (int) sizeof(float));
fprintf (stderr, "| double | %3d |\n", (int) sizeof(double));
fprintf (stderr, "| long double | %3d |\n", (int) sizeof(long double));
fprintf (stderr, "+-------------+-------+\n\n");
#define XSTRING(x) #x #define XSTRING(x) #x
#define STRING(x) XSTRING(x) #define STRING(x) XSTRING(x)
fprintf (stderr, "+-------------+-----------+\n"); fprintf (stderr, "+-------------+-------+\n"
fprintf (stderr, "| INT32 | %-9s |\n", STRING(INT32)); "| types | bytes |\n"
fprintf (stderr, "| INT64 | %-9s |\n", STRING(INT64)); "+-------------+-------+\n"
fprintf (stderr, "| FLT32 | %-9s |\n", STRING(FLT32)); "| void * | %3d |\n"
fprintf (stderr, "| FLT64 | %-9s |\n", STRING(FLT64)); "+-------------+-------+\n"
fprintf (stderr, "+-------------+-----------+\n"); "| char | %3d |\n"
"+-------------+-------+\n"
if ( IsBigendian() ) "| short | %3d |\n"
fprintf (stderr, "\n byte ordering is BIGENDIAN\n\n"); "| int | %3d |\n"
else "| long | %3d |\n"
fprintf (stderr, "\n byte ordering is LITTLEENDIAN\n\n"); "| long long | %3d |\n"
"| size_t | %3d |\n"
"| off_t | %3d |\n"
"+-------------+-------+\n"
"| float | %3d |\n"
"| double | %3d |\n"
"| long double | %3d |\n"
"+-------------+-------+\n\n"
"+-------------+-----------+\n"
"| INT32 | %-9s |\n"
"| INT64 | %-9s |\n"
"| FLT32 | %-9s |\n"
"| FLT64 | %-9s |\n"
"+-------------+-----------+\n"
"\n byte ordering is %s\n\n",
(int) sizeof(void *), (int) sizeof(char),
(int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(long long),
(int) sizeof(size_t), (int) sizeof(off_t),
(int) sizeof(float), (int) sizeof(double), (int) sizeof(long double),
STRING(INT32), STRING(INT64), STRING(FLT32), STRING(FLT64),
((HOST_ENDIANNESS == CDI_BIGENDIAN) ? "BIGENDIAN"
: ((HOST_ENDIANNESS == CDI_LITTLEENDIAN) ? "LITTLEENDIAN"
: "Unhandled endianness!")));
#undef STRING
#undef XSTRING
} }
static const char uuidFmt[] = "%02hhx%02hhx%02hhx%02hhx-" static const char uuidFmt[] = "%02hhx%02hhx%02hhx%02hhx-"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment