lua-users home
lua-l archive

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


On Wed, Aug 17, 2005 at 12:15:22AM +1000, David Burgess wrote:

> 1) we often package the Lua code as Windows resources. We found
> this to be simple and convenient. A Lua script that creates the resource
> file does most of the work. When the script is in an associated DLL it is
> rather simple (and quick) to write a loader that loads the code from a resource.
> This approach requires some small mods to loadlib.c in both 5.0.2 and 5.1w6.

One platform-independent approach to doing this is to byte-compile the
Lua code, load it into a static const char* array, and pull it into the
interpreter with luaL_loadbuffer.  With a sufficient makefile mechanism
(I use Perforce Jam), this only adds a few seconds to the
edit-compile-debug cycle.

The code I wrote the generate .c/.h files from the Lua byte-code is:

    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>

    /* various buffers */
    #define BUFSIZE 2048
    #define FNBUFSZ 256

    /* number of hex codes allowed on a single line */
    #define LINELEN 10

    char buf[BUFSIZE];
    char fnbuf[FNBUFSZ];

    char func_name[BUFSIZE];

    int main( int argc, char** argv )
    {
      int i;
      long int j;
      char* s;
      size_t nbytes;
      FILE* lf;
      FILE* cf;
      FILE* hf;

      if (argc < 3) return 1;

      lf = fopen(argv[1],"r");

      snprintf(fnbuf, FNBUFSZ, "%s.h", argv[2]);
      hf = fopen(fnbuf,"w");

      snprintf(fnbuf, FNBUFSZ, "%s.c", argv[2]);
      cf = fopen(fnbuf,"w");

      strncpy( fnbuf, argv[2], FNBUFSZ );
      for(s = fnbuf; *s; ++s) {
        if (*s == '/')
          *s = '_';
        else
          *s = toupper(*s);
      }

      strncpy(func_name,argv[2],BUFSIZE);
      s = strrchr(func_name, '/');
      if (s)
        memmove(func_name,s+1,strlen(s));

      fprintf(hf, "#ifndef __%s__H__\n", fnbuf);
      fprintf(hf, "#define __%s__H__\n", fnbuf);
      fprintf(hf, "#include <stddef.h>\n");
      fprintf(hf, "extern const char lc_%s_data[];\n" , func_name);
      fprintf(hf, "extern const size_t lc_%s_size;\n", func_name);
      fprintf(hf, "#endif /* __%s__H__ */\n", fnbuf);

      fclose(hf);

      fprintf(cf, "#include \"%s.h\"\n",argv[2]);
      fprintf(cf, "const char lc_%s_data[] = {\n", func_name);
      j = 0;
      while(!feof(lf)) {
        nbytes = fread(buf, sizeof(char), BUFSIZE, lf);
        for(i=0; i < nbytes; ++i) {
          fprintf(cf, "  0x%02hhx,", buf[i]);
          if (++j % LINELEN == 0) {
            fprintf(cf,"\n");
          }
        }
      }
      fprintf(cf,"\n  0x00\n};\n\n");
      fprintf(cf,"const size_t lc_%s_size = %ld;\n\n", func_name, j);

      fclose(cf);

      return 0;
    }

I haven't hit any upper limits in terms of script size, but I haven't
yet tried to stuff large scripts into static data area.

Cheers!

-- 
Shannon Stewman         | Let us walk through the waning night,
Caught in a whirlpool,  | As dawn-rays tickle our toes, the dew soothes
A quartering act:       | Our blistered soles, and damp bones stir
Solitude or society?    | As crimson cracks under the blue-grey sky.