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 @@
# include "../src/config.h"
#endif
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
......@@ -32,6 +33,14 @@ int vlistInqVarMissvalUsed(int vlistID, int varID);
# define IS_EQUAL(x,y) (!IS_NOT_EQUAL(x,y))
#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"
......@@ -499,14 +508,10 @@ void printShortinfo(int streamID, int vlistID, int vardis)
}
#undef IsBigendian
#define IsBigendian() ( u_byteorder.c[sizeof(long) - 1] )
static
void setDefaultDataType(char *datatypestr)
{
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
int nbits = -1;
enum {D_UINT, D_INT, D_FLT, D_CPX};
int dtype = -1;
......@@ -609,12 +614,12 @@ void setDefaultDataType(char *datatypestr)
{
if ( *datatypestr == 'l' || *datatypestr == 'L' )
{
if ( IsBigendian() ) DefaultByteorder = CDI_LITTLEENDIAN;
if ( HOST_ENDIANNESS == CDI_BIGENDIAN ) DefaultByteorder = CDI_LITTLEENDIAN;
datatypestr++;
}
else if ( *datatypestr == 'b' || *datatypestr == 'B' )
{
if ( ! IsBigendian() ) DefaultByteorder = CDI_BIGENDIAN;
if ( HOST_ENDIANNESS == CDI_LITTLEENDIAN ) DefaultByteorder = CDI_BIGENDIAN;
datatypestr++;
}
else
......
......@@ -2,65 +2,76 @@
# include "config.h"
#endif
#include <inttypes.h>
#include "cdi.h"
#include "error.h"
#include "file.h"
#include "swap.h"
#include "binary.h"
#undef IsBigendian
#define IsBigendian() ( u_byteorder.c[sizeof(long) - 1] )
UINT32 get_UINT32(unsigned char *x)
{
/* IsBigendian returns 1 for big endian byte order */
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
if ( IsBigendian() )
return((UINT32)(((UINT32)x[0]<<24)+((UINT32)x[1]<<16)+((UINT32)x[2]<< 8)+ (UINT32)x[3]));
else
return((UINT32)(((UINT32)x[3]<<24)+((UINT32)x[2]<<16)+((UINT32)x[1]<< 8)+ (UINT32)x[0]));
switch (HOST_ENDIANNESS)
{
case CDI_BIGENDIAN:
return((UINT32)(((UINT32)x[0]<<24)+((UINT32)x[1]<<16)+((UINT32)x[2]<< 8)+ (UINT32)x[3]));
case CDI_LITTLEENDIAN:
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)
{
/* IsBigendian returns 1 for big endian byte order */
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
if ( IsBigendian() )
return((UINT32)(((UINT32)x[3]<<24)+((UINT32)x[2]<<16)+((UINT32)x[1]<< 8)+ (UINT32)x[0]));
else
return((UINT32)(((UINT32)x[0]<<24)+((UINT32)x[1]<<16)+((UINT32)x[2]<< 8)+ (UINT32)x[3]));
switch (HOST_ENDIANNESS)
{
case CDI_BIGENDIAN:
return((UINT32)(((UINT32)x[3]<<24)+((UINT32)x[2]<<16)+((UINT32)x[1]<< 8)+ (UINT32)x[0]));
case CDI_LITTLEENDIAN:
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)
{
/* IsBigendian returns 1 for big endian byte order */
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
if ( IsBigendian() )
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]));
else
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]));
switch (HOST_ENDIANNESS)
{
case CDI_BIGENDIAN:
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]));
case CDI_LITTLEENDIAN:
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]));
default:
Error("unhandled endianness %d", HOST_ENDIANNESS);
return UINT64_C(0xFFFFFFFFFFFFFFFF);
}
}
UINT64 get_SUINT64(unsigned char *x)
{
/* IsBigendian returns 1 for big endian byte order */
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
if ( IsBigendian() )
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]));
else
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]));
switch (HOST_ENDIANNESS)
{
case CDI_BIGENDIAN:
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]));
case CDI_LITTLEENDIAN:
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]));
default:
Error("unhandled endianness %d", HOST_ENDIANNESS);
return UINT64_C(0xFFFFFFFFFFFFFFFF);
}
}
......@@ -83,11 +94,11 @@ size_t binReadF77Block(int fileID, int byteswap)
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];
if ( IsBigendian() )
switch (HOST_ENDIANNESS)
{
case CDI_BIGENDIAN:
if ( byteswap )
{
f77block[0] = (unsigned char) (blocksize);
......@@ -102,9 +113,8 @@ void binWriteF77Block(int fileID, int byteswap, size_t blocksize)
f77block[1] = (unsigned char) (blocksize >> 16);
f77block[0] = (unsigned char) (blocksize >> 24);
}
}
else
{
break;
case CDI_LITTLEENDIAN:
if ( byteswap )
{
f77block[3] = (unsigned char) (blocksize);
......@@ -119,6 +129,9 @@ void binWriteF77Block(int fileID, int byteswap, size_t blocksize)
f77block[2] = (unsigned char) (blocksize >> 16);
f77block[3] = (unsigned char) (blocksize >> 24);
}
break;
default:
Error("unhandled endianness %d", HOST_ENDIANNESS);
}
if ( fileWrite(fileID, f77block, 4) != 4 )
......
#ifndef _BINARY_H
#define _BINARY_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <inttypes.h>
#include <stdio.h>
#ifndef _DTYPES_H
#include "dtypes.h"
#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_SUINT32(unsigned char *x);
......
......@@ -23,6 +23,7 @@ extern "C" {
#define CDI_BIGENDIAN 0 /* Byte order BIGENDIAN */
#define CDI_LITTLEENDIAN 1 /* Byte order LITTLEENDIAN */
#define CDI_PDPENDIAN 2
#define CDI_REAL 1 /* Real numbers */
#define CDI_COMP 2 /* Complex numbers */
......
......@@ -20,6 +20,8 @@
PARAMETER (CDI_BIGENDIAN = 0)
INTEGER CDI_LITTLEENDIAN
PARAMETER (CDI_LITTLEENDIAN = 1)
INTEGER CDI_PDPENDIAN
PARAMETER (CDI_PDPENDIAN = 2)
INTEGER CDI_REAL
PARAMETER (CDI_REAL = 1)
INTEGER CDI_COMP
......
......@@ -98,7 +98,6 @@ char *strdup(const char *s);
# define IS_EQUAL(x,y) (!IS_NOT_EQUAL(x,y))
#endif
#define FALSE 0
#define TRUE 1
......
......@@ -27,6 +27,7 @@ module mo_cdi
integer(c_int), public, parameter :: CDI_GLOBAL = -1
integer(c_int), public, parameter :: CDI_BIGENDIAN = 0
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_COMP = 2
integer(c_int), public, parameter :: CDI_BOTH = 3
......
......@@ -10,6 +10,7 @@
#include <stdio.h>
#include <string.h>
#include "binary.h"
#include "cdi.h"
#include "cdi_int.h"
#include "cdi_cksum.h"
......@@ -56,29 +57,25 @@ const resOps streamOps = {
#undef IsBigendian
#define IsBigendian() ( u_byteorder.c[sizeof(long) - 1] )
static
int getByteorder(int byteswap)
{
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
int byteorder = -1;
if ( IsBigendian() )
{
if ( byteswap ) byteorder = CDI_LITTLEENDIAN;
else byteorder = CDI_BIGENDIAN;
}
else
switch (HOST_ENDIANNESS)
{
if ( byteswap ) byteorder = CDI_BIGENDIAN;
else byteorder = CDI_LITTLEENDIAN;
case CDI_BIGENDIAN:
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
......@@ -206,16 +203,17 @@ int streamInqFiletype(int streamID)
int getByteswap(int byteorder)
{
static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
int byteswap = 0;
int byteswap = -1;
if ( IsBigendian() )
switch (byteorder)
{
if ( byteorder == CDI_LITTLEENDIAN ) byteswap = TRUE;
}
else
{
if ( byteorder == CDI_BIGENDIAN ) byteswap = TRUE;
case CDI_BIGENDIAN:
case CDI_LITTLEENDIAN:
case CDI_PDPENDIAN:
byteswap = (HOST_ENDIANNESS != byteorder);
break;
default:
Error("unexpected byteorder %d query!", byteorder);
}
return (byteswap);
......
......@@ -18,45 +18,45 @@
#include "binary.h"
#undef IsBigendian
#define IsBigendian() ( u_byteorder.c[sizeof(long) - 1] )
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 STRING(x) XSTRING(x)
fprintf (stderr, "+-------------+-----------+\n");
fprintf (stderr, "| INT32 | %-9s |\n", STRING(INT32));
fprintf (stderr, "| INT64 | %-9s |\n", STRING(INT64));
fprintf (stderr, "| FLT32 | %-9s |\n", STRING(FLT32));
fprintf (stderr, "| FLT64 | %-9s |\n", STRING(FLT64));
fprintf (stderr, "+-------------+-----------+\n");
if ( IsBigendian() )
fprintf (stderr, "\n byte ordering is BIGENDIAN\n\n");
else
fprintf (stderr, "\n byte ordering is LITTLEENDIAN\n\n");
fprintf (stderr, "+-------------+-------+\n"
"| types | bytes |\n"
"+-------------+-------+\n"
"| void * | %3d |\n"
"+-------------+-------+\n"
"| char | %3d |\n"
"+-------------+-------+\n"
"| short | %3d |\n"
"| int | %3d |\n"
"| long | %3d |\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-"
......
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