So, I have a C++ program which recursively goes through a directory tree and calls a certain lua function on all of the files in that directory.
Managing stack with Lua and C++
you can read my previous question for some insight on exactly how this works, but essentially it's pretty simple. The lua function returns 0 to many strings. However, the results of one lua return can effect the results of a later lua return. (specifically, I'm trying to remove duplicate strings, and some other things)
I'm wondering if there is a way to set up so that I can still make these lua calls, but have the lua state remain open for the duration of the recursive operations. In this way, I should retain variables, and other important information during this recursive process, which would allow me to extend the functionality of my program easily.
My C++ application uses my open source interface called FileDigger which allows me to fill in logic to perform beforeDig() and afterDig() and fileFound()
currently this is my code:
#include "LanguageShovel.h"
#include <FileDigger/src/FileDigger.h>
#include <fstream>
#include <iostream>
extern "C" {
#include <lua/src/lua.h>
#include <lua/src/lauxlib.h>
#include <lua/src/lualib.h>
}
void LanguageShovel::BeforeDig(string path) {
cout << "Searching Files..." << endl;
}
void LanguageShovel::AfterDig(string path) {
for (int i = 0 ; i < list_strings.size(); i++)
{
cout << list_strings[i] << endl;
}
cout << list_strings.size() << endl;
cout << "Finished..." << endl;
}
void LanguageShovel::FileFound(string path) {
list_strings.push_back(path);
int error = 0;
lua_State *L = lua_open();
luaL_openlibs(L);
// Push function to stack
if ((error = luaL_loadfile(L, "src/language.lua")) == 0)
{
// Push path to stack
lua_pushstring(L, path.c_str());
// Pop stack and call lua script, to return a single table
if ((error = lua_pcall(L, 1, 1, 0)) == 0)
{
// If single value on stack, and is table
if (lua_gettop(L) == 1 && lua_istable(L,-1))
{
int len = lua_objlen(L,-1);
// list_strings.reserve(len);
for (int i=0; i < len; i++)
{
// Push index on stack for gettable
lua_pushinteger(L,i + 1);
lua_gettable(L,-2);
size_t strLen = 0;
const char *s = lua_tolstring(L,-1, &strLen);
if (s)
{
// Lua strings may not be null terminated
// Assign will ensure null terminated end
list_strings.push_back(s);
list_strings.back().assign(s,strLen);
}
// Pop the string when finished with it
lua_pop(L,1);
}
}
}
}
lua_close(L);
}
void LanguageShovel::DirectoryFound(string path) {
}
int main(int argc, char *argv[]) {
if( argc < 2 ) {
cout << "Not enough arguments:\n\n Ex: a C:\\cpp\\a .cpp .h";
int any_number;
std::cout << "\n\n";
std::cout << "Please enter a number to end the program:";
std::cout << "\n\n";
std::cin >> any_number;
return 1;
}
FileDigger f;
LanguageShovel s;
string directory = argv[1];
// Get filters from arguments
for (int i = 2; i < argc; i++) {
s.AddFilter(argv[i]);
}
f.Dig(directory, s);
int any_number;
std::cout << "\n\n";
std::cout << "Please enter a number to end the program:";
std::cout << "\n\n";
//std::cin >> any_number;
return 0;
}
So as you can see, it creates a FileDigger class, and a Shovel. The shovel is the interface where you place your logic. After those are created it starts the recursive process by calling dig()
This calls beforeDig() then starts the recursive process. when a file is found, it calls fileFound() which then gets the strings and puts them into a vector. After the dig is finished I simply print the strings.
As you'll see, I create and remove a state in the fileFound function. I'm thinking of instead of doing this, I should start a Lua state in beforeDig() and end it in afterDig().
Also, right now my lua source is being called directly in the .lua file instead of caling a specific function which contains that code. I think I'll probably need to change that... So... If you have any more questions I'll answer them, but let's start the discussion! :D