Exemple #1
0
void EntityUpdate ()
{

  const unsigned    stop_time = 100;

  if (!TextureReady ()) {
    sorted = false;
    return;
  } 
  if (!sorted) {
    qsort (entity_list, entity_count, sizeof (struct entity), do_compare);
    sorted = true;
  }
  //We want to do several cells at once. Enough to get things done, but
  //not so many that the program is unresponsive.
  if (LOADING_SCREEN) {  //If we're using a loading screen, we want to build as fast as possible
    struct timeval then, now;
    gettimeofday(&then, NULL);
    now = then;
    
    while (!compiled && ((now.tv_sec - then.tv_sec) * 1000 + (now.tv_usec - then.tv_usec) / 1000 < stop_time)) {
      do_compile ();
      gettimeofday(&now, NULL);
    }
  } else //Take it slow
    do_compile ();

}
Exemple #2
0
DVM_ExecutableList *
DKC_compile(DKC_Compiler *compiler, FILE *fp, char *path)
{
    extern FILE *yyin;
    DVM_ExecutableList *list;
    DVM_Executable *exe;

    DBG_assert(st_compiler_list == NULL,
               ("st_compiler_list != NULL(%p)", st_compiler_list));
    set_path_to_compiler(compiler, path);
    compiler->input_mode = FILE_INPUT_MODE;

    yyin = fp;

    list = MEM_malloc(sizeof(DVM_ExecutableList));
    list->list = NULL;
    
    exe = do_compile(compiler, list, NULL, DVM_FALSE);
    exe->path = MEM_strdup(path);
    list->top_level = exe;

    /* dvm_disassemble(exe);*/

    dispose_compiler_list();
    dkc_reset_string_literal_buffer();

    return list;
}
Exemple #3
0
int compile(struct compilation_unit *cu)
{
	if (opt_llvm_enable)
		return llvm_compile(cu);

	return do_compile(cu);
}
Exemple #4
0
void
test_compile(void)
{
	struct sym_test *st;
	struct compile_env *cenv;
	test_t t;
	int need;

	for (st = next_sym_test(NULL); st; st = next_sym_test(st)) {
		if ((sym != NULL) && strcmp(sym, sym_test_name(st))) {
			continue;
		}
		/* XXX: we really want a sym_test_desc() */
		for (cenv = sym_test_env(st, NULL, &need);
		    cenv != NULL;
		    cenv = sym_test_env(st, cenv, &need)) {
			t = test_start("%s : %c%s", sym_test_name(st),
			    need ? '+' : '-', env_name(cenv));
			if (do_compile(t, st, cenv, need) == 0) {
				test_passed(t);
			}
		}
	}

	if (full_count > 0) {
		test_summary();
	}
}
Exemple #5
0
Fichier : luac.c Projet : jeske/hz
static void doit(int undump, char* filename)
{
    FILE* f= (filename==NULL) ? stdin : efopen(filename, undump ? "rb" : "r");
    ZIO z;
    if (filename==NULL) filename="(stdin)";
    zFopen(&z,f,filename);
    if (verbose) fprintf(stderr,"%s\n",filename);
    if (undump) do_undump(&z);
    else do_compile(&z);
    if (f!=stdin) fclose(f);
}
Exemple #6
0
static void
do_compile_separately (void)
{
  const char **new_new_argv;
  int i, new_new_argc;
  struct input_filename *current_ifn;

  if (num_infiles == 1 || ima_is_used)
    abort ();

  /* Total number of arguments in separate compiler invocation is :
     total number of original arguments - total no input files + one input
     file + "-o" + output file .  */
  new_new_argv = (const char **) malloc ((new_argc - num_infiles + 4) * sizeof (const char *));
  if (!new_new_argv)
    abort ();

  for (current_ifn = in_files; current_ifn && current_ifn->name;
       current_ifn = current_ifn->next)
    {
      struct input_filename *ifn = in_files;
      int go_back = 0;
      new_new_argc = 1;

      for (i = 1; i < new_argc; i++)
	{

	  if (ifn && ifn->name && !strcmp (new_argv[i], ifn->name))
	    {
	      /* This argument is one of the input file.  */

 	      if (!strcmp (new_argv[i], current_ifn->name))
		{
		  /* If it is current input file name then add it in the new
		     list.  */
		  new_new_argv[new_new_argc++] = new_argv[i];
		}
	      /* This input file can  not appear in
		 again on the command line so next time look for next input
		 file.  */
	      ifn = ifn->next;
	    }
	  else
	    {
	      /* This argument is not a input file name. Add it into new
		 list.  */
	      new_new_argv[new_new_argc++] = new_argv[i];
	    }
	}

      /* OK now we have only one input file and all other arguments.  */
      do_compile (new_new_argv, new_new_argc);
    }
}
Exemple #7
0
static void doit(int undump, char* filename)
{
 FILE* f= (filename==NULL) ? stdin : efopen(filename, undump ? "rb" : "r");
 ZIO z;
 char source[255+2];			/* +2 for '@' and '\0' */
 luaL_filesource(source,filename,sizeof(source));
 zFopen(&z,f,source);
 if (verbose) fprintf(stderr,"%s\n",source+1);
 if (undump) do_undump(&z); else do_compile(&z);
 if (f!=stdin) fclose(f);
}
Exemple #8
0
void
list_publics(int descr, dbref player, int arg[], int argc)
{
	dbref program;

	if (argc > 1) {
		notify(player,
			   "I don't understand which program you want to list PUBLIC functions for.");
		return;
	}
	program = (argc == 0) ? PLAYER_CURR_PROG(player) : arg[0];
	if (Typeof(program) != TYPE_PROGRAM) {
		notify(player, "That isn't a program.");
		return;
	}
	if (!(controls(player, program) || Linkable(program))) {
		notify(player, "That's not a public program.");
		return;
	}
	if (!(PROGRAM_CODE(program))) {
		if (program == PLAYER_CURR_PROG(player)) {
			do_compile(descr, OWNER(program), program, 0);
		} else {
			struct line *tmpline;

			tmpline = PROGRAM_FIRST(program);
			PROGRAM_SET_FIRST(program, (struct line *) read_program(program));
			do_compile(descr, OWNER(program), program, 0);
			free_prog_text(PROGRAM_FIRST(program));
			PROGRAM_SET_FIRST(program, tmpline);
		}
		if (!PROGRAM_CODE(program)) {
			notify(player, "Program not compilable.");
			return;
		}
	}
	do_list_publics(player, program);
}
Exemple #9
0
void
CRB_compile_string(CRB_Interpreter *interpreter, char **lines)
{
    extern int yyparse(void);

    crb_set_current_interpreter(interpreter);
    crb_set_source_string(lines);
    interpreter->current_line_number = 1;
    interpreter->input_mode = CRB_STRING_INPUT_MODE;

    do_compile(interpreter);

    crb_reset_string_literal_buffer();
}
Exemple #10
0
void EntityUpdate ()
{

  int stop_time;

  if (!TextureReady ()) {
    sorted = false;
    return;
  } 
  if (!sorted) {
    std::sort (entity_list.begin(), entity_list.end());
    sorted = true;
  }
  //We want to do several cells at once. Enough to get things done, but
  //not so many that the program is unresponsive.
  if (LOADING_SCREEN) {  //If we're using a loading screen, we want to build as fast as possible
    stop_time = GetTimeInMillis () + 100;
    while (!compiled && GetTimeInMillis () < stop_time)
      do_compile ();
  } else //Take it slow
    do_compile ();

}
Exemple #11
0
void
CRB_compile(CRB_Interpreter *interpreter, FILE *fp)
{
    extern FILE *yyin;

    crb_set_current_interpreter(interpreter);
    interpreter->current_line_number = 1;
    interpreter->input_mode = CRB_FILE_INPUT_MODE;

    yyin = fp;

    do_compile(interpreter);

    crb_reset_string_literal_buffer();
}
Exemple #12
0
void
prim_cancallp(PRIM_PROTOTYPE)
{
    CHECKOP(2);
    oper2 = POP();		/* string: public function name */
    oper1 = POP();		/* dbref: Program dbref to check */
    if (oper1->type != PROG_OBJECT)
	abort_interp("Expected dbref argument. (1)");
    if (!valid_object(oper1))
	abort_interp("Invalid dbref (1)");
    if (Typeof(oper1->data.objref) != TYPE_PROGRAM)
	abort_interp("Object is not a MUF Program. (1)");
    if (oper2->type != PROG_STRING)
	abort_interp("Expected string argument. (2)");
    if (!oper2->data.string)
	abort_interp("Invalid Null string argument. (2)");

    if (!(PROGRAM_CODE(oper1->data.objref))) {
	struct line *tmpline;

	tmpline = PROGRAM_FIRST(oper1->data.objref);
	PROGRAM_SET_FIRST(oper1->data.objref,
			  (struct line *) read_program(oper1->data.objref));
	do_compile(-1, OWNER(oper1->data.objref), oper1->data.objref, 0);
	free_prog_text(PROGRAM_FIRST(oper1->data.objref));
	PROGRAM_SET_FIRST(oper1->data.objref, tmpline);
    }

    result = 0;
    if (ProgMLevel(oper1->data.objref) > 0 &&
	(mlev >= 4 || OWNER(oper1->data.objref) == ProgUID || Linkable(oper1->data.objref))
	    ) {
	struct publics *pbs;

	pbs = PROGRAM_PUBS(oper1->data.objref);
	while (pbs) {
	    if (!strcasecmp(oper2->data.string->data, pbs->subname))
		break;
	    pbs = pbs->next;
	}
	if (pbs && mlev >= pbs->mlev)
	    result = 1;
    }
    CHECKOFLOW(1);
    CLEAR(oper1);
    CLEAR(oper2);
    PushInt(result);
}
Exemple #13
0
DVM_Executable *
DKC_compile_string(DKC_Compiler *compiler, char **lines)
{
    extern int yyparse(void);
    DVM_Executable *exe;

    dkc_set_source_string(lines);
    compiler->current_line_number = 1;
    compiler->input_mode = DKC_STRING_INPUT_MODE;

    exe = do_compile(compiler);

    dkc_reset_string_literal_buffer();

    return exe;
}
Exemple #14
0
DVM_Executable *
DKC_compile(DKC_Compiler *compiler, FILE *fp)
{
    extern FILE *yyin;
    DVM_Executable *exe;

    compiler->current_line_number = 1;
    compiler->input_mode = DKC_FILE_INPUT_MODE;

    yyin = fp;

    exe = do_compile(compiler);

    dkc_reset_string_literal_buffer();

    return exe;
}
Exemple #15
0
int
main (int argc, const char **argv)
{
    /* Initialization of SDCPP's environment.  */
    general_init (argv[0]);

    /* Parse the options and do minimal processing; basically just
       enough to default flags appropriately.  */
    decode_options (argc, argv);

    /* Exit early if we can (e.g. -help).  */
    if (!exit_after_options)
        do_compile ();

    if (errorcount)
        return (FATAL_EXIT_CODE);

    return (SUCCESS_EXIT_CODE);
}
Exemple #16
0
SearchFileStatus
dkc_dynamic_compile(DKC_Compiler *compiler, char *package_name,
                    DVM_ExecutableList *list, DVM_ExecutableItem **add_top,
                    char *search_file)
{
    SearchFileStatus status;
    extern FILE *yyin;
    DVM_ExecutableItem *tail;
    DVM_Executable *exe;
    SourceInput source_input;
    char found_path[FILENAME_MAX];
        
    status = get_dynamic_load_input(package_name, found_path,
                                    search_file, &source_input);
    if (status != SEARCH_FILE_SUCCESS) {
        return status;
    }
    DBG_assert(st_compiler_list == NULL,
               ("st_compiler_list != NULL(%p)", st_compiler_list));

    for (tail = list->list; tail->next; tail = tail->next)
        ;

    compiler->package_name = string_to_package_name(compiler, package_name);
    set_path_to_compiler(compiler, found_path);

    compiler->input_mode = source_input.input_mode;
    if (source_input.input_mode == FILE_INPUT_MODE) {
        yyin = source_input.u.file.fp;
    } else {
        dkc_set_source_string(source_input.u.string.lines);
    }
    exe = do_compile(compiler, list, found_path, DVM_FALSE);

    dispose_compiler_list();
    dkc_reset_string_literal_buffer();

    *add_top = tail->next;

    return SEARCH_FILE_SUCCESS;
}
Exemple #17
0
struct inst *
interp_loop(dbref player, dbref program, struct frame *fr, int rettyp)
{
	register struct inst *pc;
	register int atop;
	register struct inst *arg;
	register struct inst *temp1;
	register struct inst *temp2;
	register struct stack_addr *sys;
	register int instr_count;
	register int stop;
	int i = 0, tmp, writeonly, mlev;
	static struct inst retval;
	char dbuf[BUFFER_LEN];
	int instno_debug_line = get_primitive("debug_line");


	fr->level = ++interp_depth;	/* increment interp level */

	/* load everything into local stuff */
	pc = fr->pc;
	atop = fr->argument.top;
	stop = fr->system.top;
	arg = fr->argument.st;
	sys = fr->system.st;
	writeonly = fr->writeonly;
	already_created = 0;
	fr->brkpt.isread = 0;

	if (!pc) {
		struct line *tmpline;

		tmpline = PROGRAM_FIRST(program);
		PROGRAM_SET_FIRST(program, (struct line *) read_program(program));
		do_compile(-1, OWNER(program), program, 0);
		free_prog_text(PROGRAM_FIRST(program));
		PROGRAM_SET_FIRST(program, tmpline);
		pc = fr->pc = PROGRAM_START(program);
		if (!pc) {
			abort_loop_hard("Program not compilable. Cannot run.", NULL, NULL);
		}
		PROGRAM_INC_PROF_USES(program);
		PROGRAM_INC_INSTANCES(program);
	}
	ts_useobject(program);
	err = 0;

	instr_count = 0;
	mlev = ProgMLevel(program);
	gettimeofday(&fr->proftime, NULL);

	/* This is the 'natural' way to exit a function */
	while (stop) {

		/* Abort program if player/thing running it is recycled */
		if ((player < 0) || (player >= db_top) || ((Typeof(player) != TYPE_PLAYER) && (Typeof(player) != TYPE_THING)))
		{
			reload(fr, atop, stop);
			prog_clean(fr);
			interp_depth--;
			calc_profile_timing(program,fr);

			return NULL;
		}

		fr->instcnt++;
		instr_count++;

		if ((fr->multitask == PREEMPT) || (FLAGS(program) & BUILDER)) {
			if (mlev == 4) {
				if (tp_max_ml4_preempt_count)
				{
					if (instr_count >= tp_max_ml4_preempt_count)
						abort_loop_hard("Maximum preempt instruction count exceeded", NULL, NULL);
				}
				else
					instr_count = 0;
			} else {
				/* else make sure that the program doesn't run too long */
				if (instr_count >= tp_max_instr_count)
					abort_loop_hard("Maximum preempt instruction count exceeded", NULL, NULL);
			}
		} else {
			/* if in FOREGROUND or BACKGROUND mode, '0 sleep' every so often. */
			if ((fr->instcnt > tp_instr_slice * 4) && (instr_count >= tp_instr_slice)) {
				fr->pc = pc;
				reload(fr, atop, stop);
				PLAYER_SET_BLOCK(player, (!fr->been_background));
				add_muf_delay_event(0, fr->descr, player, NOTHING, NOTHING, program, fr,
									(fr->multitask ==
									 FOREGROUND) ? "FOREGROUND" : "BACKGROUND");
				interp_depth--;
				calc_profile_timing(program,fr);
				return NULL;
			}
		}
		if (((FLAGS(program) & ZOMBIE) || fr->brkpt.force_debugging) &&
				!fr->been_background &&
				controls(player, program)
		) {
			fr->brkpt.debugging = 1;
		} else {
			fr->brkpt.debugging = 0;
		}
		if (FLAGS(program) & DARK ||
			(fr->brkpt.debugging && fr->brkpt.showstack && !fr->brkpt.bypass)) {

			if ((pc->type != PROG_PRIMITIVE) || (pc->data.number != instno_debug_line))
			{
				char *m = debug_inst(fr, 0, pc, fr->pid, arg, dbuf, sizeof(dbuf), atop, program);

				notify_nolisten(player, m, 1);
			}
		}
		if (fr->brkpt.debugging) {
			short breakflag = 0;
			if (stop == 1 &&
					!fr->brkpt.bypass &&
					pc->type == PROG_PRIMITIVE &&
					pc->data.number == IN_RET
			) {
				/* Program is about to EXIT */
				notify_nolisten(player, "Program is about to EXIT.", 1);
				breakflag = 1;
			} else if (fr->brkpt.count) {
				for (i = 0; i < fr->brkpt.count; i++) {
					if ((!fr->brkpt.pc[i] || pc == fr->brkpt.pc[i]) &&
						/* pc matches */
						(fr->brkpt.line[i] == -1 ||
						 (fr->brkpt.lastline != pc->line &&
						  fr->brkpt.line[i] == pc->line)) &&
						/* line matches */
						(fr->brkpt.level[i] == -1 ||
						 stop <= fr->brkpt.level[i]) &&
						/* level matches */
						(fr->brkpt.prog[i] == NOTHING ||
						 fr->brkpt.prog[i] == program) &&
						/* program matches */
						(fr->brkpt.linecount[i] == -2 ||
						 (fr->brkpt.lastline != pc->line &&
						  fr->brkpt.linecount[i]-- <= 0)) &&
						/* line count matches */
						(fr->brkpt.pccount[i] == -2 ||
						 (fr->brkpt.lastpc != pc &&
						  fr->brkpt.pccount[i]-- <= 0))
						/* pc count matches */
					) {
						if (fr->brkpt.bypass) {
							if (fr->brkpt.pccount[i] == -1)
								fr->brkpt.pccount[i] = 0;
							if (fr->brkpt.linecount[i] == -1)
								fr->brkpt.linecount[i] = 0;
						} else {
							breakflag = 1;
							break;
						}
					}
				}
			}
			if (breakflag) {
				char *m;
				char buf[BUFFER_LEN];

				if (fr->brkpt.dosyspop) {
					program = sys[--stop].progref;
					pc = sys[stop].offset;
				}
				add_muf_read_event(fr->descr, player, program, fr);
				reload(fr, atop, stop);
				fr->pc = pc;
				fr->brkpt.isread = 0;
				fr->brkpt.breaknum = i;
				fr->brkpt.lastlisted = 0;
				fr->brkpt.bypass = 0;
				fr->brkpt.dosyspop = 0;
				PLAYER_SET_CURR_PROG(player, program);
				PLAYER_SET_BLOCK(player, 0);
				interp_depth--;
				if (!fr->brkpt.showstack) {
					m = debug_inst(fr, 0, pc, fr->pid, arg, dbuf, sizeof(dbuf), atop, program);
					notify_nolisten(player, m, 1);
				}
				if (pc <= PROGRAM_CODE(program) || (pc - 1)->line != pc->line) {
					list_proglines(player, program, fr, pc->line, 0);
				} else {
					m = show_line_prims(fr, program, pc, 15, 1);
					snprintf(buf, sizeof(buf), "     %s", m);
					notify_nolisten(player, buf, 1);
				}
				calc_profile_timing(program,fr);
				return NULL;
			}
			fr->brkpt.lastline = pc->line;
			fr->brkpt.lastpc = pc;
			fr->brkpt.bypass = 0;
		}
		if (mlev < 3) {
			if (fr->instcnt > (tp_max_instr_count * ((mlev == 2) ? 4 : 1)))
				abort_loop_hard("Maximum total instruction count exceeded.", NULL, NULL);
		}
		switch (pc->type) {
		case PROG_INTEGER:
		case PROG_FLOAT:
		case PROG_ADD:
		case PROG_OBJECT:
		case PROG_VAR:
		case PROG_LVAR:
		case PROG_SVAR:
		case PROG_STRING:
		case PROG_LOCK:
		case PROG_MARK:
		case PROG_ARRAY:
			if (atop >= STACK_SIZE)
				abort_loop("Stack overflow.", NULL, NULL);
			copyinst(pc, arg + atop);
			pc++;
			atop++;
			break;

		case PROG_LVAR_AT:
		case PROG_LVAR_AT_CLEAR:
			{
				struct inst *tmp;
				struct localvars *lv;

				if (atop >= STACK_SIZE)
					abort_loop("Stack overflow.", NULL, NULL);

				if (pc->data.number >= MAX_VAR || pc->data.number < 0)
					abort_loop("Scoped variable number out of range.", NULL, NULL);

				lv = localvars_get(fr, program);
				tmp = &(lv->lvars[pc->data.number]);

				copyinst(tmp, arg + atop);

				if (pc->type == PROG_LVAR_AT_CLEAR) {
					CLEAR(tmp);
					tmp->type			= PROG_INTEGER;
					tmp->data.number	= 0;
				}

				pc++;
				atop++;
			}
			break;

		case PROG_LVAR_BANG:
			{
				struct inst *the_var;
				struct localvars *lv;
				if (atop < 1)
					abort_loop("Stack Underflow.", NULL, NULL);
				if (fr->trys.top && atop - fr->trys.st->depth < 1)
					abort_loop("Stack protection fault.", NULL, NULL);

				if (pc->data.number >= MAX_VAR || pc->data.number < 0)
					abort_loop("Scoped variable number out of range.", NULL, NULL);

				lv = localvars_get(fr, program);
				the_var = &(lv->lvars[pc->data.number]);

				CLEAR(the_var);
				temp1 = arg + --atop;
				*the_var = *temp1;
				pc++;
			}
			break;

		case PROG_SVAR_AT:
		case PROG_SVAR_AT_CLEAR:
			{
				struct inst *tmp;

				if (atop >= STACK_SIZE)
					abort_loop("Stack overflow.", NULL, NULL);

				tmp = scopedvar_get(fr, 0, pc->data.number);
				if (!tmp)
					abort_loop("Scoped variable number out of range.", NULL, NULL);

				copyinst(tmp, arg + atop);

				if (pc->type == PROG_SVAR_AT_CLEAR) {
					CLEAR(tmp);

					tmp->type			= PROG_INTEGER;
					tmp->data.number	= 0;
				}

				pc++;
				atop++;
			}
			break;

		case PROG_SVAR_BANG:
			{
				struct inst *the_var;
				if (atop < 1)
					abort_loop("Stack Underflow.", NULL, NULL);
				if (fr->trys.top && atop - fr->trys.st->depth < 1)
					abort_loop("Stack protection fault.", NULL, NULL);

				the_var = scopedvar_get(fr, 0, pc->data.number);
				if (!the_var)
					abort_loop("Scoped variable number out of range.", NULL, NULL);

				CLEAR(the_var);
				temp1 = arg + --atop;
				*the_var = *temp1;
				pc++;
			}
			break;

		case PROG_FUNCTION:
			{
				int i = pc->data.mufproc->args;
				if (atop < i)
					abort_loop("Stack Underflow.", NULL, NULL);
				if (fr->trys.top && atop - fr->trys.st->depth < i)
					abort_loop("Stack protection fault.", NULL, NULL);
				if (fr->skip_declare)
					fr->skip_declare = 0;
				else
					scopedvar_addlevel(fr, pc, pc->data.mufproc->vars);
				while (i-->0)
				{
					struct inst *tmp;
					temp1 = arg + --atop;
					tmp = scopedvar_get(fr, 0, i);
					if (!tmp)
						abort_loop_hard("Internal error: Scoped variable number out of range in FUNCTION init.", temp1, NULL);
					CLEAR(tmp);
					copyinst(temp1, tmp);
					CLEAR(temp1);
				}
				pc++;
			}
			break;

		case PROG_IF:
			if (atop < 1)
				abort_loop("Stack Underflow.", NULL, NULL);
			if (fr->trys.top && atop - fr->trys.st->depth < 1)
				abort_loop("Stack protection fault.", NULL, NULL);
			temp1 = arg + --atop;
			if (false_inst(temp1))
				pc = pc->data.call;
			else
				pc++;
			CLEAR(temp1);
			break;

		case PROG_EXEC:
			if (stop >= STACK_SIZE)
				abort_loop("System Stack Overflow", NULL, NULL);
			sys[stop].progref = program;
			sys[stop++].offset = pc + 1;
			pc = pc->data.call;
			fr->skip_declare = 0;  /* Make sure we DON'T skip var decls */
			break;

		case PROG_JMP:
			/* Don't need to worry about skipping scoped var decls here. */
			/* JMP to a function header can only happen in IN_JMP */
			pc = pc->data.call;
			break;

		case PROG_TRY:
			if (atop < 1)
				abort_loop("Stack Underflow.", NULL, NULL);
			if (fr->trys.top && atop - fr->trys.st->depth < 1)
				abort_loop("Stack protection fault.", NULL, NULL);
			temp1 = arg + --atop;
			if (temp1->type != PROG_INTEGER || temp1->data.number < 0)
				abort_loop("Argument is not a positive integer.", temp1, NULL);
			if (fr->trys.top && atop - fr->trys.st->depth < temp1->data.number)
				abort_loop("Stack protection fault.", NULL, NULL);
			if (temp1->data.number > atop)
				abort_loop("Stack Underflow.", temp1, NULL);

			fr->trys.top++;
			fr->trys.st = push_try(fr->trys.st);
			fr->trys.st->depth = atop - temp1->data.number;
			fr->trys.st->call_level = stop;
			fr->trys.st->for_count = 0;
			fr->trys.st->addr = pc->data.call;

			pc++;
			CLEAR(temp1);
			break;

		case PROG_PRIMITIVE:
			/*
			 * All pc modifiers and stuff like that should stay here,
			 * everything else call with an independent dispatcher.
			 */
			switch (pc->data.number) {
			case IN_JMP:
				if (atop < 1)
					abort_loop("Stack underflow.  Missing address.", NULL, NULL);
				if (fr->trys.top && atop - fr->trys.st->depth < 1)
					abort_loop("Stack protection fault.", NULL, NULL);
				temp1 = arg + --atop;
				if (temp1->type != PROG_ADD)
					abort_loop("Argument is not an address.", temp1, NULL);
				if (temp1->data.addr->progref >= db_top ||
					temp1->data.addr->progref < 0 ||
					(Typeof(temp1->data.addr->progref) != TYPE_PROGRAM))
							abort_loop_hard("Internal error.  Invalid address.", temp1, NULL);
				if (program != temp1->data.addr->progref) {
					abort_loop("Destination outside current program.", temp1, NULL);
				}
				if (temp1->data.addr->data->type == PROG_FUNCTION) {
					fr->skip_declare = 1;
				}
				pc = temp1->data.addr->data;
				CLEAR(temp1);
				break;

			case IN_EXECUTE:
				if (atop < 1)
					abort_loop("Stack Underflow. Missing address.", NULL, NULL);
				if (fr->trys.top && atop - fr->trys.st->depth < 1)
					abort_loop("Stack protection fault.", NULL, NULL);
				temp1 = arg + --atop;
				if (temp1->type != PROG_ADD)
					abort_loop("Argument is not an address.", temp1, NULL);
				if (temp1->data.addr->progref >= db_top ||
					temp1->data.addr->progref < 0 ||
					(Typeof(temp1->data.addr->progref) != TYPE_PROGRAM))
							abort_loop_hard("Internal error.  Invalid address.", temp1, NULL);
				if (stop >= STACK_SIZE)
					abort_loop("System Stack Overflow", temp1, NULL);
				sys[stop].progref = program;
				sys[stop++].offset = pc + 1;
				if (program != temp1->data.addr->progref) {
					program = temp1->data.addr->progref;
					fr->caller.st[++fr->caller.top] = program;
					mlev = ProgMLevel(program);
					PROGRAM_INC_INSTANCES(program);
				}
				pc = temp1->data.addr->data;
				CLEAR(temp1);
				break;

			case IN_CALL:
				if (atop < 1)
					abort_loop("Stack Underflow. Missing dbref argument.", NULL, NULL);
				if (fr->trys.top && atop - fr->trys.st->depth < 1)
					abort_loop("Stack protection fault.", NULL, NULL);
				temp1 = arg + --atop;
				temp2 = 0;
				if (temp1->type != PROG_OBJECT) {
					temp2 = temp1;
					if (atop < 1)
						abort_loop("Stack Underflow. Missing dbref of func.", temp1, NULL);
					if (fr->trys.top && atop - fr->trys.st->depth < 1)
						abort_loop("Stack protection fault.", NULL, NULL);
					temp1 = arg + --atop;
					if (temp2->type != PROG_STRING)
						abort_loop("Public Func. name string required. (2)", temp1, temp2);
					if (!temp2->data.string)
						abort_loop("Null string not allowed. (2)", temp1, temp2);
				}
				if (temp1->type != PROG_OBJECT)
					abort_loop("Dbref required. (1)", temp1, temp2);
				if (!valid_object(temp1)
					|| Typeof(temp1->data.objref) != TYPE_PROGRAM)
					abort_loop("Invalid object.", temp1, temp2);
				if (!(PROGRAM_CODE(temp1->data.objref))) {
					struct line *tmpline;

					tmpline = PROGRAM_FIRST(temp1->data.objref);
					PROGRAM_SET_FIRST(temp1->data.objref,
									  (struct line *) read_program(temp1->data.objref));
					do_compile(-1, OWNER(temp1->data.objref), temp1->data.objref, 0);
					free_prog_text(PROGRAM_FIRST(temp1->data.objref));
					PROGRAM_SET_FIRST(temp1->data.objref, tmpline);
					if (!(PROGRAM_CODE(temp1->data.objref)))
						abort_loop("Program not compilable.", temp1, temp2);
				}
				if (ProgMLevel(temp1->data.objref) == 0)
					abort_loop("Permission denied", temp1, temp2);
				if (mlev < 4 && OWNER(temp1->data.objref) != ProgUID
					&& !Linkable(temp1->data.objref))
							abort_loop("Permission denied", temp1, temp2);
				if (stop >= STACK_SIZE)
					abort_loop("System Stack Overflow", temp1, temp2);
				sys[stop].progref = program;
				sys[stop].offset = pc + 1;
				if (!temp2) {
					pc = PROGRAM_START(temp1->data.objref);
				} else {
					struct publics *pbs;
					int tmpint;

					pbs = PROGRAM_PUBS(temp1->data.objref);
					while (pbs) {
						tmpint = string_compare(temp2->data.string->data, pbs->subname);
						if (!tmpint)
							break;
						pbs = pbs->next;
					}
					if (!pbs)
						abort_loop("PUBLIC or WIZCALL function not found. (2)", temp2, temp2);
					if (mlev < pbs->mlev)
						abort_loop("Insufficient permissions to call WIZCALL function. (2)",
								   temp2, temp2);
					pc = pbs->addr.ptr;
				}
				stop++;
				if (temp1->data.objref != program) {
					calc_profile_timing(program,fr);
					gettimeofday(&fr->proftime, NULL);
					program = temp1->data.objref;
					fr->caller.st[++fr->caller.top] = program;
					PROGRAM_INC_INSTANCES(program);
					mlev = ProgMLevel(program);
				}
				PROGRAM_INC_PROF_USES(program);
				ts_useobject(program);
				CLEAR(temp1);
				if (temp2)
					CLEAR(temp2);
				break;

			case IN_RET:
				if (stop > 1 && program != sys[stop - 1].progref) {
					if (sys[stop - 1].progref >= db_top ||
						sys[stop - 1].progref < 0 ||
						(Typeof(sys[stop - 1].progref) != TYPE_PROGRAM))
								abort_loop_hard("Internal error.  Invalid address.", NULL, NULL);
					calc_profile_timing(program,fr);
					gettimeofday(&fr->proftime, NULL);
					PROGRAM_DEC_INSTANCES(program);
					program = sys[stop - 1].progref;
					mlev = ProgMLevel(program);
					fr->caller.top--;
				}
				scopedvar_poplevel(fr);
				pc = sys[--stop].offset;
				break;

			case IN_CATCH:
			case IN_CATCH_DETAILED:
				{
					int depth;

					if (!(fr->trys.top))
						abort_loop_hard("Internal error.  TRY stack underflow.", NULL, NULL);

					depth = fr->trys.st->depth;
					while (atop > depth) {
						temp1 = arg + --atop;
						CLEAR(temp1);
					}

					while (fr->trys.st->for_count-->0) {
						CLEAR(&fr->fors.st->cur);
						CLEAR(&fr->fors.st->end);
						fr->fors.top--;
						fr->fors.st = pop_for(fr->fors.st);
					}

					fr->trys.top--;
					fr->trys.st = pop_try(fr->trys.st);

					if (pc->data.number == IN_CATCH) {
						/* IN_CATCH */
						if (fr->errorstr) {
							arg[atop].type = PROG_STRING;
							arg[atop++].data.string = alloc_prog_string(fr->errorstr);
							free(fr->errorstr);
							fr->errorstr = NULL;
						} else {
							arg[atop].type = PROG_STRING;
							arg[atop++].data.string = NULL;
						}
						if (fr->errorinst) {
							free(fr->errorinst);
							fr->errorinst = NULL;
						}
					} else {
						/* IN_CATCH_DETAILED */
						stk_array *nu = new_array_dictionary();
						if (fr->errorstr) {
							array_set_strkey_strval(&nu, "error", fr->errorstr);
							free(fr->errorstr);
							fr->errorstr = NULL;
						}
						if (fr->errorinst) {
							array_set_strkey_strval(&nu, "instr", fr->errorinst);
							free(fr->errorinst);
							fr->errorinst = NULL;
						}
						array_set_strkey_intval(&nu, "line", fr->errorline);
						array_set_strkey_refval(&nu, "program", fr->errorprog);
						arg[atop].type = PROG_ARRAY;
						arg[atop++].data.array = nu;
					}
					reload(fr, atop, stop);
				}
				pc++;
				break;

			case IN_EVENT_WAITFOR:
				if (atop < 1)
					abort_loop("Stack Underflow. Missing eventID list array argument.", NULL, NULL);
				if (fr->trys.top && atop - fr->trys.st->depth < 1)
					abort_loop("Stack protection fault.", NULL, NULL);
				temp1 = arg + --atop;
				if (temp1->type != PROG_ARRAY)
					abort_loop("EventID string list array expected.", temp1, NULL);
				if (temp1->data.array && temp1->data.array->type != ARRAY_PACKED)
					abort_loop("Argument must be a list array of eventid strings.", temp1, NULL);
				if (!array_is_homogenous(temp1->data.array, PROG_STRING))
					abort_loop("Argument must be a list array of eventid strings.", temp1, NULL);
				fr->pc = pc + 1;
				reload(fr, atop, stop);

				{
					int i, outcount;
					int count = array_count(temp1->data.array);
					char** events = (char**)malloc(count * sizeof(char**));
					for (outcount = i = 0; i < count; i++) {
						char *val = array_get_intkey_strval(temp1->data.array, i);
						if (val != NULL) {
							int found = 0;
							int j;
							for (j = 0; j < outcount; j++) {
								if (!strcmp(events[j], val)) {
									found = 1;
									break;
								}
							}
							if (!found) {
								events[outcount++] = val;
							}
						}
					}
					muf_event_register_specific(player, program, fr, outcount, events);
					free(events);
				}

				PLAYER_SET_BLOCK(player, (!fr->been_background));
				CLEAR(temp1);
				interp_depth--;
				calc_profile_timing(program,fr);
				return NULL;
				/* NOTREACHED */
				break;

			case IN_READ:
				if (writeonly)
					abort_loop("Program is write-only.", NULL, NULL);
				if (fr->multitask == BACKGROUND)
					abort_loop("BACKGROUND programs are write only.", NULL, NULL);
				reload(fr, atop, stop);
				fr->brkpt.isread = 1;
				fr->pc = pc + 1;
				PLAYER_SET_CURR_PROG(player, program);
				PLAYER_SET_BLOCK(player, 0);
				add_muf_read_event(fr->descr, player, program, fr);
				interp_depth--;
				calc_profile_timing(program,fr);
				return NULL;
				/* NOTREACHED */
				break;

			case IN_SLEEP:
				if (atop < 1)
					abort_loop("Stack Underflow.", NULL, NULL);
				if (fr->trys.top && atop - fr->trys.st->depth < 1)
					abort_loop("Stack protection fault.", NULL, NULL);
				temp1 = arg + --atop;
				if (temp1->type != PROG_INTEGER)
					abort_loop("Invalid argument type.", temp1, NULL);
				fr->pc = pc + 1;
				reload(fr, atop, stop);
				if (temp1->data.number < 0)
					abort_loop("Timetravel beyond scope of muf.", temp1, NULL);
				add_muf_delay_event(temp1->data.number, fr->descr, player,
									NOTHING, NOTHING, program, fr, "SLEEPING");
				PLAYER_SET_BLOCK(player, (!fr->been_background));
				interp_depth--;
				calc_profile_timing(program,fr);
				return NULL;
				/* NOTREACHED */
				break;

			default:
				nargs = 0;
				reload(fr, atop, stop);
				tmp = atop;
				prim_func[pc->data.number - 1] (player, program, mlev, pc, arg, &tmp, fr);
				atop = tmp;
				pc++;
				break;
			}					/* switch */
			break;
		case PROG_CLEARED:
			log_status("WARNING: attempt to execute instruction cleared by %s:%hd in program %d",
					   (char*)pc->data.addr, pc->line, program);
			pc = NULL;
			abort_loop_hard("Program internal error. Program erroneously freed from memory.",
							NULL, NULL);
		default:
			pc = NULL;
			abort_loop_hard("Program internal error. Unknown instruction type.",
							NULL, NULL);
		}						/* switch */
		if (err) {
			if (err != ERROR_DIE_NOW && fr->trys.top) {
				while (fr->trys.st->call_level < stop) {
					if (stop > 1 && program != sys[stop - 1].progref) {
						if (sys[stop - 1].progref >= db_top ||
							sys[stop - 1].progref < 0 ||
							(Typeof(sys[stop - 1].progref) != TYPE_PROGRAM))
									abort_loop_hard("Internal error.  Invalid address.", NULL, NULL);
						calc_profile_timing(program,fr);
						gettimeofday(&fr->proftime, NULL);
						PROGRAM_DEC_INSTANCES(program);
						program = sys[stop - 1].progref;
						mlev = ProgMLevel(program);
						fr->caller.top--;
					}
					scopedvar_poplevel(fr);
					stop--;
				}

				pc = fr->trys.st->addr;
				err = 0;
			} else {
				reload(fr, atop, stop);
				prog_clean(fr);
				PLAYER_SET_BLOCK(player, 0);
				interp_depth--;
				calc_profile_timing(program,fr);
				return NULL;
			}
		}
	}							/* while */

	PLAYER_SET_BLOCK(player, 0);
	if (atop) {
		struct inst *rv;

		if (rettyp) {
			copyinst(arg + atop - 1, &retval);
			rv = &retval;
		} else {
			if (!false_inst(arg + atop - 1)) {
				rv = (struct inst *) 1;
			} else {
				rv = NULL;
			}
		}
		reload(fr, atop, stop);
		prog_clean(fr);
		interp_depth--;
		calc_profile_timing(program,fr);
		return rv;
	}
	reload(fr, atop, stop);
	prog_clean(fr);
	interp_depth--;
	calc_profile_timing(program,fr);
	return NULL;
}
Exemple #18
0
	/*******************************************************
		Function: ld_compile

		

	 *******************************************************/
