Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
PP-1038: pbsnodes produces nonconforming json
  • Loading branch information
vstumpf committed Nov 9, 2017
1 parent 2114586 commit 896537e
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 178 deletions.
172 changes: 41 additions & 131 deletions src/cmds/pbsnodes.c
Expand Up @@ -190,9 +190,8 @@ cmp_node_name(char *n1, char *n2)
*
*/
static int
encode_to_json(struct batch_status *bstat) {

JsonNode *node;
encode_to_json(struct batch_status *bstat)
{
struct attrl *next;
struct attrl *pattr;
char *str;
Expand All @@ -209,49 +208,20 @@ encode_to_json(struct batch_status *bstat) {
if (add_json_node(JSON_OBJECT, JSON_NULL, pattr->name, NULL) == NULL)
return 1;
for (next = pattr; next; ) {
node = add_json_node(JSON_VALUE, JSON_NULL, next->resource, NULL);
if (node == NULL)
if (add_json_node(JSON_VALUE, JSON_NULL, next->resource, next->value) == NULL)
return 1;
str = next->value;
value = strtod(next->value, &pc);
while (pc) {
if (isspace(*pc))
pc++;
else
break;
}
if (strcmp(pc, "") == 0) {
ivalue = (long int)value;
if (value == ivalue) { /* This checks if value have any non zero fractional part after decimal. If not then value has to be represented as integer otherwise as float. */
node->value_type = JSON_INT;
node->value.inumber = ivalue;
} else {
node->value_type = JSON_FLOAT;
node->value.fnumber = value;
}
} else {
node->value_type = JSON_STRING;
node->value.string = strdup(str);
if (node->value.string == NULL)
if (next->next == NULL || strcmp(next->next->name, "resources_available")) {
/* Nothing left in resources_available, close object */
if (add_json_node(JSON_OBJECT_END, JSON_NULL, NULL, NULL) == NULL)
return 1;
}
if (next->next) {
if (strcmp(next->next->name, "resources_available") == 0)
next = next->next;
else {
node->node_type = JSON_OBJECT_END;
pattr = next;
next = NULL;
}
} else {
node->node_type = JSON_OBJECT_END;
pattr = next;
next = NULL;
} else {
next = next->next;
}
}
} else if (strcmp(pattr->name, "resources_assigned") == 0) {
node = add_json_node(JSON_OBJECT, JSON_NULL, pattr->name, NULL);
if (node == NULL)
if (add_json_node(JSON_OBJECT, JSON_NULL, pattr->name, NULL) == NULL)
return 1;
for (next = pattr; next; ) {
str = next->value;
Expand All @@ -264,113 +234,53 @@ encode_to_json(struct batch_status *bstat) {
}
/* Adding only non zero values.*/
if (value) {
ivalue = (long int)value;
if (strcmp(pc, "") == 0) {
if (value == ivalue)
node = add_json_node(JSON_VALUE, JSON_INT, next->resource, &ivalue);
else
node = add_json_node(JSON_VALUE, JSON_FLOAT, next->resource, &value);
if (node == NULL)
return 1;
} else if (str[0] != '0') {
node = add_json_node(JSON_VALUE, JSON_STRING, next->resource, str);
if (node == NULL)
return 1;
}
if (add_json_node(JSON_VALUE, JSON_NULL, next->resource, next->value) == NULL)
return 1;
} else {
if (str[0] != '0') {
node = add_json_node(JSON_VALUE, JSON_STRING, next->resource, str);
if (node == NULL)
if (add_json_node(JSON_VALUE, JSON_STRING, next->resource, str) == NULL)
return 1;
}
}
if (next->next) {
if (strcmp(next->next->name, "resources_assigned") == 0)
next = next->next;
else {
/* In case of an empty object */
if (node->node_type == JSON_OBJECT) {
node = add_json_node(JSON_OBJECT_END, JSON_NULL, NULL, NULL);
if (node == NULL)
return 1;
} else {
node->node_type = JSON_OBJECT_END;
pattr = next;
next = NULL;
break;
}
}
if (next->next == NULL || strcmp(next->next->name, "resources_assigned")) {
/* Nothing left in resources_assigned, close object */
if (add_json_node(JSON_OBJECT_END, JSON_NULL, NULL, NULL) == NULL)
return 1;
pattr = next;
next = NULL;
} else {
/* In case of an empty object adding an extra node to end the object. */
if (node->node_type == JSON_OBJECT) {
node = add_json_node(JSON_OBJECT_END, JSON_NULL, NULL, NULL);
if (node == NULL)
return 1;
} else {
node->node_type = JSON_OBJECT_END;
pattr = next;
next = NULL;
break;
}
next = next->next;
}
}
} else {
node = add_json_node(JSON_VALUE, JSON_NULL, pattr->name, NULL);
if (node == NULL)
} else if (strcmp(pattr->name, "jobs") == 0) {
if (add_json_node(JSON_ARRAY, JSON_NULL, pattr->name, NULL) == NULL)
return 1;
str = pattr->value;
value = strtod(pattr->value, &pc);
while (pc) {
if (isspace(*pc))
pc++;
else
break;
pc = pc1 = str = pattr->value;
while (*pc1) {
if (*pc1 != ' ')
*pc++ = *(pc1);
pc1++;
}
if (strcmp(pc, "") == 0) {
ivalue = (long int)value;
if (value == ivalue) {
node->value_type = JSON_INT;
node->value.inumber = ivalue;
} else {
node->value_type = JSON_FLOAT;
node->value.fnumber = value;
}
} else if (strcmp(pattr->name, "jobs")== 0) {
node->node_type = JSON_ARRAY;
pc = pc1 = str;
while (*pc1) {
if (*pc1 != ' ')
*pc++ = *(pc1);
pc1++;
}
*pc = '\0';
pc = strtok(str, ",");
while (pc) {
pc1 = strchr(pc, '/');
if(pc1)
*pc1 = '\0';
if (strcmp(pc, prev_jobid) != 0) {
node = add_json_node(JSON_VALUE, JSON_STRING, NULL, pc);
if (node == NULL)
return 1;
}
prev_jobid = pc;
pc = strtok(NULL, ",");
*pc = '\0';
for (pc = strtok(str, ","); pc != NULL; pc = strtok(NULL, ",")) {
pc1 = strchr(pc, '/');
if (pc1)
*pc1 = '\0';
if (strcmp(pc, prev_jobid) != 0) {
if (add_json_node(JSON_VALUE, JSON_STRING, NULL, pc) == NULL)
return 1;
}
node = add_json_node(JSON_ARRAY_END, JSON_NULL, NULL, NULL);
if (node == NULL)
return 1;
} else {
node->value_type = JSON_STRING;
node->value.string = strdup(str);
if (node->value.string == NULL)
return 1;
prev_jobid = pc;
}
if (add_json_node(JSON_ARRAY_END, JSON_NULL, NULL, NULL) == NULL)
return 1;
} else {
if (add_json_node(JSON_VALUE, JSON_NULL, pattr->name, pattr->value) == NULL)
return 1;
}

}
node = add_json_node(JSON_OBJECT_END, JSON_NULL, NULL, NULL);
if (node == NULL)
if (add_json_node(JSON_OBJECT_END, JSON_NULL, NULL, NULL) == NULL)
return 1;
return 0;

Expand Down
1 change: 1 addition & 0 deletions src/include/pbs_json.h
Expand Up @@ -30,5 +30,6 @@ struct JsonNode{
}value;
};
JsonNode* add_json_node(JsonNodeType ntype, JsonValueType vtype, char *key, void *value);
char *strdup_escape(const char *str);
int generate_json(FILE *stream);
void free_json_node();
118 changes: 71 additions & 47 deletions src/lib/Libcmds/pbs_json.c
Expand Up @@ -57,6 +57,75 @@ link_node(JsonNode *node) {
return 0;
}

/**
* @brief
* Duplicates a string where the new string conforms to JSON
*
* @param[in] str - string to be duplicated
*
* @return string
* @retval JSON conforming string success
* @retval NULL error
*
*/
char*
strdup_escape(const char *str)
{
int i = 0;
int len = 0;
char *temp = NULL;
char *buf = NULL;
if (str != NULL) {
i = 0;
len = MAXBUFLEN;
buf = (char *) malloc(len);
if (buf == NULL)
return NULL;
while (*str) {
switch (*str) {
case '\b':
buf[i++] = '\\';
buf[i++] = 'b';
str++;
break;
case '\f':
buf[i++] = '\\';
buf[i++] = 'f';
str++;
break;
case '\n':
buf[i++] = '\\';
buf[i++] = 'n';
str++;
break;
case '\r':
buf[i++] = '\\';
buf[i++] = 'r';
str++;
break;
case '\t':
buf[i++] = '\\';
buf[i++] = 't';
str++;
break;
default:
buf[i++] = *str++;
}
if (i >= len - 2) {
len *= BUFFER_GROWTH_RATE;
temp = (char *) realloc(buf, len);
if (temp == NULL) {
free(buf);
return NULL;
}
buf = temp;
}
}
buf[i] = '\0';
}
return buf;
}

/**
* @brief
* add node to json list
Expand Down Expand Up @@ -129,54 +198,9 @@ add_json_node(JsonNodeType ntype, JsonValueType vtype, char *key, void *value) {

if (node->value_type == JSON_STRING) {
if (value != NULL) {
ptr = value;
i = 0;
len = MAXBUFLEN;
buf = (char *) malloc(len);
if (buf == NULL)
ptr = strdup_escape(value);
if (ptr == NULL)
return NULL;
while (*ptr) {
switch (*ptr) {
case '\b':
buf[i++] = '\\';
buf[i++] = 'b';
ptr++;
break;
case '\f':
buf[i++] = '\\';
buf[i++] = 'f';
ptr++;
break;
case '\n':
buf[i++] = '\\';
buf[i++] = 'n';
ptr++;
break;
case '\r':
buf[i++] = '\\';
buf[i++] = 'r';
ptr++;
break;
case '\t':
buf[i++] = '\\';
buf[i++] = 't';
ptr++;
break;
default:
buf[i++] = *ptr++;
}
if (i >= len - 2) {
len *= BUFFER_GROWTH_RATE;
temp = (char *) realloc(buf, len);
if (temp == NULL) {
free(buf);
return NULL;
}
buf = temp;
}
}
buf[i] = '\0';
ptr = buf;
}
node->value.string = ptr;
}
Expand Down

0 comments on commit 896537e

Please sign in to comment.