Branch: Tag:

1995-08-09

1995-08-09 10:21:55 by Fredrik Hübinette (Hubbe) <hubbe@hubbe.net>

ulpc dist

Rev: bin/create_testsuite:1.1.1.1
Rev: bin/hilfe.lpc:1.1.1.1
Rev: bin/rsif:1.1.1.1
Rev: bin/uhttpd.lpc:1.1.1.1
Rev: doc/README:1.1.1.1
Rev: doc/builtin/aggregate:1.1.1.1
Rev: doc/builtin/aggregate_list:1.1.1.1
Rev: doc/builtin/aggregate_mapping:1.1.1.1
Rev: doc/builtin/all_efuns:1.1.1.1
Rev: doc/builtin/allocate:1.1.1.1
Rev: doc/builtin/arrayp:1.1.1.1
Rev: doc/builtin/backtrace:1.1.1.1
Rev: doc/builtin/call_function:1.1.1.1
Rev: doc/builtin/call_out:1.1.1.1
Rev: doc/builtin/call_out_info:1.1.1.1
Rev: doc/builtin/catch:1.1.1.1
Rev: doc/builtin/clone:1.1.1.1
Rev: doc/builtin/combine_path:1.1.1.1
Rev: doc/builtin/compile_file:1.1.1.1
Rev: doc/builtin/compile_string:1.1.1.1
Rev: doc/builtin/copy_value:1.1.1.1
Rev: doc/builtin/crypt:1.1.1.1
Rev: doc/builtin/ctime:1.1.1.1
Rev: doc/builtin/destruct:1.1.1.1
Rev: doc/builtin/equal:1.1.1.1
Rev: doc/builtin/exit:1.1.1.1
Rev: doc/builtin/explode:1.1.1.1
Rev: doc/builtin/find_call_out:1.1.1.1
Rev: doc/builtin/floatp:1.1.1.1
Rev: doc/builtin/function_name:1.1.1.1
Rev: doc/builtin/function_object:1.1.1.1
Rev: doc/builtin/functionp:1.1.1.1
Rev: doc/builtin/hash:1.1.1.1
Rev: doc/builtin/implode:1.1.1.1
Rev: doc/builtin/indices:1.1.1.1
Rev: doc/builtin/intp:1.1.1.1
Rev: doc/builtin/listp:1.1.1.1
Rev: doc/builtin/lower_case:1.1.1.1
Rev: doc/builtin/m_delete:1.1.1.1
Rev: doc/builtin/mappingp:1.1.1.1
Rev: doc/builtin/mkmapping:1.1.1.1
Rev: doc/builtin/next_object:1.1.1.1
Rev: doc/builtin/object_program:1.1.1.1
Rev: doc/builtin/objectp:1.1.1.1
Rev: doc/builtin/programp:1.1.1.1
Rev: doc/builtin/query_host_name:1.1.1.1
Rev: doc/builtin/query_num_arg:1.1.1.1
Rev: doc/builtin/random:1.1.1.1
Rev: doc/builtin/regexpp:1.1.1.1
Rev: doc/builtin/remove_call_out:1.1.1.1
Rev: doc/builtin/replace:1.1.1.1
Rev: doc/builtin/reverse:1.1.1.1
Rev: doc/builtin/rusage:1.1.1.1
Rev: doc/builtin/search:1.1.1.1
Rev: doc/builtin/sizeof:1.1.1.1
Rev: doc/builtin/sscanf:1.1.1.1
Rev: doc/builtin/stringp:1.1.1.1
Rev: doc/builtin/sum:1.1.1.1
Rev: doc/builtin/this_object:1.1.1.1
Rev: doc/builtin/throw:1.1.1.1
Rev: doc/builtin/time:1.1.1.1
Rev: doc/builtin/trace:1.1.1.1
Rev: doc/builtin/upper_case:1.1.1.1
Rev: doc/builtin/values:1.1.1.1
Rev: doc/builtin/zero_type:1.1.1.1
Rev: doc/files/cd:1.1.1.1
Rev: doc/files/exec:1.1.1.1
Rev: doc/files/file:1.1.1.1
Rev: doc/files/file_stat:1.1.1.1
Rev: doc/files/fork:1.1.1.1
Rev: doc/files/get_dir:1.1.1.1
Rev: doc/files/getcwd:1.1.1.1
Rev: doc/files/mkdir:1.1.1.1
Rev: doc/files/mv:1.1.1.1
Rev: doc/files/perror:1.1.1.1
Rev: doc/files/port:1.1.1.1
Rev: doc/files/rm:1.1.1.1
Rev: doc/lpc/command_line_options:1.1.1.1
Rev: doc/lpc/control_structures:1.1.1.1
Rev: doc/lpc/hilfe.hilfe:1.1.1.1
Rev: doc/lpc/how_to_make_modules:1.1.1.1
Rev: doc/manual/i-overview.html:1.1.1.1
Rev: doc/manual/index.html:1.1.1.1
Rev: doc/manual/t-hello.html:1.1.1.1
Rev: doc/manual/ulpc-inside3.gif:1.1.1.1
Rev: doc/math/acos:1.1.1.1
Rev: doc/math/asin:1.1.1.1
Rev: doc/math/atan:1.1.1.1
Rev: doc/math/ceil:1.1.1.1
Rev: doc/math/cos:1.1.1.1
Rev: doc/math/exp:1.1.1.1
Rev: doc/math/floor:1.1.1.1
Rev: doc/math/log:1.1.1.1
Rev: doc/math/pow:1.1.1.1
Rev: doc/math/sin:1.1.1.1
Rev: doc/math/sqrt:1.1.1.1
Rev: doc/math/tan:1.1.1.1
Rev: doc/operators/addition:1.1.1.1
Rev: doc/regexp/regexp:1.1.1.1
Rev: doc/simulated/PI:1.1.1.1
Rev: doc/simulated/capitalize:1.1.1.1
Rev: doc/simulated/code_value:1.1.1.1
Rev: doc/simulated/describe_backtrace:1.1.1.1
Rev: doc/simulated/file_size:1.1.1.1
Rev: doc/simulated/filter_array:1.1.1.1
Rev: doc/simulated/get_function:1.1.1.1
Rev: doc/simulated/getenv:1.1.1.1
Rev: doc/simulated/l_sizeof:1.1.1.1
Rev: doc/simulated/m_indices:1.1.1.1
Rev: doc/simulated/m_sizeof:1.1.1.1
Rev: doc/simulated/m_values:1.1.1.1
Rev: doc/simulated/map_array:1.1.1.1
Rev: doc/simulated/master:1.1.1.1
Rev: doc/simulated/member_array:1.1.1.1
Rev: doc/simulated/popen:1.1.1.1
Rev: doc/simulated/previous_object:1.1.1.1
Rev: doc/simulated/read_bytes:1.1.1.1
Rev: doc/simulated/regexp:1.1.1.1
Rev: doc/simulated/search_array:1.1.1.1
Rev: doc/simulated/sort_array:1.1.1.1
Rev: doc/simulated/spawn:1.1.1.1
Rev: doc/simulated/strlen:1.1.1.1
Rev: doc/simulated/strstr:1.1.1.1
Rev: doc/simulated/sum_arrays:1.1.1.1
Rev: doc/simulated/this_function:1.1.1.1
Rev: doc/simulated/write:1.1.1.1
Rev: doc/simulated/write_file:1.1.1.1
Rev: doc/sprintf/sprintf:1.1.1.1
Rev: doc/types/array:1.1.1.1
Rev: doc/types/float:1.1.1.1
Rev: doc/types/function:1.1.1.1
Rev: doc/types/int:1.1.1.1
Rev: doc/types/list:1.1.1.1
Rev: doc/types/mapping:1.1.1.1
Rev: doc/types/object:1.1.1.1
Rev: doc/types/program:1.1.1.1
Rev: doc/types/string:1.1.1.1
Rev: lib/conftest.h:1.1.1.1
Rev: lib/master.lpc:1.1.1.1
Rev: lib/simulate.lpc:1.1.1.1
Rev: lib/testsuite.lpc:1.1.1.1
Rev: src/BUGS:1.1.1.1
Rev: src/COPYING:1.1.1.1
Rev: src/COPYRIGHT:1.1.1.1
Rev: src/DISCLAIMER:1.1.1.1
Rev: src/Makefile.in:1.1.1.1
Rev: src/README:1.1.1.1
Rev: src/add_efun.c:1.1.1.1
Rev: src/add_efun.h:1.1.1.1
Rev: src/alloca.c:1.1.1.1
Rev: src/array.c:1.1.1.1
Rev: src/array.h:1.1.1.1
Rev: src/backend.c:1.1.1.1
Rev: src/backend.h:1.1.1.1
Rev: src/builtin_efuns.c:1.1.1.1
Rev: src/builtin_efuns.h:1.1.1.1
Rev: src/call_out.c:1.1.1.1
Rev: src/call_out.h:1.1.1.1
Rev: src/callback.c:1.1.1.1
Rev: src/callback.h:1.1.1.1
Rev: src/config.h:1.1.1.1
Rev: src/configure.in:1.1.1.1
Rev: src/debug.c:1.1.1.1
Rev: src/debug.h:1.1.1.1
Rev: src/docode.c:1.1.1.1
Rev: src/docode.h:1.1.1.1
Rev: src/dynamic_buffer.c:1.1.1.1
Rev: src/dynamic_buffer.h:1.1.1.1
Rev: src/efun.h:1.1.1.1
Rev: src/error.c:1.1.1.1
Rev: src/error.h:1.1.1.1
Rev: src/fd_control.c:1.1.1.1
Rev: src/fd_control.h:1.1.1.1
Rev: src/fsort.c:1.1.1.1
Rev: src/fsort.h:1.1.1.1
Rev: src/global.h:1.1.1.1
Rev: src/hashtable.c:1.1.1.1
Rev: src/hashtable.h:1.1.1.1
Rev: src/install-sh:1.1.1.1
Rev: src/interpret.c:1.1.1.1
Rev: src/interpret.h:1.1.1.1
Rev: src/language.y:1.1.1.1
Rev: src/las.c:1.1.1.1
Rev: src/las.h:1.1.1.1
Rev: src/lex.c:1.1.1.1
Rev: src/lex.h:1.1.1.1
Rev: src/list.c:1.1.1.1
Rev: src/list.h:1.1.1.1
Rev: src/lpc_types.c:1.1.1.1
Rev: src/lpc_types.h:1.1.1.1
Rev: src/machine.h.in:1.1.1.1
Rev: src/macros.h:1.1.1.1
Rev: src/main.c:1.1.1.1
Rev: src/main.h:1.1.1.1
Rev: src/mapping.c:1.1.1.1
Rev: src/mapping.h:1.1.1.1
Rev: src/memory.c:1.1.1.1
Rev: src/memory.h:1.1.1.1
Rev: src/module.c:1.1.1.1
Rev: src/module.h:1.1.1.1
Rev: src/modules/efuns.c:1.1.1.1
Rev: src/modules/files/Makefile.in:1.1.1.1
Rev: src/modules/files/configure.in:1.1.1.1
Rev: src/modules/files/datagram.c:1.1.1.1
Rev: src/modules/files/efuns.c:1.1.1.1
Rev: src/modules/files/file.c:1.1.1.1
Rev: src/modules/files/file.h:1.1.1.1
Rev: src/modules/files/file_machine.h.in:1.1.1.1
Rev: src/modules/files/socket.c:1.1.1.1
Rev: src/modules/math/Makefile.in:1.1.1.1
Rev: src/modules/math/configure.in:1.1.1.1
Rev: src/modules/math/math.c:1.1.1.1
Rev: src/modules/regexp/Makefile.in:1.1.1.1
Rev: src/modules/regexp/configure.in:1.1.1.1
Rev: src/modules/regexp/glue.c:1.1.1.1
Rev: src/modules/regexp/regexp.c:1.1.1.1
Rev: src/modules/regexp/regexp.h:1.1.1.1
Rev: src/modules/sprintf/Makefile.in:1.1.1.1
Rev: src/modules/sprintf/configure.in:1.1.1.1
Rev: src/modules/sprintf/sprintf.c:1.1.1.1
Rev: src/object.c:1.1.1.1
Rev: src/object.h:1.1.1.1
Rev: src/opcodes.c:1.1.1.1
Rev: src/opcodes.h:1.1.1.1
Rev: src/operators.c:1.1.1.1
Rev: src/operators.h:1.1.1.1
Rev: src/otable.h:1.1.1.1
Rev: src/port.c:1.1.1.1
Rev: src/port.h:1.1.1.1
Rev: src/program.c:1.1.1.1
Rev: src/program.h:1.1.1.1
Rev: src/rusage.c:1.1.1.1
Rev: src/rusage.h:1.1.1.1
Rev: src/stralloc.c:1.1.1.1
Rev: src/stralloc.h:1.1.1.1
Rev: src/stuff.c:1.1.1.1
Rev: src/stuff.h:1.1.1.1
Rev: src/svalue.c:1.1.1.1
Rev: src/svalue.h:1.1.1.1
Rev: src/todo:1.1.1.1
Rev: src/types.h:1.1.1.1
Rev: src/ualarm.c:1.1.1.1

