void * parse_dest_group(char *buff, void *state) { dest_group_t *group; dest_t *dest; if (*buff == CONF_BEGIN_CHAR) { group = (dest_group_t *) malloc(sizeof(dest_group_t)); MEMSET(group, 0, sizeof(dest_group_t)); return ((void *) group); } else if (*buff == CONF_END_CHAR) { ASSERT(state != NULL); group = (dest_group_t *) state; if (group->name == NULL || !dest_group_add(group)) { free(group); /* Duplicate/invalid group, so delete the structure */ } return (NULL); } else { ASSERT(state != NULL); group = (dest_group_t *) state; if (!BEG_STRCASECMP(buff, "name")) { group->name = Word(2, buff); } else if (!BEG_STRCASECMP(buff, "dest")) { dest = (dest_t *) malloc(sizeof(dest_t)); dest->name = Word(2, buff); if (dest->name == NULL || !dest_group_add_dest(group, dest)) { free(dest); } } else { print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid in the current context.", file_peek_path(), file_peek_line(), buff); } return (state); } }
spif_cmp_t spiftool_version_compare(spif_charptr_t v1, spif_charptr_t v2) { spif_char_t buff1[128], buff2[128]; D_CONF(("Comparing version strings \"%s\" and \"%s\"\n", NONULL(v1), NONULL(v2))); SPIF_COMP_CHECK_NULL(v1, v2); for (; *v1 && *v2; ) { D_CONF((" -> Looking at \"%s\" and \"%s\"\n", v1, v2)); if (isalpha(*v1) && isalpha(*v2)) { spif_charptr_t p1 = buff1, p2 = buff2; spif_int8_t ival1 = 6, ival2 = 6; /* Compare words. First, copy each word into buffers. */ for (; *v1 && isalpha(*v1); v1++, p1++) *p1 = *v1; for (; *v2 && isalpha(*v2); v2++, p2++) *p2 = *v2; *p1 = *p2 = 0; /* Change the buffered strings to lowercase for easier comparison. */ spiftool_downcase_str(buff1); spiftool_downcase_str(buff2); D_CONF((" -> Comparing as words \"%s\" vs. \"%s\"\n", buff1, buff2)); /* Some strings require special handling. */ if (!strcmp((char *) buff1, "snap")) { ival1 = 1; } else if (!strcmp((char *) buff1, "pre")) { ival1 = 2; } else if (!strcmp((char *) buff1, "alpha")) { ival1 = 3; } else if (!strcmp((char *) buff1, "beta")) { ival1 = 4; } else if (!strcmp((char *) buff1, "rc")) { ival1 = 5; } if (!strcmp((char *) buff2, "snap")) { ival2 = 1; } else if (!strcmp((char *) buff2, "pre")) { ival2 = 2; } else if (!strcmp((char *) buff2, "alpha")) { ival2 = 3; } else if (!strcmp((char *) buff2, "beta")) { ival2 = 4; } else if (!strcmp((char *) buff2, "rc")) { ival2 = 5; } if (ival1 != ival2) { /* If the values are different, compare them. */ D_CONF((" -> %d\n", (int) SPIF_CMP_FROM_INT(ival1 - ival2))); return SPIF_CMP_FROM_INT(ival1 - ival2); } else if (ival1 == 6) { int c; /* Two arbitrary strings. Compare them too. */ if ((c = strcmp((char *) buff1, (char *) buff2)) != 0) { D_CONF((" -> %d\n", (int) SPIF_CMP_FROM_INT(c))); return SPIF_CMP_FROM_INT(c); } } } else if (isdigit(*v1) && isdigit(*v2)) { spif_charptr_t p1 = buff1, p2 = buff2; spif_int32_t ival1, ival2; spif_cmp_t c; /* Compare numbers. First, copy each number into buffers. */ for (; *v1 && isdigit(*v1); v1++, p1++) *p1 = *v1; for (; *v2 && isdigit(*v2); v2++, p2++) *p2 = *v2; *p1 = *p2 = 0; /* Convert the strings into actual integers. */ ival1 = (spif_int32_t) strtol((char *) buff1, (char **) NULL, 10); ival2 = (spif_int32_t) strtol((char *) buff2, (char **) NULL, 10); D_CONF((" -> Comparing as integers %d vs. %d\n", (int) ival1, (int) ival2)); /* Compare the integers and return if not equal. */ c = SPIF_CMP_FROM_INT(ival1 - ival2); if (!SPIF_CMP_IS_EQUAL(c)) { D_CONF((" -> %d\n", (int) c)); return c; } } else if (!isalnum(*v1) && !isalnum(*v2)) { spif_charptr_t p1 = buff1, p2 = buff2; spif_cmp_t c; /* Compare non-alphanumeric strings. */ for (; *v1 && !isalnum(*v1); v1++, p1++) *p1 = *v1; for (; *v2 && !isalnum(*v2); v2++, p2++) *p2 = *v2; *p1 = *p2 = 0; D_CONF((" -> Comparing as non-alphanumeric strings \"%s\" vs. \"%s\"\n", buff1, buff2)); c = SPIF_CMP_FROM_INT(strcasecmp((char *) buff1, (char *) buff2)); if (!SPIF_CMP_IS_EQUAL(c)) { D_CONF((" -> %d\n", (int) c)); return c; } } else { D_CONF((" -> Comparing as alphanumeric strings \"%s\" vs. \"%s\"\n", buff1, buff2)); D_CONF((" -> %d\n", (int) SPIF_CMP_FROM_INT(strcasecmp((char *) buff1, (char *) buff2)))); return SPIF_CMP_FROM_INT(strcasecmp((char *) buff1, (char *) buff2)); } } /* We've reached the end of one of the strings. */ if (*v1) { if (!BEG_STRCASECMP((char *) v1, "snap") || !BEG_STRCASECMP((char *) v1, "pre") || !BEG_STRCASECMP((char *) v1, "alpha") || !BEG_STRCASECMP((char *) v1, "beta")) { D_CONF((" -> <\n")); return SPIF_CMP_LESS; } else { D_CONF((" -> >\n")); return SPIF_CMP_GREATER; } } else if (*v2) { if (!BEG_STRCASECMP((char *) v2, "snap") || !BEG_STRCASECMP((char *) v2, "pre") || !BEG_STRCASECMP((char *) v2, "alpha") || !BEG_STRCASECMP((char *) v2, "beta")) { D_CONF((" -> >\n")); return SPIF_CMP_GREATER; } else { D_CONF((" -> <\n")); return SPIF_CMP_LESS; } } D_CONF((" -> ==\n")); return SPIF_CMP_EQUAL; }