Beispiel #1
0
LIBUPCOREAPI
int create_directory(wchar_t const* p) noexcept {
    BOOL result;
    wchar_t* pext;
    size_t plen;

    if (!p) {
        errno = EINVAL;
        return -1;
    }

    plen = wcslen(p);
    if (plen >= 248) {
        pext = static_cast<wchar_t*>(malloca((plen + 16) * sizeof(wchar_t)));
        if (!pext) {
            return -1;
        }

        wcscpy(pext, L"\\\\?\\");
        wcscpy(pext + 4, p);
        result = ::CreateDirectoryW(pext, NULL);
        freea(pext);
    }
    else {
        result = ::CreateDirectoryW(p, NULL);
    }

    if (!result) {
        set_errno_with_last_oserror();
        return -1;
    }

    return 0;
}
static int
message_list_hash_insert_entry (hash_table *htable, message_ty *mp)
{
  char *alloced_key;
  const char *key;
  size_t keylen;
  int found;

  if (mp->msgctxt != NULL)
    {
      /* Concatenate mp->msgctxt and mp->msgid, to form the hash table key.  */
      size_t msgctxt_len = strlen (mp->msgctxt);
      size_t msgid_len = strlen (mp->msgid);
      keylen = msgctxt_len + 1 + msgid_len + 1;
      alloced_key = (char *) xmalloca (keylen);
      memcpy (alloced_key, mp->msgctxt, msgctxt_len);
      alloced_key[msgctxt_len] = MSGCTXT_SEPARATOR;
      memcpy (alloced_key + msgctxt_len + 1, mp->msgid, msgid_len + 1);
      key = alloced_key;
    }
  else
    {
      alloced_key = NULL;
      key = mp->msgid;
      keylen = strlen (mp->msgid) + 1;
    }

  found = (hash_insert_entry (htable, key, keylen, mp) == NULL);

  if (mp->msgctxt != NULL)
    freea (alloced_key);

  return found;
}
static int
execute_csharp_using_sscli (const char *assembly_path,
                            const char * const *libdirs,
                            unsigned int libdirs_count,
                            const char * const *args, unsigned int nargs,
                            bool verbose, bool quiet,
                            execute_fn *executer, void *private_data)
{
  static bool clix_tested;
  static bool clix_present;

  if (!clix_tested)
    {
      /* Test for presence of clix:
         "clix >/dev/null 2>/dev/null ; test $? = 1"  */
      char *argv[2];
      int exitstatus;

      argv[0] = "clix";
      argv[1] = NULL;
      exitstatus = execute ("clix", "clix", argv, false, false, true, true,
                            true, false, NULL);
      clix_present = (exitstatus == 0 || exitstatus == 1);
      clix_tested = true;
    }

  if (clix_present)
    {
      char *old_clixpath;
      char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
      unsigned int i;
      bool err;

      /* Set clix' PATH variable.  */
      old_clixpath = set_clixpath (libdirs, libdirs_count, false, verbose);

      argv[0] = "clix";
      argv[1] = (char *) assembly_path;
      for (i = 0; i <= nargs; i++)
        argv[2 + i] = (char *) args[i];

      if (verbose)
        {
          char *command = shell_quote_argv (argv);
          printf ("%s\n", command);
          free (command);
        }

      err = executer ("clix", "clix", argv, private_data);

      /* Reset clix' PATH variable.  */
      reset_clixpath (old_clixpath);

      freea (argv);

      return err;
    }
  else
    return -1;
}
Beispiel #4
0
static void
do_allocation (int n)
{
  void *ptr = malloca (n);
  freea (ptr);
  ptr = safe_alloca (n);
}
Beispiel #5
0
int
rpl_setenv (const char *name, const char *value, int replace)
{
  int result;
  if (!name || !*name || strchr (name, '='))
    {
      errno = EINVAL;
      return -1;
    }
  /* Call the real setenv even if replace is 0, in case implementation
     has underlying data to update, such as when environ changes.  */
  result = setenv (name, value, replace);
  if (result == 0 && replace && *value == '=')
    {
      char *tmp = getenv (name);
      if (!STREQ (tmp, value))
        {
          int saved_errno;
          size_t len = strlen (value);
          tmp = malloca (len + 2);
          /* Since leading '=' is eaten, double it up.  */
          *tmp = '=';
          memcpy (tmp + 1, value, len + 1);
          result = setenv (name, tmp, replace);
          saved_errno = errno;
          freea (tmp);
          errno = saved_errno;
        }
    }
  return result;
}
message_ty *
message_list_search (message_list_ty *mlp,
                     const char *msgctxt, const char *msgid)
{
  if (mlp->use_hashtable)
    {
      char *alloced_key;
      const char *key;
      size_t keylen;

      if (msgctxt != NULL)
        {
          /* Concatenate the msgctxt and msgid, to form the hash table key.  */
          size_t msgctxt_len = strlen (msgctxt);
          size_t msgid_len = strlen (msgid);
          keylen = msgctxt_len + 1 + msgid_len + 1;
          alloced_key = (char *) xmalloca (keylen);
          memcpy (alloced_key, msgctxt, msgctxt_len);
          alloced_key[msgctxt_len] = MSGCTXT_SEPARATOR;
          memcpy (alloced_key + msgctxt_len + 1, msgid, msgid_len + 1);
          key = alloced_key;
        }
      else
        {
          alloced_key = NULL;
          key = msgid;
          keylen = strlen (msgid) + 1;
        }

      {
        void *htable_value;
        int found = !hash_find_entry (&mlp->htable, key, keylen, &htable_value);

        if (msgctxt != NULL)
          freea (alloced_key);

        if (found)
          return (message_ty *) htable_value;
        else
          return NULL;
      }
    }
  else
    {
      size_t j;

      for (j = 0; j < mlp->nitems; ++j)
        {
          message_ty *mp;

          mp = mlp->item[j];
          if ((msgctxt != NULL
               ? mp->msgctxt != NULL && strcmp (msgctxt, mp->msgctxt) == 0
               : mp->msgctxt == NULL)
              && strcmp (msgid, mp->msgid) == 0)
            return mp;
        }
      return NULL;
    }
}
Beispiel #7
0
/* File open routine that understands `-' as stdin/stdout and `|cmd'
   as a pipe to command `cmd'.  Returns resultant FILE on success,
   NULL on failure.  If NULL is returned then errno is set to a
   sensible value.  */
FILE *
fn_open (const char *fn, const char *mode)
{
  assert (mode[0] == 'r' || mode[0] == 'w' || mode[0] == 'a');

  if (mode[0] == 'r')
    {
      if (!strcmp (fn, "stdin") || !strcmp (fn, "-"))
        return stdin;
    }
  else
    {
      if (!strcmp (fn, "stdout") || !strcmp (fn, "-"))
        return stdout;
      if (!strcmp (fn, "stderr"))
        return stderr;
    }

#if HAVE_POPEN
  if (fn[0] == '|')
    {
      if (settings_get_safer_mode ())
	return safety_violation (fn);

      return popen (&fn[1], mode[0] == 'r' ? "r" : "w");
    }
  else if (*fn && fn[strlen (fn) - 1] == '|')
    {
      char *s;
      FILE *f;

      if (settings_get_safer_mode ())
	return safety_violation (fn);

      s = xmalloca (strlen (fn));
      memcpy (s, fn, strlen (fn) - 1);
      s[strlen (fn) - 1] = 0;

      f = popen (s, mode[0] == 'r' ? "r" : "w");

      freea (s);

      return f;
    }
  else
#endif
    return fopen (fn, mode);
}
Beispiel #8
0
int
mem_iconveha (const char *src, size_t srclen,
              const char *from_codeset, const char *to_codeset,
              bool transliterate,
              enum iconv_ilseq_handler handler,
              size_t *offsets,
              char **resultp, size_t *lengthp)
{
  if (srclen == 0)
    {
      /* Nothing to convert.  */
      *lengthp = 0;
      return 0;
    }

  /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
     we want to use transliteration.  */
#if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) \
     && !defined __UCLIBC__) \
    || _LIBICONV_VERSION >= 0x0105
  if (transliterate)
    {
      int retval;
      size_t len = strlen (to_codeset);
      char *to_codeset_suffixed = (char *) malloca (len + 10 + 1);
      memcpy (to_codeset_suffixed, to_codeset, len);
      memcpy (to_codeset_suffixed + len, "//TRANSLIT", 10 + 1);

      retval = mem_iconveha_notranslit (src, srclen,
                                        from_codeset, to_codeset_suffixed,
                                        handler, offsets, resultp, lengthp);

      freea (to_codeset_suffixed);

      return retval;
    }
  else
#endif
    return mem_iconveha_notranslit (src, srclen,
                                    from_codeset, to_codeset,
                                    handler, offsets, resultp, lengthp);
}
Beispiel #9
0
char *
str_iconveha (const char *src,
              const char *from_codeset, const char *to_codeset,
              bool transliterate,
              enum iconv_ilseq_handler handler)
{
  if (*src == '\0' || c_strcasecmp (from_codeset, to_codeset) == 0)
    {
      char *result = strdup (src);

      if (result == NULL)
        errno = ENOMEM;
      return result;
    }

  /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
     we want to use transliteration.  */
#if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) \
     && !defined __UCLIBC__) \
    || _LIBICONV_VERSION >= 0x0105
  if (transliterate)
    {
      char *result;
      size_t len = strlen (to_codeset);
      char *to_codeset_suffixed = (char *) malloca (len + 10 + 1);
      memcpy (to_codeset_suffixed, to_codeset, len);
      memcpy (to_codeset_suffixed + len, "//TRANSLIT", 10 + 1);

      result = str_iconveha_notranslit (src, from_codeset, to_codeset_suffixed,
                                        handler);

      freea (to_codeset_suffixed);

      return result;
    }
  else
#endif
    return str_iconveha_notranslit (src, from_codeset, to_codeset, handler);
}
Beispiel #10
0
    LIBUPCOREAPI
    ssize_t absolute_path(char* d, size_t dsz, char const* p, char const* base) noexcept {
        wchar_t* native_d = nullptr, * native_p = nullptr, * native_base = nullptr;
        ssize_t retval = -1;
        size_t length;

        if (dsz) {
            native_d = static_cast<wchar_t *>(malloca(dsz * sizeof(wchar_t)));
            if (!native_d) {
                return -1;
            }
        }

        native_p = transcode(p);
        if (!native_p) {
            goto error;
        }

        if (base) {
            native_base = transcode(base);
            if (!native_base) {
                goto error;
            }
        }

        retval = absolute_path(native_d, dsz, native_p, native_base);
        if (!retval) {
            length = static_cast<size_t>(retval);
            retval = transcode(d, dsz, native_d, length);
        }

    error:

        free(native_base);
        free(native_p);
        freea(native_d);
        return retval;
    }
Beispiel #11
0
/* Return true if a format is a valid messageFormatPattern.
   Extracts argument type information into spec.  */
