diff --git a/README.md b/README.md index 2e2da91..9f930c2 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,4 @@ instead of jq's .object.object[arrayindex]|command Although uclcmd commands are not actually 'piped' and only the 'each' command can be stacked. Running other commands just runs them sequentially +uclcmd currently targets the master branch of [vstakhov/libucl](https://github.com/vstakhov/libucl), as some used features are not available in an existing release. \ No newline at end of file diff --git a/uclcmd.c b/uclcmd.c index 227351c..cff4654 100755 --- a/uclcmd.c +++ b/uclcmd.c @@ -55,6 +55,7 @@ char *include_file = NULL; int main(int argc, char *argv[]) { + atexit(cleanup); int ret = 0, i = 0; bool verbfound = false; verbmap_t cmdmap[] = @@ -163,4 +164,3 @@ cleanup() ucl_object_unref(set_obj); } } - diff --git a/uclcmd.h b/uclcmd.h index dc89e48..fd51a14 100755 --- a/uclcmd.h +++ b/uclcmd.h @@ -104,6 +104,6 @@ int get_cmd_type(const ucl_object_t *obj, char *nodepath, const char *command_str, char *remaining_commands, int recurse); int get_cmd_values(const ucl_object_t *obj, char *nodepath, const char *command_str, char *remaining_commands, int recurse); - +void asprintf_check_enomem(int retcode); #endif /* UCLCMD_H_ */ diff --git a/uclcmd_common.c b/uclcmd_common.c index 1cad602..ab4e792 100755 --- a/uclcmd_common.c +++ b/uclcmd_common.c @@ -26,8 +26,25 @@ * $FreeBSD$ */ +#include + #include "uclcmd.h" +void +asprintf_check_enomem(int retcode) { + /* + * This method is called with the return code of asprintf() as parameter. + * asprintf returns -1 when it cannot allocate memory. + * See printf(3) for details. + */ + if (retcode != -1) + return; + errno = ENOMEM; + fprintf(stderr, "ENOMEM(%d): Could not allocate memory.\n", ENOMEM); + cleanup(); + abort(); +} + char* expand_subkeys(const ucl_object_t *obj, char *nodepath) { @@ -170,31 +187,31 @@ type_as_string (const ucl_object_t *obj) if (obj == NULL) { return NULL; } else if (ucl_object_type(obj) == UCL_OBJECT) { - asprintf(&ret, "UCL_OBJECT"); + asprintf_check_enomem(asprintf(&ret, "UCL_OBJECT")); } else if (ucl_object_type(obj) == UCL_ARRAY) { - asprintf(&ret, "UCL_ARRAY"); + asprintf_check_enomem(asprintf(&ret, "UCL_ARRAY")); } else if (ucl_object_type(obj) == UCL_INT) { - asprintf(&ret, "UCL_INT"); + asprintf_check_enomem(asprintf(&ret, "UCL_INT")); } else if (ucl_object_type(obj) == UCL_FLOAT) { - asprintf(&ret, "UCL_FLOAT"); + asprintf_check_enomem(asprintf(&ret, "UCL_FLOAT")); } else if (ucl_object_type(obj) == UCL_STRING) { - asprintf(&ret, "UCL_STRING"); + asprintf_check_enomem(asprintf(&ret, "UCL_STRING")); } else if (ucl_object_type(obj) == UCL_BOOLEAN) { - asprintf(&ret, "UCL_BOOLEAN"); + asprintf_check_enomem(asprintf(&ret, "UCL_BOOLEAN")); } else if (ucl_object_type(obj) == UCL_TIME) { - asprintf(&ret, "UCL_TIME"); + asprintf_check_enomem(asprintf(&ret, "UCL_TIME")); } else if (ucl_object_type(obj) == UCL_USERDATA) { - asprintf(&ret, "UCL_USERDATA"); + asprintf_check_enomem(asprintf(&ret, "UCL_USERDATA")); } else if (ucl_object_type(obj) == UCL_NULL) { - asprintf(&ret, "UCL_NULL"); + asprintf_check_enomem(asprintf(&ret, "UCL_NULL")); } return ret; diff --git a/uclcmd_get.c b/uclcmd_get.c index cd6594a..6e3db6e 100755 --- a/uclcmd_get.c +++ b/uclcmd_get.c @@ -136,8 +136,6 @@ get_main(int argc, char *argv[]) get_mode(argv[k]); } - cleanup(); - if (nonewline) { printf("\n"); } @@ -152,10 +150,9 @@ get_mode(char *requested_node) char *cmd = requested_node; char *node_name = strsep(&cmd, "|"); char *command_str = strsep(&cmd, "|"); - char *nodepath = NULL; + char *nodepath = ""; int command_count = 0, i; - asprintf(&nodepath, ""); found_object = root_obj; if (strlen(node_name) == 0) { @@ -180,7 +177,7 @@ get_mode(char *requested_node) } found_object = ucl_lookup_path_char(found_object, node_name, input_sepchar); free(nodepath); - asprintf(&nodepath, "%s", node_name); + asprintf_check_enomem(asprintf(&nodepath, "%s", node_name)); } while (command_str != NULL) { @@ -403,12 +400,12 @@ get_cmd_values(const ucl_object_t *obj, char *nodepath, continue; } if (ucl_object_type(obj) == UCL_ARRAY) { - asprintf(&newkey, "%c%i", output_sepchar, arrindex); + asprintf_check_enomem(asprintf(&newkey, "%c%i", output_sepchar, arrindex)); arrindex++; } else { newkey = __DECONST(char *, ucl_object_key(cur)); if (newkey != NULL) { - asprintf(&newkey, "%c%s", output_sepchar, ucl_object_key(cur)); + asprintf_check_enomem(asprintf(&newkey, "%c%s", output_sepchar, ucl_object_key(cur))); } } output_key(cur, nodepath, newkey); @@ -482,7 +479,7 @@ get_cmd_recurse(const ucl_object_t *obj, char *nodepath, ucl_object_t *arrlen = NULL; arrlen = ucl_object_fromint(obj->len); - asprintf(&tmpkeyname, "%c%s", output_sepchar, "_length"); + asprintf_check_enomem(asprintf(&tmpkeyname, "%c%s", output_sepchar, "_length")); output_chunk(arrlen, nodepath, tmpkeyname); free(tmpkeyname); } @@ -494,7 +491,7 @@ get_cmd_recurse(const ucl_object_t *obj, char *nodepath, keylist = expand_subkeys(obj, nodepath); if (keylist != NULL) { keystr = ucl_object_fromstring(keylist); - asprintf(&tmpkeyname, "%c%s", output_sepchar, "_keys"); + asprintf_check_enomem(asprintf(&tmpkeyname, "%c%s", output_sepchar, "_keys")); output_chunk(keystr, nodepath, tmpkeyname); free(tmpkeyname); free(keylist); @@ -505,24 +502,24 @@ get_cmd_recurse(const ucl_object_t *obj, char *nodepath, char *newkey = NULL; char *newnodepath = NULL; if (ucl_object_type(obj) == UCL_ARRAY) { - asprintf(&newkey, "%c%i", output_sepchar, arrindex); + asprintf_check_enomem(asprintf(&newkey, "%c%i", output_sepchar, arrindex)); arrindex++; } else if (strlen(nodepath) == 0) { asprintf(&newkey, "%s", ucl_object_key(cur)); } else { - asprintf(&newkey, "%c%s", output_sepchar, ucl_object_key(cur)); + asprintf_check_enomem(asprintf(&newkey, "%c%s", output_sepchar, ucl_object_key(cur))); } if (ucl_object_type(cur) == UCL_OBJECT || ucl_object_type(cur) == UCL_ARRAY) { it2 = NULL; while ((cur2 = ucl_iterate_object(cur, &it2, false))) { if (nodepath != NULL && strlen(nodepath) > 0) { - asprintf(&newnodepath, "%s%s", nodepath, newkey); + asprintf_check_enomem(asprintf(&newnodepath, "%s%s", nodepath, newkey)); } else { if (ucl_object_type(obj) == UCL_ARRAY) { - asprintf(&newnodepath, "%i", arrindex); + asprintf_check_enomem(asprintf(&newnodepath, "%i", arrindex)); } else { - asprintf(&newnodepath, "%s", ucl_object_key(cur2)); + asprintf_check_enomem(asprintf(&newnodepath, "%s", ucl_object_key(cur2))); } } recurse_level = process_get_command(cur2, @@ -560,10 +557,10 @@ get_cmd_each(const ucl_object_t *obj, char *nodepath, while ((cur = ucl_iterate_object(obj, &it, true))) { char *newkey = NULL; if (ucl_object_type(obj) == UCL_ARRAY) { - asprintf(&newkey, "%c%i", output_sepchar, arrindex); + asprintf_check_enomem(asprintf(&newkey, "%c%i", output_sepchar, arrindex)); arrindex++; } else { - asprintf(&newkey, "%c%s", output_sepchar, ucl_object_key(cur)); + asprintf_check_enomem(asprintf(&newkey, "%c%s", output_sepchar, ucl_object_key(cur))); } if (cur->next != 0 && cur->type != UCL_ARRAY) { /* Implicit array */ @@ -586,12 +583,12 @@ get_cmd_each(const ucl_object_t *obj, char *nodepath, while ((cur = ucl_iterate_object(obj, &it, true))) { char *newnodepath = NULL; if (ucl_object_type(obj) == UCL_ARRAY) { - asprintf(&newnodepath, "%s%c%i", nodepath, output_sepchar, - arrindex); + asprintf_check_enomem(asprintf(&newnodepath, "%s%c%i", nodepath, output_sepchar, + arrindex)); arrindex++; } else { - asprintf(&newnodepath, "%s%c%s", nodepath, output_sepchar, - ucl_object_key(cur)); + asprintf_check_enomem(asprintf(&newnodepath, "%s%c%s", nodepath, output_sepchar, + ucl_object_key(cur))); } if (cur->next != 0 && cur->type != UCL_ARRAY) { /* Implicit array */ @@ -648,12 +645,12 @@ get_cmd_none(const ucl_object_t *obj, char *nodepath, if (next_command != NULL) { char *newnodepath = NULL; if (ucl_object_type(obj) == UCL_ARRAY) { - asprintf(&newnodepath, "%s%c%i", nodepath, output_sepchar, - arrindex); + asprintf_check_enomem(asprintf(&newnodepath, "%s%c%i", nodepath, output_sepchar, + arrindex)); arrindex++; } else { - asprintf(&newnodepath, "%s%c%s", nodepath, output_sepchar, - ucl_object_key(cur)); + asprintf_check_enomem(asprintf(&newnodepath, "%s%c%s", nodepath, output_sepchar, + ucl_object_key(cur))); } if (debug > 2) { fprintf(stderr, "DEBUG: Calling recurse with %s.%s on %s\n", diff --git a/uclcmd_merge.c b/uclcmd_merge.c index 6b6e6d8..b0c2811 100755 --- a/uclcmd_merge.c +++ b/uclcmd_merge.c @@ -144,8 +144,6 @@ merge_main(int argc, char *argv[]) ret = 1; } - cleanup(); - if (nonewline) { printf("\n"); } diff --git a/uclcmd_output.c b/uclcmd_output.c index 6e75d0a..d51655b 100755 --- a/uclcmd_output.c +++ b/uclcmd_output.c @@ -75,8 +75,6 @@ output_main(int argc, char *argv[]) ucl_obj_dump(root_obj, 0); - cleanup(); - if (nonewline) { printf("\n"); } @@ -173,7 +171,7 @@ output_key(const ucl_object_t *obj, char *nodepath, const char *inkey) char *key; if (inkey == NULL) { - asprintf(&key, ""); + key = ""; } else { key = strdup(inkey); } diff --git a/uclcmd_parse.c b/uclcmd_parse.c index 910d902..905c86e 100755 --- a/uclcmd_parse.c +++ b/uclcmd_parse.c @@ -38,7 +38,6 @@ parse_file(struct ucl_parser *parser, const char *filename) if (ucl_parser_get_error(parser)) { fprintf(stderr, "Error occured: %s\n", ucl_parser_get_error(parser)); - cleanup(); exit(2); } @@ -46,7 +45,6 @@ parse_file(struct ucl_parser *parser, const char *filename) if (ucl_parser_get_error(parser)) { fprintf(stderr, "Error: Parse Error occured: %s\n", ucl_parser_get_error(parser)); - cleanup(); exit(3); } @@ -72,7 +70,7 @@ parse_input(struct ucl_parser *parser, FILE *source) /* There must be a better way to detect a string */ ucl_parser_clear_error(parser); success = true; - asprintf(&data, "%s", inbuf); + asprintf_check_enomem(asprintf(&data, "%s", inbuf)); obj = ucl_object_fromstring_common(data, 0, UCL_STRING_PARSE); } else { obj = ucl_parser_get_object(parser); @@ -81,7 +79,6 @@ parse_input(struct ucl_parser *parser, FILE *source) if (ucl_parser_get_error(parser)) { fprintf(stderr, "Error: Parse Error occured: %s\n", ucl_parser_get_error(parser)); - cleanup(); exit(3); } @@ -107,7 +104,6 @@ parse_string(struct ucl_parser *parser, char *data) if (ucl_parser_get_error(parser)) { fprintf(stderr, "Error: Parse Error occured: %s\n", ucl_parser_get_error(parser)); - cleanup(); exit(3); } diff --git a/uclcmd_remove.c b/uclcmd_remove.c index 3acc52b..28952a2 100755 --- a/uclcmd_remove.c +++ b/uclcmd_remove.c @@ -178,8 +178,6 @@ remove_main(int argc, char *argv[]) } get_mode(""); - cleanup(); - if (nonewline) { printf("\n"); } diff --git a/uclcmd_set.c b/uclcmd_set.c index d92319f..14ed8c0 100755 --- a/uclcmd_set.c +++ b/uclcmd_set.c @@ -144,8 +144,6 @@ set_main(int argc, char *argv[]) ret = 1; } - cleanup(); - if (nonewline) { printf("\n"); }