Ejemplo n.º 1
0
static string
element (kpathsea kpse, const_string passed_path,  boolean env_p)
{
  const_string p;
  string ret;
  int brace_level;
  unsigned len;

  if (passed_path)
    kpse->path = passed_path;
  /* Check if called with NULL, and no previous path (perhaps we reached
     the end).  */
  else if (!kpse->path)
    return NULL;

  /* OK, we have a non-null `path' if we get here.  */
  assert (kpse->path);
  p = kpse->path;

  /* Find the next colon not enclosed by braces (or the end of the path).  */
  brace_level = 0;
  while (*p != 0  && !(brace_level == 0
                       && (env_p ? IS_ENV_SEP (*p) : IS_DIR_SEP (*p)))) {
    if (*p == '{') ++brace_level;
    else if (*p == '}') --brace_level;
#if defined(WIN32)
    else if (kpathsea_IS_KANJI(kpse, p))
        p++;
#endif
    p++;
  }

  /* Return the substring starting at `path'.  */
  len = p - kpse->path;

  /* Make sure we have enough space (including the null byte).  */
  if (len + 1 > kpse->elt_alloc)
    {
      kpse->elt_alloc = len + 1;
      kpse->elt = (string)xrealloc (kpse->elt, kpse->elt_alloc);
    }

  strncpy (kpse->elt, kpse->path, len);
  kpse->elt[len] = 0;
  ret = kpse->elt;

  /* If we are at the end, return NULL next time.  */
  if (kpse->path[len] == 0)
    kpse->path = NULL;
  else
    kpse->path += len + 1;

  return ret;
}
Ejemplo n.º 2
0
static string
element P2C(const_string, passed_path,  boolean, env_p)
{
  const_string p;
  string ret;
  int brace_level;
  unsigned len;
  
  if (passed_path)
    path = passed_path;
  /* Check if called with NULL, and no previous path (perhaps we reached
     the end).  */
  else if (!path)
    return NULL;
  
  /* OK, we have a non-null `path' if we get here.  */
  assert (path);
  p = path;
  
  /* Find the next colon not enclosed by braces (or the end of the path).  */
  brace_level = 0;
  while (*p != 0  && !(brace_level == 0
                       && (env_p ? IS_ENV_SEP (*p) : IS_DIR_SEP (*p)))) {
    if (*p == '{') ++brace_level;
    else if (*p == '}') --brace_level;
    ++p;
  }
   
  /* Return the substring starting at `path'.  */
  len = p - path;

  /* Make sure we have enough space (including the null byte).  */
  if (len + 1 > elt_alloc)
    {
      elt_alloc = len + 1;
      elt = (string)xrealloc (elt, elt_alloc);
    }

  strncpy (elt, path, len);
  elt[len] = 0;
  ret = elt;

  /* If we are at the end, return NULL next time.  */
  if (path[len] == 0)
    path = NULL;
  else
    path += len + 1;

  return ret;
}
Ejemplo n.º 3
0
static string
do_line (kpathsea kpse, string line)
{
  unsigned len;
  string start;
  string value, var;
  string prog = NULL;

  /* Skip leading whitespace.  */
  while (*line && ISSPACE (*line))
    line++;

  /* More to do only if we have non-comment material left.  */
  if (*line == 0 || *line == '%' || *line == '#')
    return NULL;

  /* Remove trailing comment: a % or # preceded by whitespace.  Also
     remove any whitespace before that.  For example, the value for
       foo = a#b  %something
     is a#b.  */
  value = line + strlen (line) - 1; /* start at end of line */
  while (value > line) {            
    if (*value == '%' || *value == '#') {
      value--;                      /* move before comment char */
      while (ISSPACE (*value))
        *value-- = 0;               /* wipe out as much preceding whitespace
      continue;                        (and comment) as we find */
    }
    value--;                        /* move before the new null byte */
  }

  /* The variable name is everything up to the next space or = or `.'.  */
  start = line;
  while (*line && !ISSPACE (*line) && *line != '=' && *line != '.')
    line++;

  /* `line' is now one character past the end of the variable name.  */
  len = line - start;
  if (len == 0) {
    return ("No cnf variable name");
  }
  
  var = (string) xmalloc (len + 1);
  strncpy (var, start, len);
  var[len] = 0;

  /* If the variable is qualified with a program name, find out which. */
  while (*line && ISSPACE (*line))
    line++;
  if (*line == '.') {
    /* Skip spaces, then everything up to the next space or =.  */
    line++;
    while (ISSPACE (*line))
      line++;
    start = line;
    while (*line && !ISSPACE (*line) && *line != '=')
      line++;

    /* It's annoying to repeat all this, but making a tokenizing
       subroutine would be just as long and annoying.  */
    len = line - start;
    prog = (string) xmalloc (len + 1);
    strncpy (prog, start, len);
    prog[len] = 0;
  }

  /* Skip whitespace, an optional =, more whitespace.  */
  while (*line && ISSPACE (*line))
    line++;
  if (*line == '=') {
    line++;
    while (*line && ISSPACE (*line))
      line++;
  }

  /* The value is whatever remains.  Remove trailing whitespace.  */
  start = line;
  len = strlen (start);
  while (len > 0 && ISSPACE (start[len - 1]))
    len--;
  if (len == 0) {
    return ("No cnf value");
  }
  
  value = (string) xmalloc (len + 1);
  strncpy (value, start, len);
  value[len] = 0;

  /* Suppose we want to write a single texmf.cnf that can be used under
     both Windows and Unix. This is feasible except for the path
     separators: : on Unix, ; on Windows. We can't switch Windows to
     allowing :, since : is the drive separator. So we switch Unix to
     allowing ;. On the other hand, we don't want to change IS_ENV_SEP
     and all the rest.

     So, translate all ;'s in the path values to :'s if we'd normally
     use :. (Fortunately we don't use ; as a normal character in values.)  */

  if (IS_ENV_SEP(':')) {
      string loc;
      for (loc = value; *loc; loc++) {
          if (*loc == ';')
              *loc = ':';
      }
  }

  /* We want TEXINPUTS.prog to override plain TEXINPUTS.  The simplest
     way is to put both in the hash table (so we don't have to write
     hash_delete and hash_replace, and keep track of values' sources),
     and then look up the .prog version first in `kpse_cnf_get'.  */
  if (prog) {
    string lhs = concat3 (var, ".", prog);
    free (var);
    free (prog);
    var = lhs;
  }
  /* last-ditch debug */
  /* fprintf (stderr, "kpse/cnf.c hash_insert(%s,%s)\n", var, value); */
  hash_insert (&(kpse->cnf_hash), var, value);

  /* We should check that anything remaining is preceded by a comment
     character, but we don't.  Sorry.  */
  return NULL;
}
Ejemplo n.º 4
0
Archivo: cnf.c Proyecto: genesi/luatex
static void
do_line (kpathsea kpse, string line)
{
  unsigned len;
  string start;
  string value, var;
  string prog = NULL;
  
  /* Skip leading whitespace.  */
  while (ISSPACE (*line))
    line++;
  
  /* More to do only if we have non-comment material left.  */
  if (*line == 0 || *line == '%' || *line == '#')
    return;
  
  /* The variable name is everything up to the next space or = or `.'.  */
  start = line;
  while (!ISSPACE (*line) && *line != '=' && *line != '.')
    line++;

  /* `line' is now one character past the end of the variable name.  */
  len = line - start;
  var = (string)xmalloc (len + 1);
  strncpy (var, start, len);
  var[len] = 0;
  
  /* If the variable is qualified with a program name, find out which. */
  while (ISSPACE (*line))
    line++;
  if (*line == '.') {
    /* Skip spaces, then everything up to the next space or =.  */
    line++;
    while (ISSPACE (*line))
      line++;
    start = line;
    while (!ISSPACE (*line) && *line != '=')
      line++;

    /* It's annoying to repeat all this, but making a tokenizing
       subroutine would be just as long and annoying.  */
    len = line - start;
    prog = (string)xmalloc (len + 1);
    strncpy (prog, start, len);
    prog[len] = 0;
  }

  /* Skip whitespace, an optional =, more whitespace.  */
  while (ISSPACE (*line))
    line++;
  if (*line == '=') {
    line++;
    while (ISSPACE (*line))
      line++;
  }
  
  /* The value is whatever remains.  Remove trailing whitespace.  */
  start = line;
  len = strlen (start);
  while (len > 0 && ISSPACE (start[len - 1]))
    len--;
  
  value = (string)xmalloc (len + 1);
  strncpy (value, start, len);
  value[len] = 0;

  /* Suppose we want to write a single texmf.cnf that can be used under
     both NT and Unix.  This is feasible except for the path separators
     : on Unix, ; on NT.  We can't switch NT to allowing :'s, since :
     is the drive separator.  So we switch Unix to allowing ;'s.  On the
     other hand, we don't want to change IS_ENV_SEP and all the rest.
     
     So, simply translate all ;'s in the path
     values to :'s if we are a Unix binary.  (Fortunately we don't use ;
     in other kinds of texmf.cnf values.)  */
     
  if (IS_ENV_SEP(':')) {
      string loc;
      for (loc = value; *loc; loc++) {
          if (*loc == ';')
              *loc = ':';
      }
  }

  /* We want TEXINPUTS.prog to override plain TEXINPUTS.  The simplest
     way is to put both in the hash table (so we don't have to write
     hash_delete and hash_replace, and keep track of values' sources),
     and then look up the .prog version first in `kpse_cnf_get'.  */
  if (prog) {
    string lhs = concat3 (var, ".", prog);
    free (var);
    free (prog);
    var = lhs;
  }
  hash_insert (&(kpse->cnf_hash), var, value);
  
  /* We could check that anything remaining is preceded by a comment
     character, but let's not bother.  */
}
Ejemplo n.º 5
0
/* kpse:lookup("plain.tex", {}) */
static int do_lua_kpathsea_lookup(lua_State * L, kpathsea kpse, int idx)
{
    int i;
    string ret = NULL;
    string *ret_list = NULL;
    const_string name = NULL;
    string user_path = NULL;
    boolean show_all = false;
    boolean must_exist = false;
    kpse_file_format_type user_format = kpse_last_format;
    int dpi = 600;
    str_list_type subdir_paths = { 0, NULL };
    unsigned saved_debug = kpse->debug;
    int saved_mktexpk = kpse->format_info[kpse_pk_format].program_enabled_p;
    int saved_mktexmf = kpse->format_info[kpse_mf_format].program_enabled_p;
    int saved_mktextex = kpse->format_info[kpse_tex_format].program_enabled_p;
    int saved_mktextfm = kpse->format_info[kpse_tfm_format].program_enabled_p;
    name = luaL_checkstring(L, idx);
    /* todo: fetch parameter values */

    if (lua_type(L, idx + 1) == LUA_TTABLE) {
        lua_pushstring(L, "format");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TSTRING) {
            int op = luaL_checkoption(L, -1, NULL, filetypenames);
            user_format = filetypes[op];
        }
        lua_pop(L, 1);
        lua_pushstring(L, "dpi");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TNUMBER) {
            dpi = (int) lua_tointeger(L, -1);
        }
        lua_pop(L, 1);
        lua_pushstring(L, "debug");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TNUMBER) {
            int d = 0;
            d = (int) lua_tointeger(L, -1);
            kpse->debug |= d;
        }
        lua_pop(L, 1);
        lua_pushstring(L, "path");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TSTRING) {
            user_path = xstrdup(lua_tostring(L, -1));
        }
        lua_pop(L, 1);
        lua_pushstring(L, "all");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TBOOLEAN) {
            show_all = lua_toboolean(L, -1);
        }
        lua_pop(L, 1);

        lua_pushstring(L, "mktexpk");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TBOOLEAN) {
            kpathsea_maketex_option(kpse, "pk", lua_toboolean(L, -1));
        }
        lua_pop(L, 1);

        lua_pushstring(L, "mktextex");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TBOOLEAN) {
            kpathsea_maketex_option(kpse, "tex", lua_toboolean(L, -1));
        }
        lua_pop(L, 1);

        lua_pushstring(L, "mktexmf");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TBOOLEAN) {
            kpathsea_maketex_option(kpse, "mf", lua_toboolean(L, -1));
        }
        lua_pop(L, 1);

        lua_pushstring(L, "mktextfm");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TBOOLEAN) {
            kpathsea_maketex_option(kpse, "tfm", lua_toboolean(L, -1));
        }
        lua_pop(L, 1);


        lua_pushstring(L, "mustexist");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TBOOLEAN) {
            must_exist = lua_toboolean(L, -1);
        }
        lua_pop(L, 1);
        lua_pushstring(L, "subdir");
        lua_gettable(L, idx + 1);
        if (lua_istable(L, -1)) {
            lua_pushnil(L);
            while (lua_next(L, -2) != 0) {      /* numeric value */
                if (lua_type(L, -1) == LUA_TSTRING) {
                    char *s = xstrdup(lua_tostring(L, -1));
                    str_list_add(&subdir_paths, s);
                    xfree(s);
                }
                lua_pop(L, 1);
            }
        } else if (lua_type(L, -1) == LUA_TSTRING) {
            char *s = xstrdup(lua_tostring(L, -1));
            str_list_add(&subdir_paths, s);
            xfree(s);
        }
        lua_pop(L, 1);
        if (STR_LIST_LENGTH(subdir_paths) > 0) {
            show_all = 1;
        }
    }
    if (user_path) {
        /* Translate ; to : if that's our ENV_SEP.  See cnf.c.  */
        if (IS_ENV_SEP(':')) {
            string loc;
            for (loc = user_path; *loc; loc++) {
                if (*loc == ';')
                    *loc = ':';
            }
        }
        user_path = kpathsea_path_expand(kpse, user_path);
        if (show_all) {
            ret_list = kpathsea_all_path_search(kpse, user_path, name);
        } else {
            ret = kpathsea_path_search(kpse, user_path, name, must_exist);
        }
        free(user_path);
    } else {
        /* No user-specified search path, check user format or guess from NAME.  */
        kpse_file_format_type fmt;
        if (user_format != kpse_last_format)
            fmt = user_format;
        else
            fmt = find_format(kpse, name, true);

        switch (fmt) {
        case kpse_pk_format:
        case kpse_gf_format:
        case kpse_any_glyph_format:
            {
                kpse_glyph_file_type glyph_ret;
                string temp = remove_suffix (name);
                /* Try to extract the resolution from the name.  */
                unsigned local_dpi = find_dpi(name);
                if (!local_dpi)
                    local_dpi = (unsigned) dpi;
                ret =
                    kpathsea_find_glyph(kpse, temp, local_dpi,
                                        fmt, &glyph_ret);
                if (temp != name)
                    free (temp);
            }
            break;

        case kpse_last_format:
            /* If the suffix isn't recognized, assume it's a tex file. */
            fmt = kpse_tex_format;
            /* fall through */

        default:
            if (show_all) {
                ret_list =
                    kpathsea_find_file_generic(kpse, name, fmt, must_exist,
                                               true);
            } else {
                ret = kpathsea_find_file(kpse, name, fmt, must_exist);
            }
        }
    }

    /* Turn single return into a null-terminated list for uniform treatment.  */
    if (ret) {
        ret_list = XTALLOC(2, string);
        ret_list[0] = ret;
        ret_list[1] = NULL;
    }

    /* Filter by subdirectories, if specified.  */
    if (STR_LIST_LENGTH(subdir_paths) > 0) {
        string *new_list = subdir_match(subdir_paths, ret_list);
        free(ret_list);
        ret_list = new_list;
    }
    kpse->debug = saved_debug;
    kpse->format_info[kpse_pk_format].program_enabled_p = saved_mktexpk;
    kpse->format_info[kpse_mf_format].program_enabled_p = saved_mktexmf;
    kpse->format_info[kpse_tex_format].program_enabled_p = saved_mktextex;
    kpse->format_info[kpse_tfm_format].program_enabled_p = saved_mktextfm;

    /* Print output.  */
    i = 0;
    if (ret_list) {
        for (; ret_list[i]; i++) {
            lua_pushstring(L, ret_list[i]);
        }
        free(ret_list);
    }
    if (i == 0) {
        i++;
        lua_pushnil(L);
    }
    return i;
}
Ejemplo n.º 6
0
static void
init_path (kpathsea kpse, kpse_format_info_type *info,
           const_string default_path, ...)
{
  string env_name;
  string env_value = NULL;
  string var = NULL;
  string tmp;
  va_list ap;

  info->default_path = default_path;

  va_start (ap, default_path);
  /* First envvar that's set to a nonempty value will exit the loop.  If
     none are set, we want the first cnf entry that matches.  Find the
     cnf value simultaneously with the envvar value, to avoid having to
     go through the envvar list twice,
     that would mean having to create a str_list and use it twice.  */
  while ((env_name = va_arg (ap, string)) != NULL) {
    /* Since sh doesn't like envvar names with `.', check PATH_prog
       as well as PATH.prog.  */
    if (!var) { /* Try PATH.prog. */
      string evar = concat3 (env_name, ".", kpse->program_name);
      env_value = getenv (evar);
      if (env_value && *env_value) {
        var = evar;
      } else { /* Try PATH_prog. */
        free (evar);
        evar = concat3 (env_name, "_", kpse->program_name);
        env_value = getenv (evar);
        if (env_value && *env_value) {
          var = evar;
        } else { /* Try simply PATH.  */
          free (evar);
          env_value = getenv (env_name);
          if (env_value && *env_value) {
            var = env_name;
          }
        }
      }
    }

    /* If we are initializing the cnf path, don't try to get any
       values from the cnf files; that's infinite loop time.  */
    if (!info->cnf_path && info != &(kpse->format_info[kpse_cnf_format]))
      info->cnf_path = kpathsea_cnf_get (kpse, env_name);

    if (var && info->cnf_path)
      break;
  }
  va_end (ap);

  /* Expand any extra :'s.  For each level, we replace an extra : with
     the path at the next lower level.  For example, an extra : in a
     user-set envvar should be replaced with the path from the cnf file.
     things are complicated because none of the levels above the very
     bottom are guaranteed to exist.  */

  /* Assume we can reliably start with the compile-time default.  */
  info->raw_path = info->default_path;
  info->path = xstrdup (info->raw_path);
  info->path_source = "compile-time paths.h";

  EXPAND_DEFAULT (info->cnf_path, "texmf.cnf");
  EXPAND_DEFAULT (info->client_path, "program config file");

  if (var) {
    /* Translate `;' in the envvar into `:' if that's our ENV_SEP. */
    if (IS_ENV_SEP (':')) {
      string loc;
      env_value = xstrdup (env_value);  /* Freed below. */
      for (loc = env_value; *loc; loc++) {
        if (*loc == ';')
          *loc = ':';
      }
    }
    EXPAND_DEFAULT (env_value, concat (var, " environment variable"));
    /* Do not free the copied env_value, because EXPAND_DEFAULT set
       raw_path to point to it.  If it gets overwritten again, tough.  */
  }

  EXPAND_DEFAULT (info->override_path, "application override variable");
  tmp = info->path;
  info->path = kpathsea_brace_expand (kpse, info->path);
  free (tmp);
}