title: Lua: Calling Lua function which returns a string, many times. How to make it so there are fields which cross over to the next instance
body: <p>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. </p>
  
  <p><a href="https://stackoverflow.com/questions/6511432/managing-stack-with-lua-and-c">Managing stack with Lua and C++</a></p>
  
  <p>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) </p>
  
  <p>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. </p>
  
  <p>My C++ application uses my open source interface called FileDigger which allows me to fill in logic to perform beforeDig() and afterDig() and fileFound()</p>
  
  <p>currently this is my code:</p>
  
  <pre><code>#include "LanguageShovel.h"
  #include &lt;FileDigger/src/FileDigger.h&gt;
  #include &lt;fstream&gt;
  #include &lt;iostream&gt;
  
  extern "C" {
  #include &lt;lua/src/lua.h&gt;
  #include &lt;lua/src/lauxlib.h&gt;
  #include &lt;lua/src/lualib.h&gt;
  }
  
  void LanguageShovel::BeforeDig(string path) {
      cout &lt;&lt; "Searching Files..." &lt;&lt; endl;
  }
  
  void LanguageShovel::AfterDig(string path) {
  
      for (int i = 0 ; i &lt; list_strings.size(); i++) 
      {
          cout &lt;&lt; list_strings[i] &lt;&lt; endl;
      }
  
      cout &lt;&lt; list_strings.size() &lt;&lt; endl;
      cout &lt;&lt; "Finished..." &lt;&lt; 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 &amp;&amp; lua_istable(L,-1))
              {
                  int len = lua_objlen(L,-1);
                  // list_strings.reserve(len);
                  for (int i=0; i &lt; 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, &amp;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 &lt; 2 ) {
          cout &lt;&lt; "Not enough arguments:\n\n Ex: a C:\\cpp\\a .cpp .h";
  
          int any_number;
          std::cout &lt;&lt; "\n\n";
          std::cout &lt;&lt; "Please enter a number to end the program:";
          std::cout &lt;&lt; "\n\n";
          std::cin &gt;&gt; any_number;
          return 1;
      }
  
      FileDigger f;
      LanguageShovel s;
      string directory = argv[1];
  
      // Get filters from arguments
      for (int i = 2; i &lt; argc; i++) {
          s.AddFilter(argv[i]);
      }
  
      f.Dig(directory, s);
  
      int any_number;
      std::cout &lt;&lt; "\n\n";
      std::cout &lt;&lt; "Please enter a number to end the program:";
      std::cout &lt;&lt; "\n\n";
      //std::cin &gt;&gt; any_number;
      return 0;
  }
  </code></pre>
  
  <p>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()</p>
  
  <p>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.</p>
  
  <p>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(). </p>
  
  <p>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</p>