diff options
Diffstat (limited to 'deps/sysobj_early')
| -rw-r--r-- | deps/sysobj_early/src/util_edid.c | 62 | ||||
| -rw-r--r-- | deps/sysobj_early/src/util_sysobj.c | 125 | 
2 files changed, 179 insertions, 8 deletions
| diff --git a/deps/sysobj_early/src/util_edid.c b/deps/sysobj_early/src/util_edid.c index 06c5534e..906aeff0 100644 --- a/deps/sysobj_early/src/util_edid.c +++ b/deps/sysobj_early/src/util_edid.c @@ -31,17 +31,55 @@  #include "util_edid_svd_table.c" -// TODO: find a better fix, I've seen a few EDID strings with bogus chars -#if !GLIB_CHECK_VERSION(2,52,0) -__attribute__ ((weak)) -gchar *g_utf8_make_valid(const gchar *s, const gssize l) { -    if (l < 0) -        return g_strdup(s); -    else -        return g_strndup(s, (gsize)l); +#if GLIB_CHECK_VERSION(2,52,0) +#else +gchar * +g2_utf8_make_valid (const gchar *str, +                   gssize       len) +{ +  GString *string; +  const gchar *remainder, *invalid; +  gsize remaining_bytes, valid_bytes; + +  g_return_val_if_fail (str != NULL, NULL); + +  if (len < 0) +    len = strlen (str); + +  string = NULL; +  remainder = str; +  remaining_bytes = len; + +  while (remaining_bytes != 0) +    { +      if (g_utf8_validate (remainder, remaining_bytes, &invalid)) +	break; +      valid_bytes = invalid - remainder; + +      if (string == NULL) +	string = g_string_sized_new (remaining_bytes); + +      g_string_append_len (string, remainder, valid_bytes); +      /* append U+FFFD REPLACEMENT CHARACTER */ +      g_string_append (string, "\357\277\275"); + +      remaining_bytes -= valid_bytes + 1; +      remainder = invalid + 1; +    } + +  if (string == NULL) +    return g_strndup (str, len); + +  g_string_append_len (string, remainder, remaining_bytes); +  g_string_append_c (string, '\0'); + +  g_assert (g_utf8_validate (string->str, -1, NULL)); + +  return g_string_free (string, FALSE);  }  #endif +  #define NOMASK (~0U)  #define BFMASK(LSB, MASK) (MASK << LSB) @@ -89,7 +127,11 @@ char *rstr(edid *e, uint32_t offset, uint32_t len) {      char *raw = malloc(len+1), *ret = NULL;      strncpy(raw, (char*)&e->u8[offset], len);      raw[len] = 0; +#if GLIB_CHECK_VERSION(2,52,0)      ret = g_utf8_make_valid(raw, len); +#else +    ret = g2_utf8_make_valid(raw, len); +#endif      g_free(raw);      return ret;  } @@ -100,7 +142,11 @@ char *rstr_strip(edid *e, uint32_t offset, uint32_t len) {      char *raw = malloc(len+1), *ret = NULL;      strncpy(raw, (char*)&e->u8[offset], len);      raw[len] = 0; +#if GLIB_CHECK_VERSION(2,52,0)      ret = g_strstrip(g_utf8_make_valid(raw, len)); +#else +    ret = g_strstrip(g2_utf8_make_valid(raw, len)); +#endif      g_free(raw);      return ret;  } diff --git a/deps/sysobj_early/src/util_sysobj.c b/deps/sysobj_early/src/util_sysobj.c index 94f71944..d0f09a68 100644 --- a/deps/sysobj_early/src/util_sysobj.c +++ b/deps/sysobj_early/src/util_sysobj.c @@ -177,12 +177,137 @@ gchar *util_strchomp_float(gchar* str_float) {      return str_float;  } + +#if GLIB_CHECK_VERSION(2, 58, 0) +#else +gchar * +g2_canonicalize_filename (const gchar *filename, +                         const gchar *relative_to) +{ +  gchar *canon, *input, *output, *after_root, *output_start; + +  g_return_val_if_fail (relative_to == NULL || g_path_is_absolute (relative_to), NULL); + +  if (!g_path_is_absolute (filename)) +    { +      gchar *cwd_allocated = NULL; +      const gchar  *cwd; + +      if (relative_to != NULL) +        cwd = relative_to; +      else +        cwd = cwd_allocated = g_get_current_dir (); + +      canon = g_build_filename (cwd, filename, NULL); +      g_free (cwd_allocated); +    } +  else +    { +      canon = g_strdup (filename); +    } + +  after_root = (char *)g_path_skip_root (canon); + +  if (after_root == NULL) +    { +      /* This shouldn't really happen, as g_get_current_dir() should +         return an absolute pathname, but bug 573843 shows this is +         not always happening */ +      g_free (canon); +      return g_build_filename (G_DIR_SEPARATOR_S, filename, NULL); +    } + +  /* Find the first dir separator and use the canonical dir separator. */ +  for (output = after_root - 1; +       (output >= canon) && G_IS_DIR_SEPARATOR (*output); +       output--) +    *output = G_DIR_SEPARATOR; + +  /* 1 to re-increment after the final decrement above (so that output >= canon), +   * and 1 to skip the first `/`. There might not be a first `/` if +   * the @canon is a Windows `//server/share` style path with no +   * trailing directories. @after_root will be '\0' in that case. */ +  output++; +  if (*output == G_DIR_SEPARATOR) +    output++; + +  /* POSIX allows double slashes at the start to mean something special +   * (as does windows too). So, "//" != "/", but more than two slashes +   * is treated as "/". +   */ +  if (after_root - output == 1) +    output++; + +  input = after_root; +  output_start = output; +  while (*input) +    { +      /* input points to the next non-separator to be processed. */ +      /* output points to the next location to write to. */ +      g_assert (input > canon && G_IS_DIR_SEPARATOR (input[-1])); +      g_assert (output > canon && G_IS_DIR_SEPARATOR (output[-1])); +      g_assert (input >= output); + +      /* Ignore repeated dir separators. */ +      while (G_IS_DIR_SEPARATOR (input[0])) +       input++; + +      /* Ignore single dot directory components. */ +      if (input[0] == '.' && (input[1] == 0 || G_IS_DIR_SEPARATOR (input[1]))) +        { +           if (input[1] == 0) +             break; +           input += 2; +        } +      /* Remove double-dot directory components along with the preceding +       * path component. */ +      else if (input[0] == '.' && input[1] == '.' && +               (input[2] == 0 || G_IS_DIR_SEPARATOR (input[2]))) +        { +          if (output > output_start) +            { +              do +                { +                  output--; +                } +              while (!G_IS_DIR_SEPARATOR (output[-1]) && output > output_start); +            } +          if (input[2] == 0) +            break; +          input += 3; +        } +      /* Copy the input to the output until the next separator, +       * while converting it to canonical separator */ +      else +        { +          while (*input && !G_IS_DIR_SEPARATOR (*input)) +            *output++ = *input++; +          if (input[0] == 0) +            break; +          input++; +          *output++ = G_DIR_SEPARATOR; +        } +    } + +  /* Remove a potentially trailing dir separator */ +  if (output > output_start && G_IS_DIR_SEPARATOR (output[-1])) +    output--; + +  *output = '\0'; + +  return canon; +} +#endif +  /* resolve . and .., but not symlinks */  gchar *util_normalize_path(const gchar *path, const gchar *relto) {      gchar *resolved = NULL;  #if GLIB_CHECK_VERSION(2, 58, 0)      resolved = g_canonicalize_filename(path, relto);  #else +    resolved = g2_canonicalize_filename(path, relto); +#endif +#if NOT_DEFINED      /* burt's hack version */      gchar *frt = relto ? g_strdup(relto) : NULL;      util_null_trailing_slash(frt); | 
