示例#1
0
static char *
catpath(const char *from, const char *fname)
{
  SB sb;
  sbinit(&sb);
  if (fname && fname[0]=='/') 
    sbadd1(&sb, '/');
  else if (from)
    sbaddsf(&sb, catpath(NULL,from));
  else {
    char *cwd = 0;
    while (sb.buffer && !cwd) {
      cwd = getcwd(sb.buffer + sb.len, sb.maxlen - sb.len);
      if (cwd || errno != ERANGE) break;
      sbgrow(&sb, sb.maxlen - sb.len + SBINCREMENT);
    }
    if (cwd)
      sb.len += strlen(cwd);
    else
      sbfree(&sb);
  }
  for (;;) {
    while (fname && fname[0]=='/')
      fname++;
    if (!fname || !fname[0]) {
      while (&sb.buffer && sb.len>0 && sb.buffer[sb.len-1]=='/')
        sb.len -= 1;
      sbadd1(&sb, 0);
      return sb.buffer;
    }
    if (fname[0]=='.') {
      if (fname[1]=='/' || fname[1]==0) {
        fname +=1;
        continue;
      }
      if (fname[1]=='.')
        if (fname[2]=='/' || fname[2]==0) {
          fname +=2;
          while (sb.buffer && sb.len>0 && sb.buffer[sb.len-1]=='/')
            sb.len -= 1;
          while (sb.buffer && sb.len>0 && sb.buffer[sb.len-1]!='/')
            sb.len -= 1;
          continue;
        }
    }
    if (sb.len==0 || (sb.buffer && sb.buffer[sb.len-1]!='/'))
      sbadd1(&sb, '/');
    while (*fname!=0 && *fname!='/')
      sbadd1(&sb, *fname++);
  }
  sbadd1(&sb, 0);
  return sb.buffer;
}
示例#2
0
static const char *
executable_dir(const char *progname)
{
  SB sb;
  struct stat sbuf;
  if (! progname)
    return 0;
  sbinit(&sb);
  if (progname[0]=='/')
    sbaddn(&sb, progname, strlen(progname));
  else if (strchr(progname,'/'))
    sbaddsf(&sb,catpath(NULL,progname));
  else {
    char *p = getenv("PATH");
    for (;;) {
      sb.len = 0;
      if (! (p && *p))
        return sbfree(&sb);
      while (*p && *p!=':')
        sbadd1(&sb, *p++);
      if (*p ==':')
        p++;
      sbadd1(&sb, 0);
      sb.len = 0;
      sbaddsf(&sb, catpath(sb.buffer, progname));
      sbadd1(&sb, 0);
      if (sb.buffer && stat(sb.buffer,&sbuf)>=0 && S_ISREG(sbuf.st_mode))
        if (access(sb.buffer, X_OK) >= 0)
          break;
    }
  }
#ifdef S_ISLNK
  sbadd1(&sb, 0);
  while(sb.buffer && lstat(sb.buffer,&sbuf)>=0 && S_ISLNK(sbuf.st_mode))
    {
      int h,l;
      sbaddn(&sb,"../",3);
      h = sb.len;
      while ((l=readlink(sb.buffer,sb.buffer+h,sb.maxlen-h))>=sb.maxlen-h)
        sbgrow(&sb, sb.maxlen - h + SBINCREMENT);
      if (l < 0)
        return sbfree(&sb);
      sb.len = h + l;
      sbadd1(&sb,0);
      sb.len = 0;
      sbaddsf(&sb, catpath(sb.buffer,sb.buffer+h-3));
      sbadd1(&sb,0);
    }
#endif
  while (sb.buffer && sb.len>0 && sb.buffer[sb.len-1]=='/')
    sb.len -= 1;
  while (sb.buffer && sb.len>0 && sb.buffer[sb.len-1]!='/')
    sb.len -= 1;
  while (sb.buffer && sb.len>0 && sb.buffer[sb.len-1]=='/')
    sb.len -= 1;
  sbadd1(&sb, 0);
  return sb.buffer;
}
示例#3
0
static const char *
relocate_path(const char *dir, const char *s)
{
  SB sb;
  const char *r;
  const char *execdir = LUA_EXECDIR;
  int lexecdir = strlen(execdir);
  int ldir = strlen(dir);
  sbinit(&sb);
  while ((r = strstr(s, execdir)))
    {
      sbaddn(&sb, s, r-s);
      sbaddn(&sb, dir, ldir);
      s = r + lexecdir;
      while (is_slash(s[0]))
        {
          if (is_dot(s[1]) && is_slash(s[2]))
            {
              s += 2;
              continue;
            }
          if (is_dot(s[1]) && is_dot(s[2]) && is_slash(s[3]) )
            {
              s += 3;
              while (sb.buffer && sb.len>0 && is_slash(sb.buffer[sb.len-1]))
                sb.len -= 1;
              while (sb.buffer && sb.len>0 && !is_slash(sb.buffer[sb.len-1]))
                sb.len -= 1;
              while (sb.buffer && sb.len>0 && is_slash(sb.buffer[sb.len-1]))
                sb.len -= 1;
              continue;
            }
          break;
        }
    }
  sbaddn(&sb, s, strlen(s));
  sbadd1(&sb, 0);
#ifdef LUA_WIN
  r = _strdup(sb.buffer);
#else
  r = strdup(sb.buffer);
#endif
  sbfree(&sb);
  return r;
}
示例#4
0
文件: paths.c 项目: leesitong/paths
static int
lua_dir(lua_State *L)
{
  int k = 0;
  const char *s = luaL_checkstring(L, 1);

#ifdef _WIN32

  SB sb;
  struct _finddata_t info;
  long hfind;
  /* special cases */
  lua_createtable(L, 0, 0);
  if ((s[0]=='/' || s[0]=='\\') && 
      (s[1]=='/' || s[1]=='\\') && !s[2]) 
    {
      int drive;
      hfind = GetLogicalDrives();
      for (drive='A'; drive<='Z'; drive++)
        if (hfind & (1<<(drive-'A'))) {
          lua_pushfstring(L, "%c:/", drive);
          lua_rawseti(L, -2, ++k);
        }
    } 
  else if (dirp(L, 1)) {
    lua_pushliteral(L, "..");
    lua_rawseti(L, -2, ++k);
  } else {
    lua_pushnil(L);
    return 1;
  }
  /* files */
  sbinit(&sb);
  sbaddn(&sb, s, strlen(s));
  if (sb.len>0 && sb.buffer[sb.len-1]!='/' && sb.buffer[sb.len-1]!='\\')
    sbadd1(&sb, '/');
  sbaddn(&sb, "*.*", 3);
  sbadd1(&sb, 0);
  hfind = _findfirst(sb.buffer, &info);
  if (hfind != -1) {
    do {
      if (strcmp(".",info.name) && strcmp("..",info.name)) {
        lua_pushstring(L, info.name);
        lua_rawseti(L, -2, ++k);
      }
    } while ( _findnext(hfind, &info) != -1 );
    _findclose(hfind);
  }
  sbfree(&sb);

#else

  DIR *dirp;
  struct dirent *d;
  dirp = opendir(s);
  if (dirp) {
    lua_createtable(L, 0, 0);
    while ((d = readdir(dirp))) {
      int n = NAMLEN(d);
      lua_pushlstring(L, d->d_name, n);
      lua_rawseti(L, -2, ++k);
    }
    closedir(dirp);
  } else
    lua_pushnil(L);

#endif
  
  return 1;
}
示例#5
0
文件: paths.c 项目: leesitong/paths
static int 
concat_fname(lua_State *L, const char *fname)
{
  const char *from = lua_tostring(L, -1);

#ifdef _WIN32

  const char *s;
  SB sb;
  sbinit(&sb);
  sbaddn(&sb, from, strlen(from));
  if (fname==0)
    return sbpush(L, &sb);
  /* Handle absolute part of fname */
  if (fname[0]=='/' || fname[0]=='\\') {
    if (fname[1]=='/' || fname[1]=='\\') {
      sb.len = 0;                            /* Case //abcd */
      sbaddn(&sb, "//", 2);
    } else {
      char drive;
      if (sb.len >= 2 && sb.buffer[1]==':'   /* Case "/abcd" */
          && isalpha((unsigned char)(sb.buffer[0])) )
        drive = sb.buffer[0];
      else
        drive = _getdrive() + 'A' - 1;
      sb.len = 0;
      sbadd1(&sb, drive);
      sbaddn(&sb, ":/", 2);
    }
  } else if (fname[0] && 	              /* Case "x:abcd"   */
             isalpha((unsigned char)(fname[0])) && fname[1]==':') {
    if (fname[2]!='/' && fname[2]!='\\') {
      if (sb.len < 2 || sb.buffer[1]!=':' 
          || !isalpha((unsigned char)(sb.buffer[0]))
          || (toupper((unsigned char)sb.buffer[0]) !=
              toupper((unsigned char)fname[0]) ) ) 
        {
          int l;
          char drv[4];
          sb.len = 0;
          drv[0]=fname[0]; drv[1]=':'; drv[2]='.'; drv[3]=0;
          l = GetFullPathNameA(drv, sb.maxlen, sb.buffer, 0);
          if (l > sb.maxlen) {
            sbgrow(&sb, l+1);
            l = GetFullPathNameA(drv, sb.maxlen, sb.buffer, 0);
          }
          if (l <= 0)
            sbaddn(&sb, drv, 3);
          else
            sb.len += l;
        }
      fname += 2;
    } else {
      sb.len = 0;                              /* Case "x:/abcd"  */
      sbadd1(&sb, toupper((unsigned char)fname[0])); 
      sbaddn(&sb, ":/", 2);
      fname += 2;
      while (*fname == '/' || *fname == '\\')
        fname += 1;
    }
  }
  /* Process path components */
  for (;;)
  {
    while (*fname=='/' || *fname=='\\')
      fname ++;
    if (*fname == 0)
      return sbpush(L, &sb);
    if (fname[0]=='.') {
      if (fname[1]=='/' || fname[1]=='\\' || fname[1]==0) {
	fname += 1;
	continue;
      }
      if (fname[1]=='.')
        if (fname[2]=='/' || fname[2]=='\\' || fname[2]==0) {
          size_t l;
	  fname += 2;
          lua_pushcfunction(L, lua_dirname);
          sbpush(L, &sb);
          lua_call(L, 1, 1);
          s = lua_tolstring(L, -1, &l);
          sbinit(&sb);
          sbaddn(&sb, s, l);
          lua_pop(L, 1);
	  continue;
      }
    }
    if (sb.len==0 || 
        (sb.buffer[sb.len-1]!='/' && sb.buffer[sb.len-1]!='\\') )
      sbadd1(&sb, '/');
    while (*fname && *fname!='/' && *fname!='\\')
      sbadd1(&sb, *fname++);
  }
             
#else
  SB sb;
  sbinit(&sb);

  if (fname && fname[0]=='/') 
    sbadd1(&sb, '/');
  else
    sbaddn(&sb, from, strlen(from));
  for (;;) {
    while (fname && fname[0]=='/')
      fname++;
    if (!fname || !fname[0]) {
      sbadd1(&sb, '/');
      while (sb.len > 1 && sb.buffer[sb.len-1]=='/')
        sb.len --;
      return sbpush(L, &sb);
    }
    if (fname[0]=='.') {
      if (fname[1]=='/' || fname[1]==0) {
	fname +=1;
	continue;
      }
      if (fname[1]=='.')
	if (fname[2]=='/' || fname[2]==0) {
	  fname +=2;
          while (sb.len > 0 && sb.buffer[sb.len-1]=='/')
            sb.len --;
          while (sb.len > 0 && sb.buffer[sb.len-1]!='/')
            sb.len --;
	  continue;
	}
    }
    if (sb.len == 0 || sb.buffer[sb.len-1] != '/')
      sbadd1(&sb, '/');
    while (*fname!=0 && *fname!='/')
      sbadd1(&sb, *fname++);
  }
  
  
#endif

}
示例#6
0
文件: paths.c 项目: leesitong/paths
static int 
lua_dirname(lua_State *L)
{
  const char *fname = luaL_checkstring(L, 1);

#ifdef _WIN32

  const char *s;
  const char *p;
  SB sb;
  sbinit(&sb);
  /* Handle leading drive specifier */
  if (isalpha((unsigned char)fname[0]) && fname[1]==':') {
    sbadd1(&sb, *fname++);
    sbadd1(&sb, *fname++);
  }
  /* Search last non terminal / or \ */
  p = 0;
  s = fname;
  while (*s) {
    if ((s[0]=='\\' || s[0]=='/') &&
        (s[1] && s[1]!='/' && s[1]!='\\') )
      p = s;
    s++;
  }
  /* Cannot find non terminal / or \ */
  if (p == 0) {
    if (sb.len > 0) {
      if (fname[0]==0 || fname[0]=='/' || fname[0]=='\\')
	sbadd1(&sb, '/');
      return sbpush(L, &sb);
    } else {
      if (fname[0]=='/' || fname[0]=='\\')
	return sbsetpush(L, &sb, "//");
      else
	return sbsetpush(L, &sb, ".");
    }
  }
  /* Single leading slash */
  if (p == fname) {
    sbadd1(&sb, '/');
    return sbpush(L, &sb);
  }
  /* Backtrack all slashes */
  while (p>fname && (p[-1]=='/' || p[-1]=='\\'))
    p--;
  /* Multiple leading slashes */
  if (p == fname)
    return sbsetpush(L, &sb, "//");
  /* Regular case */
  s = fname;
  do {
    sbadd1(&sb, *s++);
  } while (s<p);
  return sbpush(L, &sb);

#else

  const char *s = fname;
  const char *p = 0;
  SB sb; 
  sbinit(&sb);
  while (*s) {
    if (s[0]=='/' && s[1] && s[1]!='/')
      p = s;
    s++;
  }
  if (!p) {
    if (fname[0]=='/')
      return sbsetpush(L, &sb, fname);
    else
      return sbsetpush(L, &sb, ".");
  }
  s = fname;
  do {
    sbadd1(&sb, *s++);
  } while (s<p);
  return sbpush(L, &sb);

#endif
}
示例#7
0
文件: paths.c 项目: leesitong/paths
static int 
lua_basename(lua_State *L)
{
  const char *fname = luaL_checkstring(L, 1);
  const char *suffix = luaL_optstring(L, 2, 0);

#ifdef _WIN32

  int sl;
  const char *p, *s;
  SB sb;
  sbinit(&sb);
  /* Special cases */
  if (fname[0] && fname[1]==':') {
    sbaddn(&sb, fname, 2);
    fname += 2;
    if (fname[0]=='/' || fname[0]=='\\')
      sbadd1(&sb, '/');
    while (fname[0]=='/' || fname[0]=='\\')
      fname += 1;
    if (fname[0]==0)
      return sbpush(L, &sb);
    sb.len = 0;
  }
  /* Position p after last nontrivial slash */
  s = p = fname;
  while (*s) {
    if ((s[0]=='\\' || s[0]=='/') &&
        (s[1] && s[1]!='/' && s[1]!='\\' ) )
      p = s + 1;
    s++;
  }
  /* Copy into buffer */
  while (*p && *p!='/' && *p!='\\')
    sbadd1(&sb, *p++);
  /* Process suffix */
  if (suffix==0 || suffix[0]==0)
    return sbpush(L, &sb);
  if (suffix[0]=='.')
    suffix += 1;
  if (suffix[0]==0)
    return sbpush(L, &sb);
  sl = strlen(suffix);
  if (sb.len > sl) {
    s =  sb.buffer + sb.len - (sl + 1);
    if (s[0]=='.' && _strnicmp(s+1,suffix, sl)==0)
      sb.len = s - sb.buffer;
  }
  return sbpush(L, &sb);
  
#else

  int sl;
  const char *s, *p;
  SB sb;
  sbinit(&sb);
  /* Position p after last nontrivial slash */
  s = p = fname;
  while (*s) {
    if (s[0]=='/' && s[1] && s[1]!='/')
      p = s + 1;
    s++;
  }
  /* Copy into buffer */
  while (*p && *p!='/')
    sbadd1(&sb, *p++);
  /* Process suffix */
  if (suffix==0 || suffix[0]==0)
    return sbpush(L, &sb);
  if (suffix[0]=='.')
    suffix += 1;
  if (suffix[0]==0)
    return sbpush(L, &sb);
  sl = strlen(suffix);
  if (sb.len > sl) {
    s =  sb.buffer + sb.len - (sl + 1);
    if (s[0]=='.' && strncmp(s+1,suffix, sl)==0)
      sb.len = s - sb.buffer;
  }
  return sbpush(L, &sb);

#endif
}