lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Thank's for those replyed !
I got to know what I want not require or dofile, but a "C" style include.
why ? I get used to organized my lua source files in C style like:
src 
   base 
      crc.lua ...
   tools
      ftp.lua ... 
   tests
   exe
and donot want to install them or modify lua path.

so, I write a luaB_include

/* .. plus include .. */
#define CURRENT_PATH "current_path"

const char* get_current_path(lua_State *L) {
  const char* path;
  unsigned int table_len = 0;
  lua_getfield(L, LUA_GLOBALSINDEX, CURRENT_PATH);
  if (!lua_istable(L, -1))
  {
 lua_pop(L,1);
 return "";
  }
  table_len = lua_objlen(L,-1);
  lua_rawgeti(L,-1,table_len);
  path = luaL_checkstring(L,-1);
  lua_pop(L,2);
  return path;
}

int right_find(const char* str, char c)
{
  int len = strlen(str);
  const char* p = str + len - 1;
  while (*p-- != c && --len > 0);
  return len - 1;
}

void filename_2_path(const char* filename, char* path)
{
  int pos = right_find(filename,'\\');
  int pos2 = right_find(filename,'/');
  if (pos2 > pos)
   pos = pos2;
  if (pos == -1)
   return;
  memcpy(path,filename,pos+1);
  path[pos+1] = 0;
}

LUALIB_API void luaL_push_current_path(lua_State *L,const char* filename){
  unsigned int table_len = 0;
  char path[256] = {0};
  lua_getfield(L, LUA_GLOBALSINDEX, CURRENT_PATH);
  if (lua_isnil(L, -1))
  {
 lua_pop(L,1);
 lua_newtable(L);
 lua_pushvalue(L, -1);
 lua_setfield(L, LUA_GLOBALSINDEX, CURRENT_PATH);
    //if (lua_istable(L, -1))
   //printf("table is good");
  }

  table_len = lua_objlen(L,-1);
  filename_2_path(filename,path);
  lua_pushstring(L,path);
  lua_rawseti(L,-2,table_len+1);
  lua_pop(L,1);
}

void pop_current_path(lua_State *L){
  unsigned int table_len = 0;
  lua_getfield(L, LUA_GLOBALSINDEX, CURRENT_PATH);
  if (!lua_istable(L, -1))
  {
 lua_pop(L,1);
 return ;
  }
  table_len = lua_objlen(L,-1);
  lua_pushnil(L);
  lua_rawseti(L,-2,table_len);
  lua_pop(L,1);
}

static int readable (const char *filename) {
  FILE *f = fopen(filename, "r");  /* try to open file */
  if (f == NULL) return 0;  /* open failed */
  fclose(f);
  return 1;
}

LUALIB_API int luaL_includefile(lua_State* L, const char* filename)
{
  int error;
  luaL_push_current_path(L,filename);
  error = luaL_loadfile(L, filename);
  if (error == 0)
   lua_call(L, 0, LUA_MULTRET);
  pop_current_path(L);
  return error;
}

static int luaB_include (lua_State *L) {
  const char *filename = luaL_optstring(L, 1, NULL);
  int n = lua_gettop(L);
  const char *path ;
  char pathname[256];
  if (!readable(filename))
  {
 path = get_current_path(L);
    strcpy(pathname,path);
    filename = strcat(pathname,filename);
  }
  luaL_push_current_path(L,filename);
  if (luaL_loadfile(L, filename) != 0) lua_error(L);
  lua_call(L, 0, LUA_MULTRET);
  pop_current_path(L);
  return lua_gettop(L) - n;
}

and regist luaB_include as "include" 
then include "..\\a\\a.lua" will ok!

the code is long, please forgive. 

----- Original Message ----- 
From: "mos" <mmosquito@163.com>
To: "Lua list" <lua@bazar2.conectiva.com.br>
Sent: Thursday, June 24, 2010 2:13 PM
Subject: require vs dofile (lua 5.1.4 windows)


> Hi!
>    there are 2 files in 2 fold like:
> a 
>  a.lua
> b 
>  b.lua
> 
> the b.lua use
>  require "..\\a\\a.lua"
> will get a error can not find a.lua
> 
> but use
>  dofile("..\\a\\a.lua")
> will ok
> 
> I don't konw why.
> 
> Best Regard
> yujiang
>