diff options
Diffstat (limited to 'deps')
| -rw-r--r-- | deps/sysobj_early/include/util_ids.h | 12 | ||||
| -rw-r--r-- | deps/sysobj_early/src/util_ids.c | 153 | 
2 files changed, 151 insertions, 14 deletions
| diff --git a/deps/sysobj_early/include/util_ids.h b/deps/sysobj_early/include/util_ids.h index 53656443..e9d495ea 100644 --- a/deps/sysobj_early/include/util_ids.h +++ b/deps/sysobj_early/include/util_ids.h @@ -33,6 +33,7 @@ typedef struct {  } ids_query_result;  #define ids_query_result_new() g_new0(ids_query_result, 1)  #define ids_query_result_free(s) g_free(s); +void ids_query_result_cpy(ids_query_result *dest, ids_query_result *src);  /* Given a qpath "/X/Y/Z", find names as:   * X <name> ->result[0] @@ -46,6 +47,7 @@ typedef struct {   * - sdio.ids "<vendor>/<device>", "C <class>"   * - sdcard.ids "OEMID <code>", "MANFID <code>"   * - usb.ids "<vendor>/<device>", "C <class>" etc. + * - edid.ids "<3letter_vendor>"   */  long scan_ids_file(const gchar *file, const gchar *qpath, ids_query_result *result, long start_offset); @@ -54,6 +56,8 @@ typedef struct {      ids_query_result result;  } ids_query; +void ids_query_result_cpy(ids_query_result *dest, ids_query_result *src); +  ids_query *ids_query_new(const gchar *qpath);  void ids_query_free(ids_query *s);  typedef GSList* ids_query_list; @@ -63,4 +67,12 @@ long scan_ids_file_list(const gchar *file, ids_query_list query_list, long start  /* after scan_ids_file_list(), count hits */  int query_list_count_found(ids_query_list query_list); +/* returns GSList of ids_query* */ +typedef gchar* (*split_loc_function)(const char *line); +ids_query_list ids_file_all_get_all(const gchar *file, split_loc_function split_loc_func); + +/* debugging */ +void ids_trace_start(); +void ids_trace_stop(); +  #endif diff --git a/deps/sysobj_early/src/util_ids.c b/deps/sysobj_early/src/util_ids.c index 00ff63c5..b24dba59 100644 --- a/deps/sysobj_early/src/util_ids.c +++ b/deps/sysobj_early/src/util_ids.c @@ -25,6 +25,9 @@  #include <ctype.h>  #define ids_msg(msg, ...)  fprintf (stderr, "[%s] " msg "\n", __FUNCTION__, ##__VA_ARGS__) /**/ +static int ids_tracing = 0; +void ids_trace_start() { ids_tracing = 1; } +void ids_trace_stop() { ids_tracing = 0; }  ids_query *ids_query_new(const gchar *qpath) {      ids_query *s = g_new0(ids_query, 1); @@ -37,6 +40,13 @@ void ids_query_free(ids_query *s) {      g_free(s);  } +void ids_query_result_cpy(ids_query_result *dest, ids_query_result *src) { +    if (!dest || !src) return; +    memcpy(dest, src, sizeof(ids_query_result)); +    for(int i = 0; dest->results[i]; i++) +        dest->results[i] = dest->_strs + (src->results[i] - src->_strs); +} +  /* c001 < C 01 */  //TODO: compare more than the first char  static int ids_cmp(const char *s1, const char *s2) { @@ -49,6 +59,23 @@ static int ids_cmp(const char *s1, const char *s2) {          return cmp;  } +static void ids_query_result_set_str(ids_query_result *ret, int tabs, gchar *p) { +    if (!p) { +        ret->results[tabs] = p; +    } else { +        if (tabs == 0) { +            ret->results[tabs] = ret->_strs; +            strncpy(ret->results[tabs], p, IDS_LOOKUP_BUFF_SIZE-1); +        } else { +            ret->results[tabs] = ret->results[tabs-1] + strlen(ret->results[tabs-1]) + 1; +            strncpy(ret->results[tabs], p, IDS_LOOKUP_BUFF_SIZE-1); +        } +    } +    /* all following strings become invalid */ +    while(tabs < IDS_LOOKUP_MAX_DEPTH) +        ret->results[++tabs] = NULL; +} +  /* Given a qpath "/X/Y/Z", find names as:   * X <name> ->result[0]   * \tY <name> ->result[1] @@ -59,6 +86,7 @@ static int ids_cmp(const char *s1, const char *s2) {   * - arm.ids "<implementer>/<part>"   * - sdio.ids "<vendor>/<device>", "C <class>"   * - usb.ids "<vendor>/<device>", "C <class>" etc + * - edid.ids "<3letter_vendor>"   */  long scan_ids_file(const gchar *file, const gchar *qpath, ids_query_result *result, long start_offset) {      gchar **qparts = NULL; @@ -119,8 +147,10 @@ long scan_ids_file(const gchar *file, const gchar *qpath, ids_query_result *resu          if (tabs >= qdepth) continue; /* too deep */          if (tabs != 0 && !ret.results[tabs-1])              continue; /* not looking at this depth, yet */ +        if (ret.results[tabs]) +            goto ids_lookup_done; /* answered at this level */ -        //ids_msg("looking at (%d) %s...", tabs, p); +        if (ids_tracing) ids_msg("[%s] looking at (%d) %s...", file, tabs, p);          if (g_str_has_prefix(p, qparts[tabs])              && isspace(*(p + qpartlen[tabs])) ) { @@ -128,33 +158,34 @@ long scan_ids_file(const gchar *file, const gchar *qpath, ids_query_result *resu              p += qpartlen[tabs];              while(isspace((unsigned char)*p)) p++; /* ffwd */ -            if (tabs == 0) { -                last_root_fpos = fpos; -                ret.results[tabs] = ret._strs; -                strncpy(ret.results[tabs], p, IDS_LOOKUP_BUFF_SIZE-1); -            } else { -                ret.results[tabs] = ret.results[tabs-1] + strlen(ret.results[tabs-1]) + 1; -                strncpy(ret.results[tabs], p, IDS_LOOKUP_BUFF_SIZE-1); +            if (tabs == 0) last_root_fpos = fpos; +            ids_query_result_set_str(&ret, tabs, p); + +            if (ids_tracing) { +                int i = 0; +                for(; i < IDS_LOOKUP_MAX_DEPTH; i++) { +                    if (!qparts[i]) break; +                    ids_msg(" ...[%d]: %s\t--> %s", i, qparts[i], ret.results[i]); +                }              }              continue;          }          if (ids_cmp(p, qparts[tabs]) == 1) { -            //ids_msg("will not be found p = %s (%d) qparts[tabs] = %s", p, qparts[tabs]); +            if (ids_tracing) +                ids_msg("will not be found qparts[tabs] = %s, p = %s", qparts[tabs], p);              goto ids_lookup_done; /* will not be found */          }      } /* for each line */  ids_lookup_done: -    //ids_msg("bailed at line %ld...", line); +    if (ids_tracing) +        ids_msg("bailed at line %ld...", line);      fclose(fd);      if (result) { -        memcpy(result, &ret, sizeof(ids_query_result)); -        for(int i = 0; result->results[i]; i++) -            result->results[i] = result->_strs + (ret.results[i] - ret._strs); - +        ids_query_result_cpy(result, &ret);          return last_root_fpos;      }      return last_root_fpos; @@ -187,3 +218,97 @@ int query_list_count_found(ids_query_list query_list) {      }      return count;  } + +static gchar *split_loc_default(const char *line) { +    return g_utf8_strchr(line, -1, ' '); +} + +GSList *ids_file_all_get_all(const gchar *file, split_loc_function split_loc_func) { +    GSList *ret = NULL; +    gchar buff[IDS_LOOKUP_BUFF_SIZE] = ""; +    gchar *p = NULL, *name = NULL; + +    FILE *fd; +    int tabs = 0, tabs_last = 0; +    long fpos, line = -1; + +    fd = fopen(file, "r"); +    if (!fd) { +        ids_msg("file could not be read: %s", file); +        return ret; +    } + +    ids_query_result *working = g_new0(ids_query_result, 1); +    gchar **qparts = g_new0(gchar*, IDS_LOOKUP_MAX_DEPTH + 1); +    for(tabs = IDS_LOOKUP_MAX_DEPTH-1; tabs>=0; tabs--) +        qparts[tabs] = g_malloc0(IDS_LOOKUP_BUFF_SIZE); +    tabs = 0; + +    if (!split_loc_func) split_loc_func = split_loc_default; + +    for (fpos = ftell(fd); fgets(buff, IDS_LOOKUP_BUFF_SIZE, fd); fpos = ftell(fd)) { +        p = strchr(buff, '\n'); +        if (!p) +            ids_msg("line longer than IDS_LOOKUP_BUFF_SIZE (%d), file: %s, offset: %ld", IDS_LOOKUP_BUFF_SIZE, file, fpos); +        line++; + +        /* line ends at comment */ +        p = strchr(buff, '#'); +        if (p) *p = 0; +        /* trim trailing white space */ +        if (!p) p = buff + strlen(buff); +        p--; +        while(p > buff && isspace((unsigned char)*p)) p--; +        *(p+1) = 0; +        p = buff; + +        if (buff[0] == 0)    continue; /* empty line */ +        if (buff[0] == '\n') continue; /* empty line */ + +        /* scan for fields */ +        tabs = 0; +        while(*p == '\t') { tabs++; p++; } + +        if (tabs >= IDS_LOOKUP_MAX_DEPTH) continue; /* too deep */ +        if (tabs > tabs_last + 1) { +            /* jump too big, there's a qpath part that is "" */ +            ids_msg("jump too big from depth %d to %d, file: %s, offset: %ld", tabs_last, tabs, file, fpos); +            continue; +        } + +        name = split_loc_func(p); +        if (!name) { +            ids_msg("expected name/value split not found, file: %s, offset: %ld", file, fpos); +            continue; +        } +        *name = 0; name++; /* split ptr is the first char of split string */ +        g_strstrip(p); +        g_strstrip(name); + +        // now  p = id, name = name +        // ids_msg("p: %s -- name: %s", p, name); + +        strncpy(qparts[tabs], p, IDS_LOOKUP_BUFF_SIZE-1); +        ids_query_result_set_str(working, tabs, name); +        if (tabs < tabs_last) +            for(;tabs_last > tabs; tabs_last--) { +                qparts[tabs_last][0] = 0; +                working->results[tabs_last] = NULL; +        } + +        ids_query *found = ids_query_new(NULL); +        ids_query_result_cpy(&found->result, working); +        found->qpath = g_strjoinv("/", qparts); +        p = found->qpath + strlen(found->qpath) - 1; +        while(*p == '/') { *p = 0; p--; } +        ret = g_slist_append(ret, found); + +        tabs_last = tabs; +    } /* for each line */ + +    fclose(fd); +    g_strfreev(qparts); +    ids_query_result_free(working); + +    return ret; +} | 
