Logo Search packages:      
Sourcecode: w3mmee version File versions  Download package

indep.c

#include "fm.h"
#include <stdio.h>
#include <pwd.h>
#include <sys/param.h>
#include <sys/types.h>
#include <stdlib.h>
#include "indep.h"
#include "Str.h"
#include "gc.h"
#include "myctype.h"

clen_t
strtoclen(const char *s, int base)
{
#ifdef HAVE_STRTOLL
    return strtoll(s, NULL, base);
#elif HAVE_STRTOQ
    return strtoq(s, NULL, base);
#else
    int minus, digit;
    clen_t clen;

    SKIP_BLANKS(s);

    switch (*s) {
    case '+':
      ++s;
    default:
      minus = 0;
      break;
    case '-':
      ++s;
      minus = 1;
      break;
    }

    switch (base) {
    case 0:
      if (*s == '0') {
          if (*(s + 1) == 'x' || *(s + 1) == 'X') {
            s += 2;
            base = 16;
            break;
          }
          else {
            ++s;
            base = 8;
            break;
          }
      }

      base = 10;
      break;
    case 16:
      if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))
          s += 2;

      break;
    case 8:
      if (*s == '0')
          ++s;
    default:
      break;
    }

    for (clen = 0 ; *s ;)
      if ((digit = GET_MYCDIGIT(*s++)) != MYCTYPE_NOTDIGIT && digit < base)
          clen = clen * base + digit;
      else
          break;

    if (minus)
      return -clen;
    else
      return clen;
#endif
}

#ifndef HAVE_BCOPY
void
bcopy(const void *src, void *dest, int len)
{
    int i;
    if (src == dest)
      return;
    if (src < dest) {
      for (i = len - 1; i >= 0; i--)
          ((char *)dest)[i] = ((const char *)src)[i];
    }
    else {              /* src > dest */
      for (i = 0; i < len; i++)
          ((char *)dest)[i] = ((const char *)src)[i];
    }
}

void
bzero(void *ptr, int len)
{
    int i;
    char *p;
    for (p = ptr, i = 0; i < len; i++)
      *(p++) = 0;
}
#endif                        /* not HAVE_BCOPY */

char *
allocStr(const char *s, int len)
{
    char *ptr;

    if (s == NULL)
      return NULL;
    if (len < 0)
      len = strlen(s);
    ptr = NewAtom_N(char, len + 1);
    if (ptr == NULL) {
      fprintf(stderr, "fm: Can't allocate string. Give me more memory!\n");
      exit(-1);
    }
    bcopy(s, ptr, len);
    ptr[len] = '\0';
    return ptr;
}

int
strCmp(const void *s1, const void *s2)
{
    return strcmp(*(const char **)s1, *(const char **)s2);
}

char *
currentdir()
{
    char *path;
#ifdef HAVE_GETCWD
#ifdef MAXPATHLEN
    path = NewAtom_N(char, MAXPATHLEN);
    getcwd(path, MAXPATHLEN);
#else
    path = getcwd(NULL, 0);
#endif
#else                   /* not HAVE_GETCWD */
#ifdef HAVE_GETWD
    path = NewAtom_N(char, 1024);
    getwd(path);
#else                   /* not HAVE_GETWD */
    FILE *f;
    char *p;
    path = NewAtom_N(char, 1024);
    f = popen("pwd", "r");
    fgets(path, 1024, f);
    pclose(f);
    for (p = path; *p; p++)
      if (*p == '\n') {
          *p = '\0';
          break;
      }
#endif                        /* not HAVE_GETWD */
#endif                        /* not HAVE_GETCWD */
    return path;
}