static bool
message_format_parse (const char *format, char *fdi, struct spec *spec,
                      char **invalid_reason)
{
  const char *const format_start = format;
  bool quoting = false;

  for (;;)
    {
      HANDLE_QUOTE;
      if (!quoting && *format == '{')
        {
          unsigned int depth;
          const char *element_start;
          const char *element_end;
          size_t n;
          char *element_alloced;
          char *element;
          unsigned int number;
          enum format_arg_type type;

          FDI_SET (format, FMTDIR_START);
          spec->directives++;

          element_start = ++format;
          depth = 0;
          for (; *format != '\0'; format++)
            {
              if (*format == '{')
                depth++;
              else if (*format == '}')
                {
                  if (depth == 0)
                    break;
                  else
                    depth--;
                }
            }
          if (*format == '\0')
            {
              *invalid_reason =
                xstrdup (_("The string ends in the middle of a directive: found '{' without matching '}'."));
              FDI_SET (format - 1, FMTDIR_ERROR);
              return false;
            }
          element_end = format++;

          n = element_end - element_start;
          element = element_alloced = (char *) xmalloca (n + 1);
          memcpy (element, element_start, n);
          element[n] = '\0';

          if (!c_isdigit (*element))
            {
              *invalid_reason =
                xasprintf (_("In the directive number %u, '{' is not followed by an argument number."), spec->directives);
              FDI_SET (format - 1, FMTDIR_ERROR);
              freea (element_alloced);
              return false;
            }
          number = 0;
          do
            {
              number = 10 * number + (*element - '0');
              element++;
            }
          while (c_isdigit (*element));

          type = FAT_OBJECT;
          if (*element == '\0')
            ;
          else if (strncmp (element, ",time", 5) == 0
                   || strncmp (element, ",date", 5) == 0)
            {
              type = FAT_DATE;
              element += 5;
              if (*element == '\0')
                ;
              else if (*element == ',')
                {
                  element++;
                  if (strcmp (element, "short") == 0
                      || strcmp (element, "medium") == 0
                      || strcmp (element, "long") == 0
                      || strcmp (element, "full") == 0
                      || date_format_parse (element))
                    ;
                  else
                    {
                      *invalid_reason =
                        xasprintf (_("In the directive number %u, the substring \"%s\" is not a valid date/time style."), spec->directives, element);
                      FDI_SET (format - 1, FMTDIR_ERROR);
                      freea (element_alloced);
                      return false;
                    }
                }
              else
                {
                  *element = '\0';
                  element -= 4;
                  *invalid_reason =
                    xasprintf (_("In the directive number %u, \"%s\" is not followed by a comma."), spec->directives, element);
                  FDI_SET (format - 1, FMTDIR_ERROR);
                  freea (element_alloced);
                  return false;
                }
            }
          else if (strncmp (element, ",number", 7) == 0)
            {
              type = FAT_NUMBER;
              element += 7;
              if (*element == '\0')
                ;
              else if (*element == ',')
                {
                  element++;
                  if (strcmp (element, "currency") == 0
                      || strcmp (element, "percent") == 0
                      || strcmp (element, "integer") == 0
                      || number_format_parse (element))
                    ;
                  else
                    {
                      *invalid_reason =
                        xasprintf (_("In the directive number %u, the substring \"%s\" is not a valid number style."), spec->directives, element);
                      FDI_SET (format - 1, FMTDIR_ERROR);
                      freea (element_alloced);
                      return false;
                    }
                }
              else
                {
                  *element = '\0';
                  element -= 6;
                  *invalid_reason =
                    xasprintf (_("In the directive number %u, \"%s\" is not followed by a comma."), spec->directives, element);
                  FDI_SET (format - 1, FMTDIR_ERROR);
                  freea (element_alloced);
                  return false;
                }
            }
          else if (strncmp (element, ",choice", 7) == 0)
            {
              type = FAT_NUMBER; /* because ChoiceFormat extends NumberFormat */
              element += 7;
              if (*element == '\0')
                ;
              else if (*element == ',')
                {
                  element++;
                  if (choice_format_parse (element, spec, invalid_reason))
                    ;
                  else
                    {
                      FDI_SET (format - 1, FMTDIR_ERROR);
                      freea (element_alloced);
                      return false;
                    }
                }
              else
                {
                  *element = '\0';
                  element -= 6;
                  *invalid_reason =
                    xasprintf (_("In the directive number %u, \"%s\" is not followed by a comma."), spec->directives, element);
                  FDI_SET (format - 1, FMTDIR_ERROR);
                  freea (element_alloced);
                  return false;
                }
            }
          else
            {
              *invalid_reason =
                xasprintf (_("In the directive number %u, the argument number is not followed by a comma and one of \"%s\", \"%s\", \"%s\", \"%s\"."), spec->directives, "time", "date", "number", "choice");
              FDI_SET (format - 1, FMTDIR_ERROR);
              freea (element_alloced);
              return false;
            }
          freea (element_alloced);

          if (spec->allocated == spec->numbered_arg_count)
            {
              spec->allocated = 2 * spec->allocated + 1;
              spec->numbered = (struct numbered_arg *) xrealloc (spec->numbered, spec->allocated * sizeof (struct numbered_arg));
            }
          spec->numbered[spec->numbered_arg_count].number = number;
          spec->numbered[spec->numbered_arg_count].type = type;
          spec->numbered_arg_count++;

          FDI_SET (format - 1, FMTDIR_END);
        }
      /* The doc says "ab}de" is invalid.  Even though JDK accepts it.  */
      else if (!quoting && *format == '}')
        {
          FDI_SET (format, FMTDIR_START);
          *invalid_reason =
            xstrdup (_("The string starts in the middle of a directive: found '}' without matching '{'."));
          FDI_SET (format, FMTDIR_ERROR);
          return false;
        }
      else if (*format != '\0')
        format++;
      else
        break;
    }

  return true;
}
static int
compile_csharp_using_mono (const char * const *sources,
                           unsigned int sources_count,
                           const char * const *libdirs,
                           unsigned int libdirs_count,
                           const char * const *libraries,
                           unsigned int libraries_count,
                           const char *output_file, bool output_is_library,
                           bool optimize, bool debug,
                           bool verbose)
{
  static bool mcs_tested;
  static bool mcs_present;

  if (!mcs_tested)
    {
      /* Test for presence of mcs:
         "mcs --version >/dev/null 2>/dev/null"
         and (to exclude an unrelated 'mcs' program on QNX 6)
         "mcs --version 2>/dev/null | grep Mono >/dev/null"  */
      char *argv[3];
      pid_t child;
      int fd[1];
      int exitstatus;

      argv[0] = "mcs";
      argv[1] = "--version";
      argv[2] = NULL;
      child = create_pipe_in ("mcs", "mcs", argv, DEV_NULL, true, true, false,
                              fd);
      mcs_present = false;
      if (child != -1)
        {
          /* Read the subprocess output, and test whether it contains the
             string "Mono".  */
          char c[4];
          size_t count = 0;

          while (safe_read (fd[0], &c[count], 1) > 0)
            {
              count++;
              if (count == 4)
                {
                  if (memcmp (c, "Mono", 4) == 0)
                    mcs_present = true;
                  c[0] = c[1]; c[1] = c[2]; c[2] = c[3];
                  count--;
                }
            }

          close (fd[0]);

          /* Remove zombie process from process list, and retrieve exit
             status.  */
          exitstatus =
            wait_subprocess (child, "mcs", false, true, true, false, NULL);
          if (exitstatus != 0)
            mcs_present = false;
        }
      mcs_tested = true;
    }

  if (mcs_present)
    {
      unsigned int argc;
      char **argv;
      char **argp;
      pid_t child;
      int fd[1];
      FILE *fp;
      char *line[2];
      size_t linesize[2];
      size_t linelen[2];
      unsigned int l;
      int exitstatus;
      unsigned int i;

      argc =
        1 + (output_is_library ? 1 : 0) + 1 + libdirs_count + libraries_count
        + (debug ? 1 : 0) + sources_count;
      argv = (char **) xmalloca ((argc + 1) * sizeof (char *));

      argp = argv;
      *argp++ = "mcs";
      if (output_is_library)
        *argp++ = "-target:library";
      {
        char *option = (char *) xmalloca (5 + strlen (output_file) + 1);
        memcpy (option, "-out:", 5);
        strcpy (option + 5, output_file);
        *argp++ = option;
      }
      for (i = 0; i < libdirs_count; i++)
        {
          char *option = (char *) xmalloca (5 + strlen (libdirs[i]) + 1);
          memcpy (option, "-lib:", 5);
          strcpy (option + 5, libdirs[i]);
          *argp++ = option;
        }
      for (i = 0; i < libraries_count; i++)
        {
          char *option = (char *) xmalloca (11 + strlen (libraries[i]) + 4 + 1);
          memcpy (option, "-reference:", 11);
          memcpy (option + 11, libraries[i], strlen (libraries[i]));
          strcpy (option + 11 + strlen (libraries[i]), ".dll");
          *argp++ = option;
        }
      if (debug)
        *argp++ = "-debug";
      for (i = 0; i < sources_count; i++)
        {
          const char *source_file = sources[i];
          if (strlen (source_file) >= 10
              && memcmp (source_file + strlen (source_file) - 10, ".resources",
                         10) == 0)
            {
              char *option = (char *) xmalloca (10 + strlen (source_file) + 1);

              memcpy (option, "-resource:", 10);
              strcpy (option + 10, source_file);
              *argp++ = option;
            }
          else
            *argp++ = (char *) source_file;
        }
      *argp = NULL;
      /* Ensure argv length was correctly calculated.  */
      if (argp - argv != argc)
        abort ();

      if (verbose)
        {
          char *command = shell_quote_argv (argv);
          printf ("%s\n", command);
          free (command);
        }

      child = create_pipe_in ("mcs", "mcs", argv, NULL, false, true, true, fd);

      /* Read the subprocess output, copying it to stderr.  Drop the last
         line if it starts with "Compilation succeeded".  */
      fp = fdopen (fd[0], "r");
      if (fp == NULL)
        error (EXIT_FAILURE, errno, _("fdopen() failed"));
      line[0] = NULL; linesize[0] = 0;
      line[1] = NULL; linesize[1] = 0;
      l = 0;
      for (;;)
        {
          linelen[l] = getline (&line[l], &linesize[l], fp);
          if (linelen[l] == (size_t)(-1))
            break;
          l = (l + 1) % 2;
          if (line[l] != NULL)
            fwrite (line[l], 1, linelen[l], stderr);
        }
      l = (l + 1) % 2;
      if (line[l] != NULL
          && !(linelen[l] >= 21
               && memcmp (line[l], "Compilation succeeded", 21) == 0))
        fwrite (line[l], 1, linelen[l], stderr);
      if (line[0] != NULL)
        free (line[0]);
      if (line[1] != NULL)
        free (line[1]);
      fclose (fp);

      /* Remove zombie process from process list, and retrieve exit status.  */
      exitstatus =
        wait_subprocess (child, "mcs", false, false, true, true, NULL);

      for (i = 1 + (output_is_library ? 1 : 0);
           i < 1 + (output_is_library ? 1 : 0)
               + 1 + libdirs_count + libraries_count;
           i++)
        freea (argv[i]);
      for (i = 0; i < sources_count; i++)
        if (argv[argc - sources_count + i] != sources[i])
          freea (argv[argc - sources_count + i]);
      freea (argv);

      return (exitstatus != 0);
    }
  else
    return -1;
}
Beispiel #13
0
/* Return true if a format is a valid choiceFormatPattern.
   Extracts argument type information into spec.  */
static bool
choice_format_parse (const char *format, struct spec *spec,
                     char **invalid_reason)
{
  /* Pattern syntax:
       pattern   := | choice | choice '|' pattern
       choice    := number separator messageformat
       separator := '<' | '#' | '\u2264'
     Single-quote starts a quoted section, to be terminated at the next
     single-quote or string end.  Double single-quote gives a single
     single-quote.
   */
  bool quoting = false;

  HANDLE_QUOTE;
  if (*format == '\0')
    return true;
  for (;;)
    {
      /* Don't bother looking too precisely into the syntax of the number.
         It can contain various Unicode characters.  */
      bool number_nonempty;
      char *msgformat;
      char *mp;
      bool msgformat_valid;

      /* Parse number.  */
      number_nonempty = false;
      while (*format != '\0'
             && !(!quoting && (*format == '<' || *format == '#'
                               || strncmp (format, "\\u2264", 6) == 0
                               || *format == '|')))
        {
          if (format[0] == '\\')
            {
              if (format[1] == 'u'
                  && c_isxdigit (format[2])
                  && c_isxdigit (format[3])
                  && c_isxdigit (format[4])
                  && c_isxdigit (format[5]))
                format += 6;
              else
                format += 2;
            }
          else
            format += 1;
          number_nonempty = true;
          HANDLE_QUOTE;
        }

      /* Short clause at end of pattern is valid and is ignored!  */
      if (*format == '\0')
        break;

      if (!number_nonempty)
        {
          *invalid_reason =
            xasprintf (_("In the directive number %u, a choice contains no number."), spec->directives);
          return false;
        }

      if (*format == '<' || *format == '#')
        format += 1;
      else if (strncmp (format, "\\u2264", 6) == 0)
        format += 6;
      else
        {
          *invalid_reason =
            xasprintf (_("In the directive number %u, a choice contains a number that is not followed by '<', '#' or '%s'."), spec->directives, "\\u2264");
          return false;
        }
      HANDLE_QUOTE;

      msgformat = (char *) xmalloca (strlen (format) + 1);
      mp = msgformat;

      while (*format != '\0' && !(!quoting && *format == '|'))
        {
          *mp++ = *format++;
          HANDLE_QUOTE;
        }
      *mp = '\0';

      msgformat_valid =
        message_format_parse (msgformat, NULL, spec, invalid_reason);

      freea (msgformat);

      if (!msgformat_valid)
        return false;

      if (*format == '\0')
        break;

      format++;
      HANDLE_QUOTE;
    }

  return true;
}
static int
execute_csharp_using_pnet (const char *assembly_path,
                           const char * const *libdirs,
                           unsigned int libdirs_count,
                           const char * const *args, unsigned int nargs,
                           bool verbose, bool quiet,
                           execute_fn *executer, void *private_data)
{
  static bool ilrun_tested;
  static bool ilrun_present;

  if (!ilrun_tested)
    {
      /* Test for presence of ilrun:
         "ilrun --version >/dev/null 2>/dev/null"  */
      char *argv[3];
      int exitstatus;

      argv[0] = "ilrun";
      argv[1] = "--version";
      argv[2] = NULL;
      exitstatus = execute ("ilrun", "ilrun", argv, false, false, true, true,
                            true, false, NULL);
      ilrun_present = (exitstatus == 0);
      ilrun_tested = true;
    }

  if (ilrun_present)
    {
      unsigned int argc;
      char **argv;
      char **argp;
      unsigned int i;
      bool err;

      argc = 1 + 2 * libdirs_count + 1 + nargs;
      argv = (char **) xmalloca ((argc + 1) * sizeof (char *));

      argp = argv;
      *argp++ = "ilrun";
      for (i = 0; i < libdirs_count; i++)
        {
          *argp++ = "-L";
          *argp++ = (char *) libdirs[i];
        }
      *argp++ = (char *) assembly_path;
      for (i = 0; i < nargs; i++)
        *argp++ = (char *) args[i];
      *argp = NULL;
      /* Ensure argv length was correctly calculated.  */
      if (argp - argv != argc)
        abort ();

      if (verbose)
        {
          char *command = shell_quote_argv (argv);
          printf ("%s\n", command);
          free (command);
        }

      err = executer ("ilrun", "ilrun", argv, private_data);

      freea (argv);

      return err;
    }
  else
    return -1;
}
Beispiel #15
0
/* Knuth-Morris-Pratt algorithm.
   See http://en.wikipedia.org/wiki/Knuth-Morris-Pratt_algorithm
   Return a boolean indicating success:
   Return true and set *RESULTP if the search was completed.
   Return false if it was aborted because not enough memory was available.  */
