1 /* $Id: indep.c,v 1.38 2007/05/23 15:06:05 inu Exp $ */
4 #ifndef __MINGW32_VERSION
6 #endif /* __MINGW32_VERSION */
16 unsigned char QUOTE_MAP[0x100] = {
17 /* NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI */
18 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
19 /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US */
20 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
21 /* SPC ! " # $ % & ' ( ) * + , - . / */
22 24, 72, 76, 40, 8, 40, 41, 72, 72, 72, 72, 40, 72, 8, 0, 64,
23 /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
24 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 72, 74, 72, 75, 40,
25 /* @ A B C D E F G H I J K L M N O */
26 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
27 /* P Q R S T U V W X Y Z [ \ ] ^ _ */
28 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 72, 72, 72, 0,
29 /* ` a b c d e f g h i j k l m n o */
30 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31 /* p q r s t u v w x y z { | } ~ DEL */
32 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 72, 72, 72, 24,
34 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
35 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
36 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
37 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
38 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
39 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
40 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
41 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
44 char *HTML_QUOTE_MAP[] = {
56 strtoclen(const char *s)
59 return strtoll(s, NULL, 10);
60 #elif defined(HAVE_STRTOQ)
61 return strtoq(s, NULL, 10);
62 #elif defined(HAVE_ATOLL)
64 #elif defined(HAVE_ATOQ)
73 bcopy(const void *src, void *dest, int len)
79 for (i = len - 1; i >= 0; i--)
80 ((char *)dest)[i] = ((const char *)src)[i];
82 else { /* src > dest */
83 for (i = 0; i < len; i++)
84 ((char *)dest)[i] = ((const char *)src)[i];
89 bzero(void *ptr, int len)
93 for (i = 0; i < len; i++)
96 #endif /* not HAVE_BCOPY */
99 allocStr(const char *s, int len)
107 ptr = NewAtom_N(char, len + 1);
109 fprintf(stderr, "fm: Can't allocate string. Give me more memory!\n");
118 strCmp(const void *s1, const void *s2)
120 return strcmp(*(const char **)s1, *(const char **)s2);
129 path = NewAtom_N(char, MAXPATHLEN);
130 getcwd(path, MAXPATHLEN);
132 path = getcwd(NULL, 0);
134 #else /* not HAVE_GETCWD */
136 path = NewAtom_N(char, 1024);
138 #else /* not HAVE_GETWD */
141 path = NewAtom_N(char, 1024);
142 f = popen("pwd", "r");
143 fgets(path, 1024, f);
145 for (p = path; *p; p++)
150 #endif /* not HAVE_GETWD */
151 #endif /* not HAVE_GETCWD */
156 cleanupName(char *name)
160 buf = allocStr(name, -1);
164 if (strncmp(p, "/../", 4) == 0) { /* foo/bar/../FOO */
165 if (p - 2 == buf && strncmp(p - 2, "..", 2) == 0) {
170 else if (p - 3 >= buf && strncmp(p - 3, "/..", 3) == 0) {
176 while (p != buf && *--p != '/') ; /* ->foo/FOO */
182 else if (strcmp(p, "/..") == 0) { /* foo/bar/.. */
183 if (p - 2 == buf && strncmp(p - 2, "..", 2) == 0) {
186 else if (p - 3 >= buf && strncmp(p - 3, "/..", 3) == 0) {
190 while (p != buf && *--p != '/') ; /* ->foo/ */
195 else if (strncmp(p, "/./", 3) == 0) { /* foo/./bar */
196 *p = '\0'; /* -> foo/bar */
200 else if (strcmp(p, "/.") == 0) { /* foo/. */
201 *++p = '\0'; /* -> foo/ */
204 else if (strncmp(p, "//", 2) == 0) { /* foo//bar */
219 expandPath(char *name)
222 struct passwd *passent, *getpwnam(const char *);
230 #ifndef __MINGW32_VERSION
232 char *q = strchr(p, '/');
233 if (q) { /* ~user/dir... */
234 passent = getpwnam(allocStr(p, q - p));
238 passent = getpwnam(p);
243 extpath = Strnew_charp(passent->pw_dir);
245 #endif /* __MINGW32_VERSION */
246 if (*p == '/' || *p == '\0') { /* ~/dir... or ~ */
247 extpath = Strnew_charp(getenv("HOME"));
251 if (Strcmp_charp(extpath, "/") == 0 && *p == '/')
253 Strcat_charp(extpath, p);
262 strchr(const char *s, int c)
265 if ((unsigned char)*s == c)
271 #endif /* not HAVE_STRCHR */
273 #ifndef HAVE_STRCASECMP
275 strcasecmp(const char *s1, const char *s2)
279 x = TOLOWER(*s1) - TOLOWER(*s2);
285 return -TOLOWER(*s2);
289 strncasecmp(const char *s1, const char *s2, size_t n)
293 x = TOLOWER(*s1) - TOLOWER(*s2);
300 return n ? -TOLOWER(*s2) : 0;
302 #endif /* not HAVE_STRCASECMP */
304 #ifndef HAVE_STRCASESTR
305 /* string search using the simplest algorithm */
307 strcasestr(const char *s1, const char *s2)
316 while (*s1 && len1 >= len2) {
317 if (strncasecmp(s1, s2, len2) == 0)
327 strcasematch(char *s1, char *s2)
333 x = TOLOWER(*s1) - TOLOWER(*s2);
339 return (*s2 == '\0');
342 /* search multiple strings */
344 strcasemstr(char *str, char *srch[], char **ret_ptr)
348 for (i = 0; srch[i]; i++) {
349 if (strcasematch(str, srch[i])) {
361 remove_space(char *str)
365 for (p = str; *p && IS_SPACE(*p); p++) ;
366 for (q = p; *q; q++) ;
367 for (; q > p && IS_SPACE(*(q - 1)); q--) ;
369 return Strnew_charp_n(p, q - p)->ptr;
387 cleanup_line(Str s, int mode)
389 if (s->length >= 2 &&
390 s->ptr[s->length - 2] == '\r' && s->ptr[s->length - 1] == '\n') {
392 Strcat_char(s, '\n');
394 else if (Strlastchar(s) == '\r')
395 s->ptr[s->length - 1] = '\n';
396 else if (Strlastchar(s) != '\n')
397 Strcat_char(s, '\n');
398 if (mode != PAGER_MODE) {
400 for (i = 0; i < s->length; i++) {
401 if (s->ptr[i] == '\0')
408 getescapechar(char **str)
412 int strict_entity = TRUE;
418 if (*p == 'x' || *p == 'X') {
420 if (!IS_XDIGIT(*p)) {
424 for (dummy = GET_MYCDIGIT(*p), p++; IS_XDIGIT(*p); p++)
425 dummy = dummy * 0x10 + GET_MYCDIGIT(*p);
436 for (dummy = GET_MYCDIGIT(*p), p++; IS_DIGIT(*p); p++)
437 dummy = dummy * 10 + GET_MYCDIGIT(*p);
449 for (p++; IS_ALNUM(*p); p++) ;
450 q = allocStr(q, p - q);
451 if (strcasestr("lt gt amp quot nbsp", q) && *p != '=') {
452 /* a character entity MUST be terminated with ";". However,
453 * there's MANY web pages which uses < , > or something
454 * like them as <, >, etc. Therefore, we treat the most
455 * popular character entities (including &#xxxx;) without
456 * the last ";" as character entities. If the trailing character
457 * is "=", it must be a part of query in an URL. So <=, >=, etc.
458 * are not regarded as character entities.
460 strict_entity = FALSE;
464 else if (strict_entity) {
469 return getHash_si(&entity, q, -1);
473 getescapecmd(char **s)
477 int ch = getescapechar(s);
480 return conv_entity(ch);
483 tmp = Strnew_charp("&");
486 Strcat_charp_n(tmp, save, *s - save);
491 html_quote(char *str)
496 for (p = str; *p; p++) {
497 q = html_quote_char(*p);
500 tmp = Strnew_charp_n(str, (int)(p - str));
501 Strcat_charp(tmp, q);
505 Strcat_char(tmp, *p);
514 html_unquote(char *str)
522 tmp = Strnew_charp_n(str, (int)(p - str));
523 q = getescapecmd(&p);
524 Strcat_charp(tmp, q);
528 Strcat_char(tmp, *p);
538 static char xdigit[0x10] = "0123456789ABCDEF";
540 #define url_unquote_char(pstr) \
541 ((IS_XDIGIT((*(pstr))[1]) && IS_XDIGIT((*(pstr))[2])) ? \
542 (*(pstr) += 3, (GET_MYCDIGIT((*(pstr))[-2]) << 4) | GET_MYCDIGIT((*(pstr))[-1])) : \
551 for (p = str; *p; p++) {
552 if (is_url_quote(*p)) {
554 tmp = Strnew_charp_n(str, (int)(p - str));
555 Strcat_char(tmp, '%');
556 Strcat_char(tmp, xdigit[((unsigned char)*p >> 4) & 0xF]);
557 Strcat_char(tmp, xdigit[(unsigned char)*p & 0xF]);
561 Strcat_char(tmp, *p);
570 file_quote(char *str)
576 for (p = str; *p; p++) {
577 if (is_file_quote(*p)) {
579 tmp = Strnew_charp_n(str, (int)(p - str));
580 sprintf(buf, "%%%02X", (unsigned char)*p);
581 Strcat_charp(tmp, buf);
585 Strcat_char(tmp, *p);
594 file_unquote(char *str)
603 c = url_unquote_char(&q);
606 tmp = Strnew_charp_n(str, (int)(p - str));
607 if (c != '\0' && c != '\n' && c != '\r')
608 Strcat_char(tmp, (char)c);
614 Strcat_char(tmp, *p);
623 Str_form_quote(Str x)
626 char *p = x->ptr, *ep = x->ptr + x->length;
629 for (; p < ep; p++) {
632 tmp = Strnew_charp_n(x->ptr, (int)(p - x->ptr));
633 Strcat_char(tmp, '+');
635 else if (is_url_unsafe(*p)) {
637 tmp = Strnew_charp_n(x->ptr, (int)(p - x->ptr));
638 sprintf(buf, "%%%02X", (unsigned char)*p);
639 Strcat_charp(tmp, buf);
643 Strcat_char(tmp, *p);
653 Str_url_unquote(Str x, int is_form, int safe)
656 char *p = x->ptr, *ep = x->ptr + x->length, *q;
660 if (is_form && *p == '+') {
662 tmp = Strnew_charp_n(x->ptr, (int)(p - x->ptr));
663 Strcat_char(tmp, ' ');
667 else if (*p == '%') {
669 c = url_unquote_char(&q);
670 if (c >= 0 && (!safe || !IS_ASCII(c) || !is_file_quote(c))) {
672 tmp = Strnew_charp_n(x->ptr, (int)(p - x->ptr));
673 Strcat_char(tmp, (char)c);
679 Strcat_char(tmp, *p);
688 shell_quote(char *str)
693 for (p = str; *p; p++) {
694 if (is_shell_unsafe(*p)) {
696 tmp = Strnew_charp_n(str, (int)(p - str));
697 Strcat_char(tmp, '\\');
698 Strcat_char(tmp, *p);
702 Strcat_char(tmp, *p);
711 w3m_dir(const char *name, char *dft)
713 #ifdef USE_PATH_ENVVAR
714 char *value = getenv(name);
715 return value ? value : dft;
724 return w3m_dir("W3M_AUXBIN_DIR", AUXBIN_DIR);
730 /* FIXME: use W3M_CGIBIN_DIR? */
731 return w3m_dir("W3M_LIB_DIR", CGIBIN_DIR);
737 return w3m_dir("W3M_ETC_DIR", ETC_DIR);
743 return w3m_dir("W3M_CONF_DIR", CONF_DIR);
749 return w3m_dir("W3M_HELP_DIR", HELP_DIR);
751 /* Local Variables: */
752 /* c-basic-offset: 4 */