Reputation: 1208
I am using a simple json library in an embedded environment, and trying to get rid of a global variable in my user code. I have a snippet here that tries to explain my situation.
The library has a function libjson_parser
that can be called everytime a char array needs to be parsed. Once the operation is complete it passes on the result of the operation to a function that is registered as a callback(json_post_parse
in the following example) using libjson_callback_register
.
Since I have different types of json packets to be analyzed, I use a global variable parsing_config
that is set before the parser is called so that the right operation can be performed within the json_post_parse
function.
I know that using global variables is frowned upon, so I'm looking for ways to get rid of this global variable, but not sure how to go about doing it?
// library functions:
// libjson_callback_register
// libjson_parser
// user function, function signature fixed by library:
// json_post_parse
static uint8_t parsing_config = 0;
int main()
{
// register callback
libjson_callback_register(json_post_parse);
// dummy load
char[32] payload;
uint16_t len = 32;
// type A post parsing
parsing_config = 1;
libjson_parser(payload, len);
// type B
parsing_config = 2;
libjson_parser(payload, len);
return 0;
}
json_post_parse(json_obj* json)
{
switch(parsing_config) {
case 1:
//do something
break;
case 2:
// do something
break;
default:
break;
}
}
Upvotes: 0
Views: 176
Reputation: 93476
You should probably dynamically alter the call back as suggested by @CharlieBurns, but an alternative would be to hide the static in a get/set function:
int main()
{
// register callback
libjson_callback_register(json_post_parse);
// dummy load
char[32] payload;
uint16_t len = 32;
// type A post parsing
parse_config(1);
libjson_parser(payload, len);
// type B
parse_config(2);
libjson_parser(payload, len);
return 0;
}
uint8_t parse_config( uint8_t config )
{
static uint8_t parsing_config = 0;
if( parse_config != 0 )
{
parsing_config = config ;
}
return parsing_config ;
}
void json_post_parse(json_obj* json)
{
switch( parse_config(0) )
{
...
}
}
Alternatively (and more conventionally) you could place json_post_parse(json_obj* json)
in a separate translation unit with a public setter function. The variable still has file scope, but it is then visible only to those functions that have business accessing it. File scope is not global scope, and so long as the variable is not visible to functions that do not need to see it, that avoids the issues associated with global variables. So:
json_parse_callback.c
static uint8_t parsing_config = 0;
void parse_set_config( uint8_t config )
{
parsing_config = config ;
}
void json_post_parse(json_obj* json)
{
switch( parsing_config )
{
...
}
}
json_parse_callback.h
#if !defined json_parse_callback_h
#define json_parse_callback_h
void parse_set_config( uint8_t config ) ;
void json_post_parse(json_obj* json) ;
#endif
main.c
int main()
{
// register callback
libjson_callback_register(json_post_parse);
// dummy load
char[32] payload;
uint16_t len = 32;
// type A post parsing
parse_set_config(1);
libjson_parser(payload, len);
// type B
parse_set_config(2);
libjson_parser(payload, len);
return 0;
}
Upvotes: 1
Reputation: 7044
// library functions:
// libjson_callback_register
// libjson_parser
// user function, function signature fixed by library:
// json_post_parse
int main()
{
// dummy load
char[32] payload;
uint16_t len = 32;
// type A post parsing
// register callback1
libjson_callback_register(json_post_parse1);
libjson_parser(payload, len);
// type B
// register callback2
libjson_callback_register(json_post_parse2);
libjson_parser(payload, len);
return 0;
}
json_post_parse1(json_obj* json)
{
// do something1
}
json_post_parse2(json_obj* json)
{
// do something2
}
Upvotes: 2