root/lib/lua/luac.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fatal
  2. cannot
  3. usage
  4. doargs
  5. combine
  6. writer
  7. pmain
  8. main

   1 /*
   2 ** $Id: luac.c,v 1.54 2006/06/02 17:37:11 lhf Exp $
   3 ** Lua compiler (saves bytecodes to files; also list bytecodes)
   4 ** See Copyright Notice in lua.h
   5 */
   6 
   7 #include <errno.h>
   8 #include <stdio.h>
   9 #include <stdlib.h>
  10 #include <string.h>
  11 
  12 #define luac_c
  13 #define LUA_CORE
  14 
  15 #include "lua.h"
  16 #include "lauxlib.h"
  17 
  18 #include "ldo.h"
  19 #include "lfunc.h"
  20 #include "lmem.h"
  21 #include "lobject.h"
  22 #include "lopcodes.h"
  23 #include "lstring.h"
  24 #include "lundump.h"
  25 
  26 #define PROGNAME        "luac"          /* default program name */
  27 #define OUTPUT          PROGNAME ".out" /* default output file */
  28 
  29 static int listing=0;                   /* list bytecodes? */
  30 static int dumping=1;                   /* dump bytecodes? */
  31 static int stripping=0;                 /* strip debug information? */
  32 static char Output[]={ OUTPUT };        /* default output file name */
  33 static const char* output=Output;       /* actual output file name */
  34 static const char* progname=PROGNAME;   /* actual program name */
  35 
  36 static void fatal(const char* message)
  37 {
  38  fprintf(stderr,"%s: %s\n",progname,message);
  39  exit(EXIT_FAILURE);
  40 }
  41 
  42 static void cannot(const char* what)
  43 {
  44  fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno));
  45  exit(EXIT_FAILURE);
  46 }
  47 
  48 static void usage(const char* message)
  49 {
  50  if (*message=='-')
  51   fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message);
  52  else
  53   fprintf(stderr,"%s: %s\n",progname,message);
  54  fprintf(stderr,
  55  "usage: %s [options] [filenames].\n"
  56  "Available options are:\n"
  57  "  -        process stdin\n"
  58  "  -l       list\n"
  59  "  -o name  output to file " LUA_QL("name") " (default is \"%s\")\n"
  60  "  -p       parse only\n"
  61  "  -s       strip debug information\n"
  62  "  -v       show version information\n"
  63  "  --       stop handling options\n",
  64  progname,Output);
  65  exit(EXIT_FAILURE);
  66 }
  67 
  68 #define IS(s)   (strcmp(argv[i],s)==0)
  69 
  70 static int doargs(int argc, char* argv[])
  71 {
  72  int i;
  73  int version=0;
  74  if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0];
  75  for (i=1; i<argc; i++)
  76  {
  77   if (*argv[i]!='-')                    /* end of options; keep it */
  78    break;
  79   else if (IS("--"))                    /* end of options; skip it */
  80   {
  81    ++i;
  82    if (version) ++version;
  83    break;
  84   }
  85   else if (IS("-"))                     /* end of options; use stdin */
  86    break;
  87   else if (IS("-l"))                    /* list */
  88    ++listing;
  89   else if (IS("-o"))                    /* output file */
  90   {
  91    output=argv[++i];
  92    if (output==NULL || *output==0) usage(LUA_QL("-o") " needs argument");
  93    if (IS("-")) output=NULL;
  94   }
  95   else if (IS("-p"))                    /* parse only */
  96    dumping=0;
  97   else if (IS("-s"))                    /* strip debug information */
  98    stripping=1;
  99   else if (IS("-v"))                    /* show version */
 100    ++version;
 101   else                                  /* unknown option */
 102    usage(argv[i]);
 103  }
 104  if (i==argc && (listing || !dumping))
 105  {
 106   dumping=0;
 107   argv[--i]=Output;
 108  }
 109  if (version)
 110  {
 111   printf("%s  %s\n",LUA_RELEASE,LUA_COPYRIGHT);
 112   if (version==argc-1) exit(EXIT_SUCCESS);
 113  }
 114  return i;
 115 }
 116 
 117 #define toproto(L,i) (clvalue(L->top+(i))->l.p)
 118 
 119 static const Proto* combine(lua_State* L, int n)
 120 {
 121  if (n==1)
 122   return toproto(L,-1);
 123  else
 124  {
 125   int i,pc;
 126   Proto* f=luaF_newproto(L);
 127   setptvalue2s(L,L->top,f); incr_top(L);
 128   f->source=luaS_newliteral(L,"=(" PROGNAME ")");
 129   f->maxstacksize=1;
 130   pc=2*n+1;
 131   f->code=luaM_newvector(L,pc,Instruction);
 132   f->sizecode=pc;
 133   f->p=luaM_newvector(L,n,Proto*);
 134   f->sizep=n;
 135   pc=0;
 136   for (i=0; i<n; i++)
 137   {
 138    f->p[i]=toproto(L,i-n-1);
 139    f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i);
 140    f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1);
 141   }
 142   f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0);
 143   return f;
 144  }
 145 }
 146 
 147 static int writer(lua_State* L, const void* p, size_t size, void* u)
 148 {
 149  UNUSED(L);
 150  return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0);
 151 }
 152 
 153 struct Smain {
 154  int argc;
 155  char** argv;
 156 };
 157 
 158 static int pmain(lua_State* L)
 159 {
 160  struct Smain* s = (struct Smain*)lua_touserdata(L, 1);
 161  int argc=s->argc;
 162  char** argv=s->argv;
 163  const Proto* f;
 164  int i;
 165  if (!lua_checkstack(L,argc)) fatal("too many input files");
 166  for (i=0; i<argc; i++)
 167  {
 168   const char* filename=IS("-") ? NULL : argv[i];
 169   if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1));
 170  }
 171  f=combine(L,argc);
 172  if (listing) luaU_print(f,listing>1);
 173  if (dumping)
 174  {
 175   FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
 176   if (D==NULL) cannot("open");
 177   lua_lock(L);
 178   luaU_dump(L,f,writer,D,stripping);
 179   lua_unlock(L);
 180   if (ferror(D)) cannot("write");
 181   if (fclose(D)) cannot("close");
 182  }
 183  return 0;
 184 }
 185 
 186 int main(int argc, char* argv[])
 187 {
 188  lua_State* L;
 189  struct Smain s;
 190  int i=doargs(argc,argv);
 191  argc-=i; argv+=i;
 192  if (argc<=0) usage("no input files given");
 193  L=lua_open();
 194  if (L==NULL) fatal("not enough memory for state");
 195  s.argc=argc;
 196  s.argv=argv;
 197  if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1));
 198  lua_close(L);
 199  return EXIT_SUCCESS;
 200 }

/* [<][>][^][v][top][bottom][index][help] */