+static const char *
+pkg_state_want_to_str(pkg_state_want_t sw)
+{
+ int i;
+
+ for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
+ if (pkg_state_want_map[i].value == sw) {
+ return pkg_state_want_map[i].str;
+ }
+ }
+
+ opkg_msg(ERROR, "Internal error: state_want=%d\n", sw);
+ return "<STATE_WANT_UNKNOWN>";
+}
+
+pkg_state_want_t
+pkg_state_want_from_str(char *str)
+{
+ int i;
+
+ for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
+ if (strcmp(str, pkg_state_want_map[i].str) == 0) {
+ return pkg_state_want_map[i].value;
+ }
+ }
+
+ opkg_msg(ERROR, "Internal error: state_want=%s\n", str);
+ return SW_UNKNOWN;
+}
+
+static char *
+pkg_state_flag_to_str(pkg_state_flag_t sf)
+{
+ int i;
+ unsigned int len;
+ char *str;
+
+ /* clear the temporary flags before converting to string */
+ sf &= SF_NONVOLATILE_FLAGS;
+
+ if (sf == 0)
+ return xstrdup("ok");
+
+ len = 0;
+ for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
+ if (sf & pkg_state_flag_map[i].value)
+ len += strlen(pkg_state_flag_map[i].str) + 1;
+ }
+
+ str = xmalloc(len+1);
+ str[0] = '\0';
+
+ for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
+ if (sf & pkg_state_flag_map[i].value) {
+ strncat(str, pkg_state_flag_map[i].str, len);
+ strncat(str, ",", len);
+ }
+ }
+
+ len = strlen(str);
+ str[len-1] = '\0'; /* squash last comma */
+
+ return str;
+}
+
+pkg_state_flag_t
+pkg_state_flag_from_str(const char *str)
+{
+ int i;
+ int sf = SF_OK;
+ const char *sfname;
+ unsigned int sfname_len;
+
+ if (strcmp(str, "ok") == 0) {
+ return SF_OK;
+ }
+ for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
+ sfname = pkg_state_flag_map[i].str;
+ sfname_len = strlen(sfname);
+ if (strncmp(str, sfname, sfname_len) == 0) {
+ sf |= pkg_state_flag_map[i].value;
+ str += sfname_len;
+ if (str[0] == ',') {
+ str++;
+ } else {
+ break;
+ }
+ }
+ }
+
+ return sf;
+}
+
+static const char *
+pkg_state_status_to_str(pkg_state_status_t ss)
+{
+ int i;
+
+ for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
+ if (pkg_state_status_map[i].value == ss) {
+ return pkg_state_status_map[i].str;
+ }
+ }
+
+ opkg_msg(ERROR, "Internal error: state_status=%d\n", ss);
+ return "<STATE_STATUS_UNKNOWN>";
+}
+
+pkg_state_status_t
+pkg_state_status_from_str(const char *str)
+{
+ int i;
+
+ for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
+ if (strcmp(str, pkg_state_status_map[i].str) == 0) {
+ return pkg_state_status_map[i].value;
+ }
+ }
+
+ opkg_msg(ERROR, "Internal error: state_status=%s\n", str);
+ return SS_NOT_INSTALLED;
+}
+
+void
+pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field)