summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreban <eban@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2000-12-18 14:22:37 +0000
committereban <eban@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2000-12-18 14:22:37 +0000
commit8d393f1855483314e98269980a728b44c34c8bea (patch)
tree2b8378da148be0679f0ef0b3f0e88a4a049965b6
parent117b7d5c47f31b02cf891c792f919afceaddd080 (diff)
eban
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1066 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--util.c300
2 files changed, 112 insertions, 193 deletions
diff --git a/ChangeLog b/ChangeLog
index cc61d22c58e..0615966f1a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Mon Dec 18 23:18:39 2000 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * util.c (mblen, __crt0_glob_function): add for multibyte
+ on DJGPP 2.03.
+
Mon Dec 18 18:10:30 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
* time.c (time_plus): usec might underflow (ruby-bugs-ja:#PR33).
diff --git a/util.c b/util.c
index 83c5a943c50..9cbfb5fc74a 100644
--- a/util.c
+++ b/util.c
@@ -299,216 +299,130 @@ valid_filename(char *s)
#endif
#endif
-#ifdef DJGPP
-#include <libc/stubs.h>
-#include <stdio.h> /* For FILENAME_MAX */
-#include <errno.h> /* For errno */
-#include <fcntl.h> /* For LFN stuff */
-#include <go32.h>
-#include <dpmi.h> /* For dpmisim */
-#include <crt0.h> /* For crt0 flags */
-#include <libc/dosio.h>
+#if defined __DJGPP__
-static unsigned use_lfn;
+#include <dpmi.h>
-static char *__get_current_directory(char *out, int drive_number);
+static char dbcs_table[256];
-static char *
-__get_current_directory(char *out, int drive_number)
-{
- __dpmi_regs r;
- char tmpbuf[FILENAME_MAX];
-
- memset(&r, 0, sizeof(r));
- if(use_lfn)
- r.x.ax = 0x7147;
- else
- r.h.ah = 0x47;
- r.h.dl = drive_number + 1;
- r.x.si = __tb_offset;
- r.x.ds = __tb_segment;
- __dpmi_int(0x21, &r);
-
- if (r.x.flags & 1)
- {
- errno = r.x.ax;
- return out;
- }
- else
- {
- dosmemget(__tb, sizeof(tmpbuf), tmpbuf);
- strcpy(out+1,tmpbuf);
-
- /* Root path, don't insert "/", it'll be added later */
- if (*(out + 1) != '\0')
- *out = '/';
- else
- *out = '\0';
- return out + strlen(out);
- }
-}
-
-__inline__ static int
-is_slash(int c)
-{
- return c == '/' || c == '\\';
-}
-
-__inline__ static int
-is_term(int c)
-{
- return c == '/' || c == '\\' || c == '\0';
-}
-
-#ifdef SJIS
-__inline__ static int
-is_sjis1(int c)
-{
- return 0x81 <= c && (c <= 0x9f || 0xe0 <= c);
-}
-#endif
-
-/* Takes as input an arbitrary path. Fixes up the path by:
- 1. Removing consecutive slashes
- 2. Removing trailing slashes
- 3. Making the path absolute if it wasn't already
- 4. Removing "." in the path
- 5. Removing ".." entries in the path (and the directory above them)
- 6. Adding a drive specification if one wasn't there
- 7. Converting all slashes to '/'
- */
-void
-fixpath(const char *in, char *out)
+int
+make_dbcs_table()
{
- int drive_number;
- const char *ip = in;
- char *op = out;
- int preserve_case = _preserve_fncase();
- char *name_start;
-
- use_lfn = _USE_LFN;
-
- /* Add drive specification to output string */
- if (((*ip >= 'a' && *ip <= 'z') ||
- (*ip >= 'A' && *ip <= 'Z'))
- && (*(ip + 1) == ':'))
- {
- if (*ip >= 'a' && *ip <= 'z')
- {
- drive_number = *ip - 'a';
- *op++ = *ip++;
- }
- else
- {
- drive_number = *ip - 'A';
- if (*ip <= 'Z')
- *op++ = drive_number + 'a';
- else
- *op++ = *ip;
- ++ip;
- }
- *op++ = *ip++;
- }
- else
- {
__dpmi_regs r;
- r.h.ah = 0x19;
+ struct {
+ unsigned char start;
+ unsigned char end;
+ } vec;
+ int offset;
+
+ memset(&r, 0, sizeof(r));
+ r.x.ax = 0x6300;
__dpmi_int(0x21, &r);
- drive_number = r.h.al;
- *op++ = drive_number + (drive_number < 26 ? 'a' : 'A');
- *op++ = ':';
- }
-
- /* Convert relative path to absolute */
- if (!is_slash(*ip))
- op = __get_current_directory(op, drive_number);
-
- /* Step through the input path */
- while (*ip)
- {
- /* Skip input slashes */
- if (is_slash(*ip))
- {
- ip++;
- continue;
+ offset = r.x.ds * 16 + r.x.si;
+
+ for (;;) {
+ int i;
+ dosmemget(offset, sizeof vec, &vec);
+ if (!vec.start && !vec.end)
+ break;
+ for (i = vec.start; i <= vec.end; i++)
+ dbcs_table[i] = 1;
+ offset += 2;
}
+}
- /* Skip "." and output nothing */
- if (*ip == '.' && is_term(*(ip + 1)))
- {
- ip++;
- continue;
+int
+mblen(const char *s, size_t n)
+{
+ static int need_init = 1;
+ if (need_init) {
+ make_dbcs_table();
+ need_init = 0;
}
-
- /* Skip ".." and remove previous output directory */
- if (*ip == '.' && *(ip + 1) == '.' && is_term(*(ip + 2)))
- {
- ip += 2;
- /* Don't back up over drive spec */
- if (op > out + 2)
- /* This requires "/" to follow drive spec */
- while (!is_slash(*--op));
- continue;
+ if (s) {
+ if (n == 0 || *s == 0)
+ return 0;
+ return dbcs_table[(unsigned char)*s] + 1;
}
+ else
+ return 1;
+}
- /* Copy path component from in to out */
- *op++ = '/';
-#ifndef SJIS
- while (!is_term(*ip)) *op++ = *ip++;
-#else
- while (!is_term(*ip)) {
- if (is_sjis1((unsigned char)*ip))
- *op++ = *ip++;
- *op++ = *ip++;
- }
-#endif
- }
+struct PathList {
+ struct PathList *next;
+ char *path;
+};
- /* If root directory, insert trailing slash */
- if (op == out + 2) *op++ = '/';
+struct PathInfo {
+ struct PathList *head;
+ int count;
+};
- /* Null terminate the output */
- *op = '\0';
+static void
+push_element(char *path, struct PathInfo *info)
+{
+ struct PathList *p;
+
+ p = ALLOC(struct PathList);
+ MEMZERO(p, struct PathList, 1);
+ p->path = ruby_strdup(path);
+ p->next = info->head;
+ info->head = p;
+ info->count++;
+}
- /* switch FOO\BAR to foo/bar, downcase where appropriate */
- for (op = out + 3, name_start = op - 1; *name_start; op++)
- {
- char long_name[FILENAME_MAX], short_name[13];
+#include <dirent.h>
+int __opendir_flags = __OPENDIR_PRESERVE_CASE;
-#ifdef SJIS
- if (is_sjis1((unsigned char)*op)) {
- op++;
- continue;
- }
-#endif
- if (*op == '\\')
- *op = '/';
- if (!preserve_case && (*op == '/' || *op == '\0'))
- {
- memcpy(long_name, name_start+1, op - name_start - 1);
- long_name[op - name_start - 1] = '\0';
- if (!strcmp(_lfn_gen_short_fname(long_name, short_name), long_name))
- {
-#ifndef SJIS
- while (++name_start < op)
- if (*name_start >= 'A' && *name_start <= 'Z')
- *name_start += 'a' - 'A';
-#else
- while (++name_start < op) {
- if (is_sjis1((unsigned char)*name_start))
- name_start++;
- else if (*name_start >= 'A' && *name_start <= 'Z')
- *name_start += 'a' - 'A';
- }
-#endif
- }
- else
- name_start = op;
+char **
+__crt0_glob_function(char *path)
+{
+ int len = strlen(path);
+ int i;
+ char **rv;
+ char path_buffer[PATH_MAX];
+ char *buf = path_buffer;
+ char *p;
+ struct PathInfo info;
+ struct PathList *plist;
+
+ if (PATH_MAX <= len)
+ buf = ruby_xmalloc(len + 1);
+
+ strncpy(buf, path, len);
+ buf[len] = '\0';
+
+ for (p = buf; *p; p += mblen(p, MB_CUR_MAX))
+ if (*p == '\\')
+ *p = '/';
+
+ info.count = 0;
+ info.head = 0;
+
+ rb_iglob(buf, push_element, (VALUE)&info);
+
+ if (buf != path_buffer)
+ ruby_xfree(buf);
+
+ if (info.count == 0)
+ return 0;
+
+ rv = ruby_xmalloc((info.count + 1) * sizeof (char *));
+
+ plist = info.head;
+ i = 0;
+ while (plist) {
+ struct PathList *cur;
+ rv[i] = plist->path;
+ cur = plist;
+ plist = plist->next;
+ ruby_xfree(cur);
+ i++;
}
- else if (*op == '\0')
- break;
- }
+ rv[i] = 0;
+ return rv;
}
+
#endif
/* mm.c */