static bool
knuth_morris_pratt_multibyte (const char *haystack, const char *needle,
                              const char **resultp)
{
  size_t m = mbslen (needle);
  mbchar_t *needle_mbchars;
  size_t *table;

  /* Allocate room for needle_mbchars and the table.  */
  char *memory = (char *) nmalloca (m, sizeof (mbchar_t) + sizeof (size_t));
  if (memory == NULL)
    return false;
  needle_mbchars = (mbchar_t *) memory;
  table = (size_t *) (memory + m * sizeof (mbchar_t));

  /* Fill needle_mbchars.  */
  {
    mbui_iterator_t iter;
    size_t j;

    j = 0;
    for (mbui_init (iter, needle); mbui_avail (iter); mbui_advance (iter), j++)
      mb_copy (&needle_mbchars[j], &mbui_cur (iter));
  }

  /* Fill the table.
     For 0 < i < m:
       0 < table[i] <= i is defined such that
       forall 0 < x < table[i]: needle[x..i-1] != needle[0..i-1-x],
       and table[i] is as large as possible with this property.
     This implies:
     1) For 0 < i < m:
          If table[i] < i,
          needle[table[i]..i-1] = needle[0..i-1-table[i]].
     2) For 0 < i < m:
          rhaystack[0..i-1] == needle[0..i-1]
          and exists h, i <= h < m: rhaystack[h] != needle[h]
          implies
          forall 0 <= x < table[i]: rhaystack[x..x+m-1] != needle[0..m-1].
     table[0] remains uninitialized.  */
  {
    size_t i, j;

    /* i = 1: Nothing to verify for x = 0.  */
    table[1] = 1;
    j = 0;

    for (i = 2; i < m; i++)
      {
        /* Here: j = i-1 - table[i-1].
           The inequality needle[x..i-1] != needle[0..i-1-x] is known to hold
           for x < table[i-1], by induction.
           Furthermore, if j>0: needle[i-1-j..i-2] = needle[0..j-1].  */
        mbchar_t *b = &needle_mbchars[i - 1];

        for (;;)
          {
            /* Invariants: The inequality needle[x..i-1] != needle[0..i-1-x]
               is known to hold for x < i-1-j.
               Furthermore, if j>0: needle[i-1-j..i-2] = needle[0..j-1].  */
            if (mb_equal (*b, needle_mbchars[j]))
              {
                /* Set table[i] := i-1-j.  */
                table[i] = i - ++j;
                break;
              }
            /* The inequality needle[x..i-1] != needle[0..i-1-x] also holds
               for x = i-1-j, because
                 needle[i-1] != needle[j] = needle[i-1-x].  */
            if (j == 0)
              {
                /* The inequality holds for all possible x.  */
                table[i] = i;
                break;
              }
            /* The inequality needle[x..i-1] != needle[0..i-1-x] also holds
               for i-1-j < x < i-1-j+table[j], because for these x:
                 needle[x..i-2]
                 = needle[x-(i-1-j)..j-1]
                 != needle[0..j-1-(x-(i-1-j))]  (by definition of table[j])
                    = needle[0..i-2-x],
               hence needle[x..i-1] != needle[0..i-1-x].
               Furthermore
                 needle[i-1-j+table[j]..i-2]
                 = needle[table[j]..j-1]
                 = needle[0..j-1-table[j]]  (by definition of table[j]).  */
            j = j - table[j];
          }
        /* Here: j = i - table[i].  */
      }
  }

  /* Search, using the table to accelerate the processing.  */
  {
    size_t j;
    mbui_iterator_t rhaystack;
    mbui_iterator_t phaystack;

    *resultp = NULL;
    j = 0;
    mbui_init (rhaystack, haystack);
    mbui_init (phaystack, haystack);
    /* Invariant: phaystack = rhaystack + j.  */
    while (mbui_avail (phaystack))
      if (mb_equal (needle_mbchars[j], mbui_cur (phaystack)))
        {
          j++;
          mbui_advance (phaystack);
          if (j == m)
            {
              /* The entire needle has been found.  */
              *resultp = mbui_cur_ptr (rhaystack);
              break;
            }
        }
      else if (j > 0)
        {
          /* Found a match of needle[0..j-1], mismatch at needle[j].  */
          size_t count = table[j];
          j -= count;
          for (; count > 0; count--)
            {
              if (!mbui_avail (rhaystack))
                abort ();
              mbui_advance (rhaystack);
            }
        }
      else
        {
          /* Found a mismatch at needle[0] already.  */
          if (!mbui_avail (rhaystack))
            abort ();
          mbui_advance (rhaystack);
          mbui_advance (phaystack);
        }
  }

  freea (memory);
  return true;
}
static int
execute_csharp_using_mono (const char *assembly_path,
                           const char * const *libdirs,
                           unsigned int libdirs_count,
                           const char * const *args, unsigned int nargs,
                           bool verbose, bool quiet,
                           execute_fn *executer, void *private_data)
{
  static bool mono_tested;
  static bool mono_present;

  if (!mono_tested)
    {
      /* Test for presence of mono:
         "mono --version >/dev/null 2>/dev/null"  */
      char *argv[3];
      int exitstatus;

      argv[0] = "mono";
      argv[1] = "--version";
      argv[2] = NULL;
      exitstatus = execute ("mono", "mono", argv, false, false, true, true,
                            true, false, NULL);
      mono_present = (exitstatus == 0);
      mono_tested = true;
    }

  if (mono_present)
    {
      char *old_monopath;
      char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
      unsigned int i;
      bool err;

      /* Set MONO_PATH.  */
      old_monopath = set_monopath (libdirs, libdirs_count, false, verbose);

      argv[0] = "mono";
      argv[1] = (char *) assembly_path;
      for (i = 0; i <= nargs; i++)
        argv[2 + i] = (char *) args[i];

      if (verbose)
        {
          char *command = shell_quote_argv (argv);
          printf ("%s\n", command);
          free (command);
        }

      err = executer ("mono", "mono", argv, private_data);

      /* Reset MONO_PATH.  */
      reset_monopath (old_monopath);

      freea (argv);

      return err;
    }
  else
    return -1;
}
Beispiel #17
0
char *
__realpath (const char *name, char *resolved)
{
  char *rpath, *dest, *extra_buf = NULL;
  const char *start, *end, *rpath_limit;
  long int path_max;
#if HAVE_READLINK
  int num_links = 0;
#endif

  if (name == NULL)
    {
      /* As per Single Unix Specification V2 we must return an error if
	 either parameter is a null pointer.  We extend this to allow
	 the RESOLVED parameter to be NULL in case the we are expected to
	 allocate the room for the return value.  */
      __set_errno (EINVAL);
      return NULL;
    }

  if (name[0] == '\0')
    {
      /* As per Single Unix Specification V2 we must return an error if
	 the name argument points to an empty string.  */
      __set_errno (ENOENT);
      return NULL;
    }

#ifdef PATH_MAX
  path_max = PATH_MAX;
#else
  path_max = pathconf (name, _PC_PATH_MAX);
  if (path_max <= 0)
    path_max = 1024;
#endif

  if (resolved == NULL)
    {
      rpath = malloc (path_max);
      if (rpath == NULL)
	{
	  /* It's easier to set errno to ENOMEM than to rely on the
	     'malloc-posix' gnulib module.  */
	  errno = ENOMEM;
	  return NULL;
	}
    }
  else
    rpath = resolved;
  rpath_limit = rpath + path_max;

  if (name[0] != '/')
    {
      if (!__getcwd (rpath, path_max))
	{
	  rpath[0] = '\0';
	  goto error;
	}
      dest = strchr (rpath, '\0');
    }
  else
    {
      rpath[0] = '/';
      dest = rpath + 1;
    }

  for (start = end = name; *start; start = end)
    {
#ifdef _LIBC
      struct stat64 st;
#else
      struct stat st;
#endif

      /* Skip sequence of multiple path-separators.  */
      while (*start == '/')
	++start;

      /* Find end of path component.  */
      for (end = start; *end && *end != '/'; ++end)
	/* Nothing.  */;

      if (end - start == 0)
	break;
      else if (end - start == 1 && start[0] == '.')
	/* nothing */;
      else if (end - start == 2 && start[0] == '.' && start[1] == '.')
	{
	  /* Back up to previous component, ignore if at root already.  */
	  if (dest > rpath + 1)
	    while ((--dest)[-1] != '/');
	}
      else
	{
	  size_t new_size;

	  if (dest[-1] != '/')
	    *dest++ = '/';

	  if (dest + (end - start) >= rpath_limit)
	    {
	      ptrdiff_t dest_offset = dest - rpath;
	      char *new_rpath;

	      if (resolved)
		{
		  __set_errno (ENAMETOOLONG);
		  if (dest > rpath + 1)
		    dest--;
		  *dest = '\0';
		  goto error;
		}
	      new_size = rpath_limit - rpath;
	      if (end - start + 1 > path_max)
		new_size += end - start + 1;
	      else
		new_size += path_max;
	      new_rpath = (char *) realloc (rpath, new_size);
	      if (new_rpath == NULL)
		{
		  /* It's easier to set errno to ENOMEM than to rely on the
		     'realloc-posix' gnulib module.  */
		  errno = ENOMEM;
		  goto error;
		}
	      rpath = new_rpath;
	      rpath_limit = rpath + new_size;

	      dest = rpath + dest_offset;
	    }

#ifdef _LIBC
	  dest = __mempcpy (dest, start, end - start);
#else
	  memcpy (dest, start, end - start);
	  dest += end - start;
#endif
	  *dest = '\0';

#ifdef _LIBC
	  if (__lxstat64 (_STAT_VER, rpath, &st) < 0)
#else
	  if (lstat (rpath, &st) < 0)
#endif
	    goto error;

#if HAVE_READLINK
	  if (S_ISLNK (st.st_mode))
	    {
	      char *buf;
	      size_t len;
	      int n;

	      if (++num_links > MAXSYMLINKS)
		{
		  __set_errno (ELOOP);
		  goto error;
		}

	      buf = malloca (path_max);
	      if (!buf)
		{
		  errno = ENOMEM;
		  goto error;
		}

	      n = __readlink (rpath, buf, path_max - 1);
	      if (n < 0)
		{
		  int saved_errno = errno;
		  freea (buf);
		  errno = saved_errno;
		  goto error;
		}
	      buf[n] = '\0';

	      if (!extra_buf)
		{
		  extra_buf = malloca (path_max);
		  if (!extra_buf)
		    {
		      freea (buf);
		      errno = ENOMEM;
		      goto error;
		    }
		}

	      len = strlen (end);
	      if ((long int) (n + len) >= path_max)
		{
		  freea (buf);
		  __set_errno (ENAMETOOLONG);
		  goto error;
		}

	      /* Careful here, end may be a pointer into extra_buf... */
	      memmove (&extra_buf[n], end, len + 1);
	      name = end = memcpy (extra_buf, buf, n);

	      if (buf[0] == '/')
		dest = rpath + 1;	/* It's an absolute symlink */
	      else
		/* Back up to previous component, ignore if at root already: */
		if (dest > rpath + 1)
		  while ((--dest)[-1] != '/');
	    }
#endif
	}
    }
  if (dest > rpath + 1 && dest[-1] == '/')
    --dest;
  *dest = '\0';

  if (extra_buf)
    freea (extra_buf);

  return resolved ? memcpy (resolved, rpath, dest - rpath + 1) : rpath;

error:
  {
    int saved_errno = errno;
    if (extra_buf)
      freea (extra_buf);
    if (resolved)
      strcpy (resolved, rpath);
    else
      free (rpath);
    errno = saved_errno;
  }
  return NULL;
}
Beispiel #18
0
bool
execute_java_class (const char *class_name,
		    const char * const *classpaths,
		    unsigned int classpaths_count,
		    bool use_minimal_classpath,
		    const char *exe_dir,
		    const char * const *args,
		    bool verbose, bool quiet,
		    execute_fn *executer, void *private_data)
{
  bool err = false;
  unsigned int nargs;
  char *old_JAVA_HOME;

  /* Count args.  */
  {
    const char * const *arg;

    for (nargs = 0, arg = args; *arg != NULL; nargs++, arg++)
     ;
  }

  /* First, try a class compiled to a native code executable.  */
  if (exe_dir != NULL)
    {
      char *exe_pathname = concatenated_filename (exe_dir, class_name, EXEEXT);
      char *old_classpath;
      char **argv = (char **) xmalloca ((1 + nargs + 1) * sizeof (char *));
      unsigned int i;

      /* Set CLASSPATH.  */
      old_classpath =
	set_classpath (classpaths, classpaths_count, use_minimal_classpath,
		       verbose);

      argv[0] = exe_pathname;
      for (i = 0; i <= nargs; i++)
	argv[1 + i] = (char *) args[i];

      if (verbose)
	{
	  char *command = shell_quote_argv (argv);
	  printf ("%s\n", command);
	  free (command);
	}

      err = executer (class_name, exe_pathname, argv, private_data);

      /* Reset CLASSPATH.  */
      reset_classpath (old_classpath);

      freea (argv);

      goto done1;
    }

  {
    const char *java = getenv ("JAVA");
    if (java != NULL && java[0] != '\0')
      {
	/* Because $JAVA may consist of a command and options, we use the
	   shell.  Because $JAVA has been set by the user, we leave all
	   all environment variables in place, including JAVA_HOME, and
	   we don't erase the user's CLASSPATH.  */
	char *old_classpath;
	unsigned int command_length;
	char *command;
	char *argv[4];
	const char * const *arg;
	char *p;

	/* Set CLASSPATH.  */
	old_classpath =
	  set_classpath (classpaths, classpaths_count, false,
			 verbose);

	command_length = strlen (java);
	command_length += 1 + shell_quote_length (class_name);
	for (arg = args; *arg != NULL; arg++)
	  command_length += 1 + shell_quote_length (*arg);
	command_length += 1;

	command = (char *) xmalloca (command_length);
	p = command;
	/* Don't shell_quote $JAVA, because it may consist of a command
	   and options.  */
	memcpy (p, java, strlen (java));
	p += strlen (java);
	*p++ = ' ';
	p = shell_quote_copy (p, class_name);
	for (arg = args; *arg != NULL; arg++)
	  {
	    *p++ = ' ';
	    p = shell_quote_copy (p, *arg);
	  }
	*p++ = '\0';
	/* Ensure command_length was correctly calculated.  */
	if (p - command > command_length)
	  abort ();

	if (verbose)
	  printf ("%s\n", command);

	argv[0] = "/bin/sh";
	argv[1] = "-c";
	argv[2] = command;
	argv[3] = NULL;
	err = executer (java, "/bin/sh", argv, private_data);

	freea (command);

	/* Reset CLASSPATH.  */
	reset_classpath (old_classpath);

	goto done1;
      }
  }

  /* Unset the JAVA_HOME environment variable.  */
  old_JAVA_HOME = getenv ("JAVA_HOME");
  if (old_JAVA_HOME != NULL)
    {
      old_JAVA_HOME = xstrdup (old_JAVA_HOME);
      unsetenv ("JAVA_HOME");
    }

  {
    static bool gij_tested;
    static bool gij_present;

    if (!gij_tested)
      {
	/* Test for presence of gij: "gij --version > /dev/null"  */
	char *argv[3];
	int exitstatus;

	argv[0] = "gij";
	argv[1] = "--version";
	argv[2] = NULL;
	exitstatus = execute ("gij", "gij", argv, false, false, true, true,
			      true, false);
	gij_present = (exitstatus == 0);
	gij_tested = true;
      }

    if (gij_present)
      {
	char *old_classpath;
	char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
	unsigned int i;

	/* Set CLASSPATH.  */
	old_classpath =
	  set_classpath (classpaths, classpaths_count, use_minimal_classpath,
			 verbose);

	argv[0] = "gij";
	argv[1] = (char *) class_name;
	for (i = 0; i <= nargs; i++)
	  argv[2 + i] = (char *) args[i];

	if (verbose)
	  {
	    char *command = shell_quote_argv (argv);
	    printf ("%s\n", command);
	    free (command);
	  }

	err = executer ("gij", "gij", argv, private_data);

	/* Reset CLASSPATH.  */
	reset_classpath (old_classpath);

	freea (argv);

	goto done2;
      }
  }

  {
    static bool java_tested;
    static bool java_present;

    if (!java_tested)
      {
	/* Test for presence of java: "java -version 2> /dev/null"  */
	char *argv[3];
	int exitstatus;

	argv[0] = "java";
	argv[1] = "-version";
	argv[2] = NULL;
	exitstatus = execute ("java", "java", argv, false, false, true, true,
			      true, false);
	java_present = (exitstatus == 0);
	java_tested = true;
      }

    if (java_present)
      {
	char *old_classpath;
	char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
	unsigned int i;

	/* Set CLASSPATH.  We don't use the "-classpath ..." option because
	   in JDK 1.1.x its argument should also contain the JDK's classes.zip,
	   but we don't know its location.  (In JDK 1.3.0 it would work.)  */
	old_classpath =
	  set_classpath (classpaths, classpaths_count, use_minimal_classpath,
			 verbose);

	argv[0] = "java";
	argv[1] = (char *) class_name;
	for (i = 0; i <= nargs; i++)
	  argv[2 + i] = (char *) args[i];

	if (verbose)
	  {
	    char *command = shell_quote_argv (argv);
	    printf ("%s\n", command);
	    free (command);
	  }

	err = executer ("java", "java", argv, private_data);

	/* Reset CLASSPATH.  */
	reset_classpath (old_classpath);

	freea (argv);

	goto done2;
      }
  }

  {
    static bool jre_tested;
    static bool jre_present;

    if (!jre_tested)
      {
	/* Test for presence of jre: "jre 2> /dev/null ; test $? = 1"  */
	char *argv[2];
	int exitstatus;

	argv[0] = "jre";
	argv[1] = NULL;
	exitstatus = execute ("jre", "jre", argv, false, false, true, true,
			      true, false);
	jre_present = (exitstatus == 0 || exitstatus == 1);
	jre_tested = true;
      }

    if (jre_present)
      {
	char *old_classpath;
	char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
	unsigned int i;

	/* Set CLASSPATH.  We don't use the "-classpath ..." option because
	   in JDK 1.1.x its argument should also contain the JDK's classes.zip,
	   but we don't know its location.  */
	old_classpath =
	  set_classpath (classpaths, classpaths_count, use_minimal_classpath,
			 verbose);

	argv[0] = "jre";
	argv[1] = (char *) class_name;
	for (i = 0; i <= nargs; i++)
	  argv[2 + i] = (char *) args[i];

	if (verbose)
	  {
	    char *command = shell_quote_argv (argv);
	    printf ("%s\n", command);
	    free (command);
	  }

	err = executer ("jre", "jre", argv, private_data);

	/* Reset CLASSPATH.  */
	reset_classpath (old_classpath);

	freea (argv);

	goto done2;
      }
  }

#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__
  /* Win32, Cygwin */
  {
    static bool jview_tested;
    static bool jview_present;

    if (!jview_tested)
      {
	/* Test for presence of jview: "jview -? >nul ; test $? = 1"  */
	char *argv[3];
	int exitstatus;

	argv[0] = "jview";
	argv[1] = "-?";
	argv[2] = NULL;
	exitstatus = execute ("jview", "jview", argv, false, false, true, true,
			      true, false);
	jview_present = (exitstatus == 0 || exitstatus == 1);
	jview_tested = true;
      }

    if (jview_present)
      {
	char *old_classpath;
	char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
	unsigned int i;

	/* Set CLASSPATH.  */
	old_classpath =
	  set_classpath (classpaths, classpaths_count, use_minimal_classpath,
			 verbose);

	argv[0] = "jview";
	argv[1] = (char *) class_name;
	for (i = 0; i <= nargs; i++)
	  argv[2 + i] = (char *) args[i];

	if (verbose)
	  {
	    char *command = shell_quote_argv (argv);
	    printf ("%s\n", command);
	    free (command);
	  }

	err = executer ("jview", "jview", argv, private_data);

	/* Reset CLASSPATH.  */
	reset_classpath (old_classpath);

	freea (argv);

	goto done2;
      }
  }
#endif

  if (!quiet)
    error (0, 0, _("Java virtual machine not found, try installing gij or set $JAVA"));
  err = true;

 done2:
  if (old_JAVA_HOME != NULL)
    {
      xsetenv ("JAVA_HOME", old_JAVA_HOME, 1);
      free (old_JAVA_HOME);
    }

 done1:
  return err;
}
char *
__realpath (const char *name, char *resolved)
{
  char *rpath, *dest, *extra_buf = NULL;
  const char *start, *end, *rpath_limit;
  long int path_max;
  int num_links = 0;
  size_t prefix_len;

  if (name == NULL)
    {
      /* As per Single Unix Specification V2 we must return an error if
         either parameter is a null pointer.  We extend this to allow
         the RESOLVED parameter to be NULL in case the we are expected to
         allocate the room for the return value.  */
      __set_errno (EINVAL);
      return NULL;
    }

  if (name[0] == '\0')
    {
      /* As per Single Unix Specification V2 we must return an error if
         the name argument points to an empty string.  */
      __set_errno (ENOENT);
      return NULL;
    }

#ifdef PATH_MAX
  path_max = PATH_MAX;
#else
  path_max = pathconf (name, _PC_PATH_MAX);
  if (path_max <= 0)
    path_max = 8192;
#endif

  if (resolved == NULL)
    {
      rpath = malloc (path_max);
      if (rpath == NULL)
        {
          /* It's easier to set errno to ENOMEM than to rely on the
             'malloc-posix' gnulib module.  */
          errno = ENOMEM;
          return NULL;
        }
    }
  else
    rpath = resolved;
  rpath_limit = rpath + path_max;

  /* This is always zero for Posix hosts, but can be 2 for MS-Windows
     and MS-DOS X:/foo/bar file names.  */
  prefix_len = FILE_SYSTEM_PREFIX_LEN (name);

  if (!IS_ABSOLUTE_FILE_NAME (name))
    {
      if (!__getcwd (rpath, path_max))
        {
          rpath[0] = '\0';
          goto error;
        }
      dest = strchr (rpath, '\0');
      start = name;
      prefix_len = FILE_SYSTEM_PREFIX_LEN (rpath);
    }
  else
    {
      dest = rpath;
      if (prefix_len)
        {
          memcpy (rpath, name, prefix_len);
          dest += prefix_len;
        }
      *dest++ = '/';
      if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
        {
          if (ISSLASH (name[1]) && !ISSLASH (name[2]) && !prefix_len)
            *dest++ = '/';
          *dest = '\0';
        }
      start = name + prefix_len;
    }

  for (end = start; *start; start = end)
    {
#ifdef _LIBC
      struct stat64 st;
#else
      struct stat st;
#endif
      int n;

      /* Skip sequence of multiple path-separators.  */
      while (ISSLASH (*start))
        ++start;

      /* Find end of path component.  */
      for (end = start; *end && !ISSLASH (*end); ++end)
        /* Nothing.  */;

      if (end - start == 0)
        break;
      else if (end - start == 1 && start[0] == '.')
        /* nothing */;
      else if (end - start == 2 && start[0] == '.' && start[1] == '.')
        {
          /* Back up to previous component, ignore if at root already.  */
          if (dest > rpath + prefix_len + 1)
            for (--dest; dest > rpath && !ISSLASH (dest[-1]); --dest)
              continue;
          if (DOUBLE_SLASH_IS_DISTINCT_ROOT
              && dest == rpath + 1 && !prefix_len
              && ISSLASH (*dest) && !ISSLASH (dest[1]))
            dest++;
        }
      else
        {
          size_t new_size;

          if (!ISSLASH (dest[-1]))
            *dest++ = '/';

          if (dest + (end - start) >= rpath_limit)
            {
              ptrdiff_t dest_offset = dest - rpath;
              char *new_rpath;

              if (resolved)
                {
                  __set_errno (ENAMETOOLONG);
                  if (dest > rpath + prefix_len + 1)
                    dest--;
                  *dest = '\0';
                  goto error;
                }
              new_size = rpath_limit - rpath;
              if (end - start + 1 > path_max)
                new_size += end - start + 1;
              else
                new_size += path_max;
              new_rpath = (char *) realloc (rpath, new_size);
              if (new_rpath == NULL)
                {
                  /* It's easier to set errno to ENOMEM than to rely on the
                     'realloc-posix' gnulib module.  */
                  errno = ENOMEM;
                  goto error;
                }
              rpath = new_rpath;
              rpath_limit = rpath + new_size;

              dest = rpath + dest_offset;
            }

#ifdef _LIBC
          dest = __mempcpy (dest, start, end - start);
#else
          memcpy (dest, start, end - start);
          dest += end - start;
#endif
          *dest = '\0';

#ifdef _LIBC
          if (__lxstat64 (_STAT_VER, rpath, &st) < 0)
#else
          if (lstat (rpath, &st) < 0)
#endif
            goto error;

          if (S_ISLNK (st.st_mode))
            {
              char *buf;
              size_t len;

              if (++num_links > MAXSYMLINKS)
                {
                  __set_errno (ELOOP);
                  goto error;
                }

              buf = malloca (path_max);
              if (!buf)
                {
                  errno = ENOMEM;
                  goto error;
                }

              n = __readlink (rpath, buf, path_max - 1);
              if (n < 0)
                {
                  int saved_errno = errno;
                  freea (buf);
                  errno = saved_errno;
                  goto error;
                }
              buf[n] = '\0';

              if (!extra_buf)
                {
                  extra_buf = malloca (path_max);
                  if (!extra_buf)
                    {
                      freea (buf);
                      errno = ENOMEM;
                      goto error;
                    }
                }

              len = strlen (end);
              if ((long int) (n + len) >= path_max)
                {
                  freea (buf);
                  __set_errno (ENAMETOOLONG);
                  goto error;
                }

              /* Careful here, end may be a pointer into extra_buf... */
              memmove (&extra_buf[n], end, len + 1);
              name = end = memcpy (extra_buf, buf, n);

              if (IS_ABSOLUTE_FILE_NAME (buf))
                {
                  size_t pfxlen = FILE_SYSTEM_PREFIX_LEN (buf);

                  if (pfxlen)
                    memcpy (rpath, buf, pfxlen);
                  dest = rpath + pfxlen;
                  *dest++ = '/'; /* It's an absolute symlink */
                  if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
                    {
                      if (ISSLASH (buf[1]) && !ISSLASH (buf[2]) && !pfxlen)
                        *dest++ = '/';
                      *dest = '\0';
                    }
                  /* Install the new prefix to be in effect hereafter.  */
                  prefix_len = pfxlen;
                }
              else
                {
                  /* Back up to previous component, ignore if at root
                     already: */
                  if (dest > rpath + prefix_len + 1)
                    for (--dest; dest > rpath && !ISSLASH (dest[-1]); --dest)
                      continue;
                  if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1
                      && ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len)
                    dest++;
                }
            }
          else if (!S_ISDIR (st.st_mode) && *end != '\0')
            {
              __set_errno (ENOTDIR);
              goto error;
            }
        }
    }
  if (dest > rpath + prefix_len + 1 && ISSLASH (dest[-1]))
    --dest;
  if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1 && !prefix_len
      && ISSLASH (*dest) && !ISSLASH (dest[1]))
    dest++;
  *dest = '\0';

  if (extra_buf)
    freea (extra_buf);

  return rpath;

