/// Returns a table array containing all the file names of the // files in the specified directory. // // <b>Important</b>: this function lists both files from actual directories on // hard disk, and virtual directories loaded through // @{blitwizard.loadResourceArchive|loaded zip resource archives}. // Virtual files will take precedence over real files (you won't // receive duplicates). // // If you don't want virtual files listed (e.g. because you want // to examine any directory supplied by the user and not part of your // project) // @function ls // @tparam string directory path, empty string ("") for current directory // @tparam boolean virtual_files (optional) Specify true to list virtual files inside virtual directories aswell (the default behaviour), false to list only files in the actual file system on disk // @usage // -- list all files in current directory: // for i,file in ipairs(os.ls("")) do // print("file name: " .. file) // end int luafuncs_ls(lua_State *l) { const char *p = lua_tostring(l, 1); if (!p) { lua_pushstring(l, "First argument is not a valid path string"); return lua_error(l); } char *pnative = file_getAbsolutePathFromRelativePath(p); char *pcross = strdup(pnative); char *pcrossResourceDir = strdup(pnative); if (!pnative || !pcross || !pcrossResourceDir) { free(pnative); free(pcross); free(pcrossResourceDir); return haveluaerror(l, "failed to allocate file paths"); } file_makeSlashesNative(pnative); file_makeSlashesCrossplatform(pcross); file_makePathRelative(pcrossResourceDir, main_getRunDir()); if (!file_IsPathRelative(pcrossResourceDir)) { free(pcrossResourceDir); pcrossResourceDir = NULL; } // check parameter if we want to list internal zip stuff or not: int list_virtual = 1; if (lua_gettop(l) >= 2 && lua_type(l, 2) != LUA_TNIL) { if (lua_type(l, 2) != LUA_TNUMBER) { free(pnative); free(pcross); free(pcrossResourceDir); return haveluaerror(l, badargument1, 2, "os.ls", "boolean or nil", lua_strtype(l, 2)); } list_virtual = lua_toboolean(l, 2); } // get virtual filelist: char **filelist = NULL; #ifdef USE_PHYSFS if (list_virtual && pcrossResourceDir) { filelist = resource_getFileList(pcrossResourceDir); //printf("got filelist for %s: %p\n", pcrossrelative, filelist); char **p = filelist; if (p) { while (*p) { assert(strlen(*p) <= 512); assert(*p[0] >= 32); p++; } } } #endif // get iteration context for "real" on disk directory: struct filelistcontext *ctx = filelist_Create(pnative); if (!ctx && (!list_virtual || !filelist)) { char errmsg[500]; snprintf(errmsg, sizeof(errmsg), "failed to ls folder: %s", pnative); errmsg[sizeof(errmsg)-1] = 0; lua_pushstring(l, errmsg); free(pnative); free(pcross); free(pcrossResourceDir); if (filelist) { size_t i = 0; while (filelist[i]) { free(filelist[i]); i++; } free(filelist); } return lua_error(l); } // create file listing table lua_newtable(l); // add all files/folders to file listing table char filenamebuf[500]; int isdir; int returnvalue = 0; unsigned int i = 0; // loop through all files: if (ctx) { while ((returnvalue = filelist_GetNextFile(ctx, filenamebuf, sizeof(filenamebuf), &isdir)) == 1) { i++; lua_checkstack(l, 3); int duplicate = 0; // if we list against virtual folders too, // check for this being a duplicate: if (filelist) { unsigned int i2 = 0; while (filelist[i2]) { if (strcasecmp(filelist[i2], filenamebuf) == 0) { duplicate = 1; break; } i2++; } } if (duplicate) { // don't add this one. i--; continue; } lua_pushinteger(l, i); lua_pushstring(l, filenamebuf); lua_settable(l, -3); } // free file list filelist_Free(ctx); } if (filelist) { // add file list to table: i = 0; while (filelist[i]) { lua_pushinteger(l, i + 1); lua_pushstring(l, filelist[i]); lua_settable(l, -3); i++; } // free virtual file list: i = 0; while (filelist[i]) { free(filelist[i]); i++; } free(filelist); } // process error during listing if (returnvalue < 0) { lua_pop(l, 1); // remove file listing table char errmsg[500]; snprintf(errmsg, sizeof(errmsg), "Error while processing ls in folder: %s", pnative); errmsg[sizeof(errmsg)-1] = 0; lua_pushstring(l, errmsg); free(pnative); free(pcross); free(pcrossResourceDir); return lua_error(l); } // return file list free(pnative); free(pcross); free(pcrossResourceDir); return 1; }
/// Returns a table array containing all the file names of the // files in the specified directory. // // <b>Important</b>: this function lists both files from actual directories on // hard disk, and virtual directories loaded through // @{blitwizard.loadResourceArchive|loaded zip resource archives}. // Virtual files will take precedence over real files (you won't // receive duplicates). // // If you don't want virtual files listed (e.g. because you want // to examine any directory supplied by the user and not part of your // project) // @function ls // @tparam string directory path, empty string ("") for current directory // @tparam boolean virtual_files (optional) Specify true to list virtual files inside virtual directories aswell (the default behaviour), false to list only files in the actual file system on disk // @usage // -- list all files in current directory: // for i,file in ipairs(os.ls("")) do // print("file name: " .. file) // end int luafuncs_ls(lua_State* l) { const char* p = lua_tostring(l, 1); if (!p) { lua_pushstring(l, "First argument is not a valid path string"); return lua_error(l); } int list_virtual = 1; if (lua_gettop(l) >= 2 && lua_type(l, 2) != LUA_TNIL) { if (lua_type(l, 2) != LUA_TNUMBER) { return haveluaerror(l, badargument1, 2, "os.ls", "boolean or nil", lua_strtype(l, 2)); } list_virtual = lua_toboolean(l, 2); } // get virtual filelist: char** filelist = NULL; #ifdef USE_PHYSFS if (list_virtual) { filelist = resource_FileList(p); } #endif // get iteration context for "real" on disk directory: struct filelistcontext* ctx = filelist_Create(p); if (!ctx && (!list_virtual || !filelist)) { char errmsg[500]; snprintf(errmsg, sizeof(errmsg), "Failed to ls folder: %s", p); errmsg[sizeof(errmsg)-1] = 0; lua_pushstring(l, errmsg); return lua_error(l); } // create file listing table lua_newtable(l); // add all files/folders to file listing table char filenamebuf[500]; int isdir; int returnvalue; int i = 0; // loop through all files: while ((returnvalue = filelist_GetNextFile(ctx, filenamebuf, sizeof(filenamebuf), &isdir)) == 1) { i++; lua_checkstack(l, 3); int duplicate = 0; // if we list against virtual folders too, // check for this being a duplicate: if (filelist) { size_t i = 0; while (filelist[i]) { if (strcasecmp(filelist[i], filenamebuf) == 0) { duplicate = 1; break; } i++; } } if (duplicate) { // don't add this one. i--; continue; } lua_pushinteger(l, i); lua_pushstring(l, filenamebuf); lua_settable(l, -3); } // free file list filelist_Free(ctx); // free virtual file list: if (filelist) { size_t i = 0; while (filelist[i]) { free(filelist[i]); i++; } free(filelist); } // process error during listing if (returnvalue < 0) { lua_pop(l, 1); // remove file listing table char errmsg[500]; snprintf(errmsg, sizeof(errmsg), "Error while processing ls in folder: %s", p); errmsg[sizeof(errmsg)-1] = 0; lua_pushstring(l, errmsg); return lua_error(l); } // return file list return 1; }