1: + #include "global.h" + #include "language.h" + #include "array.h" + #include "lex.h" + #include "stralloc.h" + #include "dynamic_buffer.h" + #include "add_efun.h" + #include "hashtable.h" + #include "stuff.h" + #include "memory.h" + #include "interpret.h" + #include "error.h" + #include "object.h" + #include "las.h" + #include "operators.h" + #include "opcodes.h" + #include "builtin_efuns.h"    -  + #include "macros.h" + #include <sys/param.h> + #include <ctype.h> + #include <math.h> + #include <fcntl.h> + #include <errno.h> + #include <time.h> +  + #define LEXDEBUG 0 + #define EXPANDMAX 50000 +  + struct lpc_string *current_file; +  + INT32 current_line; + INT32 old_line; + INT32 total_lines; + INT32 nexpands; + int pragma_all_inline; /* inline all possible inlines */ +  + struct lpc_predef_s + { +  char *name; +  char *value; +  struct lpc_predef_s *next; + }; +  + struct lpc_predef_s *lpc_predefs=0; +  + static int calc(); + static void calc1(); +  + void exit_lex() + { +  while(local_variables) +  { +  int e; +  struct locals *l; +  for(e=0;e<local_variables->current_number_of_locals;e++) +  { +  free_string(local_variables->variable[e].name); +  free_string(local_variables->variable[e].type); +  } +  l=local_variables->next; +  free((char *)local_variables); +  local_variables=l; +  } +  +  if(current_file) free_string(current_file); +  free_reswords(); + } +  + struct keyword reserved_words[] = + { + { "array", F_ARRAY_ID, }, + { "break", F_BREAK, }, + { "case", F_CASE, }, + { "catch", F_CATCH, }, + { "continue", F_CONTINUE, }, + { "default", F_DEFAULT, }, + { "do", F_DO, }, + { "efun", F_EFUN, }, + { "else", F_ELSE, }, + { "float", F_FLOAT_ID, }, + { "for", F_FOR, }, + { "foreach", F_FOREACH, }, + { "function", F_FUNCTION_ID, }, + { "gauge", F_GAUGE, }, + { "if", F_IF, }, + { "inherit", F_INHERIT, }, + { "inline", F_INLINE, }, + { "int", F_INT_ID, }, + { "lambda", F_LAMBDA, }, + { "list", F_LIST_ID, }, + { "mapping", F_MAPPING_ID, }, + { "mixed", F_MIXED_ID, }, + { "nomask", F_NO_MASK, }, + { "object", F_OBJECT_ID, }, + { "private", F_PRIVATE, }, + { "program", F_PROGRAM_ID, }, + { "protected", F_PROTECTED, }, + { "public", F_PUBLIC, }, + { "return", F_RETURN, }, + { "sscanf", F_SSCANF, }, + { "static", F_STATIC, }, + { "string", F_STRING_ID, }, + { "switch", F_SWITCH, }, + { "varargs", F_VARARGS, }, + { "void", F_VOID_ID, }, + { "while", F_WHILE, }, + { "call_other", F_CALL_OTHER, }, + }; +  + struct keyword instr_names[]= + { + { "!", F_NOT }, + { "!=", F_NE }, + { "%", F_MOD }, + { "%=", F_MOD_EQ }, + { "& global", F_GLOBAL_LVALUE }, + { "& local", F_LOCAL_LVALUE }, + { "&", F_AND }, + { "&&", F_LAND }, + { "&=", F_AND_EQ }, + { "*", F_MULTIPLY }, + { "*=", F_MULT_EQ }, + { "+", F_ADD }, + { "++Loop", F_INC_LOOP }, + { "++Loop!=", F_INC_NEQ_LOOP }, + { "++x", F_INC }, + { "+=", F_ADD_EQ }, + { "-", F_SUBTRACT }, + { "-", F_SUBTRACT }, + { "--Loop", F_DEC_LOOP }, + { "--Loop!=", F_DEC_NEQ_LOOP }, + { "--x", F_DEC }, + { "-=", F_SUB_EQ }, + { "/", F_DIVIDE }, + { "/=", F_DIV_EQ }, + { "<", F_LT }, + { "<<", F_LSH }, + { "<<=", F_LSH_EQ }, + { "<=", F_LE }, + { "==", F_EQ }, + { ">", F_GT }, + { ">=", F_GE }, + { ">>", F_RSH }, + { ">>=", F_RSH_EQ }, + { "@", F_PUSH_ARRAY }, + { "^", F_XOR }, + { "^=", F_XOR_EQ }, + { "add 1024 to opcode", F_ADD_1024 }, + { "add 256 to opcode", F_ADD_256 }, + { "add 512 to opcode", F_ADD_512 }, + { "add 768 to opcode", F_ADD_768 }, + { "add X*256 to opcode",F_ADD_256X }, + { "arg+=1024", F_PREFIX_1024 }, + { "arg+=256", F_PREFIX_256 }, + { "arg+=256*X", F_PREFIX_CHARX256 }, + { "arg+=256*XX", F_PREFIX_WORDX256 }, + { "arg+=256*XXX", F_PREFIX_24BITX256 }, + { "arg+=512", F_PREFIX_512 }, + { "arg+=768", F_PREFIX_768 }, + { "assign and pop", F_ASSIGN_AND_POP }, + { "assign global", F_ASSIGN_GLOBAL }, + { "assign global and pop", F_ASSIGN_GLOBAL_AND_POP }, + { "assign local", F_ASSIGN_LOCAL }, + { "assign local and pop", F_ASSIGN_LOCAL_AND_POP }, + { "assign", F_ASSIGN }, + { "branch non zero", F_BRANCH_WHEN_NON_ZERO }, + { "branch when zero", F_BRANCH_WHEN_ZERO }, + { "break", F_BREAK }, + { "case", F_CASE }, + { "cast", F_CAST }, + { "catch", F_CATCH }, + { "const-1", F_CONST_1 }, + { "constant", F_CONSTANT }, + { "continue", F_CONTINUE }, + { "copy_value", F_COPY_VALUE }, + { "default", F_DEFAULT }, + { "do-while", F_DO }, + { "dumb return", F_DUMB_RETURN }, + { "float number", F_FLOAT }, + { "for", F_FOR }, + { "foreach", F_FOREACH }, + { "global", F_GLOBAL }, + { "index", F_INDEX }, + { "indirect", F_INDIRECT }, + { "jump", F_BRANCH }, + { "local function call",F_CALL_LFUN }, + { "local function", F_LFUN }, + { "local", F_LOCAL }, + { "ltosval2", F_LTOSVAL2 }, + { "lvalue to svalue", F_LTOSVAL }, + { "lvalue_list", F_LVALUE_LIST }, + { "mark", F_MARK }, + { "negative number", F_NEG_NUMBER }, + { "number", F_NUMBER }, + { "pop", F_POP_VALUE }, + { "pop_n_elems", F_POP_N_ELEMS }, + { "push 0", F_CONST0 }, + { "push 1", F_CONST1 }, + { "range", F_RANGE }, + { "return", F_RETURN }, + { "return 0", F_RETURN_0 }, + { "sscanf", F_SSCANF }, + { "string", F_STRING }, + { "switch", F_SWITCH }, + { "unary minus", F_NEGATE }, + { "while", F_WHILE }, + { "write opcode", F_WRITE_OPCODE }, + { "x++ and pop", F_INC_AND_POP }, + { "x++", F_POST_INC }, + { "x-- and pop", F_DEC_AND_POP }, + { "x--", F_POST_DEC }, + { "|", F_OR }, + { "|=", F_OR_EQ }, + { "||", F_LOR }, + { "~", F_COMPL }, + }; +  + struct instr instrs[F_MAX_INSTR - F_OFFSET]; +  + struct reserved + { +  struct hash_entry link; +  int token; + }; +  + struct hash_table *reswords; +  + void init_lex() + { +  unsigned int i; +  for(i=0; i<NELEM(instr_names);i++) +  { +  if(instr_names[i].token >= F_MAX_INSTR) +  fatal("Error in instr_names[%u]\n\n",i); +  instrs[instr_names[i].token - F_OFFSET].name = instr_names[i].word; +  } +  +  reswords=create_hash_table(); +  +  for(i=0; i<NELEM(reserved_words); i++) +  { +  struct reserved *r=ALLOC_STRUCT(reserved); +  r->token = reserved_words[i].token; +  r->link.s = make_shared_string(reserved_words[i].word); +  reswords=hash_insert(reswords, &r->link); +  } +  +  /* Enlarge this hashtable heruetically */ +  reswords = hash_rehash(reswords, 2<<my_log2(NELEM(reserved_words))); + } +  + void free_reswords() + { +  free_hashtable(reswords,0); + } +  + char *low_get_f_name(int n,struct program *p) + { +  static char buf[30]; +  +  if (n<F_MAX_OPCODE && instrs[n-F_OFFSET].name) +  { +  return instrs[n-F_OFFSET].name; +  }else if(n >= F_MAX_OPCODE) { +  if(p && +  p->num_constants > n-F_MAX_OPCODE && +  p->constants[n-F_MAX_OPCODE].type==T_FUNCTION && +  p->constants[n-F_MAX_OPCODE].subtype == -1 && +  p->constants[n-F_MAX_OPCODE].u.efun) +  { +  return p->constants[n-F_MAX_OPCODE].u.efun->name->str; +  }else{ +  sprintf(buf, "Call efun %d", n - F_MAX_OPCODE); +  return buf; +  } +  }else{ +  sprintf(buf, "<OTHER %d>", n); +  return buf; +  } + } +  + char *get_f_name(int n) + { +  static char buf[30]; +  if (n<F_MAX_OPCODE && instrs[n-F_OFFSET].name) +  { +  return instrs[n-F_OFFSET].name; +  }else if(n >= F_MAX_OPCODE) { +  if(fp && fp->context.prog && +  fp->context.prog->num_constants > n-F_MAX_OPCODE && +  fp->context.prog->constants[n-F_MAX_OPCODE].type==T_FUNCTION && +  fp->context.prog->constants[n-F_MAX_OPCODE].subtype == -1 && +  fp->context.prog->constants[n-F_MAX_OPCODE].u.efun) +  { +  return fp->context.prog->constants[n-F_MAX_OPCODE].u.efun->name->str; +  }else{ +  sprintf(buf, "Call efun %d", n - F_MAX_OPCODE); +  return buf; +  } +  }else{ +  sprintf(buf, "<OTHER %d>", n); +  return buf; +  } + } +  + /* foo must be a shared string */ + static int lookup_resword(struct lpc_string *s) + { +  struct hash_entry *h; +  h=hash_lookup(reswords, s); +  if(!h) return -1; +  return BASEOF(h, reserved, link)->token; + } +  +  +  + /*** input routines ***/ + struct inputstate + { +  struct inputstate *next; +  int fd; +  char *data; +  INT32 buflen; +  INT32 pos; +  int dont_free_data; +  +  int (*my_getc)(); +  int (*gobble)(int); +  int (*look)(); +  void (*my_ungetc)(int); +  void (*ungetstr)(char *,INT32); + }; +  + struct inputstate *istate=NULL; +  + static void link_inputstate(struct inputstate *i) + { +  i->next=istate; +  istate=i; + } +  + static void free_inputstate(struct inputstate *i) + { +  if(!i) return; +  if(i->fd>=0) close(i->fd); +  if(i->data && !i->dont_free_data) free(i->data); +  free_inputstate(i->next); +  free((char *)i); + } +  + static struct inputstate *new_inputstate(); + static struct inputstate *memory_inputstate(INT32 size); +  + static int default_gobble(int c) + { +  if(istate->look()==c) +  { +  istate->my_getc(); +  return 1; +  }else{ +  return 0; +  } + } +  + static void default_ungetstr(char *s,INT32 len) + { +  link_inputstate(memory_inputstate(len+1000)); +  istate->ungetstr(s,len); + } +  + static void default_ungetc(int s) + { +  char c=s; +  istate->ungetstr(&c,1); + } +  + static int default_look() + { +  int c; +  c=istate->my_getc(); +  istate->my_ungetc(c); +  return c; + } +  + static struct inputstate *new_inputstate() + { +  struct inputstate *i; +  i=(struct inputstate *)xalloc(sizeof(struct inputstate)); +  i->fd=-1; +  i->data=NULL; +  i->next=NULL; +  i->dont_free_data=0; +  i->gobble=default_gobble; +  i->ungetstr=default_ungetstr; +  i->my_ungetc=default_ungetc; +  i->look=default_look; +  return i; + } +  + /*** EOF input ***/ + static int end_getc() { return EOF; } + static int end_gobble(int c) { return c==EOF; } + static void end_ungetc(int c) + { +  if(c==EOF) return; +  default_ungetc(c); + } +  + static struct inputstate *end_inputstate() + { +  struct inputstate *i; +  i=new_inputstate(); +  i->gobble=end_gobble; +  i->look=end_getc; +  i->my_getc=end_getc; +  i->my_ungetc=end_ungetc; +  return i; + } +  + /*** MEMORY input ***/ + static void memory_ungetstr(char *s,INT32 len) + { +  INT32 tmp; +  tmp=MINIMUM(len,istate->pos); +  if(tmp) +  { +  istate->pos -= tmp; +  MEMCPY(istate->data + istate->pos , s+len-tmp , tmp); +  len-=tmp; +  } +  if(len) default_ungetstr(s,len); + } +  + static void memory_ungetc(int s) + { +  if(istate->pos) +  { +  istate->pos --; +  istate->data[istate->pos]=s; +  }else{ +  default_ungetc(s); +  } + } +  + static int memory_getc() + { +  if(istate->pos<istate->buflen) +  { + #if LEXDEBUG>9 +  fprintf(stderr,"lex: reading from memory '%c' (%d).\n",istate->data[istate->pos],istate->data[istate->pos]); + #endif +  return istate->data[(istate->pos)++]; +  }else{ +  struct inputstate *i; +  i=istate; +  istate=i->next; +  if(!i->dont_free_data) free(i->data); +  free((char *)i); +  return istate->my_getc(); +  } + } +  + static int memory_look() + { +  if(istate->pos<istate->buflen) +  { +  return istate->data[istate->pos]; +  }else{ +  struct inputstate *i; +  i=istate; +  istate=i->next; +  if(!i->dont_free_data) free(i->data); +  free((char *)i); +  return istate->look(); +  } + } +  + /* allocate an empty memory state */ + static struct inputstate *memory_inputstate(INT32 size) + { +  struct inputstate *i; +  if(!size) size=10000; +  i=new_inputstate(); +  i->data=xalloc(size); +  i->buflen=size; +  i->pos=size; +  i->ungetstr=memory_ungetstr; +  i->my_getc=memory_getc; +  i->look=memory_look; +  i->my_ungetc=memory_ungetc; +  return i; + } +  + static void prot_memory_ungetstr(char *s,INT32 len) + { +  INT32 tmp; +  tmp=MINIMUM(len,istate->pos); +  if(tmp) +  { +  if(!MEMCMP(istate->data + istate->pos - tmp, s+len-tmp , tmp)) +  { +  istate->pos-=tmp; +  len-=tmp; +  } +  } +  if(len) default_ungetstr(s,len); + } +  + static void prot_memory_ungetc(int s) + { +  if(istate->pos && istate->data[istate->pos-1] == s) +  { +  istate->pos--; +  }else{ +  default_ungetc(s); +  } + } +  + /* allocate a memory, read-only, inputstate */ + static struct inputstate *prot_memory_inputstate(char *data,INT32 len) + { +  struct inputstate *i; +  i=new_inputstate(); +  i->data=data; +  i->buflen=len; +  i->dont_free_data=1; +  i->pos=0; +  i->my_getc=memory_getc; +  i->look=memory_look; +  i->ungetstr=prot_memory_ungetstr; +  i->my_ungetc=prot_memory_ungetc; +  return i; + } +  + /*** FILE input ***/ +  + #define READAHEAD 8192 + static int file_getc() + { +  char buf[READAHEAD]; +  int got; +  do { +  got=read(istate->fd, buf, READAHEAD); +  if(got > 0) +  { +  default_ungetstr(buf, got); +  return istate->my_getc(); +  } +  else if(got==0 || errno != EINTR) +  { +  struct inputstate *i; +  if(got<0 && errno != EINTR) +  my_yyerror("Lex: Read failed with error %d\n",errno); +  +  i=istate->next; +  close(istate->fd); +  free((char *)istate); +  istate=i; +  return istate->my_getc(); +  } +  }while(1); + } +  + static struct inputstate *file_inputstate(int fd) + { +  struct inputstate *i; +  i=new_inputstate(); +  i->fd=fd; +  i->my_getc=file_getc; +  return i; + } +  + static int GETC() + { +  int c; +  c=istate->my_getc(); +  if(c=='\n') current_line++; +  return c; + } +  + static void UNGETC(int c) + { +  if(c=='\n') current_line--; +  istate->my_ungetc(c); + } +  + static void UNGETSTR(char *s,INT32 len) + { +  INT32 e; +  for(e=0;e<len;e++) if(s[e]=='\n') current_line--; +  istate->ungetstr(s,len); + } +  + static int GOBBLE(char c) + { +  if(istate->gobble(c)) +  { +  if(c=='\n') current_line++; +  return 1; +  }else{ +  return 0; +  } + } +  + #define LOOK() (istate->look()) + #define SKIPWHITE() { int c; while(isspace(c=GETC())); UNGETC(c); } + #define SKIPTO(X) { int c; while((c=GETC())!=(X) && (c!=EOF)); } + #define SKIPUPTO(X) { int c; while((c=GETC())!=(X) && (c!=EOF)); UNGETC(c); } + #define READBUF(X) { \ +  register unsigned INT32 p; \ +  register int C; \ +  for(p=0;(C=GETC())!=EOF && p<sizeof(buf) && (X);p++) \ +  buf[p]=C; \ +  if(p==sizeof(buf)) { \ +  yyerror("Internal buffer overflow.\n"); p--; \ +  } \ +  UNGETC(C); \ +  buf[p]=0; \ + } +  + static char buf[1024]; +  + /*** Define handling ***/ +  + struct define + { +  struct hash_entry link; /* must be first */ +  void (*magic)(); +  int args; +  struct array *parts; + }; +  + struct hash_table *defines = 0; +  + #define find_define(N) (defines?BASEOF(hash_lookup(defines, N), define, link):0) +  + /* argument must be shared string */ + static void undefine(struct lpc_string *name) + { +  struct define *d; +  +  d=find_define(name); +  +  if(!d) return; +  +  defines=hash_unlink(defines, & d->link); +  free_string(d->link.s); +  free_array(d->parts); +  free((char *)d); + } +  + /* name and as are supposed to be SHARED strings */ + static void add_define(struct lpc_string *name, +  int args, +  int parts_on_stack, +  void (*magic)()) + { +  struct define *d; +  +  f_aggregate(parts_on_stack); +  if(sp[-1].type != T_ARRAY) +  { +  yyerror("Define failed for unknown reason.\n"); +  free_string(name); +  pop_stack(); +  return; +  } +  + #if 0 +  if(find_define(name)) +  { +  my_yyerror("Redefining '%s'",name->str); +  free_string(name); +  pop_stack(); +  return; +  } + #else +  undefine(name); + #endif +  +  d=(struct define *)xalloc(sizeof(struct define)); +  d->link.s=name; +  d->args=args; +  d->magic=magic; +  d->parts=sp[-1].u.array; +  sp--; +  +  defines=hash_insert(defines, & d->link); + } +  + static void simple_add_define(char *name,char *as,void (*magic)()) + { +  if(magic) +  { +  add_define(make_shared_string(name),0,0,magic); +  }else{ +  push_string(make_shared_string(as)); +  add_define(make_shared_string(name),0,1,magic); +  } + } +  + void free_one_define(struct hash_entry *h) + { +  struct define *d; +  d=BASEOF(h, define, link); +  if(d->parts) free_array(d->parts); +  free((void *)d); + } +  + static void free_all_defines() + { +  if(defines) +  free_hashtable(defines, free_one_define); +  defines=0; + } +  + static void do_define() + { +  int c,e,t,argc; +  struct svalue *save_sp=sp; +  struct lpc_string *s, *s2; +  +  SKIPWHITE(); +  READBUF(isidchar(C)); +  +  s=make_shared_string(buf); +  +  if(GOBBLE('(')) +  { +  argc=0; +  +  SKIPWHITE(); +  READBUF(isidchar(C)); +  if(buf[0]) +  { +  push_string(make_shared_string(buf)); +  argc++; +  SKIPWHITE(); +  while(GOBBLE(',')) +  { +  SKIPWHITE(); +  READBUF(isidchar(C)); +  push_string(make_shared_string(buf)); +  argc++; +  } +  } +  SKIPWHITE(); +  +  if(!GOBBLE(')')) +  yyerror("Missing ')'"); +  }else{ +  argc=0; +  } +  +  init_buf(); +  t=0; +  sp->type=T_STRING; +  sp->u.string=make_shared_string(""); +  sp++; +  +  while(1) +  { +  c=GETC(); +  if(c=='\\') if(GOBBLE('\n')) continue; +  if( (t!=!!isidchar(c) && argc>0) || c=='\n' || c==EOF) +  { +  s2=free_buf(); +  for(e=0;e<argc;e++) +  { +  if(save_sp[e].u.string==s2) +  { +  free_string(s2); +  push_int(e); +  break; +  } +  } +  if(e==argc) +  { +  push_string(s2); +  if(sp[-2].type==T_STRING) f_add(); +  } +  if(c=='\n' || c==EOF) +  { +  push_string(make_shared_string(" ")); +  if(sp[-2].type==T_STRING) f_add(); +  break; +  } +  t=!!isidchar(c); +  init_buf(); +  } +  my_putchar(c); +  } +  UNGETC(c); +  add_define(s,argc,sp-save_sp-argc,0); +  while(sp>save_sp) pop_stack(); + } +  + /* s is a shared string */ + static int expand_define(struct lpc_string *s, int save_newline) + { +  struct svalue *save_sp=sp; +  struct define *d; +  int len,e,tmp,args; +  d=find_define(s); +  if(!d) return 0; +  +  if(nexpands>EXPANDMAX) +  { +  yyerror("Macro limit exceeded."); +  return 0; +  } +  +  if(d->magic) +  { +  d->magic(); +  return 1; +  } +  +  if(!save_newline) +  { +  SKIPWHITE(); +  }else{ +  do { e=GETC(); }while(isspace(e) && e!='\n'); +  UNGETC(e); +  } +  +  if(GOBBLE('(')) +  { +  int parlvl,quote; +  int c; +  args=0; +  +  SKIPWHITE(); +  init_buf(); +  parlvl=1; +  quote=0; +  while(parlvl) +  { +  switch(c=GETC()) +  { +  case EOF: +  yyerror("Unexpected end of file."); +  while(sp>save_sp) pop_stack(); +  return 0; +  case '"': if(!(quote&2)) quote^=1; break; +  case '\'': if(!(quote&1)) quote^=2; break; +  case '(': if(!quote) parlvl++; break; +  case ')': if(!quote) parlvl--; break; +  case '\\': my_putchar(c); c=GETC(); break; +  case ',': +  if(!quote && parlvl==1) +  { +  push_string(free_buf()); +  init_buf(); +  args++; +  continue; +  } +  } +  if(parlvl) my_putchar(c); +  } +  push_string(free_buf()); +  if(args==0 && !d->args && !sp[-1].u.string->len) +  { +  pop_stack(); +  }else{ +  args++; +  } +  }else{ +  args=0; +  } +  +  if(args>d->args) +  { +  my_yyerror("Too many arguments to macro '%s'.\n",s->str); +  while(sp>save_sp) pop_stack(); +  return 0; +  } +  +  if(args<d->args) +  { +  my_yyerror("Too few arguments to macro '%s'.\n",s->str); +  while(sp>save_sp) pop_stack(); +  return 0; +  } +  len=0; +  for(e=d->parts->size-1;e>=0;e--) +  { +  switch(ITEM(d->parts)[e].type) +  { +  case T_STRING: +  tmp=ITEM(d->parts)[e].u.string->len; +  UNGETSTR(ITEM(d->parts)[e].u.string->str,tmp); +  break; +  +  case T_INT: +  tmp=save_sp[ITEM(d->parts)[e].u.integer].u.string->len; +  UNGETSTR(save_sp[ITEM(d->parts)[e].u.integer].u.string->str,tmp); +  break; +  +  default: tmp=0; +  } +  len+=tmp; +  } +  while(sp>save_sp) pop_stack(); +  nexpands+=len; +  return 1; + } +  + /*** Handle include ****/ +  + static void handle_include(char *name) + { +  int fd; +  char buf[400]; +  +  push_string(make_shared_string(name)); +  push_string(current_file); +  reference_shared_string(current_file); +  +  SAFE_APPLY_MASTER("handle_include",2); +  +  if(sp[-1].type != T_STRING) +  { +  my_yyerror("Couldn't include file '%s'.",name); +  return; +  } +  +  fd=open(sp[-1].u.string->str,O_RDONLY); +  if(fd < 0) +  { +  my_yyerror("Couldn't open file to include '%s'.",sp[-1].u.string->str); +  return; +  } +  +  UNGETSTR("\" 2",3); +  UNGETSTR(current_file->str,current_file->len); +  sprintf(buf,"\n# %ld \"",current_line+1); +  UNGETSTR(buf,strlen(buf)); +  +  total_lines+=current_line-old_line; +  old_line=current_line=1; +  free_string(current_file); +  current_file=sp[-1].u.string; +  sp--; +  link_inputstate(file_inputstate(fd)); +  UNGETSTR("\n",1); + } +  + /*** Lexical analyzing ***/ +  + static int char_const() + { +  int c; +  switch(c=GETC()) +  { +  case '0': case '1': case '2': case '3': +  case '4': case '5': case '6': case '7': +  c-='0'; +  if(LOOK()<'0' || LOOK()>'8') return c; +  c=c*8+(GETC()-'0'); +  if(LOOK()<'0' || LOOK()>'8') return c; +  c=c*8+(GETC()-'0'); +  return c; +  +  case 'r': return '\r'; +  case 'n': return '\n'; +  case 't': return '\t'; +  case 'b': return '\b'; +  } +  return c; + } +  + #define SKIPTO_ENDIF 1 + #define SKIPTO_ELSE 2 +  + static void do_skip(int to) + { +  int lvl; + #if LEXDEBUG>3 +  fprintf(stderr,"Skipping from %ld to ",(long)current_line); + #endif +  lvl=1; +  while(lvl) +  { +  switch(GETC()) +  { +  case '/': +  if(GOBBLE('*')) +  { +  do{ +  SKIPTO('*'); +  }while(!GOBBLE('/')); +  } +  continue; +  +  case EOF: +  yyerror("Unexpected end of file while skipping."); +  return; +  +  case '\\': +  GETC(); +  continue; +  +  case '\n': +  if(GOBBLE('#')) +  { +  SKIPWHITE(); +  READBUF(C!=' ' && C!='\t' && C!='\n'); +  +  switch(buf[0]) +  { +  case 'l': +  if(strcmp("line",buf)) break; +  READBUF(C!=' ' && C!='\t' && C!='\n'); +  +  case '0': case '1': case '2': case '3': case '4': +  case '5': case '6': case '7': case '8': case '9': +  SKIPWHITE(); +  READBUF(C!='\n'); +  if(buf[0]=='"' && +  buf[strlen(buf)-1]=='2' && +  isspace(buf[strlen(buf)-2])) +  { +  if(lvl) +  { +  yyerror("Unterminated '#if' conditional."); +  num_parse_error+=1000; +  } +  } +  continue; +  +  case 'i': +  if(!strcmp("include",buf)) continue; +  if(!strcmp("if",buf) || !strcmp("ifdef",buf) || !strcmp("ifndef",buf)) +  { +  lvl++; +  continue; +  } +  break; +  +  case 'e': +  if(!strcmp("endif",buf)) +  { +  lvl--; +  if(lvl<0) +  { +  yyerror("Unbalanced '#endif'\n"); +  lvl=0; +  } +  continue; +  } +  if(!strcmp("else",buf)) +  { +  if(lvl==1 && to==SKIPTO_ELSE) lvl=0; +  continue; +  } +  if(!strcmp("elif",buf) || !strcmp("elseif",buf)) +  { +  if(lvl==1 && to==SKIPTO_ELSE && calc()) lvl--; +  continue; +  } +  if(!strcmp("error",buf)) continue; +  break; +  +  case 'd': +  if(!strcmp("define",buf)) continue; +  break; +  +  case 'u': +  if(!strcmp("undef",buf)) continue; +  break; +  +  case 'p': +  if(!strcmp("pragma",buf)) continue; +  break; +  } +  +  my_yyerror("Unknown directive #%s.",buf); +  SKIPUPTO('\n'); +  continue; +  } +  } +  } + #if LEXDEBUG>3 +  fprintf(stderr,"%ld in %s.\n",(long)current_line,current_file->str); + #endif + } +  + static int do_lex(int literal, YYSTYPE *yylval) + #if LEXDEBUG>4 + { +  int t; +  int do_lex2(int literal, YYSTYPE *yylval); +  t=do_lex2(literal, yylval); +  if(t<256) +  { +  fprintf(stderr,"do_lex(%d) -> '%c' (%d)\n",literal,t,t); +  }else{ +  fprintf(stderr,"do_lex(%d) -> %s (%d)\n",literal,get_f_name(t),t); +  } +  return t; + } +  + static int do_lex2(int literal, YYSTYPE *yylval) + #endif + { +  int c; + #ifdef MALLOC_DEBUG +  check_sfltable(); + #endif +  while(1) +  { +  switch(c=GETC()) +  { +  case '\n': +  if(literal) +  { +  UNGETC('\n'); +  return '\n'; +  } +  if(GOBBLE('#')) +  { +  if(GOBBLE('!')) +  { +  SKIPUPTO('\n'); +  continue; +  } +  +  SKIPWHITE(); +  READBUF(C!=' ' && C!='\t' && C!='\n'); +  +  switch(buf[0]) +  { +  char *p; +  +  case 'l': +  if(strcmp("line",buf)) goto badhash; +  READBUF(C!=' ' && C!='\t' && C!='\n'); +  +  case '0': case '1': case '2': case '3': case '4': +  case '5': case '6': case '7': case '8': case '9': +  total_lines+=current_line-old_line; +  old_line=current_line=atoi(buf)-1; +  SKIPWHITE(); +  READBUF(C!='\n'); +  +  p=buf; +  if(*p=='"' && STRCHR(p+1,'"')) +  { +  char *p2; +  p++; +  if((p2=STRCHR(p+1,'"'))) +  { +  *p2=0; +  free_string(current_file); +  current_file=make_shared_string(p); +  } +  } +  break; +  +  case 'i': +  if(!strcmp("include",buf)) +  { +  SKIPWHITE(); +  c=do_lex(1, yylval); +  if(c=='<') +  { +  READBUF(C!='>' && C!='\n'); +  if(!GOBBLE('>')) +  { +  yyerror("Missing `>`"); +  SKIPUPTO('\n'); +  continue; +  } +  }else{ +  if(c!=F_STRING) +  { +  yyerror("Couldn't find include filename.\n"); +  SKIPUPTO('\n'); +  continue; +  } +  } +  handle_include(buf); +  break; +  } +  +  if(!strcmp("if",buf)) +  { +  if(!calc()) do_skip(SKIPTO_ELSE); +  break; +  } +  +  if(!strcmp("ifdef",buf)) +  { +  struct lpc_string *s; +  SKIPWHITE(); +  READBUF(isidchar(C)); +  s=findstring(buf); +  if(!s || !find_define(s)) do_skip(SKIPTO_ELSE); +  break; +  } +  +  if(!strcmp("ifndef",buf)) +  { +  struct lpc_string *s; +  SKIPWHITE(); +  READBUF(isidchar(C)); +  s=findstring(buf); +  if(s && find_define(s)) do_skip(SKIPTO_ELSE); +  break; +  } +  goto badhash; +  +  case 'e': +  if(!strcmp("endif",buf)) break; +  if(!strcmp("else",buf)) +  { +  SKIPUPTO('\n'); +  do_skip(SKIPTO_ENDIF); +  break; +  } +  if(!strcmp("elif",buf) || !strcmp("elseif",buf)) +  { +  SKIPUPTO('\n'); +  do_skip(SKIPTO_ENDIF); +  break; +  } +  if(!strcmp("error",buf)) +  { +  SKIPWHITE(); +  READBUF(C!='\n'); +  yyerror(buf); +  break; +  } +  goto badhash; +  +  case 'u': +  if(!strcmp("undef",buf)) +  { +  struct lpc_string *s; +  SKIPWHITE(); +  READBUF(isidchar(C)); +  if((s=findstring(buf))) undefine(s); +  break; +  } +  goto badhash; +  +  case 'd': +  if(!strcmp("define",buf)) +  { +  do_define(); +  break; +  } +  goto badhash; +  +  case 'p': +  if(!strcmp("pragma",buf)) +  { +  SKIPWHITE(); +  READBUF(C!='\n'); +  if (strcmp(buf, "all_inline") == 0) +  { +  pragma_all_inline = 1; +  } +  break; +  } +  +  badhash: +  my_yyerror("Unknown directive #%s.",buf); +  SKIPUPTO('\n'); +  continue; +  +  } +  } +  continue; +  +  case ' ': +  case '\t': +  continue; +  +  case EOF: +  return 0; +  +  case '\'': +  c=GETC(); +  if(c=='\\') c=char_const(); +  if(GETC()!='\'') +  yyerror("Unterminated character constant.\n"); +  yylval->number=c; +  return F_NUMBER; +  +  case '"': +  init_buf(); +  while(1) +  { +  c=GETC(); +  +  switch(c) +  { +  case -1: +  yyerror("End of file in string.\n"); +  free(simple_free_buf()); +  return 0; +  +  case '\n': +  yyerror("Newline in string.\n"); +  free(simple_free_buf()); +  return 0; +  +  case '\\': +  my_putchar(char_const()); +  continue; +  +  case '"': +  break; +  +  default: +  my_putchar(c); +  continue; +  } +  break; +  } +  if(literal) +  { +  strncpy(buf,return_buf(),sizeof(buf)); +  buf[sizeof(buf)-1]=0; +  yylval->str=buf; +  }else{ +  yylval->string=free_buf(); +  } +  return F_STRING; +  +  case ':': +  if(GOBBLE(':')) return F_COLON_COLON; +  return c; +  +  case '.': +  if(GOBBLE('.')) +  { +  if(GOBBLE('.')) return F_DOT_DOT_DOT; +  return F_DOT_DOT; +  } +  return c; +  +  case '0': +  if(GOBBLE('x')) +  { +  READBUF(isxdigit(C)); +  yylval->number=STRTOL(buf,NULL,16); +  return F_NUMBER; +  } +  +  case '1': case '2': case '3': case '4': +  case '5': case '6': case '7': case '8': case '9': +  { +  char *p; +  UNGETC(c); +  READBUF(isdigit(C) || C=='.'); +  +  p=STRCHR(buf,'.'); +  +  if(p) +  { +  if(p[1]=='.') +  { +  UNGETSTR(p,strlen(p)); +  *p=0; +  p=NULL; +  }else if((p=STRCHR(p+1,'.'))) +  { +  UNGETSTR(p,strlen(p)); +  *p=0; +  } +  if((p=STRCHR(buf,'.'))) +  { +  yylval->fnum=STRTOD(buf,NULL); +  return F_FLOAT; +  } +  } +  if(buf[0]=='0') +  yylval->number=STRTOL(buf,NULL,8); +  else +  yylval->number=STRTOL(buf,NULL,10); +  return F_NUMBER; +  } +  +  case '-': +  if(GOBBLE('=')) return F_SUB_EQ; +  if(GOBBLE('>')) return F_ARROW; +  if(GOBBLE('-')) return F_DEC; +  return '-'; +  +  case '+': +  if(GOBBLE('=')) return F_ADD_EQ; +  if(GOBBLE('+')) return F_INC; +  return '+'; +  +  case '&': +  if(GOBBLE('=')) return F_AND_EQ; +  if(GOBBLE('&')) return F_LAND; +  return '&'; +  +  case '|': +  if(GOBBLE('=')) return F_OR_EQ; +  if(GOBBLE('|')) return F_LOR; +  return '|'; +  +  case '^': +  if(GOBBLE('=')) return F_XOR_EQ; +  return '^'; +  +  case '*': +  if(GOBBLE('=')) return F_MULT_EQ; +  return '*'; +  +  case '%': +  if(GOBBLE('=')) return F_MOD_EQ; +  return '%'; +  +  case '/': +  if(GOBBLE('*')) +  { +  do{ +  SKIPTO('*'); +  }while(!GOBBLE('/')); +  continue; +  }else if(GOBBLE('/')) +  { +  SKIPUPTO('\n'); +  continue; +  } +  if(GOBBLE('=')) return F_DIV_EQ; +  return '/'; +  +  case '=': +  if(GOBBLE('=')) return F_EQ; +  return '='; +  +  case '<': +  if(GOBBLE('<')) +  { +  if(GOBBLE('=')) return F_LSH_EQ; +  return F_LSH; +  } +  if(GOBBLE('=')) return F_LE; +  return '<'; +  +  case '>': +  if(GOBBLE(')')) return F_LIST_END; +  if(GOBBLE('=')) return F_GE; +  if(GOBBLE('>')) +  { +  if(GOBBLE('=')) return F_RSH_EQ; +  return F_RSH; +  } +  return '>'; +  +  case '!': +  if(GOBBLE('=')) return F_NE; +  return F_NOT; +  +  case '(': +  if(GOBBLE('<')) return F_LIST_START; +  return '('; +  +  case '?': +  case ',': +  case '~': +  case '@': +  case ')': +  case '[': +  case ']': +  case '{': +  case ';': +  case '}': return c; +  +  default: +  if(isidchar(c)) +  { +  struct lpc_string *s; +  UNGETC(c); +  READBUF(isidchar(C)); +  +  if(!literal) +  { +  /* identify identifier, if it is not a shared string, +  * then it is neither a define, reserved word, local variable +  * or efun, at least not yet. +  */ +  +  s=findstring(buf); +  if(s) +  { +  int i; +  if(expand_define(s,0)) continue; +  +  i=lookup_resword(s); +  if(i >= 0) +  { +  yylval->number=current_line; +  return i; +  } +  +  reference_shared_string(s); +  }else{ +  s=make_shared_string(buf); +  } +  yylval->string=s; +  return F_IDENTIFIER; +  } +  +  yylval->str=buf; +  return F_IDENTIFIER; +  }else{ +  char buff[100]; +  sprintf(buff, "Illegal character (hex %02x) '%c'", c, c); +  yyerror(buff); +  return ' '; +  } +  } +  } + } +  + int yylex(YYSTYPE *yylval) + { + #ifdef __CHECKER__ +  MEMSET((char *)yylval,0,sizeof(YYSTYPE)); + #endif +  return do_lex(0, yylval); + } +  + static YYSTYPE my_yylval; + static int lookahead; +  + static void low_lex() + { +  while(1) +  { +  struct lpc_string *s; +  +  lookahead=do_lex(1, &my_yylval); +  if(lookahead == F_IDENTIFIER) +  { +  if(!strcmp("defined",my_yylval.str)) +  { +  SKIPWHITE(); +  if(!GOBBLE('(')) +  { +  yyerror("Missing '(' in defined.\n"); +  return; +  } +  READBUF(isidchar(C)); +  if(!GOBBLE(')')) +  { +  yyerror("Missing ')' in defined.\n"); +  return; +  } +  s=findstring(buf); +  +  if(s && find_define(s)) +  UNGETSTR(" 1 ",3); +  else +  UNGETSTR(" 0 ",3); +  +  continue; +  } +  +  if(!strcmp("efun",my_yylval.str)) +  { +  SKIPWHITE(); +  if(!GOBBLE('(')) +  { +  yyerror("Missing '(' in #if efun().\n"); +  return; +  } +  READBUF(isidchar(C)); +  if(!GOBBLE(')')) +  { +  yyerror("Missing ')' in #if efun().\n"); +  return; +  } +  s=findstring(buf); +  +  if(s && lookup_efun(s)) +  UNGETSTR(" 1 ",3); +  else +  UNGETSTR(" 0 ",3); +  +  continue; +  } +  +  s=findstring(my_yylval.str); +  if(!s || !expand_define(s,1)) +  UNGETSTR(" 0 ",3); +  continue; +  } +  +  break; +  } + } +  + static void calcC() + { +  switch(lookahead) +  { +  case '(': +  low_lex(); +  calc1(); +  if(lookahead != ')') +  error("Missing ')'\n"); +  break; +  +  case F_FLOAT: +  push_float(my_yylval.fnum); +  break; +  +  case F_STRING: +  push_string(make_shared_string(my_yylval.str)); +  break; +  +  case F_NUMBER: +  push_int(my_yylval.number); +  break; +  +  default: +  yyerror("Syntax error in #if."); +  return; +  } +  +  low_lex(); +  +  while(lookahead=='[') +  { +  low_lex(); +  calc1(); +  f_index(); +  if(lookahead!=']') +  error("Missing ']'\n"); +  else +  low_lex(); +  } + } +  + static void calcB() + { +  switch(lookahead) +  { +  case '-': low_lex(); calcB(); f_negate(); break; +  case F_NOT: low_lex(); calcB(); f_not(); break; +  case '~': low_lex(); calcB(); f_compl(); break; +  default: calcC(); +  } + } +  + static void calcA() + { +  calcB(); +  while(1) +  { +  switch(lookahead) +  { +  case '/': low_lex(); calcB(); f_divide(); continue; +  case '*': low_lex(); calcB(); f_multiply(); continue; +  case '%': low_lex(); calcB(); f_mod(); continue; +  } +  break; +  } + } +  + static void calc9() + { +  calcA(); +  +  while(1) +  { +  switch(lookahead) +  { +  case '+': low_lex(); calcA(); f_add(); continue; +  case '-': low_lex(); calcA(); f_subtract(); continue; +  } +  break; +  } + } +  + static void calc8() + { +  calc9(); +  +  while(1) +  { +  switch(lookahead) +  { +  case F_LSH: low_lex(); calc9(); f_lsh(); continue; +  case F_RSH: low_lex(); calc9(); f_rsh(); continue; +  } +  break; +  } + } +  + static void calc7b() + { +  calc8(); +  +  while(1) +  { +  switch(lookahead) +  { +  case '<': low_lex(); calc8(); f_lt(); continue; +  case '>': low_lex(); calc8(); f_gt(); continue; +  case F_GE: low_lex(); calc8(); f_ge(); continue; +  case F_LE: low_lex(); calc8(); f_le(); continue; +  } +  break; +  } + } +  + static void calc7() + { +  calc7b(); +  +  while(1) +  { +  switch(lookahead) +  { +  case F_EQ: low_lex(); calc7b(); f_eq(); continue; +  case F_NE: low_lex(); calc7b(); f_ne(); continue; +  } +  break; +  } + } +  + static void calc6() + { +  calc7(); +  +  while(lookahead=='&') +  { +  low_lex(); +  calc7(); +  f_and(); +  } + } +  + static void calc5() + { +  calc6(); +  +  while(lookahead=='^') +  { +  low_lex(); +  calc6(); +  f_xor(); +  } + } +  + static void calc4() + { +  calc5(); +  +  while(lookahead=='|') +  { +  low_lex(); +  calc5(); +  f_or(); +  } + } +  + static void calc3() + { +  calc4(); +  +  while(lookahead==F_LAND) +  { +  low_lex(); +  check_destructed(sp-1); +  if(IS_ZERO(sp-1)) +  { +  calc4(); +  pop_stack(); +  }else{ +  pop_stack(); +  calc4(); +  } +  } + } +  + static void calc2() + { +  calc3(); +  +  while(lookahead==F_LOR) +  { +  low_lex(); +  check_destructed(sp-1); +  if(!IS_ZERO(sp-1)) +  { +  calc3(); +  pop_stack(); +  }else{ +  pop_stack(); +  calc3(); +  } +  } + } +  + static void calc1() + { +  calc2(); +  +  if(lookahead=='?') +  { +  low_lex(); +  calc1(); +  if(lookahead!=':') +  error("Colon expected.\n"); +  low_lex(); +  calc1(); +  +  check_destructed(sp-3); +  assign_svalue(sp-3,IS_ZERO(sp-3)?sp-1:sp-2); +  pop_n_elems(2); +  } +  + } +  + static int calc() + { +  JMP_BUF recovery; +  int ret; +  +  ret=0; +  if (SETJMP(recovery)) +  { +  if(throw_value.type == T_ARRAY && throw_value.u.array->size) +  { +  union anything *a; +  a=low_array_get_item_ptr(throw_value.u.array, 0, T_STRING); +  if(a) +  { +  yyerror(a->string->str); +  }else{ +  yyerror("Nonstandard error format.\n"); +  } +  }else{ +  yyerror("Nonstandard error format.\n"); +  } +  ret=-1; +  }else{ +  low_lex(); +  calc1(); +  if(lookahead!='\n') +  { +  SKIPUPTO('\n'); +  yyerror("Extra characters after #if expression."); +  }else{ +  UNGETC('\n'); +  } +  check_destructed(sp-1); +  ret=!IS_ZERO(sp-1); +  pop_stack(); +  } +  UNSETJMP(recovery); +  +  return ret; + } +  + /*** Magic defines ***/ + void insert_current_line() + { +  char buf[20]; +  sprintf(buf," %ld ",current_line); +  UNGETSTR(buf,strlen(buf)); + } +  + void insert_current_file_as_string() + { +  UNGETSTR("\"",1); +  UNGETSTR(current_file->str, current_file->len); +  UNGETSTR("\"",1); + } +  + void insert_current_time_as_string() + { +  time_t tmp; +  char *buf; +  time(&tmp); +  buf=ctime(&tmp); +  +  UNGETSTR("\"",1); +  UNGETSTR(buf+11, 8); +  UNGETSTR("\"",1); + } +  + void insert_current_date_as_string() + { +  time_t tmp; +  char *buf; +  time(&tmp); +  buf=ctime(&tmp); +  +  UNGETSTR("\"",1); +  UNGETSTR(buf+19, 5); +  UNGETSTR(buf+4, 6); +  UNGETSTR("\"",1); + } +  + /*** ***/ +  + static void start_new() + { +  struct lpc_predef_s *tmpf; +  +  free_all_defines(); +  +  if(!local_variables) +  local_variables=ALLOC_STRUCT(locals); +  local_variables->next=0; +  local_variables->current_number_of_locals=0; +  simple_add_define("__uLPC__", "1",0); +  +  for (tmpf=lpc_predefs; tmpf; tmpf=tmpf->next) +  simple_add_define(tmpf->name, tmpf->value,0); +  +  simple_add_define("__LINE__",0,insert_current_line); +  simple_add_define("__FILE__",0,insert_current_file_as_string); +  simple_add_define("__DATE__",0,insert_current_date_as_string); +  simple_add_define("__TIME__",0,insert_current_time_as_string); +  +  free_inputstate(istate); +  istate=NULL; +  link_inputstate(end_inputstate()); +  old_line=current_line = 1; +  pragma_all_inline=0; +  nexpands=0; +  if(current_file) free_string(current_file); +  current_file=0; + } +  + void start_new_file(int fd,struct lpc_string *filename) + { +  start_new(); +  copy_shared_string(current_file,filename); +  +  link_inputstate(file_inputstate(fd)); +  UNGETSTR("\n",1); + } +  + void start_new_string(char *s,INT32 len,struct lpc_string *name) + { +  start_new(); +  copy_shared_string(current_file,name); +  link_inputstate(prot_memory_inputstate(s,len)); +  UNGETSTR("\n",1); + } +  + void end_new_file() + { +  while(local_variables) +  { +  int e; +  struct locals *l; +  for(e=0;e<local_variables->current_number_of_locals;e++) +  { +  free_string(local_variables->variable[e].name); +  free_string(local_variables->variable[e].type); +  } +  l=local_variables->next; +  free((char *)local_variables); +  local_variables=l; +  } +  +  free_inputstate(istate); +  istate=NULL; +  free_all_defines(); +  total_lines+=current_line-old_line; + } +  +  + void add_predefine(char *s) + { +  char buffer1[100],buffer2[10000]; +  struct lpc_predef_s *tmp; +  +  if(sscanf(s,"%[^=]=%[ -~=]",buffer1,buffer2) ==2) +  { +  s=buffer1; +  }else{ +  buffer2[0]='1'; +  buffer2[1]=0; +  } +  tmp=ALLOC_STRUCT(lpc_predef_s); +  tmp->name=(char *)xalloc(strlen(s)+1); +  strcpy(tmp->name,s); +  tmp->value=(char *)xalloc(strlen(buffer2)+1); +  strcpy(tmp->value,buffer2); +  tmp->next=lpc_predefs; +  lpc_predefs=tmp; + }   Newline at end of file added.