char *
cleanupName(char *name)
{
    char *buf, *p, *q;

    buf = allocStr(name, -1);
    p = buf;
    q = name;
    while (*q != '\0') {
      if (strncmp(p, "/../", 4) == 0) {   /* foo/bar/../FOO */
          if (p - 2 == buf && strncmp(p - 2, "..", 2) == 0) {
            /* ../../       */
            p += 3;
            q += 3;
          }
          else if (p - 3 >= buf && strncmp(p - 3, "/..", 3) == 0) {
            /* ../../../    */
            p += 3;
            q += 3;
          }
          else {
            while (p != buf && *--p != '/');    /* ->foo/FOO */
            *p = '\0';
            q += 3;
            strcat(buf, q);
          }
      }
      else if (strcmp(p, "/..") == 0) {   /* foo/bar/..   */
          if (p - 2 == buf && strncmp(p - 2, "..", 2) == 0) {
            /* ../..        */
          }
          else if (p - 3 >= buf && strncmp(p - 3, "/..", 3) == 0) {
            /* ../../..     */
          }
          else {
            while (p != buf && *--p != '/');    /* ->foo/ */
            *++p = '\0';
          }
          break;
      }
      else if (strncmp(p, "/./", 3) == 0) {     /* foo/./bar */
          *p = '\0';          /* -> foo/bar           */
          q += 2;
          strcat(buf, q);
      }
      else if (strcmp(p, "/.") == 0) {    /* foo/. */
          *++p = '\0';  /* -> foo/              */
          break;
      }
      else if (strncmp(p, "//", 2) == 0) {      /* foo//bar */
          /* -> foo/bar           */
          *p = '\0';
          q++;
          strcat(buf, q);
      }
      else {
          p++;
          q++;
      }
    }
    return buf;
}

char *
expandPath(char *name)
{
   Str userName = NULL;
   char *p;
   struct passwd *passent, *getpwnam(const char *);
   Str extpath = Strnew();

   if (name == NULL)
      return NULL;
   p = name;
   if (*p == '~') {
      p++;
      if (IS_ALPHA(*p)) {
          userName = Strnew();
          while (IS_ALNUM(*p) || *p == '_' || *p == '-')
            Strcat_char(userName, *(p++));
          passent = getpwnam(userName->ptr);
          if (passent == NULL) {
            p = name;
            goto rest;
          }
          Strcat_charp(extpath, passent->pw_dir);
      }
      else {
          Strcat_charp(extpath, getenv("HOME"));
      }
      if (Strcmp_charp(extpath, "/") == 0 && *p == '/')
          p++;
   }
 rest:
   Strcat_charp(extpath, p);
   return extpath->ptr;
}

#ifndef HAVE_STRCHR
char *
strchr(const char *s, int c)
{
    do {
      if ((unsigned char)*s == c)
          return (char *)s;
    } while (*s++);

    return NULL;
}
#endif                        /* not HAVE_STRCHR */

#ifndef HAVE_STRCASECMP
int
strcasecmp(const char *s1, const char *s2)
{
    int x;

    for (; *s1 ; ++s1, ++s2)
      if ((x = tolower(*s1) - tolower(*s2)))
          return x;

    return -tolower(*s2);
}

int
strncasecmp(const char *s1, const char *s2, size_t n)
{
    int x;

    for (; *s1 && n ; ++s1, ++s2, --n)
      if ((x = tolower(*s1) - tolower(*s2)))
          return x;

    return n ? -tolower(*s2) : 0;
}
#endif                        /* not HAVE_STRCASECMP */

#ifndef HAVE_STRCASESTR
/* string search using the simplest algorithm */
char *
strcasestr(const char *s1, const char *s2)
{
    int len1, len2;
    if (s2 == NULL)
      return (char *)s1;
    if (*s2 == '\0')
      return (char *)s1;
    len1 = strlen(s1);
    len2 = strlen(s2);
    while (*s1 && len1 >= len2) {
      if (strncasecmp(s1, s2, len2) == 0)
          return (char *)s1;
      s1++;
      len1--;
    }
    return 0;
}
#endif

static int
strcasematch(char *s1, char *s2)
{
    int x;
    while (*s1) {
      if (*s2 == '\0')
          return 1;
      x = tolower(*s1) - tolower(*s2);
      if (x != 0)
          break;
      s1++;
      s2++;
    }
    return (*s2 == '\0');
}

/* search multiple strings */
int
strcasemstr(char *str, char *srch[], char **ret_ptr)
{
    int i;
    while (*str) {
      for (i = 0; srch[i]; i++) {
          if (strcasematch(str, srch[i])) {
            if (ret_ptr)
                *ret_ptr = str;
            return i;
          }
      }
      str++;
    }
    return -1;
}

char *
remove_space(char *str)
{
    char *p, *q;

    for (p = str; *p && IS_SPACE(*p); p++)
      ;
    for (q = p; *q; q++)
      ;
    for (; q > p && IS_SPACE(*(q-1)); q--)
      ;
    if (*q != '\0')
      return Strnew_charp_n(p, q - p)->ptr;
    return p;
}

int
non_null(char *s)
{
    if (s == NULL)
      return FALSE;
    while (*s) {
      if (!IS_SPACE(*s))
          return TRUE;
      s++;
    }
    return FALSE;
}