error:
  {
    int saved_errno = errno;
    if (extra_buf)
      freea (extra_buf);
    if (resolved == NULL)
      free (rpath);
    errno = saved_errno;
  }
  return NULL;
}
int
mbmemcasecoll (const char *s1, size_t s1len, const char *s2, size_t s2len,
               bool hard_LC_COLLATE)
{
  char *t1;
  size_t t1len;
  char *t2;
  size_t t2len;
  char *memory;
  int cmp;

  if (MB_CUR_MAX > 1)
    {
      /* Application of towlower grows each character by a factor 2
         at most.  */
      t1len = 2 * s1len;
      t2len = 2 * s2len;
    }
  else
    {
      /* Application of tolower doesn't change the size.  */
      t1len = s1len;
      t2len = s2len;
    }
  /* Allocate memory for t1 and t2.  */
  memory = (char *) malloca (t1len + 1 + t2len + 1);
  if (memory == NULL)
    {
      errno = ENOMEM;
      return 0;
    }
  t1 = memory;
  t2 = memory + t1len + 1;

  /* Csae-fold the two argument strings.  */
  if (MB_CUR_MAX > 1)
    {
      t1len = apply_towlower (s1, s1len, t1, t1len);
      t2len = apply_towlower (s2, s2len, t2, t2len);
    }
  else
    {
      apply_tolower (s1, t1, s1len);
      apply_tolower (s2, t2, s2len);
    }

  /* Compare the two case-folded strings.  */
  if (hard_LC_COLLATE)
    cmp = memcoll (t1, t1len, t2, t2len);
  else
    {
      cmp = memcmp2 (t1, t1len, t2, t2len);
      errno = 0;
    }

  {
    int saved_errno = errno;
    freea (memory);
    errno = saved_errno;
  }

  return cmp;
}
Beispiel #21
0
int
rpl_stat (char const *name, struct stat *buf)
{
#ifdef WINDOWS_NATIVE
  /* Fill the fields ourselves, because the original stat function returns
     values for st_atime, st_mtime, st_ctime that depend on the current time
     zone.  See
     <https://lists.gnu.org/r/bug-gnulib/2017-04/msg00134.html>  */
  /* XXX Should we convert to wchar_t* and prepend '\\?\', in order to work
     around length limitations
     <https://msdn.microsoft.com/en-us/library/aa365247.aspx> ?  */

  /* POSIX <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>
     specifies: "More than two leading <slash> characters shall be treated as
     a single <slash> character."  */
  if (ISSLASH (name[0]) && ISSLASH (name[1]) && ISSLASH (name[2]))
    {
      name += 2;
      while (ISSLASH (name[1]))
        name++;
    }

  size_t len = strlen (name);
  size_t drive_prefix_len = (HAS_DEVICE (name) ? 2 : 0);

  /* Remove trailing slashes (except the very first one, at position
     drive_prefix_len), but remember their presence.  */
  size_t rlen;
  bool check_dir = false;

  rlen = len;
  while (rlen > drive_prefix_len && ISSLASH (name[rlen-1]))
    {
      check_dir = true;
      if (rlen == drive_prefix_len + 1)
        break;
      rlen--;
    }

  /* Handle '' and 'C:'.  */
  if (!check_dir && rlen == drive_prefix_len)
    {
      errno = ENOENT;
      return -1;
    }

  /* Handle '\\'.  */
  if (rlen == 1 && ISSLASH (name[0]) && len >= 2)
    {
      errno = ENOENT;
      return -1;
    }

  const char *rname;
  char *malloca_rname;
  if (rlen == len)
    {
      rname = name;
      malloca_rname = NULL;
    }
  else
    {
      malloca_rname = malloca (rlen + 1);
      if (malloca_rname == NULL)
        {
          errno = ENOMEM;
          return -1;
        }
      memcpy (malloca_rname, name, rlen);
      malloca_rname[rlen] = '\0';
      rname = malloca_rname;
    }

  /* There are two ways to get at the requested information:
       - by scanning the parent directory and examining the relevant
         directory entry,
       - by opening the file directly.
     The first approach fails for root directories (e.g. 'C:\') and
     UNC root directories (e.g. '\\server\share').
     The second approach fails for some system files (e.g. 'C:\pagefile.sys'
     and 'C:\hiberfil.sys'): ERROR_SHARING_VIOLATION.
     The second approach gives more information (in particular, correct
     st_dev, st_ino, st_nlink fields).
     So we use the second approach and, as a fallback except for root and
     UNC root directories, also the first approach.  */
  {
    int ret;

    {
      /* Approach based on the file.  */

      /* Open a handle to the file.
         CreateFile
         <https://msdn.microsoft.com/en-us/library/aa363858.aspx>
         <https://msdn.microsoft.com/en-us/library/aa363874.aspx>  */
      HANDLE h =
        CreateFile (rname,
                    FILE_READ_ATTRIBUTES,
                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                    NULL,
                    OPEN_EXISTING,
                    /* FILE_FLAG_POSIX_SEMANTICS (treat file names that differ only
                       in case as different) makes sense only when applied to *all*
                       filesystem operations.  */
                    FILE_FLAG_BACKUP_SEMANTICS /* | FILE_FLAG_POSIX_SEMANTICS */,
                    NULL);
      if (h != INVALID_HANDLE_VALUE)
        {
          ret = _gl_fstat_by_handle (h, rname, buf);
          CloseHandle (h);
          goto done;
        }
    }

    /* Test for root and UNC root directories.  */
    if ((rlen == drive_prefix_len + 1 && ISSLASH (rname[drive_prefix_len]))
        || is_unc_root (rname))
      goto failed;

    /* Fallback.  */
    {
      /* Approach based on the directory entry.  */

      if (strchr (rname, '?') != NULL || strchr (rname, '*') != NULL)
        {
          /* Other Windows API functions would fail with error
             ERROR_INVALID_NAME.  */
          if (malloca_rname != NULL)
            freea (malloca_rname);
          errno = ENOENT;
          return -1;
        }

      /* Get the details about the directory entry.  This can be done through
         FindFirstFile
         <https://msdn.microsoft.com/en-us/library/aa364418.aspx>
         <https://msdn.microsoft.com/en-us/library/aa365740.aspx>
         or through
         FindFirstFileEx with argument FindExInfoBasic
         <https://msdn.microsoft.com/en-us/library/aa364419.aspx>
         <https://msdn.microsoft.com/en-us/library/aa364415.aspx>
         <https://msdn.microsoft.com/en-us/library/aa365740.aspx>  */
      WIN32_FIND_DATA info;
      HANDLE h = FindFirstFile (rname, &info);
      if (h == INVALID_HANDLE_VALUE)
        goto failed;

      /* Test for error conditions before starting to fill *buf.  */
      if (sizeof (buf->st_size) <= 4 && info.nFileSizeHigh > 0)
        {
          FindClose (h);
          if (malloca_rname != NULL)
            freea (malloca_rname);
          errno = EOVERFLOW;
          return -1;
        }

# if _GL_WINDOWS_STAT_INODES
      buf->st_dev = 0;
#  if _GL_WINDOWS_STAT_INODES == 2
      buf->st_ino._gl_ino[0] = buf->st_ino._gl_ino[1] = 0;
#  else /* _GL_WINDOWS_STAT_INODES == 1 */
      buf->st_ino = 0;
#  endif
# else
      /* st_ino is not wide enough for identifying a file on a device.
         Without st_ino, st_dev is pointless.  */
      buf->st_dev = 0;
      buf->st_ino = 0;
# endif

      /* st_mode.  */
      unsigned int mode =
        /* XXX How to handle FILE_ATTRIBUTE_REPARSE_POINT ?  */
        ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? _S_IFDIR | S_IEXEC_UGO : _S_IFREG)
        | S_IREAD_UGO
        | ((info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? 0 : S_IWRITE_UGO);
      if (!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
        {
          /* Determine whether the file is executable by looking at the file
             name suffix.  */
          if (info.nFileSizeHigh > 0 || info.nFileSizeLow > 0)
            {
              const char *last_dot = NULL;
              const char *p;
              for (p = info.cFileName; *p != '\0'; p++)
                if (*p == '.')
                  last_dot = p;
              if (last_dot != NULL)
                {
                  const char *suffix = last_dot + 1;
                  if (_stricmp (suffix, "exe") == 0
                      || _stricmp (suffix, "bat") == 0
                      || _stricmp (suffix, "cmd") == 0
                      || _stricmp (suffix, "com") == 0)
                    mode |= S_IEXEC_UGO;
                }
            }
        }
      buf->st_mode = mode;

      /* st_nlink.  Ignore hard links here.  */
      buf->st_nlink = 1;

      /* There's no easy way to map the Windows SID concept to an integer.  */
      buf->st_uid = 0;
      buf->st_gid = 0;

      /* st_rdev is irrelevant for normal files and directories.  */
      buf->st_rdev = 0;

      /* st_size.  */
      if (sizeof (buf->st_size) <= 4)
        /* Range check already done above.  */
        buf->st_size = info.nFileSizeLow;
      else
        buf->st_size = ((long long) info.nFileSizeHigh << 32) | (long long) info.nFileSizeLow;

      /* st_atime, st_mtime, st_ctime.  */
# if _GL_WINDOWS_STAT_TIMESPEC
      buf->st_atim = _gl_convert_FILETIME_to_timespec (&info.ftLastAccessTime);
      buf->st_mtim = _gl_convert_FILETIME_to_timespec (&info.ftLastWriteTime);
      buf->st_ctim = _gl_convert_FILETIME_to_timespec (&info.ftCreationTime);
# else
      buf->st_atime = _gl_convert_FILETIME_to_POSIX (&info.ftLastAccessTime);
      buf->st_mtime = _gl_convert_FILETIME_to_POSIX (&info.ftLastWriteTime);
      buf->st_ctime = _gl_convert_FILETIME_to_POSIX (&info.ftCreationTime);
# endif

      FindClose (h);

      ret = 0;
    }

   done:
    if (ret >= 0 && check_dir && !S_ISDIR (buf->st_mode))
      {
        errno = ENOTDIR;
        ret = -1;
      }
    if (malloca_rname != NULL)
      {
        int saved_errno = errno;
        freea (malloca_rname);
        errno = saved_errno;
      }
    return ret;
  }

 failed:
  {
    DWORD error = GetLastError ();
    #if 0
    fprintf (stderr, "rpl_stat error 0x%x\n", (unsigned int) error);
    #endif

    if (malloca_rname != NULL)
      freea (malloca_rname);

    switch (error)
      {
      /* Some of these errors probably cannot happen with the specific flags
         that we pass to CreateFile.  But who knows...  */
      case ERROR_FILE_NOT_FOUND: /* The last component of rname does not exist.  */
      case ERROR_PATH_NOT_FOUND: /* Some directory component in rname does not exist.  */
      case ERROR_BAD_PATHNAME:   /* rname is such as '\\server'.  */
      case ERROR_BAD_NET_NAME:   /* rname is such as '\\server\nonexistentshare'.  */
      case ERROR_INVALID_NAME:   /* rname contains wildcards, misplaced colon, etc.  */
      case ERROR_DIRECTORY:
        errno = ENOENT;
        break;

      case ERROR_ACCESS_DENIED:  /* rname is such as 'C:\System Volume Information\foo'.  */
      case ERROR_SHARING_VIOLATION: /* rname is such as 'C:\pagefile.sys' (second approach only).  */
                                    /* XXX map to EACCESS or EPERM? */
        errno = EACCES;
        break;

      case ERROR_OUTOFMEMORY:
        errno = ENOMEM;
        break;

      case ERROR_WRITE_PROTECT:
        errno = EROFS;
        break;

      case ERROR_WRITE_FAULT:
      case ERROR_READ_FAULT:
      case ERROR_GEN_FAILURE:
        errno = EIO;
        break;

      case ERROR_BUFFER_OVERFLOW:
      case ERROR_FILENAME_EXCED_RANGE:
        errno = ENAMETOOLONG;
        break;

      case ERROR_DELETE_PENDING: /* XXX map to EACCESS or EPERM? */
        errno = EPERM;
        break;

      default:
        errno = EINVAL;
        break;
      }

    return -1;
  }
#else
  int result = orig_stat (name, buf);
  if (result == 0)
    {
# if REPLACE_FUNC_STAT_FILE
      /* Solaris 9 mistakenly succeeds when given a non-directory with a
         trailing slash.  */
      if (!S_ISDIR (buf->st_mode))
        {
          size_t len = strlen (name);
          if (ISSLASH (name[len - 1]))
            {
              errno = ENOTDIR;
              return -1;
            }
        }
# endif /* REPLACE_FUNC_STAT_FILE */
      result = stat_time_normalize (result, buf);
    }
  return result;
#endif
}
Beispiel #22
0
internal_function
_nl_init_domain_conv (struct loaded_l10nfile *domain_file,
                      struct loaded_domain *domain,
                      struct binding *domainbinding)
{
    /* Find out about the character set the file is encoded with.
       This can be found (in textual form) in the entry "".  If this
       entry does not exist or if this does not contain the `charset='
       information, we will assume the charset matches the one the
       current locale and we don't have to perform any conversion.  */
    char *nullentry;
    size_t nullentrylen;

    /* Preinitialize fields, to avoid recursion during _nl_find_msg.  */
    domain->codeset_cntr =
        (domainbinding != NULL ? domainbinding->codeset_cntr : 0);
#ifdef _LIBC
    domain->conv = (__gconv_t) -1;
#else
# if HAVE_ICONV
    domain->conv = (iconv_t) -1;
# endif
#endif
    domain->conv_tab = NULL;

    /* Get the header entry.  */
    nullentry = _nl_find_msg (domain_file, domainbinding, "", &nullentrylen);

    if (nullentry != NULL)
    {
#if defined _LIBC || HAVE_ICONV
        const char *charsetstr;

        charsetstr = strstr (nullentry, "charset=");
        if (charsetstr != NULL)
        {
            size_t len;
            char *charset;
            const char *outcharset;

            charsetstr += strlen ("charset=");
            len = strcspn (charsetstr, " \t\n");

            charset = (char *) alloca (len + 1);
# if defined _LIBC || HAVE_MEMPCPY
            *((char *) mempcpy (charset, charsetstr, len)) = '\0';
# else
            memcpy (charset, charsetstr, len);
            charset[len] = '\0';
# endif

            /* The output charset should normally be determined by the
               locale.  But sometimes the locale is not used or not correctly
               set up, so we provide a possibility for the user to override
               this.  Moreover, the value specified through
               bind_textdomain_codeset overrides both.  */
            if (domainbinding != NULL && domainbinding->codeset != NULL)
                outcharset = domainbinding->codeset;
            else
            {
                outcharset = getenv ("OUTPUT_CHARSET");
                if (outcharset == NULL || outcharset[0] == '\0')
                {
# ifdef _LIBC
                    outcharset = _NL_CURRENT (LC_CTYPE, CODESET);
# else
#  if HAVE_ICONV
                    extern const char *locale_charset (void);
                    outcharset = locale_charset ();
#  endif
# endif
                }
            }

# ifdef _LIBC
            /* We always want to use transliteration.  */
            outcharset = norm_add_slashes (outcharset, "TRANSLIT");
            charset = norm_add_slashes (charset, NULL);
            if (__gconv_open (outcharset, charset, &domain->conv,
                              GCONV_AVOID_NOCONV)
                    != __GCONV_OK)
                domain->conv = (__gconv_t) -1;
# else
#  if HAVE_ICONV
            /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
               we want to use transliteration.  */
#   if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \
       || _LIBICONV_VERSION >= 0x0105
            if (strchr (outcharset, '/') == NULL)
            {
                char *tmp;

                len = strlen (outcharset);
                tmp = (char *) alloca (len + 10 + 1);
                memcpy (tmp, outcharset, len);
                memcpy (tmp + len, "//TRANSLIT", 10 + 1);
                outcharset = tmp;

                domain->conv = iconv_open (outcharset, charset);

                freea (outcharset);
            }
            else
#   endif
                domain->conv = iconv_open (outcharset, charset);
#  endif
# endif

            freea (charset);
        }
#endif /* _LIBC || HAVE_ICONV */
    }

    return nullentry;
}
static int
compile_csharp_using_sscli (const char * const *sources,
                            unsigned int sources_count,
                            const char * const *libdirs,
                            unsigned int libdirs_count,
                            const char * const *libraries,
                            unsigned int libraries_count,
                            const char *output_file, bool output_is_library,
                            bool optimize, bool debug,
                            bool verbose)
{
  static bool csc_tested;
  static bool csc_present;

  if (!csc_tested)
    {
      /* Test for presence of csc:
         "csc -help >/dev/null 2>/dev/null \
          && ! { csc -help 2>/dev/null | grep -i chicken > /dev/null; }"  */
      char *argv[3];
      pid_t child;
      int fd[1];
      int exitstatus;

      argv[0] = "csc";
      argv[1] = "-help";
      argv[2] = NULL;
      child = create_pipe_in ("csc", "csc", argv, DEV_NULL, true, true, false,
                              fd);
      csc_present = false;
      if (child != -1)
        {
          /* Read the subprocess output, and test whether it contains the
             string "chicken".  */
          char c[7];
          size_t count = 0;

          csc_present = true;
          while (safe_read (fd[0], &c[count], 1) > 0)
            {
              if (c[count] >= 'A' && c[count] <= 'Z')
                c[count] += 'a' - 'A';
              count++;
              if (count == 7)
                {
                  if (memcmp (c, "chicken", 7) == 0)
                    csc_present = false;
                  c[0] = c[1]; c[1] = c[2]; c[2] = c[3];
                  c[3] = c[4]; c[4] = c[5]; c[5] = c[6];
                  count--;
                }
            }

          close (fd[0]);

          /* Remove zombie process from process list, and retrieve exit
             status.  */
          exitstatus =
            wait_subprocess (child, "csc", false, true, true, false, NULL);
          if (exitstatus != 0)
            csc_present = false;
        }
      csc_tested = true;
    }

  if (csc_present)
    {
      unsigned int argc;
      char **argv;
      char **argp;
      int exitstatus;
      unsigned int i;

      argc =
        1 + 1 + 1 + libdirs_count + libraries_count
        + (optimize ? 1 : 0) + (debug ? 1 : 0) + sources_count;
      argv = (char **) xmalloca ((argc + 1) * sizeof (char *));

      argp = argv;
      *argp++ = "csc";
      *argp++ =
        (char *) (output_is_library ? "-target:library" : "-target:exe");
      {
        char *option = (char *) xmalloca (5 + strlen (output_file) + 1);
        memcpy (option, "-out:", 5);
        strcpy (option + 5, output_file);
        *argp++ = option;
      }
      for (i = 0; i < libdirs_count; i++)
        {
          char *option = (char *) xmalloca (5 + strlen (libdirs[i]) + 1);
          memcpy (option, "-lib:", 5);
          strcpy (option + 5, libdirs[i]);
          *argp++ = option;
        }
      for (i = 0; i < libraries_count; i++)
        {
          char *option = (char *) xmalloca (11 + strlen (libraries[i]) + 4 + 1);
          memcpy (option, "-reference:", 11);
          memcpy (option + 11, libraries[i], strlen (libraries[i]));
          strcpy (option + 11 + strlen (libraries[i]), ".dll");
          *argp++ = option;
        }
      if (optimize)
        *argp++ = "-optimize+";
      if (debug)
        *argp++ = "-debug+";
      for (i = 0; i < sources_count; i++)
        {
          const char *source_file = sources[i];
          if (strlen (source_file) >= 10
              && memcmp (source_file + strlen (source_file) - 10, ".resources",
                         10) == 0)
            {
              char *option = (char *) xmalloca (10 + strlen (source_file) + 1);

              memcpy (option, "-resource:", 10);
              strcpy (option + 10, source_file);
              *argp++ = option;
            }
          else
            *argp++ = (char *) source_file;
        }
      *argp = NULL;
      /* Ensure argv length was correctly calculated.  */
      if (argp - argv != argc)
        abort ();

      if (verbose)
        {
          char *command = shell_quote_argv (argv);
          printf ("%s\n", command);
          free (command);
        }

      exitstatus = execute ("csc", "csc", argv, false, false, false, false,
                            true, true, NULL);

      for (i = 2; i < 3 + libdirs_count + libraries_count; i++)
        freea (argv[i]);
      for (i = 0; i < sources_count; i++)
        if (argv[argc - sources_count + i] != sources[i])
          freea (argv[argc - sources_count + i]);
      freea (argv);

      return (exitstatus != 0);
    }
  else
    return -1;
}
Beispiel #24
0
msgdomain_list_ty *
msgdomain_read_tcl (const char *locale_name, const char *directory)
{
  const char *gettextdatadir;
  char *tclscript;
  size_t len;
  char *frobbed_locale_name;
  char *p;
  char *file_name;
  char *argv[4];
  pid_t child;
  int fd[1];
  FILE *fp;
  msgdomain_list_ty *mdlp;
  int exitstatus;
  size_t k;

  /* Make it possible to override the msgunfmt.tcl location.  This is
     necessary for running the testsuite before "make install".  */
  gettextdatadir = getenv ("GETTEXTDATADIR");
  if (gettextdatadir == NULL || gettextdatadir[0] == '\0')
    gettextdatadir = relocate (GETTEXTDATADIR);

  tclscript = xconcatenated_filename (gettextdatadir, "msgunfmt.tcl", NULL);

  /* Convert the locale name to lowercase and remove any encoding.  */
  len = strlen (locale_name);
  frobbed_locale_name = (char *) xmalloca (len + 1);
  memcpy (frobbed_locale_name, locale_name, len + 1);
  for (p = frobbed_locale_name; *p != '\0'; p++)
    if (*p >= 'A' && *p <= 'Z')
      *p = *p - 'A' + 'a';
    else if (*p == '.')
      {
        *p = '\0';
        break;
      }

  file_name = xconcatenated_filename (directory, frobbed_locale_name, ".msg");

  freea (frobbed_locale_name);

  /* Prepare arguments.  */
  argv[0] = "tclsh";
  argv[1] = tclscript;
  argv[2] = file_name;
  argv[3] = NULL;

  if (verbose)
    {
      char *command = shell_quote_argv (argv);
      printf ("%s\n", command);
      free (command);
    }

  /* Open a pipe to the Tcl interpreter.  */
  child = create_pipe_in ("tclsh", "tclsh", argv, DEV_NULL, false, true, true,
                          fd);

  fp = fdopen (fd[0], "r");
  if (fp == NULL)
    error (EXIT_FAILURE, errno, _("fdopen() failed"));

  /* Read the message list.  */
  mdlp = read_catalog_stream (fp, "(pipe)", "(pipe)", &input_format_po);

  fclose (fp);

  /* Remove zombie process from process list, and retrieve exit status.  */
  exitstatus =
    wait_subprocess (child, "tclsh", false, false, true, true, NULL);
  if (exitstatus != 0)
    {
      if (exitstatus == 2)
        /* Special exitcode provided by msgunfmt.tcl.  */
        error (EXIT_FAILURE, ENOENT,
               _("error while opening \"%s\" for reading"), file_name);
      else
        error (EXIT_FAILURE, 0, _("%s subprocess failed with exit code %d"),
               "tclsh", exitstatus);
    }

  free (tclscript);

  /* Move the header entry to the beginning.  */
  for (k = 0; k < mdlp->nitems; k++)
    {
      message_list_ty *mlp = mdlp->item[k]->messages;
      size_t j;

      for (j = 0; j < mlp->nitems; j++)
        if (is_header (mlp->item[j]))
          {
            /* Found the header entry.  */
            if (j > 0)
              {
                message_ty *header = mlp->item[j];
                size_t i;

                for (i = j; i > 0; i--)
                  mlp->item[i] = mlp->item[i - 1];
                mlp->item[0] = header;
              }
            break;
          }
    }

  return mdlp;
}
Beispiel #25
0
/* This function is used by `setenv' and `putenv'.  The difference between
   the two functions is that for the former must create a new string which
   is then placed in the environment, while the argument of `putenv'
   must be used directly.  This is all complicated by the fact that we try
   to reuse values once generated for a `setenv' call since we can never
   free the strings.  */
int
__add_to_environ (const char *name, const char *value, const char *combined,
                  int replace)
{
  register char **ep;
  register size_t size;
  const size_t namelen = strlen (name);
  const size_t vallen = value != NULL ? strlen (value) + 1 : 0;

  LOCK;

  /* We have to get the pointer now that we have the lock and not earlier
     since another thread might have created a new environment.  */
  ep = __environ;

  size = 0;
  if (ep != NULL)
    {
      for (; *ep != NULL; ++ep)
        if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
          break;
        else
          ++size;
    }

  if (ep == NULL || *ep == NULL)
    {
      char **new_environ;
#ifdef USE_TSEARCH
      char *new_value;
#endif

      /* We allocated this space; we can extend it.  */
      new_environ =
        (char **) (last_environ == NULL
                   ? malloc ((size + 2) * sizeof (char *))
                   : realloc (last_environ, (size + 2) * sizeof (char *)));
      if (new_environ == NULL)
        {
          UNLOCK;
          return -1;
        }

      /* If the whole entry is given add it.  */
      if (combined != NULL)
        /* We must not add the string to the search tree since it belongs
           to the user.  */
        new_environ[size] = (char *) combined;
      else
        {
          /* See whether the value is already known.  */
#ifdef USE_TSEARCH
# ifdef _LIBC
          new_value = (char *) alloca (namelen + 1 + vallen);
          __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
                     value, vallen);
# else
          new_value = (char *) malloca (namelen + 1 + vallen);
          if (new_value == NULL)
            {
              __set_errno (ENOMEM);
              UNLOCK;
              return -1;
            }
          memcpy (new_value, name, namelen);
          new_value[namelen] = '=';
          memcpy (&new_value[namelen + 1], value, vallen);
# endif

          new_environ[size] = KNOWN_VALUE (new_value);
          if (new_environ[size] == NULL)
#endif
            {
              new_environ[size] = (char *) malloc (namelen + 1 + vallen);
              if (new_environ[size] == NULL)
                {
#if defined USE_TSEARCH && !defined _LIBC
                  freea (new_value);
#endif
                  __set_errno (ENOMEM);
                  UNLOCK;
                  return -1;
                }

#ifdef USE_TSEARCH
              memcpy (new_environ[size], new_value, namelen + 1 + vallen);
#else
              memcpy (new_environ[size], name, namelen);
              new_environ[size][namelen] = '=';
              memcpy (&new_environ[size][namelen + 1], value, vallen);
#endif
              /* And save the value now.  We cannot do this when we remove
                 the string since then we cannot decide whether it is a
                 user string or not.  */
              STORE_VALUE (new_environ[size]);
            }
#if defined USE_TSEARCH && !defined _LIBC
          freea (new_value);
#endif
        }

      if (__environ != last_environ)
        memcpy ((char *) new_environ, (char *) __environ,
                size * sizeof (char *));

      new_environ[size + 1] = NULL;

      last_environ = __environ = new_environ;
    }
  else if (replace)
    {
      char *np;

      /* Use the user string if given.  */
      if (combined != NULL)
        np = (char *) combined;
      else
        {
#ifdef USE_TSEARCH
          char *new_value;
# ifdef _LIBC
          new_value = alloca (namelen + 1 + vallen);
          __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
                     value, vallen);
# else
          new_value = malloca (namelen + 1 + vallen);
          if (new_value == NULL)
            {
              __set_errno (ENOMEM);
              UNLOCK;
              return -1;
            }
          memcpy (new_value, name, namelen);
          new_value[namelen] = '=';
          memcpy (&new_value[namelen + 1], value, vallen);
# endif

          np = KNOWN_VALUE (new_value);
          if (np == NULL)
#endif
            {
              np = malloc (namelen + 1 + vallen);
              if (np == NULL)
                {
#if defined USE_TSEARCH && !defined _LIBC
                  freea (new_value);
#endif
                  __set_errno (ENOMEM);
                  UNLOCK;
                  return -1;
                }

#ifdef USE_TSEARCH
              memcpy (np, new_value, namelen + 1 + vallen);
#else
              memcpy (np, name, namelen);
              np[namelen] = '=';
              memcpy (&np[namelen + 1], value, vallen);
#endif
              /* And remember the value.  */
              STORE_VALUE (np);
            }
#if defined USE_TSEARCH && !defined _LIBC
          freea (new_value);
#endif
        }

      *ep = np;
    }

  UNLOCK;

  return 0;
}
static int
compile_csharp_using_pnet (const char * const *sources,
                           unsigned int sources_count,
                           const char * const *libdirs,
                           unsigned int libdirs_count,
                           const char * const *libraries,
                           unsigned int libraries_count,
                           const char *output_file, bool output_is_library,
                           bool optimize, bool debug,
                           bool verbose)
{
  static bool cscc_tested;
  static bool cscc_present;

  if (!cscc_tested)
    {
      /* Test for presence of cscc:
         "cscc --version >/dev/null 2>/dev/null"  */
      char *argv[3];
      int exitstatus;

      argv[0] = "cscc";
      argv[1] = "--version";
      argv[2] = NULL;
      exitstatus = execute ("cscc", "cscc", argv, false, false, true, true,
                            true, false, NULL);
      cscc_present = (exitstatus == 0);
      cscc_tested = true;
    }

  if (cscc_present)
    {
      unsigned int argc;
      char **argv;
      char **argp;
      int exitstatus;
      unsigned int i;

      argc =
        1 + (output_is_library ? 1 : 0) + 2 + 2 * libdirs_count
        + 2 * libraries_count + (optimize ? 1 : 0) + (debug ? 1 : 0)
        + sources_count;
      argv = (char **) xmalloca ((argc + 1) * sizeof (char *));

      argp = argv;
      *argp++ = "cscc";
      if (output_is_library)
        *argp++ = "-shared";
      *argp++ = "-o";
      *argp++ = (char *) output_file;
      for (i = 0; i < libdirs_count; i++)
        {
          *argp++ = "-L";
          *argp++ = (char *) libdirs[i];
        }
      for (i = 0; i < libraries_count; i++)
        {
          *argp++ = "-l";
          *argp++ = (char *) libraries[i];
        }
      if (optimize)
        *argp++ = "-O";
      if (debug)
        *argp++ = "-g";
      for (i = 0; i < sources_count; i++)
        {
          const char *source_file = sources[i];
          if (strlen (source_file) >= 10
              && memcmp (source_file + strlen (source_file) - 10, ".resources",
                         10) == 0)
            {
              char *option = (char *) xmalloca (12 + strlen (source_file) + 1);

              memcpy (option, "-fresources=", 12);
              strcpy (option + 12, source_file);
              *argp++ = option;
            }
          else
            *argp++ = (char *) source_file;
        }
      *argp = NULL;
      /* Ensure argv length was correctly calculated.  */
      if (argp - argv != argc)
        abort ();

      if (verbose)
        {
          char *command = shell_quote_argv (argv);
          printf ("%s\n", command);
          free (command);
        }

      exitstatus = execute ("cscc", "cscc", argv, false, false, false, false,
                            true, true, NULL);

      for (i = 0; i < sources_count; i++)
        if (argv[argc - sources_count + i] != sources[i])
          freea (argv[argc - sources_count + i]);
      freea (argv);

      return (exitstatus != 0);
    }
  else
    return -1;
}
Beispiel #27
0
static bool
knuth_morris_pratt_multibyte (const char *haystack, const char *needle,
			      const char **resultp)
{
  size_t m = mbslen (needle);
  mbchar_t *needle_mbchars;
  size_t *table;

  /* Allocate room for needle_mbchars and the table.  */
  char *memory = (char *) malloca (m * (sizeof (mbchar_t) + sizeof (size_t)));
  if (memory == NULL)
    return false;
  needle_mbchars = (mbchar_t *) memory;
  table = (size_t *) (memory + m * sizeof (mbchar_t));

  /* Fill needle_mbchars.  */
  {
    mbui_iterator_t iter;
    size_t j;

    j = 0;
    for (mbui_init (iter, needle); mbui_avail (iter); mbui_advance (iter), j++)
      mb_copy (&needle_mbchars[j], &mbui_cur (iter));
  }

  /* Fill the table.
     For 0 < i < m:
       0 < table[i] <= i is defined such that
       rhaystack[0..i-1] == needle[0..i-1] and rhaystack[i] != needle[i]
       implies
       forall 0 <= x < table[i]: rhaystack[x..x+m-1] != needle[0..m-1],
       and table[i] is as large as possible with this property.
     table[0] remains uninitialized.  */
  {
    size_t i, j;

    table[1] = 1;
    j = 0;
    for (i = 2; i < m; i++)
      {
	mbchar_t *b = &needle_mbchars[i - 1];

	for (;;)
	  {
	    if (mb_equal (*b, needle_mbchars[j]))
	      {
		table[i] = i - ++j;
		break;
	      }
	    if (j == 0)
	      {
		table[i] = i;
		break;
	      }
	    j = j - table[j];
	  }
      }
  }

  /* Search, using the table to accelerate the processing.  */
  {
    size_t j;
    mbui_iterator_t rhaystack;
    mbui_iterator_t phaystack;

    *resultp = NULL;
    j = 0;
    mbui_init (rhaystack, haystack);
    mbui_init (phaystack, haystack);
    /* Invariant: phaystack = rhaystack + j.  */
    while (mbui_avail (phaystack))
      if (mb_equal (needle_mbchars[j], mbui_cur (phaystack)))
	{
	  j++;
	  mbui_advance (phaystack);
	  if (j == m)
	    {
	      /* The entire needle has been found.  */
	      *resultp = mbui_cur_ptr (rhaystack);
	      break;
	    }
	}
      else if (j > 0)
	{
	  /* Found a match of needle[0..j-1], mismatch at needle[j].  */
	  size_t count = table[j];
	  j -= count;
	  for (; count > 0; count--)
	    {
	      if (!mbui_avail (rhaystack))
		abort ();
	      mbui_advance (rhaystack);
	    }
	}
      else
	{
	  /* Found a mismatch at needle[0] already.  */
	  if (!mbui_avail (rhaystack))
	    abort ();
	  mbui_advance (rhaystack);
	  mbui_advance (phaystack);
	}
  }

  freea (memory);
  return true;
}
Beispiel #28
0
/* Load the message catalogs specified by FILENAME.  If it is no valid
   message catalog do nothing.  */