string
ld_compile (bfd *abfd)
{
    string input_path;
    string output_path;
    int argc;
    string *argv;
    int child_pid;
    int statptr;
    string file_name = (string)abfd->filename;
    
    if (tmpdir == 0)
	if (create_tmpdir (FALSE) != 0) {
	    fprintf(stderr,"create_tmpdir() failed for %s\n",abfd->filename);
    	    exit(1);
	}

    if ((input_path = create_unique_file (file_name, 'B')) == 0) {
	    fprintf(stderr,"create_unique_file() failed for %s\n",abfd->filename);
    	    exit(1);
    }
    
    if (abfd->arelt_data) {
	if (extract_archive_member (abfd, input_path) != 0) {
	    fprintf(stderr,"extract_archive_member() failed for %s\n",abfd->filename);
    	    exit(1);
	}
    } else {
	UNLINK (input_path);
	if (make_link (file_name, input_path) != 0) {
	    fprintf(stderr,"make_link() failed for %s\n",abfd->filename);
    	    exit(1);
	}
    }

    if ((output_path = create_unique_file (file_name, 'o')) == 0) {
	fprintf(stderr,"create_unique_file() failed for %s\n",abfd->filename);
	exit(1);
    }

    add_to_tmp_file_list (output_path);
    add_to_tmp_file_list (input_path);


    argv = get_command_line (abfd, input_path, output_path, &argc);
    

    if (ld_ipa_opt[LD_IPA_VERBOSE].flag || ld_ipa_opt[LD_IPA_SHOW].flag)
    	fprintf(stderr,"Compiling %s\n",abfd->filename);

    child_pid = do_compile (argv);

    (void) waitpid (child_pid, &statptr, 0);
    if (statptr != 0 && WEXITSTATUS(statptr) != 0)
    	{
	fprintf(stderr,"Compile of %s failed!\n",abfd->filename);
	exit(1);
	}

    active_pid = 0;
    
    FREE (argv);

    UNLINK (input_path);
    remove_from_tmp_file_list (input_path);
    FREE (input_path);

    return output_path; 

} /* ld_compile */
Exemple #19
0
void
editor(int descr, dbref player, const char *command)
{
	dbref program;
	int arg[MAX_ARG + 1];
	char buf[BUFFER_LEN];
	const char *word[MAX_ARG + 1];
	int i, j;					/* loop variables */

	program = PLAYER_CURR_PROG(player);

	/* check to see if we are insert mode */
	if (PLAYER_INSERT_MODE(player)) {
		insert(player, command);	/* insert it! */
		return;
	}
	/* parse the commands */
	for (i = 0; i <= MAX_ARG && *command; i++) {
		while (*command && isspace(*command))
			command++;
		j = 0;
		while (*command && !isspace(*command)) {
			buf[j] = *command;
			command++, j++;
		}

		buf[j] = '\0';
		word[i] = alloc_string(buf);
		if ((i == 1) && !string_compare(word[0], "def")) {
			if (word[1] && (word[1][0] == '.' || (word[1][0] >= '0' && word[1][0] <= '9'))) {
				notify(player, "Invalid macro name.");
				return;
			}
			while (*command && isspace(*command))
				command++;
			word[2] = alloc_string(command);
			if (!word[2])
				notify(player, "Invalid definition syntax.");
			else {
				if (insert_macro(word[1], word[2], player, &macrotop)) {
					notify(player, "Entry created.");
				} else {
					notify(player, "That macro already exists!");
				}
			}
			for (; i >= 0; i--) {
				if (word[i])
					free((void *) word[i]);
			}
			return;
		}
		arg[i] = atoi(buf);
		if (arg[i] < 0) {
			notify(player, "Negative arguments not allowed!");
			for (; i >= 0; i--) {
				if (word[i])
					free((void *) word[i]);
			}
			return;
		}
	}
	i--;
	while ((i >= 0) && !word[i])
		i--;
	if (i < 0) {
		return;
	} else {
		switch (word[i][0]) {
		case KILL_COMMAND:
			if (!Wizard(player)) {
				notify(player, "I'm sorry Dave, but I can't let you do that.");
			} else {
				if (kill_macro(word[0], player, &macrotop))
					notify(player, "Macro entry deleted.");
				else
					notify(player, "Macro to delete not found.");
			}
			break;
		case SHOW_COMMAND:
			list_macros(word, i, player, 1);
			break;
		case SHORTSHOW_COMMAND:
			list_macros(word, i, player, 0);
			break;
		case INSERT_COMMAND:
			do_insert(player, program, arg, i);
			notify(player, "Entering insert mode.");
			break;
		case DELETE_COMMAND:
			do_delete(player, program, arg, i);
			break;
		case QUIT_EDIT_COMMAND:
			do_quit(player, program);
			notify(player, "Editor exited.");
			break;
		case COMPILE_COMMAND:
			/* compile code belongs in compile.c, not in the editor */
			do_compile(descr, player, program, 1);
			notify(player, "Compiler done.");
			break;
		case LIST_COMMAND:
			do_list(player, program, arg, i);
			break;
		case EDITOR_HELP_COMMAND:
			spit_file(player, EDITOR_HELP_FILE);
			break;
		case VIEW_COMMAND:
			val_and_head(player, arg, i);
			break;
		case UNASSEMBLE_COMMAND:
			disassemble(player, program);
			break;
		case NUMBER_COMMAND:
			toggle_numbers(player, arg, i);
			break;
		case PUBLICS_COMMAND:
			list_publics(descr, player, arg, i);
			break;
		default:
			notify(player, "Illegal editor command.");
			break;
		}
	}
	for (; i >= 0; i--) {
		if (word[i])
			free((void *) word[i]);
	}
}
Exemple #20
0
jint Java_pp_compiler_Compile_compiler(JNIEnv* env, jobject obj, jstring jname)
{

	 int e;
	 const char*path;
	 int i;
	 char*name; // index of the file name

     initialize();

	 // error capture
	 e=0;
     if ((e=setjmp(jmp_env))!=0)
     {
    	 terminate();
         if (iStackPtr>0)
    	 {
				#ifdef DEBUG
					 return 12345;  // for debug to stay in console
				#else
					 return e;
				#endif
    		  // lauch editor on the error if e>0
    		  // stay on the console on fatal error <0
    	 }
    	 return -1;
     }

	 // Parameters are used in other functons such as emitChar
     // so save them in globals
	 Env=env;
	 Obj=obj;

	 // compute the identifier of the Java Method used by the compiler
	 jclass cls = (*env)->GetObjectClass(env, obj);
   	 emitcharID = (*env)->GetMethodID(env, cls, "emitChar", "(C)V");
     if (emitcharID == NULL) ReportError(INTERNAL,"method not found");  // Humm, method not found

	 // get the path of the file to compile
     path=(*env)->GetStringUTFChars(env,jname,NULL);
	 if (path==NULL) ReportError(OUTOFMEMORY);       // out of memory

	 // copy the path in the Pool and split it
	 // split the path into the path and the name
	 // a terminal zero is included in place of the last '/'
	 // assign LoPoolMax to the end of the path
	 name=split(path);
     (*env)->ReleaseStringUTFChars(env,jname,path);

     prompt(name);

     do_compile();

     do_link();

     build_exec();

     terminate();

     post_message();

	 return 0;

}
Exemple #21
0
static DVM_Executable *
do_compile(DKC_Compiler *compiler, DVM_ExecutableList *list,
           char *path, DVM_Boolean is_required)
{
    extern FILE *yyin;
    extern int yyparse(void);
    RequireList *req_pos;
    DKC_Compiler *req_comp;
    DVM_Executable *exe;
    DVM_Executable *req_exe;
    char found_path[FILENAME_MAX];
    DKC_Compiler *compiler_backup;
    SourceInput source_input;

    compiler_backup = dkc_get_current_compiler();
    dkc_set_current_compiler(compiler);
    if (yyparse()) {
        fprintf(stderr, "Error ! Error ! Error !\n");
        exit(1);
    }

    for (req_pos = compiler->require_list; req_pos;
         req_pos = req_pos->next) {
        req_comp = search_compiler(st_compiler_list, req_pos->package_name);
        if (req_comp) {
            compiler->required_list
                = add_compiler_to_list(compiler->required_list, req_comp);
            continue;
        }
        req_comp = DKC_create_compiler();
        
        /* BUGBUG req_comp references parent compiler's MEM_storage */
        req_comp->package_name = req_pos->package_name;
        req_comp->source_suffix = DKH_SOURCE;

        compiler->required_list
            = add_compiler_to_list(compiler->required_list, req_comp);
        st_compiler_list = add_compiler_to_list(st_compiler_list, req_comp);

        get_require_input(req_pos, found_path, &source_input);
        set_path_to_compiler(req_comp, found_path);
        req_comp->input_mode = source_input.input_mode;
        if (source_input.input_mode == FILE_INPUT_MODE) {
            yyin = source_input.u.file.fp;
        } else {
            dkc_set_source_string(source_input.u.string.lines);
        }
        req_exe = do_compile(req_comp, list, found_path, DVM_TRUE);
    }

    dkc_fix_tree(compiler);
    exe = dkc_generate(compiler);
    if (path) {
        exe->path = MEM_strdup(path);
    } else {
        exe->path = NULL;
    }
    /* dvm_disassemble(exe);*/

    exe->is_required = is_required;
    if (!add_exe_to_list(exe, list)) {
        dvm_dispose_executable(exe);
    }

    dkc_set_current_compiler(compiler_backup);

    return exe;
}
/* Main entry point. This is gcc driver driver!
   Interpret -arch flag from the list of input arguments. Invoke appropriate
   compiler driver. 'lipo' the results if more than one -arch is supplied.  */
int
main (int argc, const char **argv)
{
  size_t i;
  int l, pid, argv_0_len, prog_len;
  char *errmsg_fmt, *errmsg_arg;
  char *override_option_str = NULL;
  char path_buffer[2*PATH_MAX+1];
  int linklen;

  total_argc = argc;
  prog_len = 0;

  argv_0_len = strlen (argv[0]);

  /* Get the progname, required by pexecute () and program location.  */
  prog_len = get_prog_name_len (argv[0]);

  /* If argv[0] is all program name (no slashes), search the PATH environment
     variable to get the fully resolved path to the executable. */
  if (prog_len == argv_0_len)
    {
#ifdef DEBUG
      progname = argv[0] + argv_0_len - prog_len;
      fprintf (stderr,"%s: before PATH resolution, full progname = %s\n",
               argv[0]+argv_0_len-prog_len, argv[0]);
#endif
      argv[0] = resolve_path_to_executable (argv[0]);
      prog_len = get_prog_name_len (argv[0]);
      argv_0_len = strlen(argv[0]);
    }

  /* If argv[0] is a symbolic link, use the directory of the pointed-to file
     to find compiler components. */

  if ((linklen = readlink (argv[0], path_buffer, PATH_MAX)) != -1)
    {
      /* readlink succeeds if argv[0] is a symlink.  path_buffer now contains
	 the file referenced. */
      path_buffer[linklen] = '\0';
#ifdef DEBUG
      progname = argv[0] + argv_0_len - prog_len;
      fprintf (stderr, "%s: before symlink, full prog = %s target = %s\n",
	       progname, argv[0], path_buffer);
#endif
      argv[0] = resolve_symlink(argv[0], path_buffer, argv_0_len, prog_len);
      argv_0_len = strlen(argv[0]);

      /* Get the progname, required by pexecute () and program location.  */
      prog_len = get_prog_name_len (argv[0]);

#ifdef DEBUG
      progname = argv[0] + argv_0_len - prog_len;
      printf("%s: ARGV[0] after symlink = %s\n", progname, argv[0]);
#endif
    }

  progname = argv[0] + argv_0_len - prog_len;

  /* Setup driver prefix.  */
  prefix_len = argv_0_len - prog_len;
  curr_dir = (char *) malloc (sizeof (char) * (prefix_len + 1));
  strncpy (curr_dir, argv[0], prefix_len);
  curr_dir[prefix_len] = '\0';
  driver_exec_prefix = (argv[0], "/usr/bin", curr_dir);

#ifdef DEBUG
  fprintf (stderr,"%s: full progname = %s\n", progname, argv[0]);
  fprintf (stderr,"%s: progname = %s\n", progname, progname);
  fprintf (stderr,"%s: driver_exec_prefix = %s\n", progname, driver_exec_prefix);
#endif

  /* Before we get too far, rewrite the command line with any requested overrides */
  if ((override_option_str = getenv ("QA_OVERRIDE_GCC3_OPTIONS")) != NULL)
    rewrite_command_line(override_option_str, &argc, (char***)&argv);



  initialize ();

  /* Process arguments. Take appropriate actions when
     -arch, -c, -S, -E, -o is encountered. Find input file name.  */
  for (i = 1; i < argc; i++)
    {
      if (!strcmp (argv[i], "-arch"))
	{
	  if (i + 1 >= argc)
	    abort ();

	  add_arch (argv[i+1]);
	  i++;
	}
      else if (!strcmp (argv[i], "-c"))
	{
	  new_argv[new_argc++] = argv[i];
	  compile_only_request = 1;
	}
      else if (!strcmp (argv[i], "-S"))
	{
	  new_argv[new_argc++] = argv[i];
	  asm_output_request = 1;
	}
      else if (!strcmp (argv[i], "-E"))
	{
	  new_argv[new_argc++] = argv[i];
	  preprocessed_output_request = 1;
	}
      else if (!strcmp (argv[i], "-MD") || !strcmp (argv[i], "-MMD"))
	{
	  new_argv[new_argc++] = argv[i];
	  dash_capital_m_seen = 1;
	}
      else if (!strcmp (argv[i], "-m32"))
	{
	  new_argv[new_argc++] = argv[i];
	  dash_m32_seen = 1;
	}
      else if (!strcmp (argv[i], "-m64"))
	{
	  new_argv[new_argc++] = argv[i];
	  dash_m64_seen = 1;
	}
      else if (!strcmp (argv[i], "-dynamiclib"))
	{
	  new_argv[new_argc++] = argv[i];
	  dash_dynamiclib_seen = 1;
        }
      else if (!strcmp (argv[i], "-v"))
	{
	  new_argv[new_argc++] = argv[i];
	  verbose_flag = 1;
	}
      else if (!strcmp (argv[i], "-o"))
	{
	  if (i + 1 >= argc)
	    fatal ("argument to '-o' is missing");

	  output_filename = argv[i+1];
	  i++;
	}
      else if ((! strcmp (argv[i], "-pass-exit-codes"))
	       || (! strcmp (argv[i], "-print-search-dirs"))
	       || (! strcmp (argv[i], "-print-libgcc-file-name"))
	       || (! strncmp (argv[i], "-print-file-name=", 17))
	       || (! strncmp (argv[i], "-print-prog-name=", 17))
	       || (! strcmp (argv[i], "-print-multi-lib"))
	       || (! strcmp (argv[i], "-print-multi-directory"))
	       || (! strcmp (argv[i], "-print-multi-os-directory"))
	       || (! strcmp (argv[i], "-ftarget-help"))
	       || (! strcmp (argv[i], "-fhelp"))
	       || (! strcmp (argv[i], "+e"))
	       || (! strncmp (argv[i], "-Wa,",4))
	       || (! strncmp (argv[i], "-Wp,",4))
	       || (! strncmp (argv[i], "-Wl,",4))
	       || (! strncmp (argv[i], "-l", 2))
	       || (! strncmp (argv[i], "-weak-l", 7))
	       || (! strncmp (argv[i], "-specs=", 7))
	       || (! strcmp (argv[i], "-ObjC"))
	       || (! strcmp (argv[i], "-fobjC"))
	       || (! strcmp (argv[i], "-ObjC++"))
	       || (! strcmp (argv[i], "-time"))
	       || (! strcmp (argv[i], "-###"))
	       || (! strcmp (argv[i], "-fconstant-cfstrings"))
	       || (! strcmp (argv[i], "-fno-constant-cfstrings"))
	       || (! strcmp (argv[i], "-static-libgcc"))
	       || (! strcmp (argv[i], "-shared-libgcc"))
	       || (! strcmp (argv[i], "-pipe"))
	       )
	{
	  new_argv[new_argc++] = argv[i];
	}
      else if (! strcmp (argv[i], "-save-temps")
	       || ! strcmp (argv[i], "--save-temps"))
	{
	  new_argv[new_argc++] = argv[i];
	  save_temps_seen = 1;
	}
      else if ((! strcmp (argv[i], "-Xlinker"))
	       || (! strcmp (argv[i], "-Xassembler"))
	       || (! strcmp (argv[i], "-Xpreprocessor"))
	       || (! strcmp (argv[i], "-l"))
	       || (! strcmp (argv[i], "-weak_library"))
	       || (! strcmp (argv[i], "-weak_framework"))
	       || (! strcmp (argv[i], "-specs"))
	       || (! strcmp (argv[i], "-framework"))
	       )
	{
	  new_argv[new_argc++] = argv[i];
	  i++;
	  new_argv[new_argc++] = argv[i];
	}
      else if (! strncmp (argv[i], "-Xarch_", 7))
	{
	  arch_conditional[new_argc] = get_arch_name (argv[i] + 7);
	  i++;
	  new_argv[new_argc++] = argv[i];
	}
      else if (argv[i][0] == '-' && argv[i][1] != 0)
	{
	  const char *p = &argv[i][1];
	  int c = *p;

	  /* First copy this flag itself.  */
	  new_argv[new_argc++] = argv[i];

	  if (argv[i][1] == 'M')
	    dash_capital_m_seen = 1;

	  /* Now copy this flag's arguments, if any, appropriately.  */
	  if ((SWITCH_TAKES_ARG (c) > (p[1] != 0))
	      || WORD_SWITCH_TAKES_ARG (p))
	    {
	      int j = 0;
	      int n_args = WORD_SWITCH_TAKES_ARG (p);
	      if (n_args == 0)
		{
		  /* Count only the option arguments in separate argv elements.  */
		  n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
		}
	      if (i + n_args >= argc)
		fatal ("argument to `-%s' is missing", p);


	      while ( j < n_args)
		{
		  i++;
		  new_argv[new_argc++] = argv[i];
		  j++;
		}
	    }

	}
      else
	{
	  struct input_filename *ifn;
	  new_argv[new_argc++] = argv[i];
	  ifn = (struct input_filename *) malloc (sizeof (struct input_filename));
	  ifn->name = argv[i];
	  ifn->index = i;
	  ifn->next = NULL;
	  num_infiles++;

	  if (last_infile)
	      last_infile->next = ifn;
	  else
	    in_files = ifn;

	  last_infile = ifn;
	}
    }

#if 0
  if (num_infiles == 0)
    fatal ("no input files");
#endif

  if (num_arches == 0)
    add_arch(get_arch_name(NULL));

  if (num_arches > 1)
    {
      if (preprocessed_output_request
	  || save_temps_seen
	  || asm_output_request
	  || dash_capital_m_seen)
	fatal ("-E, -S, -save-temps and -M options are not allowed with multiple -arch flags");
    }
  /* If -arch is not present OR Only one -arch <blah> is specified.
     Invoke appropriate compiler driver.  FAT build is not required in this
     case.  */

  if (num_arches == 1)
    {
      int arch_specific_argc;
      const char **arch_specific_argv;

      /* Find compiler driver based on -arch <foo> and add approriate
	 -m* argument.  */
      new_argv[0] = get_driver_name (get_arch_name (arches[0]));
      new_argc = new_argc + add_arch_options (0, new_argv, new_argc);

#ifdef DEBUG
      printf ("%s: invoking single driver name = %s\n", progname, new_argv[0]);
#endif

      /* Re insert output file name.  */
      if (output_filename)
	{
	  new_argv[new_argc++] = "-o";
	  new_argv[new_argc++] = output_filename;
	}

      /* Add the NULL.  */
      new_argv[new_argc] = NULL;

      arch_specific_argv =
	(const char **) malloc ((new_argc + 1) * sizeof (const char *));
      arch_specific_argc = filter_args_for_arch (new_argv,
						 new_argc,
						 arch_specific_argv,
						 get_arch_name (arches[0]));

#ifdef DEBUG
      debug_command_line (arch_specific_argv, arch_specific_argc);
#endif

      pid = pexecute (arch_specific_argv[0], (char *const *)arch_specific_argv,
		      progname, NULL, &errmsg_fmt, &errmsg_arg,
		      PEXECUTE_SEARCH | PEXECUTE_ONE);

      if (pid == -1)
	pfatal_pexecute (errmsg_fmt, errmsg_arg);

      do_wait (pid, arch_specific_argv[0]);
    }
  else
    {
      /* Handle multiple -arch <blah>.  */

      /* If more than one input files are supplied but only one output filename
	 is present then IMA will be used.  */
      if (num_infiles > 1 && !compile_only_request)
	ima_is_used = 1;

      /* Linker wants to know this in case of multiple -arch.  */
      if (!compile_only_request && !dash_dynamiclib_seen)
	new_argv[new_argc++] = "-Wl,-arch_multiple";


      /* If only one input file is specified OR IMA is used then expected output
	 is one FAT binary.  */
      if (num_infiles == 1 || ima_is_used)
	{
	  const char *out_file;

	     /* Create output file name based on
	     input filename, if required.  */
	  if (compile_only_request && !output_filename && num_infiles == 1)
	    out_file = strip_path_and_suffix (in_files->name, ".o");
	  else
	    out_file = (output_filename ? output_filename : final_output);


	  /* Linker wants to know name of output file using one extra arg.  */
	  if (!compile_only_request)
	    {
	      char *oname = (char *)(output_filename ? output_filename : final_output);
	      char *n =  malloc (sizeof (char) * (strlen (oname) + 5));
	      strcpy (n, "-Wl,");
	      strcat (n, oname);
	      new_argv[new_argc++] = "-Wl,-final_output";
	      new_argv[new_argc++] = n;
	    }

	  /* Compile file(s) for each arch and lipo 'em together.  */
	  do_compile (new_argv, new_argc);

	  /* Make FAT binary by combining individual output files for each
	     architecture, using 'lipo'.  */
	  do_lipo (0, out_file);
	}
      else
	{
	  /* Multiple input files are present and IMA is not used.
	     Which means need to generate multiple FAT files.  */
	  do_compile_separately ();
	  do_lipo_separately ();
	}
    }

  final_cleanup ();
  free (curr_dir);
  return greatest_status;
}