The compiler is complaining about a macro defined in mjson.h
Documents\Arduino\libraries\microjson/mjson.h:135:28: error: expected primary-expression before '.' token
#define STRUCTOBJECT(s, f) .addr.offset = offsetof(s, f)
^
The code compiles and links ok on Windows 7 platform running Visual Studio and Ubuntu running gcc.
The full build errors are:
Arduino: 1.8.5 (Windows 7), Board: "Arduino/Genuino Uno"
C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries Documents\Arduino\libraries -fqbn=arduino:avr:uno -ide-version=10805 -build-path AppData\Local\Temp\arduino_build_106446 -warnings=all -build-cache AppData\Local\Temp\arduino_cache_49629 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.arduinoOTA.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -verbose Documents\Arduino\test_microjson\test_microjson.ino
C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries Documents\Arduino\libraries -fqbn=arduino:avr:uno -ide-version=10805 -build-path AppData\Local\Temp\arduino_build_106446 -warnings=all -build-cache AppData\Local\Temp\arduino_cache_49629 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.arduinoOTA.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -verbose Documents\Arduino\test_microjson\test_microjson.ino
Using board 'uno' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
Using core 'arduino' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
Detecting libraries used...
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "AppData\Local\Temp\arduino_build_106446\sketch\test_microjson.ino.cpp" -o "nul"
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IDocuments\Arduino\libraries\microjson" "AppData\Local\Temp\arduino_build_106446\sketch\test_microjson.ino.cpp" -o "nul"
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IDocuments\Arduino\libraries\microjson" "Documents\Arduino\libraries\microjson\mjson.c" -o "nul"
Generating function prototypes...
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IDocuments\Arduino\libraries\microjson" "AppData\Local\Temp\arduino_build_106446\sketch\test_microjson.ino.cpp" -o "AppData\Local\Temp\arduino_build_106446\preproc\ctags_target_for_gcc_minus_e.cpp"
"C:\Program Files (x86)\Arduino\tools-builder\ctags\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "AppData\Local\Temp\arduino_build_106446\preproc\ctags_target_for_gcc_minus_e.cpp"
Compiling sketch...
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -Wall -Wextra -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "-IDocuments\Arduino\libraries\microjson" "AppData\Local\Temp\arduino_build_106446\sketch\test_microjson.ino.cpp" -o "AppData\Local\Temp\arduino_build_106446\sketch\test_microjson.ino.cpp.o"
In file included from Documents\Arduino\test_microjson\test_microjson.ino:7:0:
Documents\Arduino\libraries\microjson/mjson.h:135:28: error: expected primary-expression before '.' token
#define STRUCTOBJECT(s, f) .addr.offset = offsetof(s, f)
^
Documents\Arduino\test_microjson\test_microjson.ino:31:29: note: in expansion of macro 'STRUCTOBJECT'
{ "start_pin", t_integer, STRUCTOBJECT(lights_t, start_pin) },
^
Documents\Arduino\libraries\microjson/mjson.h:135:28: error: expected primary-expression before '.' token
#define STRUCTOBJECT(s, f) .addr.offset = offsetof(s, f)
^
Documents\Arduino\test_microjson\test_microjson.ino:32:27: note: in expansion of macro 'STRUCTOBJECT'
{ "end_pin", t_integer, STRUCTOBJECT(lights_t, end_pin) },
^
Documents\Arduino\libraries\microjson/mjson.h:135:28: error: expected primary-expression before '.' token
#define STRUCTOBJECT(s, f) .addr.offset = offsetof(s, f)
^
Documents\Arduino\test_microjson\test_microjson.ino:33:30: note: in expansion of macro 'STRUCTOBJECT'
{ "colour_red", t_integer, STRUCTOBJECT(lights_t, colour_red) },
^
Documents\Arduino\libraries\microjson/mjson.h:135:28: error: expected primary-expression before '.' token
#define STRUCTOBJECT(s, f) .addr.offset = offsetof(s, f)
^
Documents\Arduino\test_microjson\test_microjson.ino:34:32: note: in expansion of macro 'STRUCTOBJECT'
{ "colour_green", t_integer, STRUCTOBJECT(lights_t, colour_green) },
^
Documents\Arduino\libraries\microjson/mjson.h:135:28: error: expected primary-expression before '.' token
#define STRUCTOBJECT(s, f) .addr.offset = offsetof(s, f)
^
Documents\Arduino\test_microjson\test_microjson.ino:35:31: note: in expansion of macro 'STRUCTOBJECT'
{ "colour_blue", t_integer, STRUCTOBJECT(lights_t, colour_blue) },
^
test_microjson:40: error: expected primary-expression before '.' token
{ "type", t_string, .addr.string = thenode.type, .len = sizeof(thenode.type) },
^
In file included from Documents\Arduino\test_microjson\test_microjson.ino:7:0:
Documents\Arduino\libraries\microjson/mjson.h:137:2: error: expected primary-expression before '.' token
.addr.array.element_type = t_structobject, \
^
Documents\Arduino\test_microjson\test_microjson.ino:41:26: note: in expansion of macro 'STRUCTARRAY'
{ "sections", t_array, STRUCTARRAY(thenode.thelight, section_attrs, &num_sections) },
^
Documents\Arduino\libraries\microjson/mjson.h:138:2: error: expected primary-expression before '.' token
.addr.array.arr.objects.subtype = e, \
^
Documents\Arduino\test_microjson\test_microjson.ino:41:26: note: in expansion of macro 'STRUCTARRAY'
{ "sections", t_array, STRUCTARRAY(thenode.thelight, section_attrs, &num_sections) },
^
Documents\Arduino\libraries\microjson/mjson.h:139:2: error: expected primary-expression before '.' token
.addr.array.arr.objects.base = (char*)a, \
^
Documents\Arduino\test_microjson\test_microjson.ino:41:26: note: in expansion of macro 'STRUCTARRAY'
{ "sections", t_array, STRUCTARRAY(thenode.thelight, section_attrs, &num_sections) },
^
Documents\Arduino\libraries\microjson/mjson.h:140:2: error: expected primary-expression before '.' token
.addr.array.arr.objects.stride = sizeof(a[0]), \
^
Documents\Arduino\test_microjson\test_microjson.ino:41:26: note: in expansion of macro 'STRUCTARRAY'
{ "sections", t_array, STRUCTARRAY(thenode.thelight, section_attrs, &num_sections) },
^
Documents\Arduino\libraries\microjson/mjson.h:141:2: error: expected primary-expression before '.' token
.addr.array.count = n, \
^
Documents\Arduino\test_microjson\test_microjson.ino:41:26: note: in expansion of macro 'STRUCTARRAY'
{ "sections", t_array, STRUCTARRAY(thenode.thelight, section_attrs, &num_sections) },
^
Documents\Arduino\libraries\microjson/mjson.h:142:2: error: expected primary-expression before '.' token
.addr.array.maxlen = (int)(sizeof(a)/sizeof(a[0]))
^
Documents\Arduino\test_microjson\test_microjson.ino:41:26: note: in expansion of macro 'STRUCTARRAY'
{ "sections", t_array, STRUCTARRAY(thenode.thelight, section_attrs, &num_sections) },
^
Using library microjson in folder: Documents\Arduino\libraries\microjson (legacy)
exit status 1
expected primary-expression before '.' token
test_microjson.ino:
#include <stdlib.h>
#include <stdbool.h>
#include <stddef.h> // offsetof - used in STRUCTOBJECT macro
#include <mjson.h>
#define MAX_SECTIONS 6 // we support up to six different sections on strip
// in json sections is an array of these light options
typedef struct light_section {
int start_pin;
int end_pin;
int colour_red;
int colour_green;
int colour_blue;
}lights_t;
typedef struct node {
char type[20];
lights_t thelight[MAX_SECTIONS];
} node_t;
node_t thenode;
static int num_sections;
const struct json_attr_t section_attrs[] = {
{ "start_pin", t_integer, STRUCTOBJECT(lights_t, start_pin) },
{ "end_pin", t_integer, STRUCTOBJECT(lights_t, end_pin) },
{ "colour_red", t_integer, STRUCTOBJECT(lights_t, colour_red) },
{ "colour_green", t_integer, STRUCTOBJECT(lights_t, colour_green) },
{ "colour_blue", t_integer, STRUCTOBJECT(lights_t, colour_blue) },
{ NULL },
};
static const struct json_attr_t json_attrs[] = {
{ "type", t_string, .addr.string = thenode.type, .len = sizeof(thenode.type) },
{ "sections", t_array, STRUCTARRAY(thenode.thelight, section_attrs, &num_sections) },
{ NULL },
};
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
// this check is only needed on the Leonardo:
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// start the Ethernet connection:
Serial.println("microjson test");
static const char *s =
"{ \"type\": \"section\", \"sections\": [{ \"start_pin\": 0, \"end_pin\": 71, \"colour_red\": 0, \"colour_green\": 255, \"colour_blue\": 0 }, { \"start_pin\": 216, \"end_pin\": 287, \"colour_red\": 255, \"colour_green\": 0, \"colour_blue\": 0 }] }";
int status = json_read_object(s, json_attrs, NULL);
if (status != 0)
Serial.println(json_error_string(status));
Serial.print("found ");
Serial.print(num_sections);
Serial.print(" sections");
Serial.print("type=");
Serial.println(thenode.type);
//printf("type=%s\n", thenode.type);
for (int i = 0; i < num_sections; ++i) {
Serial.print("section [");
Serial.print(i);
Serial.print("]: start_pin=");
Serial.print(thenode.thelight[i].start_pin);
Serial.print(", end_pin=");
Serial.print(thenode.thelight[i].end_pin);
Serial.print(", red=");
Serial.print(thenode.thelight[i].colour_red);
Serial.print(", green=");
Serial.print(thenode.thelight[i].colour_green);
Serial.print(", blue=");
Serial.println(thenode.thelight[i].colour_blue);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
And the offending macro in mjson.h STRUCTOBJECT. And also STRUCTARRAY. Here they are:
* Use the following macros to declare template initializers for structobject
* arrays. Writing the equivalents out by hand is error-prone.
*
* STRUCTOBJECT takes a structure name s, and a fieldname f in s.
*
* STRUCTARRAY takes the name of a structure array, a pointer to a an
* initializer defining the subobject type, and the address of an integer to
* store the length in.
*/
#define STRUCTOBJECT(s, f) .addr.offset = offsetof(s, f)
#define STRUCTARRAY(a, e, n) \
.addr.array.element_type = t_structobject, \
.addr.array.arr.objects.subtype = e, \
.addr.array.arr.objects.base = (char*)a, \
.addr.array.arr.objects.stride = sizeof(a[0]), \
.addr.array.count = n, \
.addr.array.maxlen = (int)(sizeof(a)/sizeof(a[0]))
How can I fix this to get it to compile using Arduino avr-g++ ?
mjson.h is from microjson library. I can provide more details of that if required.
mjson.h header:
/* Structures for JSON parsing using only fixed-extent memory
*
* This file is Copyright (c) 2014 by Eric S. Raymond.
* BSD terms apply: see the file COPYING in the distribution root for details.
*/
#include <stdbool.h>
#include <ctype.h>
#include <stdio.h>
#include <sys/types.h>
#define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
typedef enum {t_integer, t_uinteger, t_real,
t_string, t_boolean, t_character,
t_time,
t_object, t_structobject, t_array,
t_check, t_ignore}
json_type;
struct json_enum_t {
char *name;
int value;
};
struct json_array_t {
json_type element_type;
union {
struct {
const struct json_attr_t *subtype;
char *base;
size_t stride;
} objects;
struct {
char **ptrs;
char *store;
int storelen;
} strings;
struct {
int *store;
} integers;
struct {
unsigned int *store;
} uintegers;
struct {
double *store;
} reals;
struct {
bool *store;
} booleans;
} arr;
int *count, maxlen;
};
struct json_attr_t {
char *attribute;
json_type type;
union {
int *integer;
unsigned int *uinteger;
double *real;
char *string;
bool *boolean;
char *character;
struct json_array_t array;
size_t offset;
} addr;
union {
int integer;
unsigned int uinteger;
double real;
bool boolean;
char character;
char *check;
} dflt;
size_t len;
const struct json_enum_t *map;
bool nodefault;
};
#define JSON_ATTR_MAX 31 /* max chars in JSON attribute name */
#define JSON_VAL_MAX 512 /* max chars in JSON value part */
#ifdef __cplusplus
extern "C" {
#endif
int json_read_object(const char *, const struct json_attr_t *,
/*@null@*/const char **);
int json_read_array(const char *, const struct json_array_t *,
/*@null@*/const char **);
const /*@observer@*/char *json_error_string(int);
void json_enable_debug(int, FILE *);
#ifdef __cplusplus
}
#endif
#define JSON_ERR_OBSTART 1 /* non-WS when expecting object start */
#define JSON_ERR_ATTRSTART 2 /* non-WS when expecting attrib start */
#define JSON_ERR_BADATTR 3 /* unknown attribute name */
#define JSON_ERR_ATTRLEN 4 /* attribute name too long */
#define JSON_ERR_NOARRAY 5 /* saw [ when not expecting array */
#define JSON_ERR_NOBRAK 6 /* array element specified, but no [ */
#define JSON_ERR_STRLONG 7 /* string value too long */
#define JSON_ERR_TOKLONG 8 /* token value too long */
#define JSON_ERR_BADTRAIL 9 /* garbage while expecting comma or } or ] */
#define JSON_ERR_ARRAYSTART 10 /* didn't find expected array start */
#define JSON_ERR_OBJARR 11 /* error while parsing object array */
#define JSON_ERR_SUBTOOLONG 12 /* too many array elements */
#define JSON_ERR_BADSUBTRAIL 13 /* garbage while expecting array comma */
#define JSON_ERR_SUBTYPE 14 /* unsupported array element type */
#define JSON_ERR_BADSTRING 15 /* error while string parsing */
#define JSON_ERR_CHECKFAIL 16 /* check attribute not matched */
#define JSON_ERR_NOPARSTR 17 /* can't support strings in parallel arrays */
#define JSON_ERR_BADENUM 18 /* invalid enumerated value */
#define JSON_ERR_QNONSTRING 19 /* saw quoted value when expecting nonstring */
#define JSON_ERR_NONQSTRING 19 /* didn't see quoted value when expecting string */
#define JSON_ERR_MISC 20 /* other data conversion error */
#define JSON_ERR_BADNUM 21 /* error while parsing a numerical argument */
#define JSON_ERR_NULLPTR 22 /* unexpected null value or attribute pointer */
/*
* Use the following macros to declare template initializers for structobject
* arrays. Writing the equivalents out by hand is error-prone.
*
* STRUCTOBJECT takes a structure name s, and a fieldname f in s.
*
* STRUCTARRAY takes the name of a structure array, a pointer to a an
* initializer defining the subobject type, and the address of an integer to
* store the length in.
*/
#define STRUCTOBJECT(s, f) .addr.offset = offsetof(s, f)
#define STRUCTARRAY(a, e, n) \
.addr.array.element_type = t_structobject, \
.addr.array.arr.objects.subtype = e, \
.addr.array.arr.objects.base = (char*)a, \
.addr.array.arr.objects.stride = sizeof(a[0]), \
.addr.array.count = n, \
.addr.array.maxlen = (int)(sizeof(a)/sizeof(a[0]))
/* json.h ends here */