const_string xbasename (const_string name) { const_string base = name; const_string p; if (NAME_BEGINS_WITH_DEVICE(name)) base += 2; else if (IS_UNC_NAME(name)) { unsigned limit; for (limit = 2; name[limit] && !IS_DIR_SEP (name[limit]); limit++) ; if (name[limit++] && name[limit] && !IS_DIR_SEP (name[limit])) { for (; name[limit] && !IS_DIR_SEP (name[limit]); limit++) ; } else /* malformed UNC name, backup */ limit = 0; base += limit; } for (p = base; *p; p++) { if (IS_DIR_SEP(*p)) base = p + 1; #if defined(WIN32) && defined (KPSE_COMPAT_API) else if (IS_KANJI(p)) p++; #endif } return base; }
main (int ac, string *av) #endif { # ifdef __EMX__ _wildcard(&ac, &av); _response(&ac, &av); # endif # ifdef WIN32 # ifdef _MSC_VER _set_invalid_parameter_handler(myInvalidParameterHandler); # endif av[0] = kpse_program_basename (av[0]); _setmaxstdio(2048); /* We choose to crash for fatal errors: SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); */ setmode(fileno(stdin), _O_BINARY); # endif lua_initialize(ac, av); # ifdef WIN32 if (ac > 1) { char *pp; if ((strlen(av[ac-1]) > 2) && isalpha(av[ac-1][0]) && (av[ac-1][1] == ':') && (av[ac-1][2] == '\\')) { for (pp=av[ac-1]+2; *pp; pp++) { if (IS_KANJI(pp)) { pp++; continue; } if (*pp == '\\') *pp = '/'; } } } # endif /* Call the real main program. */ main_body(); return EXIT_SUCCESS; }
static unsigned hash (hash_table_type table, const_string key) { unsigned n = 0; /* Our keys aren't often anagrams of each other, so no point in weighting the characters. */ while (*key != 0) #if defined (WIN32) && defined (KPSE_COMPAT_API) if (IS_KANJI(key)) { n = (n + n + (unsigned)(*key++)) % table.size; n = (n + n + (unsigned)(*key++)) % table.size; } else #endif n = (n + n + TRANSFORM (*key++)) % table.size; return n; }
char * get_home_directory() { char *p; char *home = getenv("HOME"); if(!home) home = getenv("USERPROFILE"); if(home) { home = xstrdup(home); for(p = home; *p; p++) { if(IS_KANJI(p)) { p++; continue; } if(*p == '\\') *p = '/'; } } return home; }
unsigned kpathsea_normalize_path (kpathsea kpse, string elt) { unsigned ret; unsigned i; #if defined(WIN32) for (i = 0; elt[i]; i++) { if (elt[i] == '\\') elt[i] = '/'; else if (IS_KANJI(elt + i)) i++; } #endif if (NAME_BEGINS_WITH_DEVICE(elt)) { if (*elt >= 'A' && *elt <= 'Z') *elt += 'a' - 'A'; ret = 2; } else if (IS_UNC_NAME(elt)) { for (ret = 2; elt[ret] && !IS_DIR_SEP_CH(elt[ret]); ret++) ; } else ret = 0; for (i = ret; IS_DIR_SEP_CH(elt[i]); ++i) ; if (i > ret + 1) { #ifdef KPSE_DEBUG if (KPATHSEA_DEBUG_P (KPSE_DEBUG_STAT)) DEBUGF2 ("kpse_normalize_path (%s) => %u\n", elt, ret); #endif /* KPSE_DEBUG */ memmove (elt + ret + 1, elt + i, strlen (elt + i) + 1); } return ret; }
int main (int ac, char **av) { char rbuff[TBUF]; char buff[TBUF]; char savebuff[TBUF]; char cmd[TBUF]; char mffile[TBUF]; char *arg[4]; static char execfile[TBUF]; char kpsedot[TBUF]; char currdir[TBUF]; char *tmp; int cdrive, tdrive; FILE *fr, *fw, *fnul; int i, savo, savi; char *p, *fp, *fpp; int issetdest; char fontname[TBUF]; char texbindir[TBUF]; char fullbin[TBUF]; kpse_set_program_name (av[0], NULL); progname = kpse_program_name; /* * get tex binary dir * */ p = kpse_var_value("SELFAUTOLOC"); if(p == 0) { fprintf(stderr, "I cannot get SELFAUTOLOC\n"); exit(100); } strcpy(texbindir, p); free(p); for(p=texbindir; *p; p++) { if(*p == '/') *p = '\\'; } *p = '\\'; *(p+1) = '\0'; tmp = getenv ("TEMP"); if (!tmp) tmp = getenv ("TMP"); if (!tmp) tmp = getenv ("TMPDIR"); if (!tmp) { fprintf (stderr, "Please define TEMP | TMP | TMPDIR.\n"); return (100); } tmp = xstrdup(tmp); for (fpp = tmp; *fpp; fpp++) { if (IS_KANJI(fpp)) fpp++; else if (*fpp == '\\') *fpp = '/'; } /* issetdest = 0 : TDS issetdest = 1 : user setting issetdest = 2 : current directory */ issetdest = 0; if (ac < 2) { usage (); free(tmp); return (100); } if ((!strcmp (av[1], "--version")) || (!strcmp (av[1], "-version"))) { version (); free(tmp); return (100); } if ((!strcmp (av[1], "--help")) || (!strcmp (av[1], "-help"))) { help (); free(tmp); return (100); } for (i = 0; i < 4; i++) arg[i] = (char *) malloc (TBUF); if ((!strcmp (av[1], "--destdir")) || (!strcmp (av[1], "-destdir"))) { if (ac != 4) { usage (); relmem (arg); free(tmp); return (100); } issetdest = 1; if (strlen(av[2]) > TBUF - 1 || strlen(av[3]) > TBUF - 1) { fprintf (stderr, "Too long a string.\n"); return (100); } strcpy (buff, av[2]); strcpy (fontname, av[3]); for (p = buff; *p; p++) { if (IS_KANJI(p)) p++; else if (*p == '\\') *p = '/'; } } else { if (strlen(av[1]) > TBUF - 1) { fprintf (stderr, "Too long a string.\n"); return (100); } strcpy (fontname, av[1]); } /* fontname = font name */ if ((p = strrchr (fontname, '.'))) *p = '\0'; /* mffile is METAFONT file name */ strcpy (mffile, fontname); strcat (mffile, ".mf"); if (!(fp = kpse_var_value ("MFINPUTS"))) { fprintf (stderr, "Cannot get value of MFINPUTS\n"); relmem (arg); free(tmp); return (100); } free (fp); xputenv("MKTEXMF", "1"); if (!(p = kpse_find_file (mffile, kpse_mf_format, 1))) { fprintf (stderr, "Cannot find %s.\n", mffile); relmem (arg); free(tmp); return (100); } fpp = _getcwd (currdir, TBUF); if (!fpp) { fprintf (stderr, "Failed to get current working directory.\n"); relmem (arg); free(tmp); return (100); } for (fpp = currdir; *fpp; fpp++) { if (IS_KANJI(fpp)) fpp++; else if (*fpp == '\\') *fpp = '/'; } i = (int)strlen (currdir); if (currdir[i - 1] == '/') currdir[i - 1] = '\0'; strcpy (kpsedot, "KPSE_DOT=.;"); strcat (kpsedot, currdir); _putenv (kpsedot); if ((p[0] == '.') && (p[1] == '/') && (issetdest != 1)) { issetdest = 2; strcpy (buff, currdir); } if (issetdest == 0) { /* now path of ${name}.mf is in p */ strcpy (arg[0], "Dummy"); strcpy (arg[1], "tfm"); strcpy (arg[2], p); if (!(p = getdestdir (3, arg))) { fprintf (stderr, "Cannot get destination directory name.\n"); relmem (arg); free(tmp); return (100); } strcpy (buff, p); } /* Now buff is the destdir */ p = buff; i = (int)strlen (p); if (p[i - 1] != '/') strcat (p, "/"); strcat (p, fontname); strcat (p, ".tfm"); /* now p (or buff) is the full path name of the tfm font */ /* check if it exists */ if (_access (p, 0) == 0) { fprintf (stderr, "%s exists\n", p); printf ("%s\n", p); relmem (arg); free(tmp); return (0); } cdrive = _getdrive (); if (tmp[1] == ':') { tdrive = tolower (*tmp) - 'a' + 1; _chdrive (tdrive); } _chdir (tmp); /* save stdout and stdin */ savo = _dup (fileno (stdout)); savi = _dup (fileno (stdin)); /* connect stdout to stderr */ _dup2 (fileno (stderr), fileno (stdout)); /* connect stdin to nul device */ if (!(fnul = fopen ("nul", "r"))) { fprintf (stderr, "Cannot open nul device to read\n"); relmem (arg); _chdrive (cdrive); _chdir (currdir); free(tmp); return (100); } _dup2 (fileno (fnul), fileno (stdin)); /* METAFONT command line */ strcpy (cmd, "--progname=mf --base=mf "); strcat (cmd, "\\mode:=ljfour; \\mag:=1; nonstopmode; input "); strcat (cmd, fontname); strcat (cmd, ";"); strcpy (execfile, "mf-nowin.exe"); fprintf (stderr, "%s %s\n", execfile, cmd); strcpy(fullbin, texbindir); strcat(fullbin, execfile); (void) _spawnlp (_P_WAIT, fullbin, execfile, cmd, NULL); /* return to original stdout and stdin */ _dup2 (savo, fileno (stdout)); close (savo); _dup2 (savi, fileno (stdin)); close (savi); /* close nul device */ fclose (fnul); /* check consistency */ strcpy (cmd, fontname); strcat (cmd, ".600gf"); if (_access (cmd, 0) == -1) { fprintf (stderr, "METAFONT failed to make gf font.\n"); relmem (arg); _chdrive (cdrive); _chdir (currdir); free(tmp); return (100); } remove (cmd); strcpy (cmd, fontname); strcat (cmd, ".tfm"); /* copy the tfm file */ if (!(fr = fopen (cmd, "rb"))) { fprintf (stderr, "Cannot open %s to read\n", cmd); _chdrive (cdrive); _chdir (currdir); relmem (arg); free(tmp); return (100); } if (!(fw = fopen (buff, "wb"))) { fprintf (stderr, "Cannot open %s to write\n", buff); _chdrive (cdrive); _chdir (currdir); relmem (arg); free(tmp); return (100); } while ((i = (int)fread (rbuff, 1, TBUF, fr))) fwrite (rbuff, 1, i, fw); fclose (fr); fclose (fw); strcpy(savebuff, buff); /* copy log file into the current directory in the case that issetdest == 2, because feynmf package requires the log file. */ if(issetdest == 2) { i = (int)strlen(buff); if(i > 3) { i -= 4; buff[i] = '\0'; strcat(buff, ".log"); strcpy(cmd, fontname); strcat(cmd, ".log"); if (!(fr = fopen (cmd, "rb"))) { fprintf (stderr, "Cannot open %s to read\n", cmd); _chdrive (cdrive); _chdir (currdir); relmem (arg); free(tmp); return (100); } if (!(fw = fopen (buff, "wb"))) { fprintf (stderr, "Cannot open %s to write\n", buff); _chdrive (cdrive); _chdir (currdir); relmem (arg); free(tmp); return (100); } while ((i = (int)fread (rbuff, 1, TBUF, fr))) fwrite (rbuff, 1, i, fw); fclose (fr); fclose (fw); } } relmem (arg); if(issetdest != 2) mktexupd (savebuff); /* erase files */ strcpy (cmd, fontname); strcat (cmd, ".log"); remove (cmd); strcpy (cmd, fontname); strcat (cmd, ".tfm"); remove (cmd); _chdrive (cdrive); _chdir (currdir); /* send message to Kpathsea */ printf ("%s\n", savebuff); free(tmp); return (0); }
int getlongpath(char *buff, char *input, int len) { HANDLE hnd; WIN32_FIND_DATA ffd; int cnt = 0; char *p, *q, *r; buff[0] = '\0'; /* temporarily change directory separators into back slashs */ for(p = input; *p; p++) { if(*p == '/') *p = '\\'; } p = q = input; r = buff; /* UNC name */ if(q[0] == '\\' && q[1] == '\\') { cnt += 2; if(cnt > len) return 0; buff[0] = '/'; buff[1] = '/'; p += 2; r += 2; while(*p != '\\' && *p) { if (IS_KANJI(p)) { cnt++; if(cnt > len) return 0; *r++ = *p++; } cnt++; if(cnt > len) return 0; *r++ = *p++; } cnt++; if(cnt > len) return 0; *r++ = '/'; if(*p) p++; while(*p != '\\' && *p) { if (IS_KANJI(p)) { cnt++; if(cnt > len) return 0; *r++ = *p++; } cnt++; if(cnt > len) return 0; *r++ = *p++; } cnt++; if(cnt > len) return 0; *r++ = '/'; *r= '\0'; if(*p) p++; /* drive name */ } else if(isalpha(q[0]) && q[1] == ':' && q[2] == '\\') { *r++ = q[0]; *r++ = ':'; *r++ = '/'; *r = '\0'; p += 3; cnt += 3; if(cnt > len) return 0; } for( ; *p; p++) { if(IS_KANJI(p)) { p++; continue; } if(*p == '\\') { *p = '\0'; if((hnd = FindFirstFile(q, &ffd)) == INVALID_HANDLE_VALUE) { return 0; } FindClose(hnd); cnt += strlen(ffd.cFileName); cnt++; if(cnt > len) return 0; strcat(buff, ffd.cFileName); strcat(buff, "/"); *p = '\\'; } } /* file itself */ if((hnd = FindFirstFile(q, &ffd)) == INVALID_HANDLE_VALUE) { return 0; } FindClose(hnd); cnt += strlen(ffd.cFileName); if(cnt > len) return 0; strcat(buff, ffd.cFileName); return 1; }
string xdirname (const_string name) { string ret; unsigned limit = 0, loc; #if defined(WIN32) string p; unsigned i, j; #endif /* Ignore a NULL name. */ if (!name) return NULL; if (NAME_BEGINS_WITH_DEVICE(name)) { limit = 2; } else if (IS_UNC_NAME(name)) { for (limit = 2; name[limit] && !IS_DIR_SEP (name[limit]); limit++) #if defined(WIN32) && defined(KPSE_COMPAT_API) if (IS_KANJI(name+limit)) limit++ #endif ; if (name[limit++] && name[limit] && !IS_DIR_SEP (name[limit])) { for (; name[limit] && !IS_DIR_SEP (name[limit]); limit++) #if defined(WIN32) && defined(KPSE_COMPAT_API) if (IS_KANJI(name+limit)) limit++ #endif ; limit--; } else /* malformed UNC name, backup */ limit = 0; } #if defined(WIN32) j = loc = limit; if (j > 2) j++; for (i = j; name[i]; i++) { if (IS_DIR_SEP (name[i])) { j = i; for (i++; IS_DIR_SEP (name[i]); i++) ; loc = i + 1; } #if defined (KPSE_COMPAT_API) else if (IS_KANJI(name+i)) i++; #endif } #else for (loc = strlen (name); loc > limit && !IS_DIR_SEP (name[loc-1]); loc--) ; #endif if (loc == limit) { if (limit == 0) ret = xstrdup ("."); else if (limit == 2) { ret = (string)xmalloc(4); ret[0] = name[0]; ret[1] = name[1]; ret[2] = '.'; ret[3] = '\0'; } else { /* UNC name is "//server/share". */ ret = xstrdup (name); } } else { /* If have ///a, must return /, so don't strip off everything. */ #if defined(WIN32) loc = j; if (loc == limit && IS_DIR_SEP (name[loc])) loc++; #else while (loc > limit+1 && IS_DIR_SEP (name[loc-1])) { loc--; } #endif ret = (string)xmalloc(loc+1); strncpy(ret, name, loc); ret[loc] = '\0'; } #if defined(WIN32) for (p = ret; *p; p++) { if (*p == '\\') *p = '/'; #if defined (KPSE_COMPAT_API) else if (IS_KANJI(p)) p++; #endif } #endif return ret; }
char * getdestdir (int ac, char **av) { static char buff[MPATH]; char *pb[NUMBUF]; char *p, *q; char spec[32]; int i, Num = 0, ispk, k; char *topdir; ispk = 0; for (i = 0; i < NUMBUF; i++) { if (!(pb[i] = (char *) malloc (LENBUF))) { fatal ("Memory allocation error."); return (NULL); } } if (ac != 3 && ac != 4) { fatal ("Argument error."); for (k = 0; k < NUMBUF; k++) free (pb[k]); return (NULL); } strcpy (spec, av[1]); for (p = av[2]; *p; p++) { /* path */ if (*p == '\\') *p = '/'; else if (IS_KANJI(p)) p++; } p = av[2]; q = buff; /* UNC name support */ if (p[0] == '/' && p[1] == '/') { *q++ = *p++; *q++ = *p++; } while (*p) { if (*p == '/') { *q = *p; while (*p == '/') p++; p--; } else { *q = *p; } p++; q++; } *q = '\0'; /* now path name of ${name}.mf is in buff. */ /* #ifdef TEST return xstrdup(buff); #endif */ if (ac == 4) ispk = 1; /* called from mktexpk */ if (!(p = strrchr (buff, '/'))) { fatal ("Invalid path name."); for (k = 0; k < NUMBUF; k++) free (pb[k]); return (NULL); } *p = '\0'; /* get directory name */ for (i = 0; i < NUMBUF; i++) { if (!(p = strrchr (buff, '/'))) { fatal ("Invalid path name."); for (k = 0; k < NUMBUF; k++) free (pb[k]); return (NULL); } *p = '\0'; p++; strcpy (pb[i], p); if (!stricmp (pb[i], FTOP)) { Num = i; break; } } Num -= 2; if (Num < 0) { fprintf (stderr, "Font resources should be under a directory "); fprintf (stderr, "with the name \"fonts\".\n"); fprintf (stderr, "Furthermore, there must be at least two directories "); fprintf (stderr, "under the directory \"fonts\".\n"); fatal ("Invalid path name."); for (k = 0; k < NUMBUF; k++) free (pb[k]); return (NULL); } topdir = kpse_var_value ("MAKETEXPK_TOP_DIR"); if (topdir && *topdir && ispk) { for (i = 0; topdir[i]; i++) { if (topdir[i] == '\\') topdir[i] = '/'; else if (IS_KANJI(topdir+i)) i++; } i = strlen (topdir); while(topdir[i - 1] == '/') i--; topdir[i] = '\0'; if(!is_dir(topdir)) { if(make_dir_p(topdir)) { fprintf(stderr, "Failed to access %s.\n", topdir); return NULL; } } #ifdef TEST printf ("%s\n", topdir); #endif if (strnicmp (&topdir[i - 3], "/pk", 3) != 0) { strcat (topdir, "/pk"); if (!is_dir(topdir)) { if (make_dir(topdir)) { fprintf(stderr, "Faild to access %s.\n", topdir); for (k = 0; k < NUMBUF; k++) free (pb[k]); return (NULL); } } } strcpy (buff, topdir); free(topdir); } else { if((topdir = kpse_var_value("TEXMFVAR")) != NULL) { for (i = 0; topdir[i]; i++) { if (topdir[i] == '\\') topdir[i] = '/'; else if (IS_KANJI(topdir+i)) i++; } i = strlen (topdir); while(topdir[i - 1] == '/') i--; topdir[i] = '\0'; if(!is_dir(topdir)) { if(make_dir_p(topdir)) { fprintf(stderr, "Failed to access %s.\n", topdir); return NULL; } } strcpy(buff, topdir); free(topdir); } strcat (buff, "/fonts"); if (!is_dir (buff)) { if (make_dir (buff)) { for (k = 0; k < NUMBUF; k++) free (pb[k]); return (NULL); } } strcat (buff, "/"); strcat (buff, spec); if (!is_dir (buff)) { if (make_dir (buff)) { for (k = 0; k < NUMBUF; k++) free (pb[k]); return (NULL); } } } if (ispk) { strcat (buff, "/"); strcat (buff, av[3]); if (!is_dir (buff)) { if (make_dir (buff)) { for (k = 0; k < NUMBUF; k++) free (pb[k]); return (NULL); } } } for (i = Num; i > -1; i--) { strcat (buff, "/"); strcat (buff, pb[i]); if (is_dir (buff)) continue; else { if (make_dir (buff)) { for (k = 0; k < NUMBUF; k++) free (pb[k]); return (NULL); } } } for (k = 0; k < NUMBUF; k++) free (pb[k]); p = xstrdup(buff); return p; }
static void ipc_snd (int n, int is_eof, char *data) { struct { struct msg msg; char more_data[1024]; } ourmsg; if (!ipc_is_open ()) { return; } #ifdef IPC_DEBUG fprintf(stderr, "%d\t%d\n", ourmsg.msg.namelength, ourmsg.msg.eof); fputs ("tex: Sending message to socket ...\n", stderr); #endif ourmsg.msg.namelength = n; ourmsg.msg.eof = is_eof; if (n) { strcpy (ourmsg.more_data, data); } n += sizeof (struct msg); #ifdef IPC_DEBUG fprintf(stderr, "%d\t%d\n", ourmsg.msg.namelength, ourmsg.msg.eof); fputs ("tex: Writing to socket...\n", stderr); #endif #if defined(WIN32) if (send (sock, (char *)&ourmsg, n, 0) != n) { #else if (write (sock, &ourmsg, n) != n) { #endif ipc_close_out (); } #ifdef IPC_DEBUG fputs ("tex: IPC message sent.\n", stderr); #endif } /* This routine notifies the server if there is an eof, or the filename if a new DVI file is starting. This is the routine called by TeX. Aleph defines str_start(#) as str_start_ar[# - too_big_char], with too_big_char = biggest_char + 1 = 65536 (omstr.ch). */ void ipcpage (int is_eof) { static boolean begun = false; unsigned len = 0; string p = NULL; if (!begun) { string name; /* Just the filename. */ string cwd = xgetcwd (); ipc_open_out (); /* Have to pass whole filename to the other end, since it may have been started up and running as a daemon, e.g., as with the NeXT preview program. */ name = static_pdf->file_name; p = concat3 (cwd, DIR_SEP_STRING, name); free (cwd); free (name); #if defined (WIN32) { char *q; for (q = p; *q; q++) { if (*q == '\\') *q = '/'; else if (IS_KANJI(q)) q++; } } #endif len = strlen(p); begun = true; } ipc_snd (len, is_eof, p); if (p) free (p); } #endif /* TeX && IPC */ /* Normalize quoting of filename -- that is, only quote if there is a space, and always use the quote-name-quote style. */ string normalize_quotes(const_string name, const_string mesg) { boolean quoted = false; boolean must_quote = (strchr(name, ' ') != NULL); /* Leave room for quotes and NUL. */ string ret = (string) xmalloc((unsigned) strlen(name) + 3); string p; const_string q; p = ret; if (must_quote) *p++ = '"'; for (q = name; *q; q++) { if (*q == '"') quoted = !quoted; else *p++ = *q; } if (must_quote) *p++ = '"'; *p = '\0'; if (quoted) { fprintf(stderr, "! Unbalanced quotes in %s %s\n", mesg, name); uexit(1); } return ret; }
static boolean db_build (kpathsea kpse, hash_table_type *table, const_string db_filename) { string line; unsigned dir_count = 0, file_count = 0, ignore_dir_count = 0; unsigned len = strlen (db_filename) - sizeof (DB_NAME) + 1; /* Keep the /. */ string top_dir = (string)xmalloc (len + 1); string cur_dir = NULL; /* First thing in ls-R might be a filename. */ FILE *db_file = fopen (db_filename, FOPEN_R_MODE); #if defined(WIN32) string pp; #endif strncpy (top_dir, db_filename, len); top_dir[len] = 0; if (db_file) { while ((line = read_line (db_file)) != NULL) { len = strlen (line); #if defined(WIN32) for (pp = line; *pp; pp++) { if (IS_KANJI(pp)) pp++; else *pp = TRANSFORM(*pp); } #endif /* A line like `/foo:' = new dir foo. Allow both absolute (/...) and explicitly relative (./...) names here. It's a kludge to pass in the directory name with the trailing : still attached, but it doesn't actually hurt. */ if (len > 0 && line[len - 1] == ':' && kpathsea_absolute_p (kpse, line, true)) { /* New directory line. */ if (!ignore_dir_p (line)) { /* If they gave a relative name, prepend full directory name now. */ line[len - 1] = DIR_SEP; /* Skip over leading `./', it confuses `match' and is just a waste of space, anyway. This will lose on `../', but `match' won't work there, either, so it doesn't matter. */ cur_dir = *line == '.' ? concat (top_dir, line + 2) : xstrdup (line); dir_count++; } else { cur_dir = NULL; ignore_dir_count++; } /* Ignore blank, `.' and `..' lines. */ } else if (*line != 0 && cur_dir /* a file line? */ && !(*line == '.' && (line[1] == 0 || (line[1] == '.' && line[2] == 0)))) { /* Make a new hash table entry with a key of `line' and a data of `cur_dir'. An already-existing identical key is ok, since a file named `foo' can be in more than one directory. Share `cur_dir' among all its files (and hence never free it). Note that we assume that all names in the ls-R file have already been case-smashed to lowercase where appropriate. */ hash_insert_normalized (table, xstrdup (line), cur_dir); file_count++; } /* else ignore blank lines or top-level files or files in ignored directories*/ free (line); } xfclose (db_file, db_filename); if (file_count == 0) { WARNING1 ("kpathsea: %s: No usable entries in ls-R", db_filename); WARNING ("kpathsea: See the manual for how to generate ls-R"); db_file = NULL; } else { str_list_add (&(kpse->db_dir_list), xstrdup (top_dir)); } #ifdef KPSE_DEBUG if (KPATHSEA_DEBUG_P (KPSE_DEBUG_HASH)) { /* Don't make this a debugging bit, since the output is so voluminous, and being able to specify -1 is too useful. Instead, let people who want it run the program under a debugger and change the variable that way. */ boolean hash_summary_only = true; DEBUGF4 ("%s: %u entries in %d directories (%d hidden).\n", db_filename, file_count, dir_count, ignore_dir_count); DEBUGF ("ls-R hash table:"); hash_print (*table, hash_summary_only); fflush (stderr); } #endif /* KPSE_DEBUG */ } free (top_dir); return db_file != NULL; }
string xgetcwd (void) { /* If the system provides getcwd, use it. If not, use getwd if available. But provide a way not to use getcwd: on some systems getcwd forks, which is expensive and may in fact be impossible for large programs like tex. If your system needs this define and it is not detected by configure, let me know. -- Olaf Weber <[email protected] */ #if defined (HAVE_GETCWD) && !defined (GETCWD_FORKS) char path[PATH_MAX + 1]; #if defined(WIN32) string pp; #endif if (getcwd (path, PATH_MAX + 1) == NULL) { FATAL_PERROR ("getcwd"); } #if defined(WIN32) for (pp = path; *pp; pp++) { if (*pp == '\\') *pp = '/'; #if defined (KPSE_COMPAT_API) else if (IS_KANJI(pp)) pp++; #endif } #endif return xstrdup (path); #elif defined (HAVE_GETWD) char path[PATH_MAX + 1]; if (getwd (path) == NULL) { FATAL_PERROR ("getwd"); } return xstrdup (path); #else /* (not HAVE_GETCWD || GETCWD_FORKS) && not HAVE_GETWD */ struct stat root_stat, cwd_stat; string cwd_path = (string)xmalloc(2); /* In case we assign "/" below. */ *cwd_path = 0; /* Find the inodes of the root and current directories. */ root_stat = xstat("/"); cwd_stat = xstat("."); /* Go up the directory hierarchy until we get to root, prepending each directory we pass through to `cwd_path'. */ while (!SAME_FILE_P(root_stat, cwd_stat)) { struct dirent *e; DIR *parent_dir; boolean found = false; xchdir(".."); parent_dir = xopendir("."); /* Look through the parent directory for the entry with the same inode, so we can get its name. */ while ((e = readdir (parent_dir)) != NULL && !found) { struct stat test_stat; test_stat = xlstat(e->d_name); if (SAME_FILE_P(test_stat, cwd_stat)) { /* We've found it. Prepend the pathname. */ string temp = cwd_path; cwd_path = concat3("/", e->d_name, cwd_path); free(temp); /* Set up to test the next parent. */ cwd_stat = xstat("."); /* Stop reading this directory. */ found = true; } } if (!found) LIB_FATAL2("No inode %d/device %d in parent directory", cwd_stat.st_ino, cwd_stat.st_dev); xclosedir(parent_dir); } /* If the current directory is the root, cwd_path will be the empty string, and we will have not gone through the loop. */ if (*cwd_path == 0) strcpy(cwd_path, "/"); else /* Go back to where we were. */ xchdir(cwd_path); #ifdef DOSISH /* Prepend the drive letter to CWD_PATH, since this technique never tells us what the drive is. Note that on MS-DOS/MS-Windows, the branch that works around missing `getwd' will probably only work for DJGPP (which does have `getwd'), because only DJGPP reports meaningful st_ino numbers. But someday, somebody might need this... */ { char drive[3]; string temp = cwd_path; /* Make the drive letter lower-case, unless it is beyond Z: (yes, there ARE such drives, in case of Novell Netware on MS-DOS). */ drive[0] = root_stat.st_dev + (root_stat.st_dev < 26 ? 'a' : 'A'); drive[1] = ':'; drive[2] = '\0'; cwd_path = concat(drive, cwd_path); free(temp); } #endif return cwd_path; #endif /* (not HAVE_GETCWD || GETCWD_FORKS) && not HAVE_GETWD */ }