void
cleanup_line(Str s, int mode)
{
    if (s->length >= 2 &&
      s->ptr[s->length - 2] == '\r' &&
      s->ptr[s->length - 1] == '\n') {
      Strshrink(s, 2);
      Strcat_char(s, '\n');
    }
    else if (Strlastchar(s) == '\r')
      s->ptr[s->length - 1] = '\n';
    else if (Strlastchar(s) != '\n')
      Strcat_char(s, '\n');
    if (mode != PAGER_MODE) {
      int i;
      for (i = 0; i < s->length; i++) {
          if (s->ptr[i] == '\0')
            s->ptr[i] = ' ';
      }
    }
}

enum {
#undef def_entity
#define def_entity(name, uc, strict) ENTITY_INDEX_ ## name,
#include "entity.h"
};

static struct entity_desc {
    int uc, strict;
} entity_descv[] = {
#undef def_entity
#define def_entity(name, uc, strict) {uc, strict},
#include "entity.h"
};

static btri_string_tab_t entity_tab[] = {
#include "entity_tab.h"
};
    
int
getescapechar(char **str, char *ep)
{
    int dummy = -1;
    char *p = *str, *q;
    int strict_entity = TRUE;
    void *value;

    if (p >= ep || ((*p == '&' && ++p >= ep))) {
      *str = p;
      return -1;
    }
    if (*p == '#') {
      if (++p >= ep) {
          *str = p;
          return -1;
      }
      if (*p == 'x' || *p == 'X') {
          if ((++p >= ep) || !IS_XDIGIT(*p)) {
            *str = p;
            return -1;
          }
          for (dummy = GET_MYCDIGIT(*p) ; ++p < ep && IS_XDIGIT(*p) ;)
            dummy = dummy * 0x10 + GET_MYCDIGIT(*p);
          if (p < ep && *p == ';')
            p++;
          *str = p;
          return dummy;
      } else {
          if (!IS_DIGIT(*p)) {
            *str = p;
            return -1;
          }
          for (dummy = GET_MYCDIGIT(*p) ; ++p < ep && IS_DIGIT(*p) ;)
            dummy = dummy * 10 + GET_MYCDIGIT(*p);
          if (p < ep && *p == ';')
            p++;
          *str = p;
          return dummy;
      }
    }
    if (!IS_ALPHA(*p)) {
      *str = p;
      return -1;
    }
    q = p;
    while (++p < ep && IS_ALNUM(*p))
      ;
    if (btri_fast_search_mem(q, p - q, entity_tab, &value) != bt_failure) {
      struct entity_desc *desc;

      desc = value;
      dummy = desc->uc;
      if (!desc->strict && strchr("&<>'\"=", *p))
          strict_entity = FALSE;
    }
    if (p < ep && *p == ';')
      p++;
    else if (strict_entity)
      dummy = -1;
    *str = p;
    return dummy;
}

char *
getescapecmd(char **s, char *ep)
{
    char *save = *s;
    Str tmp;
    int ch = getescapechar(s, ep);

    if (ch >= 0)
      return conv_entity(ch);

    if (save >= ep || *save != '&')
      tmp = Strnew_charp("&");
    else
      tmp = Strnew();
    Strcat_charp_n(tmp, save, *s - save);
    return tmp->ptr;
}

char *
html_quote_char(char c)
{
    switch (c) {
    case '&':
      return "&amp;";
    case '<':
      return "&lt;";
    case '>':
      return "&gt;";
    case '"':
      return "&quot;";
    }
    return NULL;
}

char *
html_quote(char *str)
{
    Str tmp = NULL;
    char *p, *q;

    for (p = str; *p; p++) {
      q = html_quote_char(*p);
      if (q) {
          if (tmp == NULL)
            tmp = Strnew_charp_n(str, (int)(p - str));
          Strcat_charp(tmp, q);
      }
      else {
          if (tmp)
            Strcat_char(tmp, *p);
      }
    }
    if (tmp)
      return tmp->ptr;
    return str;
}

char *
html_unquote(char *str)
{
    Str tmp = NULL;
    char *p, *q, *ep = NULL;

    for (p = str; *p; ) {
      if (*p == '&') {
          if (tmp == NULL)
            tmp = Strnew_charp_n(str, (int)(p - str));
          if (ep == NULL)
            ep = p + strlen(p);
          q = getescapecmd(&p, ep);
          Strcat_charp(tmp, q);
      }
      else {
          if (tmp)
            Strcat_char(tmp, *p);
          p++;
      }
    }

    if (tmp)
      return tmp->ptr;
    return str;
}

