diff options
Diffstat (limited to 'Build/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/automatic.cc')
-rw-r--r-- | Build/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/automatic.cc | 816 |
1 files changed, 0 insertions, 816 deletions
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/automatic.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/automatic.cc deleted file mode 100644 index 0567de51e2c..00000000000 --- a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/otftotfm/automatic.cc +++ /dev/null @@ -1,816 +0,0 @@ -/* automatic.{cc,hh} -- code for automatic mode and interfacing with kpathsea - * - * Copyright (c) 2003-2019 Eddie Kohler - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. This program is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - */ - -#include <config.h> -#include "automatic.hh" -#include "kpseinterface.h" -#include "util.hh" -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <ctype.h> -#if HAVE_UNISTD_H -# include <unistd.h> -#endif -#include <sys/stat.h> -#include <sys/types.h> -#if HAVE_SYS_TIME_H -# include <sys/time.h> -#endif -#if HAVE_SYS_WAIT_H -# include <sys/wait.h> -#endif -#include <lcdf/error.hh> -#include <lcdf/straccum.hh> -#if HAVE_FCNTL_H -# include <fcntl.h> -#endif -#include <algorithm> - -#ifdef WIN32 -# include <io.h> -# include <direct.h> -# define mkdir(dir, access) _mkdir(dir) -# define COPY_CMD "copy" -# define CMD_SEP "&" -#else -# define COPY_CMD "cp" -# define CMD_SEP ";" -#endif - -/* kpathsea may already have defined this */ -#ifndef DEV_NULL -# ifdef WIN32 -# define DEV_NULL "NUL" -# else -# define DEV_NULL "/dev/null" -# endif -#endif - -#if HAVE_AUTO_T1DOTLESSJ -enum { T1DOTLESSJ_EXIT_J_NODOT = 2 }; -#endif - -static String odir[NUMODIR]; -static String typeface; -static String vendor; -static String map_file; -#define DEFAULT_VENDOR "lcdftools" -#define DEFAULT_TYPEFACE "unknown" - -static const struct { - const char *name; - const char *envvar; - const char *texdir; -} odir_info[] = { - { "encoding", "ENCODINGDESTDIR", "#fonts/enc/dvips/@#dvips/@" }, - { "TFM", "TFMDESTDIR", "fonts/tfm/%" }, - { "PL", "PLDESTDIR", "fonts/pl/%" }, - { "VF", "VFDESTDIR", "fonts/vf/%" }, - { "VPL", "VPLDESTDIR", "fonts/vpl/%" }, - { "Type 1", "T1DESTDIR", "fonts/type1/%" }, - { "DVIPS map", "DVIPS directory", "#fonts/map/dvips/@#dvips/@" }, - { "DVIPS updmap", "DVIPS directory", "dvips" }, - { "TrueType", "TTFDESTDIR", "fonts/truetype/%" }, - { "OpenType", "OPENTYPEDESTDIR", "fonts/opentype/%" }, - { "Type 42", "T42DESTDIR", "fonts/type42/%" } -}; - -#if HAVE_KPATHSEA -static String odir_kpathsea[NUMODIR]; - -static bool writable_texdir_tried = false; -static String writable_texdir; // always ends with directory separator -static int tds_1_1 = -1; - -static bool mktexupd_tried = false; -static String mktexupd; - -static String -kpsei_string(char* x) -{ - String s(x); - free((void*)x); - return s; -} - -static void -look_for_writable_texdir(const char *path_variable, bool create) -{ - String path = kpsei_string(kpsei_path_expand(path_variable)); - while (path && !writable_texdir) { - const char* colon = std::find(path.begin(), path.end(), kpsei_env_sep_char); - String texdir = path.substring(path.begin(), colon); - path = path.substring(colon + 1, path.end()); - if (access(texdir.c_str(), W_OK) >= 0) - writable_texdir = texdir; - else if (create && errno != EACCES && mkdir(texdir.c_str(), 0777) >= 0) - // create file if it doesn't exist already - writable_texdir = texdir; - } - if (writable_texdir && writable_texdir.back() != '/') - writable_texdir += "/"; -} - -static void -find_writable_texdir(ErrorHandler *errh, const char *) -{ -#if defined(W32TEX) -// W32TeX does not have TEXMFVAR - char *p = kpsei_var_value("TEXMFVAR"); - if (p == NULL) // W32TeX - look_for_writable_texdir("$TEXMFLOCAL", true); - else { // TeXLive - free (p); - look_for_writable_texdir("$TEXMFVAR", true); - } -#else - look_for_writable_texdir("$TEXMFVAR", true); -#endif - if (!writable_texdir) - look_for_writable_texdir("$VARTEXMF", false); - if (!writable_texdir) - look_for_writable_texdir("$TEXMF", false); - if (!writable_texdir) { - errh->warning("no writable directory found in $TEXMFVAR or $TEXMF"); - errh->message("(You probably need to set your TEXMF environment variable; see\n\ -the manual for more information. The current TEXMF path is\n\ -%<%s%>.)", kpsei_string(kpsei_path_expand("$TEXMF")).c_str()); - } - writable_texdir_tried = true; -} - -static String -get_vendor() -{ - return (vendor ? vendor : String(DEFAULT_VENDOR)); -} - -static String -get_typeface() -{ - return (typeface ? typeface : String(DEFAULT_TYPEFACE)); -} -#endif - -bool -set_vendor(const String &s) -{ - bool had = (bool) vendor; - vendor = s; - return !had; -} - -bool -set_typeface(const String &s, bool override) -{ - bool had = (bool) typeface; - if (!had || override) - typeface = s; - return !had; -} - -String -getodir(int o, ErrorHandler *errh) -{ - assert(o >= 0 && o < NUMODIR); - - if (!odir[o] && automatic && odir_info[o].envvar) - odir[o] = getenv(odir_info[o].envvar); - -#if HAVE_KPATHSEA - if (!odir[o] && automatic && !writable_texdir_tried) - find_writable_texdir(errh, odir_info[o].name); - - if (!odir[o] && automatic && writable_texdir) { - String suffix = odir_info[o].texdir; - - // May need to behave differently on TDS 1.1 rather than TDS 1.0. - if (suffix[0] == '#') { - // check type of TDS - if (tds_1_1 < 0) { - // using a procedure suggested by Olaf Weber - String encfonts = kpsei_string(kpsei_path_expand("$TEXMFMAIN/fonts/enc")); - if (!encfonts) - encfonts = kpsei_string(kpsei_path_expand("$TEXMFDIST/fonts/enc")); - tds_1_1 = (encfonts != String()); - } - if (tds_1_1 == 0) - suffix = suffix.substring(std::find(suffix.begin() + 1, suffix.end(), '#') + 1, suffix.end()); - else - suffix = suffix.substring(suffix.begin() + 1, std::find(suffix.begin() + 1, suffix.end(), '#')); - } - - String dir = writable_texdir + suffix; - - if (dir.back() == '%') - dir = dir.substring(0, -1) + get_vendor() + "/" + get_typeface(); - else if (dir.back() == '@') - dir = dir.substring(0, -1) + get_vendor(); - - // create parent directories as appropriate - int slash = writable_texdir.length() - 1; - while (access(dir.c_str(), F_OK) < 0 && slash < dir.length()) { - if ((slash = dir.find_left('/', slash + 1)) < 0) - slash = dir.length(); - String subdir = dir.substring(0, slash); - if (access(subdir.c_str(), F_OK) < 0 - && !no_create - && mkdir(subdir.c_str(), 0777) < 0) - goto kpathsea_done; - } - - // that's our answer - odir[o] = dir; - odir_kpathsea[o] = dir; - } - kpathsea_done: -#endif - - if (!odir[o]) { - if (automatic) { - errh->warning("%s not specified, placing %s files in %<.%>", odir_info[o].envvar, odir_info[o].name); -#if !HAVE_KPATHSEA - static int kpathsea_warning = 0; - if (++kpathsea_warning == 1) - errh->message("(This version of otftotfm lacks $TEXMF directory support.)"); -#endif - } - odir[o] = "."; - } - - while (odir[o].length() && odir[o].back() == '/') - odir[o] = odir[o].substring(0, -1); - - if (verbose) - errh->message("placing %s files in %<%s%>", odir_info[o].name, odir[o].c_str()); - return odir[o]; -} - -void -setodir(int o, const String &value) -{ - assert(o >= 0 && o < NUMODIR); - odir[o] = value; -} - -const char * -odirname(int o) -{ - if (o == NUMODIR) { - return "default"; - } else { - assert(o >= 0 && o < NUMODIR); - return odir_info[o].name; - } -} - -#if HAVE_KPATHSEA -static bool -file_in_kpathsea_odir(int o, const String &file) -{ - return odir_kpathsea[o] - && file.length() > odir[o].length() - && memcmp(file.data(), odir[o].data(), odir[o].length()) == 0 - && file[odir[o].length()] == '/'; -} -#endif - -void -update_odir(int o, String file, ErrorHandler *errh) -{ - assert(o >= 0 && o < NUMODIR); -#if HAVE_KPATHSEA - if (file.find_left('/') < 0) - file = odir[o] + "/" + file; - - // exit if this directory was not found via kpathsea, or the file is not - // in the kpathsea directory - if (!file_in_kpathsea_odir(o, file)) - return; - - assert(writable_texdir && writable_texdir.length() <= odir[o].length() - && memcmp(file.data(), writable_texdir.data(), writable_texdir.length()) == 0); - - // divide the filename into portions - // file == writable_texdir + directory + file - file = file.substring(writable_texdir.length()); - while (file && file[0] == '/') - file = file.substring(1); - int last_slash = file.find_right('/'); - String directory = (last_slash >= 0 ? file.substring(0, last_slash) : String()); - file = file.substring(last_slash >= 0 ? last_slash + 1 : 0); - if (!file) // no filename to update - return; - - // return if nocreate - if (no_create) { - errh->message("would update %sls-R for %s/%s", writable_texdir.c_str(), directory.c_str(), file.c_str()); - return; - } else if (verbose) - errh->message("updating %sls-R for %s/%s", writable_texdir.c_str(), directory.c_str(), file.c_str()); - - // try to update ls-R ourselves, rather than running mktexupd -- - // mktexupd's runtime is painful: a half second to update a file - String ls_r = writable_texdir + "ls-R"; - bool success = false; - if (access(ls_r.c_str(), R_OK) >= 0) // make sure it already exists - if (FILE *f = fopen(ls_r.c_str(), "ab")) { - fprintf(f, "./%s:\n%s\n", directory.c_str(), file.c_str()); - success = true; - fclose(f); - } - - // otherwise, run mktexupd - if (!success && writable_texdir.find_left('\'') < 0 && directory.find_left('\'') < 0 && file.find_left('\'') < 0) { - // look for mktexupd script - if (!mktexupd_tried) { -#ifdef _WIN32 - mktexupd = "mktexupd.exe"; -#else - mktexupd = kpsei_string(kpsei_find_file("mktexupd", KPSEI_FMT_WEB2C)); -#endif - mktexupd_tried = true; - } - - // run script - if (mktexupd) { - String command = mktexupd + " " + shell_quote(writable_texdir + directory) + " " + shell_quote(file); - int retval = system(command.c_str()); - if (retval == 127) - errh->error("could not run %<%s%>", command.c_str()); - else if (retval < 0) - errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); - else if (retval != 0) - errh->error("%<%s%> failed", command.c_str()); - } - } -#else - (void) file, (void) errh; -#endif -} - -bool -set_map_file(const String &s) -{ - bool had = (bool) map_file; - map_file = s; - return !had; -} - -String -installed_type1(const String &otf_filename, const String &ps_fontname, bool allow_generate, ErrorHandler *errh) -{ - (void) otf_filename, (void) allow_generate, (void) errh; - - if (!ps_fontname) - return String(); - -#if HAVE_KPATHSEA -# if HAVE_AUTO_CFFTOT1 - if (!(force && allow_generate && otf_filename && otf_filename != "-" && getodir(O_TYPE1, errh))) { -# endif - // look for .pfb and .pfa - String file, path; - if ((file = ps_fontname + ".pfb", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1))) - || (file = ps_fontname + ".pfa", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1)))) { - if (path == "./" + file || path == file) { - if (verbose) - errh->message("ignoring Type 1 file %s found with kpathsea in %<.%>", path.c_str()); - } else { - if (verbose) - errh->message("Type 1 file %s found with kpathsea at %s", file.c_str(), path.c_str()); - return path; - } - } -# if HAVE_AUTO_CFFTOT1 - } -# endif -#endif - -#if HAVE_AUTO_CFFTOT1 - // if not found, and can generate on the fly, run cfftot1 - if (allow_generate && otf_filename && otf_filename != "-" && getodir(O_TYPE1, errh)) { - String pfb_filename = odir[O_TYPE1] + "/" + ps_fontname + ".pfb"; - if (pfb_filename.find_left('\'') >= 0 || otf_filename.find_left('\'') >= 0) - return String(); - String command = "cfftot1 " + shell_quote(otf_filename) + " -n " + shell_quote(ps_fontname) + " " + shell_quote(pfb_filename); - int retval = mysystem(command.c_str(), errh); - if (retval == 127) - errh->error("could not run %<%s%>", command.c_str()); - else if (retval < 0) - errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); - else if (retval != 0) - errh->error("%<%s%> failed", command.c_str()); - if (retval == 0) { - update_odir(O_TYPE1, pfb_filename, errh); - return pfb_filename; - } - } -#endif - - return String(); -} - -String -installed_type1_dotlessj(const String &otf_filename, const String &ps_fontname, bool allow_generate, ErrorHandler *errh) -{ - (void) otf_filename, (void) allow_generate, (void) errh; - - if (!ps_fontname) - return String(); - if (verbose) - errh->message("searching for dotless-j font for %s", ps_fontname.c_str()); - - String j_ps_fontname = ps_fontname + "LCDFJ"; - -#if HAVE_KPATHSEA -# if HAVE_AUTO_T1DOTLESSJ - if (!(force && allow_generate && getodir(O_TYPE1, errh))) { -# endif - // look for existing .pfb or .pfa - String file, path; - if ((file = j_ps_fontname + ".pfb", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1))) - || (file = j_ps_fontname + ".pfa", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1)))) { - // ignore versions in the current directory - if (path == "./" + file || path == file) { - if (verbose) - errh->message("ignoring Type 1 file %s found with kpathsea in %<.%>", path.c_str()); - } else { - if (verbose) - errh->message("Type 1 file %s found with kpathsea at %s", file.c_str(), path.c_str()); - return path; - } - } -# if HAVE_AUTO_T1DOTLESSJ - } -# endif -#endif - -#if HAVE_AUTO_T1DOTLESSJ - // if not found, and can generate on the fly, try running t1dotlessj - if (allow_generate && getodir(O_TYPE1, errh)) { - if (String base_filename = installed_type1(otf_filename, ps_fontname, allow_generate, errh)) { - String pfb_filename = odir[O_TYPE1] + "/" + j_ps_fontname + ".pfb"; - if (pfb_filename.find_left('\'') >= 0 || base_filename.find_left('\'') >= 0) - return String(); - String command = "t1dotlessj " + shell_quote(base_filename) + " -n " + shell_quote(j_ps_fontname) + " " + shell_quote(pfb_filename); - int retval = mysystem(command.c_str(), errh); - if (retval == 127) - errh->warning("could not run %<%s%>", command.c_str()); - else if (retval < 0) - errh->warning("could not run %<%s%>: %s", command.c_str(), strerror(errno)); - else if (WEXITSTATUS(retval) == T1DOTLESSJ_EXIT_J_NODOT) - return String("\0", 1); - else if (retval != 0) - errh->warning("%<%s%> failed (%d)", command.c_str(), retval); - if (retval == 0) { - update_odir(O_TYPE1, pfb_filename, errh); - return pfb_filename; - } else - errh->warning("output font will not contain a dotless-j character"); - } - } -#endif - - return String(); -} - -String -installed_truetype(const String &ttf_filename, bool allow_generate, ErrorHandler *errh) -{ - String file = pathname_filename(ttf_filename); - -#if HAVE_KPATHSEA - if (!(force && allow_generate && ttf_filename && ttf_filename != "-" && getodir(O_TRUETYPE, errh))) { - if (String path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TRUETYPE))) { - if (path == "./" + file || path == file) { - if (verbose) - errh->message("ignoring TrueType file %s found with kpathsea in %<.%>", path.c_str()); - } else { - if (verbose) - errh->message("TrueType file %s found with kpathsea at %s", file.c_str(), path.c_str()); - return path; - } - } - } -#endif - - // perhaps generate type 42 in the future, for now just copy - if (allow_generate && ttf_filename && ttf_filename != "-" && getodir(O_TRUETYPE, errh)) { - String installed_ttf_filename = odir[O_TRUETYPE] + "/" + file; - if (installed_ttf_filename.find_left('\'') >= 0 || installed_ttf_filename.find_left('\"') >= 0) - return String(); - - int retval; - if (!same_filename(ttf_filename, installed_ttf_filename)) { - String command = COPY_CMD " " + shell_quote(ttf_filename) + " " + shell_quote(installed_ttf_filename); - retval = mysystem(command.c_str(), errh); - if (retval == 127) - errh->error("could not run %<%s%>", command.c_str()); - else if (retval < 0) - errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); - else if (retval != 0) - errh->error("%<%s%> failed", command.c_str()); - } else { - if (verbose) - errh->message("TrueType file %s already located in output directory", installed_ttf_filename.c_str()); - retval = 0; - } - - if (retval == 0) { - update_odir(O_TRUETYPE, installed_ttf_filename, errh); - return installed_ttf_filename; - } - } - - return String(); -} - -String -installed_type42(const String &ttf_filename, const String &ps_fontname, bool allow_generate, ErrorHandler *errh) -{ - (void) allow_generate, (void) ttf_filename, (void) errh; - - if (!ps_fontname) - return String(); - -#if HAVE_KPATHSEA -# if HAVE_AUTO_TTFTOTYPE42 - if (!(force && allow_generate && ttf_filename && ttf_filename != "-" && getodir(O_TYPE42, errh))) { -# endif - // look for .pfb and .pfa - String file, path; - if ((file = ps_fontname + ".t42", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE42)))) { - if (path == "./" + file || path == file) { - if (verbose) - errh->message("ignoring Type 42 file %s found with kpathsea in %<.%>", path.c_str()); - } else { - if (verbose) - errh->message("Type 42 file %s found with kpathsea at %s", file.c_str(), path.c_str()); - return path; - } - } -# if HAVE_AUTO_TTFTOTYPE42 - } -# endif -#endif - -#if HAVE_AUTO_TTFTOTYPE42 - // if not found, and can generate on the fly, run ttftotype42 - if (allow_generate && ttf_filename && ttf_filename != "-" && getodir(O_TYPE42, errh)) { - String t42_filename = odir[O_TYPE42] + "/" + ps_fontname + ".t42"; - if (t42_filename.find_left('\'') >= 0 || ttf_filename.find_left('\'') >= 0) - return String(); - String command = "ttftotype42 " + shell_quote(ttf_filename) + " " + shell_quote(t42_filename); - int retval = mysystem(command.c_str(), errh); - if (retval == 127) - errh->error("could not run %<%s%>", command.c_str()); - else if (retval < 0) - errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); - else if (retval != 0) - errh->error("%<%s%> failed", command.c_str()); - if (retval == 0) { - update_odir(O_TYPE42, t42_filename, errh); - return t42_filename; - } - } -#endif - - return String(); -} - -int -update_autofont_map(const String &fontname, String mapline, ErrorHandler *errh) -{ -#if HAVE_KPATHSEA - if (automatic && !map_file && getodir(O_MAP, errh)) - map_file = odir[O_MAP] + "/" + get_vendor() + ".map"; -#endif - - if (map_file == "" || map_file == "-") - fputs(mapline.c_str(), stdout); - else { - // report no_create/verbose - if (no_create) { - errh->message("would update %s for %s", map_file.c_str(), String(fontname).c_str()); - return 0; - } else if (verbose) - errh->message("updating %s for %s", map_file.c_str(), String(fontname).c_str()); - - int fd = open(map_file.c_str(), O_RDWR | O_CREAT, 0666); - if (fd < 0) - return errh->lerror(map_file, "%s", strerror(errno)); - FILE *f = fdopen(fd, "r+"); - // NB: also change encoding logic if you change this code - -#if defined(F_SETLKW) && defined(HAVE_FTRUNCATE) - { - struct flock lock; - lock.l_type = F_WRLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 0; - int result; - while ((result = fcntl(fd, F_SETLKW, &lock)) < 0 && errno == EINTR) - /* try again */; - if (result < 0) { - result = errno; - fclose(f); - return errh->error("locking %s: %s", map_file.c_str(), strerror(result)); - } - } -#endif - - // read old data from map file - StringAccum sa; - int amt; - do { - if (char *x = sa.reserve(8192)) { - amt = fread(x, 1, 8192, f); - sa.adjust_length(amt); - } else - amt = 0; - } while (amt != 0); - if (!feof(f)) - return errh->error("%s: %s", map_file.c_str(), strerror(errno)); - String text = sa.take_string(); - - // add comment if necessary - bool created = (!text); - if (created) - text = "% Automatically maintained by otftotfm or other programs. Do not edit.\n\n"; - if (text.back() != '\n') - text += "\n"; - - // append old encodings - int fl = 0; - int nl = text.find_left('\n') + 1; - bool changed = created; - while (fl < text.length()) { - if (fl + fontname.length() + 1 < nl - && memcmp(text.data() + fl, fontname.data(), fontname.length()) == 0 - && text[fl + fontname.length()] == ' ') { - // found the old name - if (text.substring(fl, nl - fl) == mapline) { - // duplicate of old name, don't change it - fclose(f); - if (verbose) - errh->message("%s unchanged", map_file.c_str()); - return 0; - } else { - text = text.substring(0, fl) + text.substring(nl); - nl = fl; - changed = true; - } - } - fl = nl; - nl = text.find_left('\n', fl) + 1; - } - - if (!mapline && !changed) { - // special case: empty mapline, unchanged file - if (verbose) - errh->message("%s unchanged", map_file.c_str()); - } else { - // add our text - text += mapline; - - // rewind file -#if HAVE_FTRUNCATE - rewind(f); - if (ftruncate(fd, 0) < 0) -#endif - { - fclose(f); - f = fopen(map_file.c_str(), "wb"); - fd = fileno(f); - } - - // write data - ignore_result(fwrite(text.data(), 1, text.length(), f)); - } - - fclose(f); - - // inform about the new file if necessary - if (created) - update_odir(O_MAP, map_file, errh); - -#if HAVE_KPATHSEA && !WIN32 - // run 'updmap' if present - String updmap_prog = output_flags & G_UPDMAP_USER ? "updmap-user" : "updmap-sys"; - String updmap_dir, updmap_file; - if (automatic && (output_flags & G_UPDMAP)) - updmap_dir = getodir(O_MAP_PARENT, errh); - if (updmap_dir - && (updmap_file = updmap_dir + "/" + updmap_prog) - && access(updmap_file.c_str(), X_OK) >= 0) { - // want to run `updmap` from its directory, can't use system() - if (verbose) - errh->message("running %s", updmap_file.c_str()); - - pid_t child = fork(); - if (child < 0) - errh->fatal("%s during fork", strerror(errno)); - else if (child == 0) { - // change to updmap directory, run it - if (chdir(updmap_dir.c_str()) < 0) - errh->fatal("%s: %s during chdir", updmap_dir.c_str(), strerror(errno)); - if (execl(output_flags & G_UPDMAP_USER ? "./updmap-user" : "./updmap-sys", - updmap_file.c_str(), - (const char*) 0) < 0) - errh->fatal("%s: %s during exec", updmap_file.c_str(), strerror(errno)); - exit(1); // should never get here - } - -# if HAVE_WAITPID - // wait for updmap to finish - int status; - while (1) { - pid_t answer = waitpid(child, &status, 0); - if (answer >= 0) - break; - else if (errno != EINTR) - errh->fatal("%s during wait", strerror(errno)); - } - if (!WIFEXITED(status)) - errh->warning("%s exited abnormally", updmap_file.c_str()); - else if (WEXITSTATUS(status) != 0) - errh->warning("%s exited with status %d", updmap_file.c_str(), WEXITSTATUS(status)); -# else -# error "need waitpid() support: report this bug to the maintainer" -# endif - goto ran_updmap; - } - -# if HAVE_AUTO_UPDMAP - // run system updmap - if (output_flags & G_UPDMAP) { - String filename = map_file; - int slash = filename.find_right('/'); - if (slash >= 0) - filename = filename.substring(slash + 1); - String redirect = verbose ? " 1>&2" : " >" DEV_NULL " 2>&1"; - String command = updmap_prog + " --nomkmap --enable Map " + shell_quote(filename) + redirect - + CMD_SEP " " + updmap_prog + redirect; - int retval = mysystem(command.c_str(), errh); - if (retval == 127) - errh->warning("could not run %<%s%>", command.c_str()); - else if (retval < 0) - errh->warning("could not run %<%s%>: %s", command.c_str(), strerror(errno)); - else if (retval != 0) - errh->warning("%<%s%> exited with status %d;\nrun it manually to check for errors", command.c_str(), WEXITSTATUS(retval)); - goto ran_updmap; - } -# endif - - if (verbose) - errh->message("not running updmap"); - - ran_updmap: ; -#endif - } - - return 0; -} - -String -locate_encoding(String encfile, ErrorHandler *errh, bool literal) -{ - if (!encfile || encfile == "-") - return encfile; - - if (!literal) { - int slash = encfile.find_right('/'); - int dot = encfile.find_left('.', slash >= 0 ? slash : 0); - if (dot < 0) - if (String file = locate_encoding(encfile + ".enc", errh, true)) - return file; - } - -#if HAVE_KPATHSEA - if (String file = kpsei_string(kpsei_find_file(encfile.c_str(), KPSEI_FMT_ENCODING))) { - if (verbose) - errh->message("encoding file %s found with kpathsea at %s", encfile.c_str(), file.c_str()); - return file; - } else if (verbose) - errh->message("encoding file %s not found with kpathsea", encfile.c_str()); -#endif - - if (access(encfile.c_str(), R_OK) >= 0) - return encfile; - else - return String(); -} |