static int pkg_object(struct pkg *pkg, ucl_object_t *obj, int attr) { struct sbuf *tmp = NULL; ucl_object_t *cur; ucl_object_iter_t it = NULL; pkg_script script_type; const char *key, *buf; size_t len; pkg_debug(3, "%s", "Manifest: parsing object"); while ((cur = ucl_iterate_object(obj, &it, true))) { key = ucl_object_key(cur); if (key == NULL) continue; switch (attr) { case PKG_DEPS: if (cur->type != UCL_OBJECT && cur->type != UCL_ARRAY) pkg_emit_error("Skipping malformed dependency %s", key); else pkg_set_deps_from_object(pkg, cur); break; case PKG_DIRS: if (cur->type != UCL_OBJECT) pkg_emit_error("Skipping malformed dirs %s", key); else pkg_set_dirs_from_object(pkg, cur); break; case PKG_USERS: if (cur->type == UCL_STRING) pkg_adduid(pkg, key, ucl_object_tostring(cur)); else pkg_emit_error("Skipping malformed users %s", key); break; case PKG_GROUPS: if (cur->type == UCL_STRING) pkg_addgid(pkg, key, ucl_object_tostring(cur)); else pkg_emit_error("Skipping malformed groups %s", key); break; case PKG_DIRECTORIES: if (cur->type == UCL_BOOLEAN) { urldecode(key, &tmp); pkg_adddir(pkg, sbuf_data(tmp), ucl_object_toboolean(cur), false); } else if (cur->type == UCL_OBJECT) { pkg_set_dirs_from_object(pkg, cur); } else if (cur->type == UCL_STRING) { urldecode(key, &tmp); if (ucl_object_tostring(cur)[0] == 'y') pkg_adddir(pkg, sbuf_data(tmp), 1, false); else pkg_adddir(pkg, sbuf_data(tmp), 0, false); } else { pkg_emit_error("Skipping malformed directories %s", key); } break; case PKG_FILES: if (cur->type == UCL_STRING) { buf = ucl_object_tolstring(cur, &len); urldecode(key, &tmp); pkg_addfile(pkg, sbuf_get(tmp), len == 64 ? buf : NULL, false); } else if (cur->type == UCL_OBJECT) pkg_set_files_from_object(pkg, cur); else pkg_emit_error("Skipping malformed files %s", key); break; case PKG_OPTIONS: if (cur->type != UCL_STRING && cur->type != UCL_BOOLEAN) pkg_emit_error("Skipping malformed option %s", key); else pkg_addoption(pkg, key, ucl_object_tostring_forced(cur)); break; case PKG_OPTION_DEFAULTS: if (cur->type != UCL_STRING) pkg_emit_error("Skipping malformed option default %s", key); else pkg_addoption_default(pkg, key, ucl_object_tostring(cur)); break; case PKG_OPTION_DESCRIPTIONS: if (cur->type != UCL_STRING) pkg_emit_error("Skipping malformed option description %s", key); else pkg_addoption_description(pkg, key, ucl_object_tostring(cur)); break; case PKG_SCRIPTS: if (cur->type != UCL_STRING) pkg_emit_error("Skipping malformed scripts %s", key); else { script_type = script_type_str(key); if (script_type == PKG_SCRIPT_UNKNOWN) { pkg_emit_error("Skipping unknown script " "type: %s", key); break; } urldecode(ucl_object_tostring(cur), &tmp); pkg_addscript(pkg, sbuf_data(tmp), script_type); } break; case PKG_ANNOTATIONS: if (cur->type != UCL_STRING) pkg_emit_error("Skipping malformed annotation %s", key); else pkg_addannotation(pkg, key, ucl_object_tostring(cur)); break; } } sbuf_free(tmp); return (EPKG_OK); }
static int parse_mapping(struct pkg *pkg, yaml_node_t *item, yaml_document_t *doc, int attr) { struct sbuf *tmp = NULL; yaml_node_pair_t *pair; yaml_node_t *key; yaml_node_t *val; pkg_script script_type; pair = item->data.mapping.pairs.start; while (pair < item->data.mapping.pairs.top) { key = yaml_document_get_node(doc, pair->key); val = yaml_document_get_node(doc, pair->value); if (key->data.scalar.length <= 0) { pkg_emit_error("Skipping empty dependency name"); ++pair; continue; } switch (attr) { case PKG_DEPS: if (val->type != YAML_MAPPING_NODE) pkg_emit_error("Skipping malformed dependency %s", key->data.scalar.value); else pkg_set_deps_from_node(pkg, val, doc, key->data.scalar.value); break; case PKG_DIRS: if (val->type != YAML_MAPPING_NODE) pkg_emit_error("Skipping malformed dirs %s", key->data.scalar.value); else pkg_set_dirs_from_node(pkg, val, doc, key->data.scalar.value); break; case PKG_USERS: if (is_valid_yaml_scalar(val)) pkg_adduid(pkg, key->data.scalar.value, val->data.scalar.value); else pkg_emit_error("Skipping malformed users %s", key->data.scalar.value); break; case PKG_GROUPS: if (is_valid_yaml_scalar(val)) pkg_addgid(pkg, key->data.scalar.value, val->data.scalar.value); else pkg_emit_error("Skipping malformed groups %s", key->data.scalar.value); break; case PKG_DIRECTORIES: if (is_valid_yaml_scalar(val)) { urldecode(key->data.scalar.value, &tmp); if (val->data.scalar.value[0] == 'y') pkg_adddir(pkg, sbuf_get(tmp), 1, false); else pkg_adddir(pkg, sbuf_get(tmp), 0, false); } else if (val->type == YAML_MAPPING_NODE) { pkg_set_dirs_from_node(pkg, val, doc, key->data.scalar.value); } else { pkg_emit_error("Skipping malformed directories %s", key->data.scalar.value); } break; case PKG_FILES: if (is_valid_yaml_scalar(val)) { const char *pkg_sum = NULL; if (val->data.scalar.length == 64) pkg_sum = val->data.scalar.value; urldecode(key->data.scalar.value, &tmp); pkg_addfile(pkg, sbuf_get(tmp), pkg_sum, false); } else if (val->type == YAML_MAPPING_NODE) pkg_set_files_from_node(pkg, val, doc, key->data.scalar.value); else pkg_emit_error("Skipping malformed files %s", key->data.scalar.value); break; case PKG_OPTIONS: if (val->type != YAML_SCALAR_NODE) pkg_emit_error("Skipping malformed option %s", key->data.scalar.value); else pkg_addoption(pkg, key->data.scalar.value, val->data.scalar.value); break; case PKG_SCRIPTS: if (val->type != YAML_SCALAR_NODE) pkg_emit_error("Skipping malformed scripts %s", key->data.scalar.value); script_type = script_type_str(key->data.scalar.value); if (script_type == PKG_SCRIPT_UNKNOWN) { pkg_emit_error("Skipping unknown script " "type: %s", key->data.scalar.value); break; } urldecode(val->data.scalar.value, &tmp); pkg_addscript(pkg, sbuf_get(tmp), script_type); break; } ++pair; } sbuf_free(tmp); return (EPKG_OK); }