static char xdigit[0x10] = "0123456789ABCDEF";

char *
url_quote(char *str)
{
    Str tmp = NULL;
    char *p;

    for (p = str ; *p ; ++p) {
      if (IS_CNTRL(*p) || *p == ' ' || ! IS_ASCII(*p)) {
          if (tmp == NULL)
            tmp = Strnew_charp_n(str, (int)(p - str));
          Strcat_char(tmp, '%');
          Strcat_char(tmp, xdigit[((unsigned char)*p >> 4) & 0xF]);
          Strcat_char(tmp, xdigit[(unsigned char)*p & 0xF]);
      } else {
          if (tmp)
            Strcat_char(tmp, *p);
      }
    }
    if (tmp)
      return tmp->ptr;
    return str;
}

#define url_unquote_char(pstr) \
(IS_XDIGIT((*(pstr))[1]) ? \
 (IS_XDIGIT((*(pstr))[2]) ? \
  (*(pstr) += 3, (GET_MYCDIGIT((*(pstr))[-2]) << 4) | GET_MYCDIGIT((*(pstr))[-1])) : \
  (*(pstr) += 2, GET_MYCDIGIT((*(pstr))[-1]))) : \
 -1)

char *
url_unquote(char *str)
{
    Str tmp = NULL;
    char *p, *q;
    int c;

    for (p = str; *p; ) {
      if (*p == '%') {
          q = p;
          c = url_unquote_char(&q);
          if (c >= 0 && (IS_CNTRL(c) || c == ' ' || ! IS_ASCII(c))) {
            if (tmp == NULL)
                tmp = Strnew_charp_n(str, (int)(p - str));
            if (c != '\0' && c != '\n' && c != '\r')
                Strcat_char(tmp, (char)c);
            p = q;
            continue;
          }
      }
      if (tmp)
          Strcat_char(tmp, *p);
      p++;
    }
    if (tmp)
      return tmp->ptr;
    return str;
}

char *
file_quote(char *str)
{
    Str tmp = NULL;
    char *p;

    for (p = str; *p; p++) {
      if (IS_CNTRL(*p) || *p == ' ' || ! IS_ASCII(*p) || *p == '+' ||
          *p == ':' || *p == '#' || *p == '?' || *p == '&' || *p == '%') {
          if (tmp == NULL)
            tmp = Strnew_charp_n(str, (int)(p - str));
          Strcat_char(tmp, '%');
          Strcat_char(tmp, xdigit[((unsigned char)*p >> 4) & 0xF]);
          Strcat_char(tmp, xdigit[(unsigned char)*p & 0xF]);
      } else {
          if (tmp)
            Strcat_char(tmp, *p);
      }
    }
    if (tmp)
      return tmp->ptr;
    return str;
}

char *
file_unquote(char *str)
{
    Str tmp = NULL;
    char *p, *q;
    int c;

    for (p = str; *p;) {
      if (*p == '%') {
          q = p;
          c = url_unquote_char(&q);
          if (c >= 0) {
            if (tmp == NULL)
                tmp = Strnew_charp_n(str, (int)(p - str));
            if (c != '\0' && c != '\n' && c != '\r')
                Strcat_char(tmp, (char)c);
            p = q;
            continue;
          }
      }
      if (tmp)
          Strcat_char(tmp, *p);
      p++;
    }
    if (tmp)
      return tmp->ptr;
    return str;
}

/* rfc1808 safe */
static int
is_url_safe(char c)
{
    switch (c) {
      /* safe */
    case '$':
    case '-':
    case '_':
    case '.':
      return 1;
    default:
      return IS_ALNUM(c);
    }
}

Str
Str_form_quote(Str x)
{
    Str tmp = NULL;
    char *p, *ep;

    for (p = x->ptr, ep = x->ptr + x->length; p < ep; p++) {
      if (*p == ' ') {
          if (tmp == NULL)
            tmp = Strnew_charp_n(x->ptr, (int)(p - x->ptr));
          Strcat_char(tmp, '+');
      } else if (! is_url_safe(*p)) {
          if (tmp == NULL)
            tmp = Strnew_charp_n(x->ptr, (int)(p - x->ptr));
          Strcat_char(tmp, '%');
          Strcat_char(tmp, xdigit[((unsigned char)*p >> 4) & 0xF]);
          Strcat_char(tmp, xdigit[(unsigned char)*p & 0xF]);
      } else {
          if (tmp)
            Strcat_char(tmp, *p);
      }
    }
    if (tmp)
      return tmp;
    return x;
}

