diff --git a/README.md b/README.md
index 55c5119..fc07d9e 100644
--- a/README.md
+++ b/README.md
@@ -75,8 +75,13 @@ prior to invoking `make`. The following build variables can be configured:
- `CPPFLAGS`: C preprocessor flags, such as externally defined compiler constants.
- - `CFLAGS`: Flags to pass onto the C compiler (default: `-Os -Wall -std=c99`). Note, `-Iinclude` will be added
+ - `CFLAGS`: Flags to pass onto the C compiler (default: `-g -Os -Wall`). Note, `-Iinclude` will be added
automatically.
+
+ - `CSTANDARD`: Optionally, specify the C standard to compile for, e.g. `c99` to compile for the C99 standard. If
+ defined then `-std=$(CSTANDARD)` is added to `CFLAGS` automatically.
+
+ - `WEXTRA`: If set to 1, `-Wextra` is added to `CFLAGS` automatically.
- `LDFLAGS`: Extra linker flags (default: _not set_). Note, `-lm` will be added automatically.
@@ -162,25 +167,18 @@ shows the (`XType`) types recognized by the library and their C equivalents etc.
|------------------|--------------------------|----------------------------------------------------------|
| `X_BOOLEAN` | `boolean`* | '`true`' or '`false`' |
| `X_BYTE` | `char` or `int8_t` | '`-128`' to '`127`' |
- | `X_BYTE_HEX` | `char` or `[u]int8_t` | '`0x0`' to '`0xff`' (hexadecimal representation) |
| `X_SHORT` | `short` or `int16_t` | '`-32768`' to '`32767`' |
- | `X_SHORT_HEX` | `short` or `[u]int16_t` | '`0x0`' to '`0xffff`' (hexadecimal representation) |
| `X_INT` | `int32_t` | '`-2,147,483,648`' to '`2,147,483,647`' |
- | `X_INT_HEX` | `[u]int32_t` | '`0x0`' to '`0xffffffff`' (hexadecimal representation) |
| `X_LONG` | `long long` or `int64_t` | '`-9,223,372,036,854,775,808`' to '`9,223,372,036,854,775,807`' |
- | `X_LONG_HEX` | `[u]int64_t` | '`0x0`' to '`0xffffffffffffffff`' (hex. representation) |
| `X_FLOAT` | `float` | `1`, `1.0`, `-1.234567e-33` |
| `X_DOUBLE` | `double` | `1`, `1.0`, `-1.2345678901234567e-111` |
| `X_STRING` | `char *` | `Hello world!`, `line1\nline2\n` (0-terminated) |
| `X_CHARS(n) ` | `char[n]` | Fixed-length character arrays (also w/o termination) |
+ | `X_FIELD` | `XField` | For irregular and/or heterogeneous arrays |
| `X_STRUCT` | `XStructure` | substructure |
* The `boolean` type is defined in `xchange.h`.
-The `[...]_HEX` types are meaningful only for ASCII representations, and are otherwise equivalent to the corresponding
-regular integer-types of the same width. They are meant only as a way to explicitly define whether or not an integer
-value is to be represented in hexadecimal format rather than the default decimal format.
-
#### Strings
diff --git a/config.mk b/config.mk
index ef2c2cb..bad8e38 100644
--- a/config.mk
+++ b/config.mk
@@ -21,10 +21,17 @@ CC ?= gcc
CPPFLAGS += -I$(INC)
# Base compiler options (if not defined externally...)
-CFLAGS ?= -g -Os -Wall -std=c99
+CFLAGS ?= -g -Os -Wall
+
+# Compile for specific C standard
+ifdef CSTANDARD
+ CFLAGS += -std=$(CSTANDARD)
+endif
# Extra warnings (not supported on all compilers)
-#CFLAGS += -Wextra
+ifeq ($(WEXTRA), 1)
+ CFLAGS += -Wextra
+endif
# Extra linker flags to use
#LDFLAGS =
diff --git a/include/xchange.h b/include/xchange.h
index b1b7924..a4d3798 100644
--- a/include/xchange.h
+++ b/include/xchange.h
@@ -85,13 +85,9 @@ typedef int XType; ///< SMA-X data type.
#define X_UNKNOWN 0 ///< Unknown XType (default)
#define X_BOOLEAN '?' ///< \hideinitializer boolean XType
#define X_BYTE 'B' ///< \hideinitializer single byte XType
-#define X_BYTE_HEX '#' ///< \hideinitializer single byte XType in dexadecimal representation
#define X_SHORT 'S' ///< \hideinitializer native short XType (usually 16-bits)
-#define X_SHORT_HEX 'h' ///< \hideinitializer native short XType in hexadecimal representation
#define X_INT 'L' ///< \hideinitializer native int XType (usually 16-bits)
-#define X_INT_HEX 'H' ///< \hideinitializer native int XType in hexadecimal representation
#define X_LONG 'Y' ///< \hideinitializer 64-bit int XType
-#define X_LONG_HEX 'Z' ///< \hideinitializer 64-bit int XType in hexadecimal representation
#define X_FLOAT 'F' ///< \hideinitializer 32-bit floating point XType
#define X_DOUBLE 'D' ///< \hideinitializer double-precision (64) bit floating point XType
#define X_STRING '$' ///< \hideinitializer a terminated string XType
diff --git a/src/xchange.c b/src/xchange.c
index f2dfc9a..2e0e979 100644
--- a/src/xchange.c
+++ b/src/xchange.c
@@ -190,13 +190,9 @@ int xStringElementSizeOf(XType type) {
else switch(type) {
case X_BOOLEAN : l = 5; break; // "false"
case X_BYTE : l = 4; break; // -255
- case X_BYTE_HEX : l = 4; break; // 0xff
case X_SHORT : l = 6; break; // -65536
- case X_SHORT_HEX : l = 6; break; // 0xffff
case X_INT : l = 11; break; // -2147483647
- case X_INT_HEX : l = 10; break; // 0xffffffff
case X_LONG : l = 19; break;
- case X_LONG_HEX : l = 18; break;
case X_FLOAT : l = 16; break; // 1 leading + 8 significant figs + 2 signs + 1 dot + 1 E + 3 exponent
case X_DOUBLE : l = 25; break; // 1 leading + 16 significant figs + (4) + 4 exponent
default : return x_error(-1, EINVAL, "xStringElementSizeOf", "invalid type: %d", type);
@@ -217,15 +213,11 @@ int xElementSizeOf(XType type) {
if(type < 0) return -type;
switch(type) {
case X_RAW: return sizeof(char *);
- case X_BYTE:
- case X_BYTE_HEX: return 1;
- case X_SHORT:
- case X_SHORT_HEX: return sizeof(short);
+ case X_BYTE: return 1;
+ case X_SHORT: return sizeof(short);
case X_BOOLEAN: return sizeof(boolean);
- case X_INT:
- case X_INT_HEX: return sizeof(int);
- case X_LONG:
- case X_LONG_HEX: return sizeof(long long);
+ case X_INT: return sizeof(int);
+ case X_LONG: return sizeof(long long);
case X_FLOAT: return sizeof(float);
case X_DOUBLE: return sizeof(double);
case X_STRUCT: return sizeof(XStructure);
diff --git a/src/xjson.c b/src/xjson.c
index dc66f10..170a6bb 100644
--- a/src/xjson.c
+++ b/src/xjson.c
@@ -760,13 +760,9 @@ static XType GetCommonType(XType t1, XType t2) {
if(t1 == X_DOUBLE || t2 == X_DOUBLE) return X_DOUBLE;
if(t1 == X_FLOAT || t2 == X_FLOAT) return X_FLOAT;
if(t1 == X_LONG || t2 == X_LONG) return X_LONG;
- if(t1 == X_LONG_HEX || t2 == X_LONG_HEX) return X_LONG;
if(t1 == X_INT || t2 == X_INT) return X_INT;
- if(t1 == X_INT_HEX || t2 == X_INT_HEX) return X_INT;
if(t1 == X_SHORT || t2 == X_SHORT) return X_SHORT;
- if(t1 == X_SHORT_HEX || t2 == X_SHORT_HEX) return X_SHORT;
if(t1 == X_BYTE || t2 == X_BYTE) return X_BYTE;
- if(t1 == X_BYTE_HEX || t2 == X_BYTE_HEX) return X_BYTE;
if(t1 == X_BOOLEAN || t2 == X_BOOLEAN) return X_BOOLEAN;
return X_UNKNOWN;
}
@@ -1207,13 +1203,9 @@ static int PrintPrimitive(const void *ptr, XType type, char *str) {
switch(type) {
case X_BOOLEAN: return sprintf(str, (*(boolean *)ptr ? JSON_TRUE : JSON_FALSE));
case X_BYTE: return sprintf(str, "%hhu", *(unsigned char *) ptr);
- case X_BYTE_HEX: return sprintf(str, "0x%hhx", *(unsigned char *) ptr);
case X_SHORT: return sprintf(str, "%hd", *(short *) ptr);
- case X_SHORT_HEX: return sprintf(str, "0x%hx", *(unsigned short *) ptr);
case X_INT: return sprintf(str, "%d", *(int *) ptr);
- case X_INT_HEX: return sprintf(str, "0x%x", *(int *) ptr);
case X_LONG: return sprintf(str, "%lld", *(long long *) ptr);
- case X_LONG_HEX: return sprintf(str, "0x%llx", *(long long *) ptr);
case X_FLOAT: return sprintf(str, "%.8g , ", *(float *) ptr);
case X_DOUBLE: return xPrintDouble(str, *(double *) ptr);
case X_STRING: