Exemplo n.º 1
0
Arquivo: main.c Projeto: perlawk/VSL
void  init_vc( int   argc,
               char *argv[] )

/* The first part of initialisation involves sorting out the arguments, and
   assigning standard input and standard output files as explained in
   decode_args and setup_files below.

   The rest involves setting various system wide variables to sensible
   values and clearing down the symbol table. Small constants are so common we
   put them in the symbol table first and record their addresses in a table. We
   do this for the integers 0 to COUNT_MAX - 1. This will permit us efficient
   access to them throughout the compiler.

   We record the entry labels for the library routines. We happen to know from
   inspection of the library code that the entry point to PRINTN is L2 and to
   PRINTS is L4. If we rewrite the library then we may have to change these.
   This is really rather clumsy, and at the very least ought to be put in a
   single table somewhere. Note that earlier we set the first label to be used
   to L10, permitting the use of labels up to L9 for library use. */

{
        int  i ;                             /* General counter */

        char *ifile ;                        /* Input file */   
        char *ofile ;                        /* Output file */


        /* Decode the arguments, and setup stdin and stdout accordingly */

        ofile = decode_args( argc, argv ) ;
        ifile = argv[1] ;                       /* Do after decode has checked
                                                   argument is OK */
        setup_files( ifile, ofile ) ;

        /* Give values to global variables */

        symb_list   = NULL ;                 /* Freelists */
        enode_list  = NULL ;

        errors_found = FALSE ;               /* No errors found yet */
        next_tmp     = 0 ;                   /* No temporaries used */
        next_label   = LAB_MIN ;             /* 10 labels reserved */

        for( i = 0 ; i < HASHSIZE ; i++ )    /* Clear symbol table */
                symbtab[i] = NULL ;

        for( i = 0 ; i < CONST_MAX ; i++ )   /* Make constants */
        {
                SYMB *c = get_symb() ;       /* Node for the constant */

                c->type      = T_INT ;
                c->VAL1      = i ;
                const_tab[i] = c ;
        }

        library[LIB_PRINTN] = mktac( TAC_LABEL, mklabel( 2 ), NULL, NULL ) ;
        library[LIB_PRINTS] = mktac( TAC_LABEL, mklabel( 4 ), NULL, NULL ) ;

}       /* void  init_vc( void ) */
Exemplo n.º 2
0
static int run_metacommand(int cnum, int *redir_offset)
/* cnum=command number to run. */
/* *redir_offset=offset of redirect header, if we exit with redirection. */
/* Return 
      0 to go on to next metacommand, 
      1 to stop running metacommands,  and 
      2 to end the turn. 
      3 indicates that redirection has just occured 
      4 indicates a subcall has just occured.
      5 Is used to go on to the next metacommand after a Return.
      -2 means we're doing disambiguation and just hit an action token. */
{
  int ip, oip;  /* ip=Instruction pointer, oip=Old instruction pointer */
  int r;        /* Used to hold return value from token execution */
  int fail_addr;  /* What address to jump to on failure */
  rbool fail;    /* Last token was a conditional token that failed */
  rbool ortrue, blocktrue, orflag; /* OR stuff 
				     orflag: Are we in an OR group? 
				     ortrue: Is current OR group true? 
				     blocktrue: Is current block w/in OR true?
				     */
  static rbool restart=0;  /* Restarting after subroutine?  */
  op_rec currop;          /* Information on the current token and its args */
  
  fail_addr=32000; /* Fall off the end when we fail */
  fail=0;
  ip=0;
  orflag=blocktrue=ortrue=0;
  *redir_offset=1;  /* Default: This is what RedirectTo does.
		       Only XRedirect can send a different value */


  if (restart)  /* finish up Return from subroutine */
    pop_subcall(&cnum,&ip,&fail_addr);

  if (DEBUG_AGT_CMD && !supress_debug) {
    debug_head(cnum);
    if (restart) debugout("   (Resuming after subroutine)\n");
  }

  restart=0;

  
  /* ==========  Main Loop ================= */
  while(ip<command[cnum].cmdsize) {

    oip=ip;
    ip+=decode_instr(&currop,command[cnum].data+ip,command[cnum].cmdsize-ip);

    /* -------  OR Logic --------------- */
    if (currop.op==109) { /* OR */
      if (!orflag) { /* First OR; set things up */
	orflag=1;
	ortrue=0;      
	blocktrue=1; 
      }
      blocktrue=blocktrue && !fail; /* Was the previous token true? */
      fail=0;
      ortrue=ortrue||blocktrue;  /* OR in last block */
      blocktrue=1;  /* New block starts out true. */     
    }
    else if (orflag) {  /* we're in the middle of a block */
      blocktrue=blocktrue&&!fail;  /* Add in previous token */
      fail=0;
      if (currop.endor) {  /* i.e. not a conditional token */
	orflag=0;                  /* End of OR block */
	ortrue=ortrue||blocktrue;  /* OR in last block */
	fail=!ortrue;  /* Success of whole group */
      }
    }

    /* ------------  FAILMESSAGE handling ------------- */
    if (currop.failmsg) {  /* Is the current token a Fail... token? */
      if (!fail) continue;  /* Skip it; look at next instruction */
      /* ErrMessage and ErrStdMessage: set disambiguation score */
      if (do_disambig) {
	if (currop.op==1130 || currop.op==1131) {
	  if (!decode_args(oip,&currop)) return 2;
	  disambig_score=currop.arg1;
	  return 2;
	}
	else return -2; /* FailMessage counts as an action token */
      }
      /* Then run the failmessage, skipping the following step... */
    } 
    /* -------- Failure routines -------------------- */
    else if (fail) {  /* ... and not failmessage */
      /* consequences of failure */
      fail=0;  /* In case fail_addr doesn't point off the edge of the world */
      ip=fail_addr;
      fail_addr=32000; /* Reset fail_addr */
      continue; /* Usually fail_addr will fall off the end, causing this to
		   return 0 */
    }

    /* - Finish decoding arguments and print out debugging message - */
    if (!decode_args(oip,&currop)) {
      if (currop.op<1000) fail=currop.negate ? 0 : 1;
      continue;
      /* return 2;*/
    }

    /* -------- Commands that need to be handled specially -------------- */
    if (currop.op==109) {  /* OR */
      if (DEBUG_AGT_CMD && !supress_debug) debug_newline(op,0);
      continue; /* OR: skip further processing */
    }

    if (currop.op==1037) {  /* DoSubroutine */
      if (!push_subcall(cnum,ip,fail_addr)) {
	writeln("GAME ERROR: Subroutine stack overflow.");
	return 2;
      }
      subcall_arg=currop.arg1;
      if (DEBUG_AGT_CMD && !supress_debug) debugout("--> Call\n");
      return 4;
    }

    if (currop.op==1038) { /* Return */
      restart=1;
      if (DEBUG_AGT_CMD && !supress_debug) debugout("--> Return\n");
      return 5;
    }

    if (currop.op==1149) { /* Goto */
      ip=currop.arg1;
      if (DEBUG_AGT_CMD && !supress_debug) debugout("\n");
      continue;
    }

    if (currop.op==1150) { /* OnFailGoto */
      fail_addr=currop.arg1;
      if (DEBUG_AGT_CMD && !supress_debug) debugout("\n");
      continue;
    }

    if (currop.op==1152)  /* XRedirect */
      *redir_offset=currop.arg1;

    /* ---------- Disambiguation Success -------------- */
    if (do_disambig && currop.disambig) {
      if (DEBUG_AGT_CMD && !supress_debug) debugout("==> ACTION\n");
      return -2;
    }

    /* ---------- Run normal metacommands -------------- */
    switch(r=exec_instr(&currop)) 
      {
      case 0:  /* Normal action token or successful conditional token */
	if (DEBUG_AGT_CMD && !supress_debug) debug_newline(op,0);
	continue;
      case 1: /* Conditional token: fail */
	if (DEBUG_AGT_CMD && !supress_debug) {
	  if (orflag) debugout("  (-->FAIL)\n");
	  else debugout("--->FAIL\n");
	}
	fail=1;
	continue;
      default: /* Return explicit value */
	if (DEBUG_AGT_CMD && !supress_debug) {
	  if (r==103) debugout("-->Redirect\n");
	  else debugout("==> END\n");
	}
	return r-100; 
      }
  }
  return 0;
}
Exemplo n.º 3
0
/*
 * parse a function and its arguments and fill the structure
 */