Str
form_unquote_charp_n(const char *s, int n)
{
    Str tmp = NULL;
    const char *p, *ep, *q;
    int c;

    for (p = s, ep = s + n; p < ep; ) {
      if (*p == '+') {
          if (tmp == NULL)
            tmp = Strnew_charp_n((char *)s, (int)(p - s));
          Strcat_char(tmp, ' ');
          p++;
          continue;
      } else if (*p == '%') {
          q = p;
          c = url_unquote_char(&q);
          if (c >= 0) {
            if (tmp == NULL)
                tmp = Strnew_charp_n((char *)s, (int)(p - s));
            Strcat_char(tmp, (char)c);
            p = q;
            continue;
          }
      }
      if (tmp)
          Strcat_char(tmp, *p);
      p++;
    }
    return tmp;
}

Str
Str_form_unquote(Str x)
{
    Str y;

    if (!(y = form_unquote_charp_n(x->ptr, x->length)))
      y = x;

    return y;
}

static int
is_shell_safe(char c)
{
    switch (c) {
      /* safe */
    case '/':
    case '.':
    case '_':
    case ':':
      return 1;
    default:
      return IS_ALNUM(c) || (c & 0x80);
    }
}

char *
shell_quote(char *str)
{
    Str tmp = NULL;
    char *p;

    for (p = str; *p; p++) {
        if (!is_shell_safe(*p)) {
          if (tmp == NULL)
            tmp = Strnew_charp_n(str, (int)(p - str));
            Strcat_char(tmp, '\\');
          Strcat_char(tmp, *p);
      } 
      else {
          if (tmp)
            Strcat_char(tmp, *p);
      }
    }
    if (tmp)
      return tmp->ptr;
    return str;
}

static char *
w3m_dir(const char *name, char *dft)
{
#ifdef USE_PATH_ENVVAR
   char *value = getenv(name);
   return value ? value : dft;
#else
   return dft;
#endif
}

char *
w3m_lib_dir()
{
   return w3m_dir("W3M_LIB_DIR", LIB_DIR);
}

char *
w3m_auxbin_dir()
{
    return w3m_dir("W3M_AUXBIN_DIR", AUXBIN_DIR);
}

char *
w3m_etc_dir()
{
    return w3m_dir("W3M_ETC_DIR", ETC_DIR);
}

char *
w3m_help_dir()
{
   return w3m_dir("W3M_HELP_DIR", HELP_DIR);
}

void
new_objv(int *p_size, int n, ...)
{
    va_list ap;

    va_start(ap, n);

    if (n >= *p_size) {
      int newsize = (n / 2 + 1) * 3;
      int elem_size, isatomic;
      void **p_v, *newv;

      while ((p_v = va_arg(ap, void **))) {
          elem_size = va_arg(ap, int);
          isatomic = va_arg(ap, int);

          if (isatomic)
            newv = GC_MALLOC_ATOMIC(elem_size * newsize);
          else
            newv = GC_MALLOC(elem_size * newsize);

          if (*p_v)
            memcpy(newv, *p_v, elem_size * *p_size);

          memset((char *)newv + elem_size * *p_size, 0, elem_size * (newsize - *p_size));
          *p_v = newv;
      }

      *p_size = newsize;
    }

    va_end(ap);
}

int
str_to_bool(char *value, int old)
{
  if (value == NULL)
    return 1;
  switch (tolower(*value)) {
  case '0':
  case 'f':             /* false */
  case 'n':             /* no */
  case 'u':             /* undef */
    return 0;
  case 'o':
    if (tolower(value[1]) == 'f')    /* off */
      return 0;
    return 1;        /* on */
  case 't':
    if (tolower(value[1]) == 'o')    /* toggle */
      return ! old;
    return 1;        /* true */
  case '!':
  case 'r':            /* reverse */
  case 'x':            /* exchange */
    return ! old;
  }
  return 1;
}


/* Local Variables:    */
/* c-basic-offset: 4   */
/* tab-width: 8        */
/* End:                */

Generated by  Doxygen 1.6.0   Back to index