diff options
Diffstat (limited to 'Build/source/texk/cjkutils/cjkutils-4.8.3/hbf2gf/emtexdir.c')
-rw-r--r-- | Build/source/texk/cjkutils/cjkutils-4.8.3/hbf2gf/emtexdir.c | 405 |
1 files changed, 405 insertions, 0 deletions
diff --git a/Build/source/texk/cjkutils/cjkutils-4.8.3/hbf2gf/emtexdir.c b/Build/source/texk/cjkutils/cjkutils-4.8.3/hbf2gf/emtexdir.c new file mode 100644 index 00000000000..9a35570adb3 --- /dev/null +++ b/Build/source/texk/cjkutils/cjkutils-4.8.3/hbf2gf/emtexdir.c @@ -0,0 +1,405 @@ +/* emtexdir.c -- written by Eberhard Mattes, donated to the public domain */ + +#if defined (__EMX__) +#include <emx/syscalls.h> +#else +#include "emdir.h" +#endif +#if defined(DJGPP) || defined(GO32) +#include <unistd.h> +#endif +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <io.h> +#include "emtexdir.h" + +#define FALSE 0 +#define TRUE 1 + +void (*emtex_dir_find_callback)(const char *name, int ok) = NULL; + +static int setup_add (struct emtex_dir *dst, const char *path) +{ + char *p; + + if (dst->used >= dst->alloc) + { + dst->alloc += 8; + dst->list = realloc (dst->list, dst->alloc * sizeof (*dst->list)); + if (dst->list == NULL) + return (FALSE); + } + p = strdup (path); + if (p == NULL) + return (FALSE); + dst->list[dst->used++] = p; + return (TRUE); +} + + +static int setup_subdir (struct emtex_dir *dst, char *path, size_t add, + unsigned flags, int recurse) +{ + int ok, i, end, len; +#if defined (__EMX__) + struct _find find; +#else + struct ll_findbuffer find; +#endif + + i = dst->used; + strcpy (path + add, "*.*"); +#if defined (__EMX__) + ok = __findfirst (path, 0x10, &find) == 0; +#else + ok = ll_findfirst (path, 0x10, &find); +#endif + while (ok) + { + if ((find.attr & 0x10) + && !(strcmp (find.name, ".") == 0 || strcmp (find.name, "..") == 0)) + { + len = strlen (find.name); + memcpy (path + add, find.name, len); + path[add+len] = '\\'; + path[add+len+1] = 0; + if (!setup_add (dst, path)) + return (FALSE); + } +#if defined (__EMX__) + ok = __findnext (&find) == 0; +#else + ok = ll_findnext (&find); +#endif + } + if (recurse) + { + end = dst->used; + while (i < end) + { + strcpy (path, dst->list[i]); + if (!setup_subdir (dst, path, strlen (path), flags, TRUE)) + return (FALSE); + ++i; + } + } + return (TRUE); +} + + +static int setup_dir (struct emtex_dir *dst, char *path, + const char *base_dir, size_t base_dir_len, + const char *sub_dir, + unsigned flags) +{ + size_t i, len; + + memcpy (path, base_dir, base_dir_len); + i = base_dir_len; + if ((flags & EDS_BANG) && sub_dir == NULL) + { + flags &= ~(EDS_ONESUBDIR|EDS_ALLSUBDIR); + if (i >= 2 && path[i-1] == '!' && path[i-2] == '!') + { + flags |= EDS_ALLSUBDIR; + i -= 2; + } + else if (i >= 1 && path[i-1] == '!') + { + flags |= EDS_ONESUBDIR; + --i; + } + } + if (sub_dir != NULL && *sub_dir != 0) + { + if (i != 0 && path[i-1] != ':' && path[i-1] != '/' && path[i-1] != '\\') + path[i++] = '\\'; + len = strlen (sub_dir); + memcpy (path+i, sub_dir, len); + i += len; + } + if (path[i-1] != ':' && path[i-1] != '/' && path[i-1] != '\\') + path[i++] = '\\'; + path[i] = 0; + if (!setup_add (dst, path)) + return (FALSE); + if (flags & EDS_ALLSUBDIR) + return (setup_subdir (dst, path, i, flags, TRUE)); + else if (flags & EDS_ONESUBDIR) + return (setup_subdir (dst, path, i, flags, FALSE)); + else + return (TRUE); +} + + +/*static */int setup_list (struct emtex_dir *dst, char *path, + const char *list, unsigned flags) +{ + const char *end; + size_t i; + + for (;;) + { + while (*list == ' ' || *list == '\t') + ++list; + if (*list == 0) + return (TRUE); + end = list; + while (*end != 0 && *end != ';') + ++end; + i = end - list; + while (i > 0 && (list[i-1] == ' ' || list[i-1] == '\t')) + --i; + if (i != 0 && !setup_dir (dst, path, list, i, NULL, flags)) + return (FALSE); + if (*end == 0) + return (TRUE); + list = end + 1; + } +} + + +int emtex_dir_setup (struct emtex_dir *ed, const char *env, const char *dir, + unsigned flags) +{ + const char *val; + char path[260]; + + ed->alloc = 0; + ed->used = 0; + ed->list = NULL; + if (env != NULL && (val = getenv (env)) != NULL) + return (setup_list (ed, path, val, flags)); + else if ((val = getenv ("EMTEXDIR")) != NULL) + return (setup_dir (ed, path, val, strlen (val), dir, flags)); + else + return (setup_dir (ed, path, "\\emtex", 6, dir, flags)); +} + + +static void pretty (char *path, unsigned flags) +{ + char *p; + + if (flags & EDF_FSLASH) + for (p = path; *p != 0; ++p) + if (*p == '\\') + *p = '/'; +} + + +#define ADDCHAR(C) \ + if (dst_size < 1) return (EDT_TOOLONG); \ + *dst++ = (C); --dst_size + +int emtex_dir_trunc (char *dst, size_t dst_size, const char *src, + unsigned flags, int method) +{ + int len, truncated, dot; + + if (src[0] != 0 && src[1] == ':') + { + ADDCHAR (src[0]); + ADDCHAR (src[1]); + src += 2; + } + + truncated = FALSE; dot = FALSE; len = 0; + for (;;) + { + switch (*src) + { + case 0: + ADDCHAR (0); + return (truncated ? EDT_CHANGED : EDT_UNCHANGED); + + case ':': + return (EDT_INVALID); + + case '/': + case '\\': + ADDCHAR (*src); + len = 0; dot = FALSE; + break; + + case '.': + if (dot) + return (EDT_INVALID); + ADDCHAR (*src); + + /* ".." is allowed -- don't return EDT_INVALID for the next + dot. */ + + if (!(len == 0 && src[1] == '.' + && (src[2] == 0 || src[2] == '/' || src[2] == '\\'))) + { + len = 0; dot = TRUE; + } + break; + + default: + if (dot && len == 3) + truncated = TRUE; + else if (!dot && len == 8) + { + truncated = TRUE; + if (method == 0) + { + dst[-3] = dst[-2]; + dst[-2] = dst[-1]; + dst[-1] = *src; + } + } + else + { + ADDCHAR (*src); + ++len; + } + break; + } + ++src; + } +} + + +static int find2 (const char *name, unsigned flags) +{ + int ok; + + ok = (access (name, 4) == 0); + if (flags & EDF_TRACE) + emtex_dir_find_callback (name, ok); + return (ok); +} + + +static int find1 (char *path, size_t path_size, const char *dir, + const char *fname, unsigned flags) +{ + char buf[260]; + int method, rc; + size_t len, tmp; + + len = 0; + if (dir != NULL) + { + tmp = strlen (dir); + if (tmp >= sizeof (buf)) + return (FALSE); + memcpy (buf, dir, tmp); + len = tmp; + } + tmp = strlen (fname); + if (len + tmp >= sizeof (buf)) + return (FALSE); + memcpy (buf + len, fname, tmp + 1); + len += tmp; +#if 0 /* wkim */ +/* disabled for Win95's long file name support */ +/* -- Wonkoo Kim (wkim+@pitt.edu), May 18, 1997 */ + if (_osmode == DOS_MODE) + { + rc = emtex_dir_trunc (path, path_size, buf, flags, EDT_5_PLUS_3); + if ((rc == EDT_UNCHANGED || rc == EDT_CHANGED) && find2 (path, flags)) + { + pretty (path, flags); + return (TRUE); + } + rc = emtex_dir_trunc (path, path_size, buf, flags, EDT_8); + if (rc == EDT_CHANGED && find2 (path, flags)) + { + pretty (path, flags); + return (TRUE); + } + return (FALSE); + } + else +#endif /* wkim */ + { + if (len < path_size && find2 (buf, flags)) + { + memcpy (path, buf, len + 1); + pretty (path, flags); + return (TRUE); + } + for (method = 0; method < 2; ++method) + { + rc = emtex_dir_trunc (path, path_size, buf, flags, method); + if (rc == EDT_CHANGED && find2 (path, flags)) + { + pretty (path, flags); + return (TRUE); + } + } + return (FALSE); + } +} + + +int emtex_dir_find (char *path, size_t path_size, + const struct emtex_dir *ed, + const char *fname, unsigned flags) +{ + int i, absp; + const char *p; + + absp = FALSE; + for (p = fname; *p != 0; ++p) + if (*p == ':' || *p == '/' || *p == '\\') + { + absp = TRUE; + break; + } + + if (absp) + return (find1 (path, path_size, NULL, fname, flags)); + + if ((flags & EDF_CWD) && find1 (path, path_size, NULL, fname, flags)) + return (TRUE); + + for (i = 0; i < ed->used; ++i) + if (find1 (path, path_size, ed->list[i], fname, flags)) + return (TRUE); + return (FALSE); +} + + +#if defined (TEST) + +#include <stdio.h> + +int main (int argc, char *argv[]) +{ + struct emtex_dir ed; + int i; + unsigned flags1, flags2; + char path[260]; + + if (argc != 6) + { + puts ("Usage: emtexdir <flags> <flags> <env> <dir> <fname>"); + return (1); + } + + flags1 = (unsigned)strtol (argv[1], NULL, 0); + flags2 = (unsigned)strtol (argv[2], NULL, 0); + + if (!emtex_dir_setup (&ed, argv[3], argv[4], flags1)) + { + fputs ("emtex_dir_setup failed\n", stderr); + return (2); + } + + printf ("Directories:\n"); + for (i = 0; i < ed.used; ++i) + printf (" %s\n", ed.list[i]); + + if (!emtex_dir_find (path, sizeof (path), &ed, argv[5], flags2)) + puts ("File not found"); + else + printf ("Path: %s\n", path); + return (0); +} + +#endif |