void
internal_function
_nl_load_domain (struct loaded_l10nfile *domain_file,
                 struct binding *domainbinding)
{
    int fd;
    size_t size;
#ifdef _LIBC
    struct stat64 st;
#else
    struct stat st;
#endif
    struct mo_file_header *data = (struct mo_file_header *) -1;
    int use_mmap = 0;
    struct loaded_domain *domain;
    int revision;
    const char *nullentry;

    domain_file->decided = 1;
    domain_file->data = NULL;

    /* Note that it would be useless to store domainbinding in domain_file
       because domainbinding might be == NULL now but != NULL later (after
       a call to bind_textdomain_codeset).  */

    /* If the record does not represent a valid locale the FILENAME
       might be NULL.  This can happen when according to the given
       specification the locale file name is different for XPG and CEN
       syntax.  */
    if (domain_file->filename == NULL)
        return;

    /* Try to open the addressed file.  */
    fd = open (domain_file->filename, O_RDONLY | O_BINARY);
    if (fd == -1)
        return;

    /* We must know about the size of the file.  */
    if (
#ifdef _LIBC
        __builtin_expect (fstat64 (fd, &st) != 0, 0)
#else
        __builtin_expect (fstat (fd, &st) != 0, 0)
#endif
        || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0)
        || __builtin_expect (size < sizeof (struct mo_file_header), 0))
    {
        /* Something went wrong.  */
        close (fd);
        return;
    }