int encode_function(char *string, struct filter_op *fop)
{
   char *str = strdup(string);
   int ret = -ENOTFOUND;
   char *name, *args;
   int nargs = 0, i;
   char **dec_args = NULL;
   char *tok;

   memset(fop, 0, sizeof(struct filter_op));
   
   /* get the name of the function */
   name = ec_strtok(string, "(", &tok);
   /* get all the args */
   args = name + strlen(name) + 1;

   /* analyze the arguments */
   dec_args = decode_args(args, &nargs);

   /* this fop is a function */
   fop->opcode = FOP_FUNC;

   /* check if it is a known function */
   if (!strcmp(name, "search")) {
      if (nargs == 2) {
         /* get the level (DATA or DECODED) */
         if (encode_offset(dec_args[0], fop) == ESUCCESS) {
            /* encode offset wipe the fop !! */
            fop->opcode = FOP_FUNC;
            fop->op.func.op = FFUNC_SEARCH;
            fop->op.func.string = (u_char*)strdup(dec_args[1]);
            fop->op.func.slen = strescape((char*)fop->op.func.string, (char*)fop->op.func.string);
            ret = ESUCCESS;
         } else
            SCRIPT_ERROR("Unknown offset %s ", dec_args[0]);
      } else
         SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
   } else if (!strcmp(name, "regex")) {
      if (nargs == 2) {
         int err;
         regex_t regex;
         char errbuf[100];
         
         /* get the level (DATA or DECODED) */
         if (encode_offset(dec_args[0], fop) == ESUCCESS) {
            /* encode offset wipe the fop !! */
            fop->opcode = FOP_FUNC;
            fop->op.func.op = FFUNC_REGEX;
            fop->op.func.string = (u_char*)strdup(dec_args[1]);
            fop->op.func.slen = strescape((char*)fop->op.func.string, (char*)fop->op.func.string);
            ret = ESUCCESS;
         } else
            SCRIPT_ERROR("Unknown offset %s ", dec_args[0]);

         /* check if the regex is valid */
         err = regcomp(&regex, (const char*)fop->op.func.string, REG_EXTENDED | REG_NOSUB | REG_ICASE );
         if (err) {
            regerror(err, &regex, errbuf, sizeof(errbuf));
            SCRIPT_ERROR("%s", errbuf);
         } 
         
         regfree(&regex);
                        
      } else
         SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
   } else if (!strcmp(name, "pcre_regex")) {
#ifndef HAVE_PCRE
      WARNING("The script contains pcre_regex, but you don't have support for it.");
#else
      pcre *pregex;
      const char *errbuf = NULL;
      int erroff;
      
      if (nargs == 2) {
                     
         /* get the level (DATA or DECODED) */
         if (encode_offset(dec_args[0], fop) == ESUCCESS) {
            /* encode offset wipe the fop !! */
            fop->opcode = FOP_FUNC;
            fop->op.func.op = FFUNC_PCRE;
            fop->op.func.string = strdup(dec_args[1]);
            fop->op.func.slen = strlen(fop->op.func.string);
            ret = ESUCCESS;
         } else
            SCRIPT_ERROR("Unknown offset %s ", dec_args[0]);

         /* check if the pcre is valid */
         pregex = pcre_compile(fop->op.func.string, 0, &errbuf, &erroff, NULL );
         if (pregex == NULL)
            SCRIPT_ERROR("%s\n", errbuf);

         pcre_free(pregex);
      } else if (nargs == 3) {
            
         fop->opcode = FOP_FUNC;
         fop->op.func.op = FFUNC_PCRE;
         /* substitution always at layer DATA */
         fop->op.func.level = 5;
         fop->op.func.string = strdup(dec_args[1]);
         fop->op.func.slen = strlen(fop->op.func.string);
         fop->op.func.replace = strdup(dec_args[2]);
         fop->op.func.rlen = strlen(fop->op.func.replace);
         ret = ESUCCESS;
         
         /* check if the pcre is valid */
         pregex = pcre_compile(fop->op.func.string, 0, &errbuf, &erroff, NULL );
         if (pregex == NULL)
            SCRIPT_ERROR("%s\n", errbuf);

         pcre_free(pregex);
      } else
         SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
#endif
   } else if (!strcmp(name, "replace")) {
      if (nargs == 2) {
         fop->op.func.op = FFUNC_REPLACE;
         /* replace always operate at DATA level */
         fop->op.func.level = 5;
         fop->op.func.string = (u_char*)strdup(dec_args[0]);
         fop->op.func.slen = strescape((char*)fop->op.func.string, (char*)fop->op.func.string);
         fop->op.func.replace = (u_char*)strdup(dec_args[1]);
         fop->op.func.rlen = strescape((char*)fop->op.func.replace, (char*)fop->op.func.replace);
         ret = ESUCCESS;
      } else
         SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
   } else if (!strcmp(name, "inject")) {
      if (nargs == 1) {
         fop->op.func.op = FFUNC_INJECT;
         /* inject always operate at DATA level */
         fop->op.func.level = 5;
         fop->op.func.string = (u_char*)strdup(dec_args[0]);
         fop->op.func.slen = strlen((const char*)fop->op.func.string);
         ret = ESUCCESS;
      } else
         SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
   } else if (!strcmp(name, "execinject")) {
      if (nargs == 1) {
         fop->op.func.op = FFUNC_EXECINJECT;
         /* execinject always operate at DATA level */
         fop->op.func.level = 5;
         fop->op.func.string = (u_char*)strdup(dec_args[0]);
         fop->op.func.slen = strlen((const char*)fop->op.func.string);
         ret = ESUCCESS;
      } else
         SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
   } else if (!strcmp(name, "log")) {
      if (nargs == 2) {
         /* get the level (DATA or DECODED) */
         if (encode_offset(dec_args[0], fop) == ESUCCESS) {
            /* encode offset wipe the fop !! */
            fop->opcode = FOP_FUNC;
            fop->op.func.op = FFUNC_LOG;
            fop->op.func.string = (u_char*)strdup(dec_args[1]);
            fop->op.func.slen = strlen((const char*)fop->op.func.string);
            ret = ESUCCESS;
         } else
            SCRIPT_ERROR("Unknown offset %s ", dec_args[0]);
      } else
         SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
   } else if (!strcmp(name, "drop")) {
      if (nargs == 0) {
         fop->op.func.op = FFUNC_DROP;
         ret = ESUCCESS;
      } else
         SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
   } else if (!strcmp(name, "kill")) {
      if (nargs == 0) {
         fop->op.func.op = FFUNC_KILL;
         ret = ESUCCESS;
      } else
         SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
   } else if (!strcmp(name, "msg")) {
      if (nargs == 1) {
         fop->op.func.op = FFUNC_MSG;
         fop->op.func.string = (u_char*)strdup(dec_args[0]);
         fop->op.func.slen = strescape((char*)fop->op.func.string, (char*)fop->op.func.string);
         ret = ESUCCESS;
      } else
         SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
   } else if (!strcmp(name, "exec")) {
      if (nargs == 1) {
         fop->op.func.op = FFUNC_EXEC;
         fop->op.func.string = (u_char*)strdup(dec_args[0]);
         fop->op.func.slen = strlen((const char*)fop->op.func.string);
         ret = ESUCCESS;
      } else
         SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
   } else if (!strcmp(name, "exit")) {
      if (nargs == 0) {
         fop->opcode = FOP_EXIT;
         ret = ESUCCESS;
      } else
         SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
   }

   /* free the array */
   for (i = 0; i < nargs; i++)
      SAFE_FREE(dec_args[i]);
      
   SAFE_FREE(dec_args);
   SAFE_FREE(str);
   return ret;
}