static int coco_problem_id_is_fine(const char *id, ...) { va_list args; const int reject = 0; const int OK = 1; const char *cp; char *s; int result = OK; va_start(args, id); s = coco_vstrdupf(id, args); va_end(args); for (cp = s; *cp != '\0'; ++cp) { if (('A' <= *cp) && (*cp <= 'Z')) continue; if (('a' <= *cp) && (*cp <= 'z')) continue; if ((*cp == '_') || (*cp == '-')) continue; if (('0' <= *cp) && (*cp <= '9')) continue; result = reject; } coco_free_memory(s); return result; }
/** * Formatted printing of a problem name, mimicking * sprintf(coco_problem_get_name(problem), name, ...) while taking care * of memory (de-)allocation, tentative, needs at the minimum some (more) testing. * */ void coco_problem_set_name(coco_problem_t *problem, const char *name, ...) { va_list args; va_start(args, name); coco_free_memory(problem->problem_name); problem->problem_name = coco_vstrdupf(name, args); va_end(args); }
/** * Optional arguments are used like in sprintf. */ char *coco_strdupf(const char *str, ...) { va_list args; char *s; va_start(args, str); s = coco_vstrdupf(str, args); va_end(args); return s; }
/** * @brief Sets the problem_type using formatted printing (as in printf). * * Takes care of memory (de-)allocation. */ static void coco_problem_set_type(coco_problem_t *problem, const char *type, ...) { va_list args; va_start(args, type); if (problem->problem_type != NULL) coco_free_memory(problem->problem_type); problem->problem_type = coco_vstrdupf(type, args); va_end(args); }
/** * Formatted printing of a problem ID, mimicking * sprintf(coco_problem_get_id(problem), id, ...) while taking care * of memory (de-)allocations. * */ void coco_problem_set_id(coco_problem_t *problem, const char *id, ...) { va_list args; va_start(args, id); coco_free_memory(problem->problem_id); problem->problem_id = coco_vstrdupf(id, args); va_end(args); if (!coco_problem_id_is_fine(problem->problem_id)) { coco_error("Problem id should only contain standard chars, not like '%s'", coco_problem_get_id(problem)); } }