#ifdef HAVE_MMAP
    /* Now we are ready to load the file.  If mmap() is available we try
       this first.  If not available or it failed we try to load it.  */
    data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
                                           MAP_PRIVATE, fd, 0);

    if (__builtin_expect (data != (struct mo_file_header *) -1, 1))
    {
        /* mmap() call was successful.  */
        close (fd);
        use_mmap = 1;
    }
#endif

    /* If the data is not yet available (i.e. mmap'ed) we try to load
       it manually.  */
    if (data == (struct mo_file_header *) -1)
    {
        size_t to_read;
        char *read_ptr;

        data = (struct mo_file_header *) malloc (size);
        if (data == NULL)
            return;

        to_read = size;
        read_ptr = (char *) data;
        do
        {
            long int nb = (long int) read (fd, read_ptr, to_read);
            if (nb <= 0)
            {
#ifdef EINTR
                if (nb == -1 && errno == EINTR)
                    continue;
#endif
                close (fd);
                return;
            }
            read_ptr += nb;
            to_read -= nb;
        }
        while (to_read > 0);

        close (fd);
    }

    /* Using the magic number we can test whether it really is a message
       catalog file.  */
    if (__builtin_expect (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED,
                          0))
    {
        /* The magic number is wrong: not a message catalog file.  */
#ifdef HAVE_MMAP
        if (use_mmap)
            munmap ((caddr_t) data, size);
        else
#endif
            free (data);
        return;
    }

    domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
    if (domain == NULL)
        return;
    domain_file->data = domain;

    domain->data = (char *) data;
    domain->use_mmap = use_mmap;
    domain->mmap_size = size;
    domain->must_swap = data->magic != _MAGIC;
    domain->malloced = NULL;

    /* Fill in the information about the available tables.  */
    revision = W (domain->must_swap, data->revision);
    /* We support only the major revisions 0 and 1.  */
    switch (revision >> 16)
    {
    case 0:
    case 1:
        domain->nstrings = W (domain->must_swap, data->nstrings);
        domain->orig_tab = (const struct string_desc *)
                           ((char *) data + W (domain->must_swap, data->orig_tab_offset));
        domain->trans_tab = (const struct string_desc *)
                            ((char *) data + W (domain->must_swap, data->trans_tab_offset));
        domain->hash_size = W (domain->must_swap, data->hash_tab_size);
        domain->hash_tab =
            (domain->hash_size > 2
             ? (const nls_uint32 *)
             ((char *) data + W (domain->must_swap, data->hash_tab_offset))
             : NULL);
        domain->must_swap_hash_tab = domain->must_swap;

        /* Now dispatch on the minor revision.  */
        switch (revision & 0xffff)
        {
        case 0:
            domain->n_sysdep_strings = 0;
            domain->orig_sysdep_tab = NULL;
            domain->trans_sysdep_tab = NULL;
            break;
        case 1:
        default:
        {
            nls_uint32 n_sysdep_strings;

            if (domain->hash_tab == NULL)
                /* This is invalid.  These minor revisions need a hash table.  */
                goto invalid;

            n_sysdep_strings =
                W (domain->must_swap, data->n_sysdep_strings);
            if (n_sysdep_strings > 0)
            {
                nls_uint32 n_sysdep_segments;
                const struct sysdep_segment *sysdep_segments;
                const char **sysdep_segment_values;
                const nls_uint32 *orig_sysdep_tab;
                const nls_uint32 *trans_sysdep_tab;
                nls_uint32 n_inmem_sysdep_strings;
                size_t memneed;
                char *mem;
                struct sysdep_string_desc *inmem_orig_sysdep_tab;
                struct sysdep_string_desc *inmem_trans_sysdep_tab;
                nls_uint32 *inmem_hash_tab;
                unsigned int i, j;

                /* Get the values of the system dependent segments.  */
                n_sysdep_segments =
                    W (domain->must_swap, data->n_sysdep_segments);
                sysdep_segments = (const struct sysdep_segment *)
                                  ((char *) data
                                   + W (domain->must_swap, data->sysdep_segments_offset));
                sysdep_segment_values =
                    alloca (n_sysdep_segments * sizeof (const char *));
                for (i = 0; i < n_sysdep_segments; i++)
                {
                    const char *name =
                        (char *) data
                        + W (domain->must_swap, sysdep_segments[i].offset);
                    nls_uint32 namelen =
                        W (domain->must_swap, sysdep_segments[i].length);

                    if (!(namelen > 0 && name[namelen - 1] == '\0'))
                    {
                        freea (sysdep_segment_values);
                        goto invalid;
                    }

                    sysdep_segment_values[i] = get_sysdep_segment_value (name);
                }

                orig_sysdep_tab = (const nls_uint32 *)
                                  ((char *) data
                                   + W (domain->must_swap, data->orig_sysdep_tab_offset));
                trans_sysdep_tab = (const nls_uint32 *)
                                   ((char *) data
                                    + W (domain->must_swap, data->trans_sysdep_tab_offset));

                /* Compute the amount of additional memory needed for the
                   system dependent strings and the augmented hash table.
                   At the same time, also drop string pairs which refer to
                   an undefined system dependent segment.  */
                n_inmem_sysdep_strings = 0;
                memneed = domain->hash_size * sizeof (nls_uint32);
                for (i = 0; i < n_sysdep_strings; i++)
                {
                    int valid = 1;
                    size_t needs[2];

                    for (j = 0; j < 2; j++)
                    {
                        const struct sysdep_string *sysdep_string =
                            (const struct sysdep_string *)
                            ((char *) data
                             + W (domain->must_swap,
                                  j == 0
                                  ? orig_sysdep_tab[i]
                                  : trans_sysdep_tab[i]));
                        size_t need = 0;
                        const struct segment_pair *p = sysdep_string->segments;

                        if (W (domain->must_swap, p->sysdepref) != SEGMENTS_END)
                            for (p = sysdep_string->segments;; p++)
                            {
                                nls_uint32 sysdepref;

                                need += W (domain->must_swap, p->segsize);

                                sysdepref = W (domain->must_swap, p->sysdepref);
                                if (sysdepref == SEGMENTS_END)
                                    break;

                                if (sysdepref >= n_sysdep_segments)
                                {
                                    /* Invalid.  */
                                    freea (sysdep_segment_values);
                                    goto invalid;
                                }

                                if (sysdep_segment_values[sysdepref] == NULL)
                                {
                                    /* This particular string pair is invalid.  */
                                    valid = 0;
                                    break;
                                }

                                need += strlen (sysdep_segment_values[sysdepref]);
                            }

                        needs[j] = need;
                        if (!valid)
                            break;
                    }

                    if (valid)
                    {
                        n_inmem_sysdep_strings++;
                        memneed += needs[0] + needs[1];
                    }
                }
                memneed += 2 * n_inmem_sysdep_strings
                           * sizeof (struct sysdep_string_desc);

                if (n_inmem_sysdep_strings > 0)
                {
                    unsigned int k;

                    /* Allocate additional memory.  */
                    mem = (char *) malloc (memneed);
                    if (mem == NULL)
                        goto invalid;

                    domain->malloced = mem;
                    inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem;
                    mem += n_inmem_sysdep_strings
                           * sizeof (struct sysdep_string_desc);
                    inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem;
                    mem += n_inmem_sysdep_strings
                           * sizeof (struct sysdep_string_desc);
                    inmem_hash_tab = (nls_uint32 *) mem;
                    mem += domain->hash_size * sizeof (nls_uint32);

                    /* Compute the system dependent strings.  */
                    k = 0;
                    for (i = 0; i < n_sysdep_strings; i++)
                    {
                        int valid = 1;

                        for (j = 0; j < 2; j++)
                        {
                            const struct sysdep_string *sysdep_string =
                                (const struct sysdep_string *)
                                ((char *) data
                                 + W (domain->must_swap,
                                      j == 0
                                      ? orig_sysdep_tab[i]
                                      : trans_sysdep_tab[i]));
                            const struct segment_pair *p =
                                    sysdep_string->segments;

                            if (W (domain->must_swap, p->sysdepref)
                                    != SEGMENTS_END)
                                for (p = sysdep_string->segments;; p++)
                                {
                                    nls_uint32 sysdepref;

                                    sysdepref =
                                        W (domain->must_swap, p->sysdepref);
                                    if (sysdepref == SEGMENTS_END)
                                        break;

                                    if (sysdep_segment_values[sysdepref] == NULL)
                                    {
                                        /* This particular string pair is
                                        invalid.  */
                                        valid = 0;
                                        break;
                                    }
                                }

                            if (!valid)
                                break;
                        }

                        if (valid)
                        {
                            for (j = 0; j < 2; j++)
                            {
                                const struct sysdep_string *sysdep_string =
                                    (const struct sysdep_string *)
                                    ((char *) data
                                     + W (domain->must_swap,
                                          j == 0
                                          ? orig_sysdep_tab[i]
                                          : trans_sysdep_tab[i]));
                                const char *static_segments =
                                    (char *) data
                                    + W (domain->must_swap, sysdep_string->offset);
                                const struct segment_pair *p =
                                        sysdep_string->segments;

                                /* Concatenate the segments, and fill
                                   inmem_orig_sysdep_tab[k] (for j == 0) and
                                   inmem_trans_sysdep_tab[k] (for j == 1).  */

                                struct sysdep_string_desc *inmem_tab_entry =
                                    (j == 0
                                     ? inmem_orig_sysdep_tab
                                     : inmem_trans_sysdep_tab)
                                    + k;

                                if (W (domain->must_swap, p->sysdepref)
                                        == SEGMENTS_END)
                                {
                                    /* Only one static segment.  */
                                    inmem_tab_entry->length =
                                        W (domain->must_swap, p->segsize);
                                    inmem_tab_entry->pointer = static_segments;
                                }
                                else
                                {
                                    inmem_tab_entry->pointer = mem;

                                    for (p = sysdep_string->segments;; p++)
                                    {
                                        nls_uint32 segsize =
                                            W (domain->must_swap, p->segsize);
                                        nls_uint32 sysdepref =
                                            W (domain->must_swap, p->sysdepref);
                                        size_t n;

                                        if (segsize > 0)
                                        {
                                            memcpy (mem, static_segments, segsize);
                                            mem += segsize;
                                            static_segments += segsize;
                                        }

                                        if (sysdepref == SEGMENTS_END)
                                            break;

                                        n = strlen (sysdep_segment_values[sysdepref]);
                                        memcpy (mem, sysdep_segment_values[sysdepref], n);
                                        mem += n;
                                    }

                                    inmem_tab_entry->length =
                                        mem - inmem_tab_entry->pointer;
                                }
                            }

                            k++;
                        }
                    }
                    if (k != n_inmem_sysdep_strings)
                        abort ();

                    /* Compute the augmented hash table.  */
                    for (i = 0; i < domain->hash_size; i++)
                        inmem_hash_tab[i] =
                            W (domain->must_swap_hash_tab, domain->hash_tab[i]);
                    for (i = 0; i < n_inmem_sysdep_strings; i++)
                    {
                        const char *msgid = inmem_orig_sysdep_tab[i].pointer;
                        nls_uint32 hash_val = hash_string (msgid);
                        nls_uint32 idx = hash_val % domain->hash_size;
                        nls_uint32 incr =
                            1 + (hash_val % (domain->hash_size - 2));

                        for (;;)
                        {
                            if (inmem_hash_tab[idx] == 0)
                            {
                                /* Hash table entry is empty.  Use it.  */
                                inmem_hash_tab[idx] = 1 + domain->nstrings + i;
                                break;
                            }

                            if (idx >= domain->hash_size - incr)
                                idx -= domain->hash_size - incr;
                            else
                                idx += incr;
                        }
                    }

                    domain->n_sysdep_strings = n_inmem_sysdep_strings;
                    domain->orig_sysdep_tab = inmem_orig_sysdep_tab;
                    domain->trans_sysdep_tab = inmem_trans_sysdep_tab;

                    domain->hash_tab = inmem_hash_tab;
                    domain->must_swap_hash_tab = 0;
                }
                else
                {
                    domain->n_sysdep_strings = 0;
                    domain->orig_sysdep_tab = NULL;
                    domain->trans_sysdep_tab = NULL;
                }

                freea (sysdep_segment_values);
            }
            else
            {
                domain->n_sysdep_strings = 0;
                domain->orig_sysdep_tab = NULL;
                domain->trans_sysdep_tab = NULL;
            }
        }
        break;
        }
        break;
    default:
        /* This is an invalid revision.  */
invalid:
        /* This is an invalid .mo file.  */
        if (domain->malloced)
            free (domain->malloced);
#ifdef HAVE_MMAP
        if (use_mmap)
            munmap ((caddr_t) data, size);
        else
#endif
            free (data);
        free (domain);
        domain_file->data = NULL;
        return;
    }

    /* Now initialize the character set converter from the character set
       the file is encoded with (found in the header entry) to the domain's
       specified character set or the locale's character set.  */
    nullentry = _nl_init_domain_conv (domain_file, domain, domainbinding);

    /* Also look for a plural specification.  */
    EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);
}
Beispiel #29
0
static bool
knuth_morris_pratt_unibyte (const char *haystack, const char *needle,
			    const char **resultp)
{
  size_t m = strlen (needle);

  /* Allocate the table.  */
  size_t *table = (size_t *) malloca (m * sizeof (size_t));
  if (table == NULL)
    return false;
  /* Fill the table.
     For 0 < i < m:
       0 < table[i] <= i is defined such that
       rhaystack[0..i-1] == needle[0..i-1] and rhaystack[i] != needle[i]
       implies
       forall 0 <= x < table[i]: rhaystack[x..x+m-1] != needle[0..m-1],
       and table[i] is as large as possible with this property.
     table[0] remains uninitialized.  */
  {
    size_t i, j;

    table[1] = 1;
    j = 0;
    for (i = 2; i < m; i++)
      {
	unsigned char b = (unsigned char) needle[i - 1];

	for (;;)
	  {
	    if (b == (unsigned char) needle[j])
	      {
		table[i] = i - ++j;
		break;
	      }
	    if (j == 0)
	      {
		table[i] = i;
		break;
	      }
	    j = j - table[j];
	  }
      }
  }

  /* Search, using the table to accelerate the processing.  */
  {
    size_t j;
    const char *rhaystack;
    const char *phaystack;

    *resultp = NULL;
    j = 0;
    rhaystack = haystack;
    phaystack = haystack;
    /* Invariant: phaystack = rhaystack + j.  */
    while (*phaystack != '\0')
      if ((unsigned char) needle[j] == (unsigned char) *phaystack)
	{
	  j++;
	  phaystack++;
	  if (j == m)
	    {
	      /* The entire needle has been found.  */
	      *resultp = rhaystack;
	      break;
	    }
	}
      else if (j > 0)
	{
	  /* Found a match of needle[0..j-1], mismatch at needle[j].  */
	  rhaystack += table[j];
	  j -= table[j];
	}
      else
	{
	  /* Found a mismatch at needle[0] already.  */
	  rhaystack++;
	  phaystack++;
	}
  }

  freea (table);
  return true;
}