Beispiel #1
0
/* Should NOT be called with cs_error held */
KHMEXP void KHMAPI
kherr_push_new_context(khm_int32 flags)
{
    kherr_context * p = NULL;
    kherr_context * c;

    flags &= KHERR_CFMASK_INITIAL;

    EnterCriticalSection(&cs_error);
    p = peek_context();
    c = get_empty_context();
    if(IS_KHERR_CTX(p)) {
        LDELETE(&ctx_root_list, c);
#ifdef DEBUG
        assert(TPARENT(c) == NULL);
#endif
        TADDCHILD(p,c);
        c->flags &= ~KHERR_CF_UNBOUND;
        kherr_hold_context(p);
    }
    c->flags |= flags;
    push_context(c);

    notify_ctx_event(KHERR_CTX_BEGIN, c, NULL, NULL, 0);
    if (IS_KHERR_CTX(p)) {
        notify_ctx_event(KHERR_CTX_NEWCHILD, p, c, NULL, 0);
    }

    LeaveCriticalSection(&cs_error);
}
Beispiel #2
0
KHMEXP void KHMAPI
kherr_push_context(kherr_context * c)
{

    if (!IS_KHERR_CTX(c))
        return;

    EnterCriticalSection(&cs_error);

    push_context(c);

    LeaveCriticalSection(&cs_error);
}
void
cp_genericize (tree fndecl)
{
  tree t;
  struct pointer_set_t *p_set;

  /* Fix up the types of parms passed by invisible reference.  */
  for (t = DECL_ARGUMENTS (fndecl); t; t = TREE_CHAIN (t))
    if (TREE_ADDRESSABLE (TREE_TYPE (t)))
      {
	/* If a function's arguments are copied to create a thunk,
	   then DECL_BY_REFERENCE will be set -- but the type of the
	   argument will be a pointer type, so we will never get
	   here.  */
	gcc_assert (!DECL_BY_REFERENCE (t));
	gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
	TREE_TYPE (t) = DECL_ARG_TYPE (t);
	DECL_BY_REFERENCE (t) = 1;
	TREE_ADDRESSABLE (t) = 0;
	relayout_decl (t);
      }

  /* Do the same for the return value.  */
  if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
    {
      t = DECL_RESULT (fndecl);
      TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
      DECL_BY_REFERENCE (t) = 1;
      TREE_ADDRESSABLE (t) = 0;
      relayout_decl (t);
    }

  /* If we're a clone, the body is already GIMPLE.  */
  if (DECL_CLONED_FUNCTION_P (fndecl))
    return;

  /* We do want to see every occurrence of the parms, so we can't just use
     walk_tree's hash functionality.  */
  p_set = pointer_set_create ();
  walk_tree (&DECL_SAVED_TREE (fndecl), cp_genericize_r, p_set, NULL);
  pointer_set_destroy (p_set);

  /* Do everything else.  */
  push_context ();
  c_genericize (fndecl);
  pop_context ();
}
Beispiel #4
0
/* Process the destination of the menu entry, and start a menu entry 
   description.  */
ELEMENT *
enter_menu_entry_node (ELEMENT *current)
{
  ELEMENT *description, *preformatted;

  description = new_element (ET_menu_entry_description);
  add_to_element_args (current, description);
  register_extra_menu_entry_information (current);
  current->line_nr = line_nr;
  current = description;

  preformatted = new_element (ET_preformatted);
  add_to_element_contents (current, preformatted);
  current = preformatted;
  push_context (ct_preformatted);
  return current;
}
Beispiel #5
0
void
c_genericize (tree fndecl)
{
  FILE *dump_file;
  int local_dump_flags;
  struct cgraph_node *cgn;

  /* Dump the C-specific tree IR.  */
  dump_file = dump_begin (TDI_original, &local_dump_flags);
  if (dump_file)
    {
      fprintf (dump_file, "\n;; Function %s",
	       lang_hooks.decl_printable_name (fndecl, 2));
      fprintf (dump_file, " (%s)\n",
	       IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)));
      fprintf (dump_file, ";; enabled by -%s\n", dump_flag_name (TDI_original));
      fprintf (dump_file, "\n");

      if (local_dump_flags & TDF_RAW)
	dump_node (DECL_SAVED_TREE (fndecl),
		   TDF_SLIM | local_dump_flags, dump_file);
      else
	print_c_tree (dump_file, DECL_SAVED_TREE (fndecl));
      fprintf (dump_file, "\n");

      dump_end (TDI_original, dump_file);
    }

  /* Go ahead and gimplify for now.  */
  push_context ();
  gimplify_function_tree (fndecl);
  pop_context ();

  /* Dump the genericized tree IR.  */
  dump_function (TDI_generic, fndecl);

  /* Genericize all nested functions now.  We do things in this order so
     that items like VLA sizes are expanded properly in the context of
     the correct function.  */
  cgn = cgraph_node (fndecl);
  for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
    c_genericize (cgn->decl);
}
Beispiel #6
0
neam::r::shell::variable_stack::variable_stack()
{
  push_context(true, false);
}
Beispiel #7
0
Datei: main.c Projekt: gvlx/gawk
int
main(int argc, char **argv)
{
	/*
	 * The + on the front tells GNU getopt not to rearrange argv.
	 */
	const char *optlist = "+F:f:v:W;m:bcCd::D::e:E:gh:i:l:L:nNo::Op::MPrStVY";
	bool stopped_early = false;
	int old_optind;
	int i;
	int c;
	char *scan, *src;
	char *extra_stack;
	int have_srcfile = 0;
	SRCFILE *s;

	/* do these checks early */
	if (getenv("TIDYMEM") != NULL)
		do_flags |= DO_TIDY_MEM;

#ifdef HAVE_MCHECK_H
#ifdef HAVE_MTRACE
	if (do_tidy_mem)
		mtrace();
#endif /* HAVE_MTRACE */
#endif /* HAVE_MCHECK_H */

#if defined(LC_CTYPE)
	setlocale(LC_CTYPE, "");
#endif
#if defined(LC_COLLATE)
	setlocale(LC_COLLATE, "");
#endif
#if defined(LC_MESSAGES)
	setlocale(LC_MESSAGES, "");
#endif
#if defined(LC_NUMERIC) && defined(HAVE_LOCALE_H)
	/*
	 * Force the issue here.  According to POSIX 2001, decimal
	 * point is used for parsing source code and for command-line
	 * assignments and the locale value for processing input,
	 * number to string conversion, and printing output.
	 *
	 * 10/2005 --- see below also; we now only use the locale's
	 * decimal point if do_posix in effect.
	 *
	 * 9/2007:
	 * This is a mess. We need to get the locale's numeric info for
	 * the thousands separator for the %'d flag.
	 */
	setlocale(LC_NUMERIC, "");
	init_locale(& loc);
	setlocale(LC_NUMERIC, "C");
#endif
#if defined(LC_TIME)
	setlocale(LC_TIME, "");
#endif

#if MBS_SUPPORT
	/*
	 * In glibc, MB_CUR_MAX is actually a function.  This value is
	 * tested *a lot* in many speed-critical places in gawk. Caching
	 * this value once makes a speed difference.
	 */
	gawk_mb_cur_max = MB_CUR_MAX;
	/* Without MBS_SUPPORT, gawk_mb_cur_max is 1. */

	/* init the cache for checking bytes if they're characters */
	init_btowc_cache();
#endif

	(void) bindtextdomain(PACKAGE, LOCALEDIR);
	(void) textdomain(PACKAGE);

	(void) signal(SIGFPE, catchsig);
#ifdef SIGBUS
	(void) signal(SIGBUS, catchsig);
#endif

	(void) sigsegv_install_handler(catchsegv);
#define STACK_SIZE (16*1024)
	emalloc(extra_stack, char *, STACK_SIZE, "main");
	(void) stackoverflow_install_handler(catchstackoverflow, extra_stack, STACK_SIZE);
#undef STACK_SIZE

	myname = gawk_name(argv[0]);
	os_arg_fixup(&argc, &argv); /* emulate redirection, expand wildcards */

	if (argc < 2)
		usage(EXIT_FAILURE, stderr);

	/* initialize the null string */
	Nnull_string = make_string("", 0);

	/* Robustness: check that file descriptors 0, 1, 2 are open */
	init_fds();

	/* init array handling. */
	array_init();

	/* init the symbol tables */
	init_symbol_table();

	output_fp = stdout;

	/* we do error messages ourselves on invalid options */
	opterr = false;

	/* copy argv before getopt gets to it; used to restart the debugger */  
	save_argv(argc, argv);

	/* initialize global (main) execution context */
	push_context(new_context());

	/* option processing. ready, set, go! */
	for (optopt = 0, old_optind = 1;
	     (c = getopt_long(argc, argv, optlist, optab, NULL)) != EOF;
	     optopt = 0, old_optind = optind) {
		if (do_posix)
			opterr = true;

		switch (c) {
		case 'F':
			add_preassign(PRE_ASSIGN_FS, optarg);
			break;

		case 'E':
			disallow_var_assigns = true;
			/* fall through */
		case 'f':
			/*
			 * Allow multiple -f options.
			 * This makes function libraries real easy.
			 * Most of the magic is in the scanner.
			 *
			 * The following is to allow for whitespace at the end
			 * of a #! /bin/gawk line in an executable file
			 */
			scan = optarg;
			if (argv[optind-1] != optarg)
				while (isspace((unsigned char) *scan))
					scan++;
			src = (*scan == '\0' ? argv[optind++] : optarg);
			(void) add_srcfile((src && src[0] == '-' && src[1] == '\0') ?
					SRC_STDIN : SRC_FILE,
					src, srcfiles, NULL, NULL);

			break;

		case 'v':
			add_preassign(PRE_ASSIGN, optarg);
			break;

		case 'm':
			/*
			 * BWK awk extension.
			 *	-mf nnn		set # fields, gawk ignores
			 *	-mr nnn		set record length, ditto
			 *
			 * As of at least 10/2007, BWK awk also ignores it.
			 */
			if (do_lint)
				lintwarn(_("`-m[fr]' option irrelevant in gawk"));
			if (optarg[0] != 'r' && optarg[0] != 'f')
				warning(_("-m option usage: `-m[fr] nnn'"));
			break;

		case 'b':
			do_binary = true;
			break;

		case 'c':
			do_flags |= DO_TRADITIONAL;
			break;

		case 'C':
			copyleft();
			break;

		case 'd':
			do_flags |= DO_DUMP_VARS;
			if (optarg != NULL && optarg[0] != '\0')
				varfile = optarg;
			break;

		case 'D':
			do_flags |= DO_DEBUG;
			if (optarg != NULL && optarg[0] != '\0')
				command_file = optarg;
			break;

		case 'e':
			if (optarg[0] == '\0')
				warning(_("empty argument to `-e/--source' ignored"));
			else
				(void) add_srcfile(SRC_CMDLINE, optarg, srcfiles, NULL, NULL);
			break;

		case 'g':
			do_flags |= DO_INTL;
			break;

		case 'h':
			/* write usage to stdout, per GNU coding stds */
			usage(EXIT_SUCCESS, stdout);
			break;

		case 'i':
			(void) add_srcfile(SRC_INC, optarg, srcfiles, NULL, NULL);
			break;

		case 'l':
			(void) add_srcfile(SRC_EXTLIB, optarg, srcfiles, NULL, NULL);
			break;

		case 'L':
#ifndef NO_LINT
			do_flags |= DO_LINT_ALL;
			if (optarg != NULL) {
				if (strcmp(optarg, "fatal") == 0)
					lintfunc = r_fatal;
				else if (strcmp(optarg, "invalid") == 0) {
					do_flags &= ~DO_LINT_ALL;
					do_flags |= DO_LINT_INVALID;
				}
			}
			break;

		case 't':
			do_flags |= DO_LINT_OLD;
			break;
#else
		case 'L':
		case 't':
			break;
#endif

		case 'n':
			do_flags |= DO_NON_DEC_DATA;
			break;

		case 'N':
			use_lc_numeric = true;
			break;

		case 'O':
			do_optimize++;
			break;

		case 'p':
			do_flags |= DO_PROFILE;
			/* fall through */
		case 'o':
			do_flags |= DO_PRETTY_PRINT;
			if (optarg != NULL)
				set_prof_file(optarg);
			else
				set_prof_file(DEFAULT_PROFILE);
			break;

		case 'M':
#ifdef HAVE_MPFR
			do_flags |= DO_MPFR;
#endif
			break;

		case 'P':
			do_flags |= DO_POSIX;
			break;

		case 'r':
			do_flags |= DO_INTERVALS;
 			break;
 
		case 'S':
			do_flags |= DO_SANDBOX;
  			break;

		case 'V':
			do_version = true;
			break;

		case 'W':       /* gawk specific options - now in getopt_long */
			fprintf(stderr, _("%s: option `-W %s' unrecognized, ignored\n"),
				argv[0], optarg);
			break;

		case 0:
			/*
			 * getopt_long found an option that sets a variable
			 * instead of returning a letter. Do nothing, just
			 * cycle around for the next one.
			 */
			break;

		case 'Y':
#if defined(YYDEBUG) || defined(GAWKDEBUG)
			if (c == 'Y') {
				yydebug = 2;
				break;
			}
#endif
			/* if not debugging, fall through */
		case '?':
		default:
			/*
			 * If not posix, an unrecognized option stops argument
			 * processing so that it can go into ARGV for the awk
			 * program to see. This makes use of ``#! /bin/gawk -f''
			 * easier.
			 *
			 * However, it's never simple. If optopt is set,
			 * an option that requires an argument didn't get the
			 * argument. We care because if opterr is 0, then
			 * getopt_long won't print the error message for us.
			 */
			if (! do_posix
			    && (optopt == '\0' || strchr(optlist, optopt) == NULL)) {
				/*
				 * can't just do optind--. In case of an
				 * option with >= 2 letters, getopt_long
				 * won't have incremented optind.
				 */
				optind = old_optind;
				stopped_early = true;
				goto out;
			} else if (optopt != '\0') {
				/* Use POSIX required message format */
				fprintf(stderr,
					_("%s: option requires an argument -- %c\n"),
					myname, optopt);
				usage(EXIT_FAILURE, stderr);
			}
			/* else
				let getopt print error message for us */
			break;
		}
		if (c == 'E')	/* --exec ends option processing */
			break;
	}
out:

	if (do_nostalgia)
		nostalgia();

	/* check for POSIXLY_CORRECT environment variable */
	if (! do_posix && getenv("POSIXLY_CORRECT") != NULL) {
		do_flags |= DO_POSIX;
		if (do_lint)
			lintwarn(
	_("environment variable `POSIXLY_CORRECT' set: turning on `--posix'"));
	}

	if (do_posix) {
		use_lc_numeric = true;
		if (do_traditional)	/* both on command line */
			warning(_("`--posix' overrides `--traditional'"));
		else
			do_flags |= DO_TRADITIONAL;
			/*
			 * POSIX compliance also implies
			 * no GNU extensions either.
			 */
	}

	if (do_traditional && do_non_decimal_data) {
		do_flags &= ~DO_NON_DEC_DATA;
		warning(_("`--posix'/`--traditional' overrides `--non-decimal-data'"));
	}

	if (do_lint && os_is_setuid())
		warning(_("running %s setuid root may be a security problem"), myname);

#if MBS_SUPPORT
	if (do_binary) {
		if (do_posix)
			warning(_("`--posix' overrides `--characters-as-bytes'"));
		else
			gawk_mb_cur_max = 1;	/* hands off my data! */
#if defined(LC_ALL)
		setlocale(LC_ALL, "C");
#endif
	}
#endif

	if (do_debug)	/* Need to register the debugger pre-exec hook before any other */
		init_debug();

#ifdef HAVE_MPFR
	/* Set up MPFR defaults, and register pre-exec hook to process arithmetic opcodes */ 
	if (do_mpfr)
		init_mpfr(DEFAULT_PREC, DEFAULT_ROUNDMODE);
#endif

	/* load group set */
	init_groupset();

#ifdef HAVE_MPFR
	if (do_mpfr) {
		mpz_init(Nnull_string->mpg_i);
		Nnull_string->flags = (MALLOC|STRCUR|STRING|MPZN|NUMCUR|NUMBER);
	} else
#endif
	{
		Nnull_string->numbr = 0.0;
		Nnull_string->flags = (MALLOC|STRCUR|STRING|NUMCUR|NUMBER);
	}

	/*
	 * Tell the regex routines how they should work.
	 * Do this before initializing variables, since
	 * they could want to do a regexp compile.
	 */
	resetup();

	/* Set up the special variables */
	init_vars();

	/* Set up the field variables */
	init_fields();

	/* Now process the pre-assignments */
	for (i = 0; i <= numassigns; i++) {
		if (preassigns[i].type == PRE_ASSIGN)
			(void) arg_assign(preassigns[i].val, true);
		else	/* PRE_ASSIGN_FS */
			cmdline_fs(preassigns[i].val);
		efree(preassigns[i].val);
	}

	if (preassigns != NULL)
		efree(preassigns);

	if ((BINMODE & 1) != 0)
		if (os_setbinmode(fileno(stdin), O_BINARY) == -1)
			fatal(_("can't set binary mode on stdin (%s)"), strerror(errno));
	if ((BINMODE & 2) != 0) {
		if (os_setbinmode(fileno(stdout), O_BINARY) == -1)
			fatal(_("can't set binary mode on stdout (%s)"), strerror(errno));
		if (os_setbinmode(fileno(stderr), O_BINARY) == -1)
			fatal(_("can't set binary mode on stderr (%s)"), strerror(errno));
	}

#ifdef GAWKDEBUG
	setbuf(stdout, (char *) NULL);	/* make debugging easier */
#endif
	if (os_isatty(fileno(stdout)))
		output_is_tty = true;

	/* initialize API before loading extension libraries */
	init_ext_api();

	/* load extension libs */
        for (s = srcfiles->next; s != srcfiles; s = s->next) {
                if (s->stype == SRC_EXTLIB)
			load_ext(s->fullpath);
		else if (s->stype != SRC_INC)
			have_srcfile++;
        }

	/* do version check after extensions are loaded to get extension info */
	if (do_version)
		version();

	/* No -f or --source options, use next arg */
	if (! have_srcfile) {
		if (optind > argc - 1 || stopped_early) /* no args left or no program */
			usage(EXIT_FAILURE, stderr);
		(void) add_srcfile(SRC_CMDLINE, argv[optind], srcfiles, NULL, NULL);
		optind++;
	}

	/* Select the interpreter routine */
	init_interpret();

	init_args(optind, argc,
			do_posix ? argv[0] : myname,
			argv);

#if defined(LC_NUMERIC)
	/*
	 * FRAGILE!  CAREFUL!
	 * Pre-initing the variables with arg_assign() can change the
	 * locale.  Force it to C before parsing the program.
	 */
	setlocale(LC_NUMERIC, "C");
#endif
	/* Read in the program */
	if (parse_program(& code_block) != 0)
		exit(EXIT_FAILURE);
	
	if (do_intl)
		exit(EXIT_SUCCESS);

	if (do_lint)
		shadow_funcs();

	if (do_lint && code_block->nexti->opcode == Op_atexit)
		lintwarn(_("no program text at all!"));

	load_symbols();

	if (do_profile)
		init_profiling_signals();

#if defined(LC_NUMERIC)
	/*
	 * See comment above about using locale's decimal point.
	 *
	 * 10/2005:
	 * Bitter experience teaches us that most people the world over
	 * use period as the decimal point, not whatever their locale
	 * uses.  Thus, only use the locale's decimal point if being
	 * posixly anal-retentive.
	 *
	 * 7/2007:
	 * Be a little bit kinder. Allow the --use-lc-numeric option
	 * to also use the local decimal point. This avoids the draconian
	 * strictness of POSIX mode if someone just wants to parse their
	 * data using the local decimal point.
	 */
	if (use_lc_numeric)
		setlocale(LC_NUMERIC, "");
#endif
	
	init_io();
	output_fp = stdout;

	if (do_debug)
		debug_prog(code_block);
	else
		interpret(code_block);

	if (do_pretty_print) {
		dump_prog(code_block);
		dump_funcs();
	}

	if (do_dump_vars)
		dump_vars(varfile);

	if (do_tidy_mem)
		release_all_vars();
	
	/* keep valgrind happier */
	if (extra_stack)
		efree(extra_stack);

	final_exit(exit_val);
	return exit_val;	/* to suppress warnings */
}
Beispiel #8
0
static void ghost_paint( FCMD_t *c, ghost *gh, context *co )
{
        size_t n = 0;
        int  i, j, k;
        char letter = (char)unpackbytes(c->data, MAXCMDDATA, &n, 1);
        int  dnx    = (int) unpack(4);
        int  dny    = (int) unpack(4);
        int  dnz    = (int) unpack(4);
        int  upx    = (int) unpack(4);
        int  upy    = (int) unpack(4);
        int  upz    = (int) unpack(4);
        int  sprnum = (int) unpack(4);

        if( letter!='p' ) { echo("Unknown edit command!"); return; }

        int tool_num = (sprites[sprnum].flags & TOOL_MASK);

        int shx = 0;
        int shy = 0;
        int shz = 0;

        int clipx = MAX(gh->clipboard_x, 1);
        int clipy = MAX(gh->clipboard_y, 1);
        int clipz = MAX(gh->clipboard_z, 1);

        //make so dn is less than up... also adjust clipboard shift
        if( dnx > upx ) { SWAP(upx, dnx, int); shx = clipx-(upx-dnx+1)%clipx; }
        if( dny > upy ) { SWAP(upy, dny, int); shy = clipy-(upy-dny+1)%clipy; }
        if( dnz > upz ) { SWAP(upz, dnz, int); shz = clipz-(upz-dnz+1)%clipz; }

        if( dnx<0 || dny<0 || dnz<0 || upx>=co->x || upy>=co->y || upz>=co->z )
        {
                echo("Paint command out of bounds!");
                return;
        }

        if( tool_num == TOOL_COPY ) //COPY tool texture
        {
                gh->clipboard_x = clipx = upx - dnx + 1;
                gh->clipboard_y = clipy = upy - dny + 1;
                gh->clipboard_z = clipz = upz - dnz + 1;
                gh->clipboard_data = malloc( clipx*clipy*clipz*(sizeof *gh->clipboard_data) ); //FIXME: mem leak
        }

        if( tool_num == TOOL_PSTE && !gh->clipboard_data ) { echo("Clipboard is empty"); return; }

        push_context(co);

        for( k=dnz; k<=upz; k++ ) for( j=dny; j<=upy; j++ ) for( i=dnx; i<=upx; i++ )
        {
                int pos = k*co->y*co->x + j*co->x + i;

                if( !tool_num ) // regular tile painting
                {
                        int dsprnum = sprnum;

                        if( co->projection == ORTHOGRAPHIC )
                                dsprnum = sprite_grid_transform_xy(sprites + sprnum, co, i, j, k, i-dnx, j-dny, upx-dnx+1, upy-dny+1) - sprites;

                        co->dmap[pos].flags &= ~CBF_NULL;
                        co->dmap[pos].flags |= CBF_VIS;
                        co->dmap[pos].spr    = dsprnum;
                        continue;
                }

                switch( tool_num )
                {
                        case TOOL_NUL:
                                co->dmap[pos] = co->map[pos];
                                co->dmap[pos].flags |= CBF_NULL;
                                break;

                        case TOOL_SOL:
                                co->dmap[pos].flags &= ~(CBF_NULL|CBF_PLAT);
                                co->dmap[pos].flags |= CBF_SOLID;
                                break;

                        case TOOL_PLAT:
                                co->dmap[pos].flags &= ~(CBF_NULL|CBF_SOLID);
                                co->dmap[pos].flags |= CBF_PLAT;
                                break;

                        case TOOL_OPN:
                                co->dmap[pos].flags &= ~(CBF_NULL|CBF_SOLID|CBF_PLAT);
                                break;

                        case TOOL_COPY:
                                gh->clipboard_data[ (k-dnz)*clipy*clipx + (j-dny)*clipx + (i-dnx) ] = co->dmap[pos];
                                break;

                        case TOOL_PSTE:
                        {
                                int x = (i-dnx+shx) % clipx;
                                int y = (j-dny+shy) % clipy;
                                int z = (k-dnz+shz) % clipz;
                                co->dmap[pos] = gh->clipboard_data[ x + y*clipx + z*clipy*clipx ];
                                break;
                        }

                        case TOOL_OBJ:
                                // disabled, PLAYER_T removed
                                break;

                        case TOOL_ERAS:
                                co->dmap[pos].flags &= ~(CBF_VIS|CBF_NULL);
                                break;

                        case TOOL_VIS:
                                co->map[pos].flags |= CBF_VIS; // hack for making a loaded-from-file tile visible (format change mess)
                                break;
                }
        }
}
Beispiel #9
0
/* Actions to be taken when a whole line of input has been processed */
ELEMENT *
end_line (ELEMENT *current)
{
  char *end_command = 0;
  enum command_id end_id;

  // 2621
  /* If empty line, start a new paragraph. */
  if (last_contents_child (current)
      && last_contents_child (current)->type == ET_empty_line)
    {
      debug ("END EMPTY LINE");
      if (current->type == ET_paragraph) /* 2625 */
        {
          ELEMENT *e;
          /* Remove empty_line element. */
          e = pop_element_from_contents (current);

          current = end_paragraph (current);

          /* Add empty_line to higher-level element. */
          add_to_element_contents (current, e);
        }
      //else if () // in menu_entry_description
      else if (!in_no_paragraph_contexts (current_context ()))
        {
          current = end_paragraph (current);
        }
    }

  // 2667
  /* The end of the line of a menu. */
  else if (current->type == ET_menu_entry_name
           || current->type == ET_menu_entry_node)
    {
      ELEMENT *end_comment;
      int empty_menu_entry_node = 0;

      if (current->type == ET_menu_entry_node)
        {
          ELEMENT *last = last_contents_child (current);

          if (current->contents.number > 0
              && (last->cmd == CM_c || last->cmd == CM_comment))
            {
              end_comment = pop_element_from_contents (current);
            }

          /* If contents empty or is all whitespace. */
          if (current->contents.number == 0
              || (current->contents.number == 1
                  && last->text.end > 0
                  && !last->text.text[strspn (last->text.text, 
                                              whitespace_chars)]))
            {
              empty_menu_entry_node = 1;
              if (end_comment)
                add_to_element_contents (current, end_comment);
            }
        }

      // 2689
      /* Abort the menu entry if there is no destination node given. */
      if (empty_menu_entry_node || current->type == ET_menu_entry_name)
        {
        }
      else // 2768
        {
          debug ("MENU ENTRY END LINE");
          current = current->parent;
          current = enter_menu_entry_node (current);
          if (end_comment)
            add_to_element_contents (current, end_comment);
        }
    }

  /* Is it a def line 2778 */
  else if (current->parent && current->parent->type == ET_def_line)
    {
      enum element_type def_command;

      if (pop_context () != ct_def)
        {
          abort ();
        }

#if 0
      /* current->parent is a ET_def_line, and current->parent->parent
         the def command. */
      def_command = current->parent->parent->cmd;
      // strip a trailing x
      parse_def (def_command, current->contents);
#endif

      current = current->parent->parent;
      current = begin_preformatted (current);

    }

  // 2872
  /* End of a line starting a block. */
  else if (current->type == ET_block_line_arg)
    {
      enum context c;
      // pop and check context_stack
      c = pop_context ();
      if (c != ct_line)
        {
          // bug
          abort ();
        }

      // 2881
      if (current->parent->cmd == CM_multitable)
        {
          /* Parse prototype row */
          // But not @columnfractions, I assume?
        }

      if (current->parent->cmd == CM_float) // 2943
        {
        }
      current = current->parent; //2965

      /* Don't consider empty argument of block @-command as argument,
         reparent them as contents. */
      if (current->args.list[0]->contents.number > 0
          && current->args.list[0]->contents.list[0]->type
             == ET_empty_line_after_command)
        {
          ELEMENT *e;
          e = current->args.list[0]->contents.list[0];
          insert_into_contents (current, e, 0);
          // TODO: Free lists?
          current->args.number = 0;
        }

      if (command_flags(current) & CF_blockitem) // 2981
        {
          if (current->cmd == CM_enumerate)
            {
            }
          else if (item_line_command (current->cmd)) // 3002
            {
              // check command_as_argument registered in 'extra', and
              // that it accepts arguments in braces
            }

          if (current->cmd == CM_itemize) // 3019
            {
              // check that command_as_argument is alone on the line
            }

          // check if command_as_argument isn't an accent command

          /* 3052 - if no command_as_argument given, default to @bullet for
             @itemize, and @asis for @table. */

          {
            ELEMENT *bi = new_element (ET_before_item);
            add_to_element_contents (current, bi);
            current = bi;
          }
        } /* CF_blockitem */

      // 3077
      if (command_flags(current) & CF_menu)
        {
          /* Start reading a menu.  Processing will continue in
             handle_menu in menus.c. */

          ELEMENT *menu_comment = new_element (ET_menu_comment);
          add_to_element_contents (current, menu_comment);
          current = menu_comment;
          debug ("MENU COMMENT OPEN");
          push_context (ct_preformatted);
        }
      current = begin_preformatted (current);
    }

  /* after an "@end verbatim" 3090 */
  else if (current->contents.number
           && last_contents_child(current)->type == ET_empty_line_after_command
    /* The Perl version gets the command with the 'command' key in 'extra'. */
           && contents_child_by_index(current, -2)
           && contents_child_by_index(current, -2)->cmd == CM_verbatim)
    {
      // I don't know what this means.  raw command is @html etc.?
      /*
     if we are after a @end verbatim, we must restart a preformatted if needed,
     since there is no @end command explicitly associated to raw commands
     it won't be done elsewhere.
      */

      current = begin_preformatted (current);
    }


  /* if it's a misc line arg 3100 */
  else if (current->type == ET_misc_line_arg)
    {
      int cmd_id, arg_type;
      enum context c;

      isolate_last_space (current, 0);

      current = current->parent;
      cmd_id = current->cmd;
      if (!cmd_id)
        abort ();

      arg_type = command_data(cmd_id).data;
       
      /* Check 'line' is top of the context stack */
      c = pop_context ();
      if (c != ct_line)
        {
          /* error */
          abort ();
        }

      // 3114
      debug ("MISC END %s", command_data(cmd_id).cmdname);

      if (arg_type > 0)
        {
          /* arg_type is number of args */
          // parse_line_command_args
          // save in 'misc_args' extra key
        }
      else if (arg_type == MISC_text) /* 3118 */
        {
          char *text;
         
          /* argument string has to be parsed as Texinfo. This calls convert in 
             Common/Text.pm on the first element of current->args. */
          /* however, this makes it impossible to decouple the parser and 
             output stages...  Any use of Texinfo::Convert is problematic. */

          if (current->args.number > 0)
            text = text_convert (current->args.list[0]);
          else
            text = "foo";

          if (!strcmp (text, ""))
            {
              /* 3123 warning - missing argument */
              abort ();
            }
          else
            {
              if (current->cmd == CM_end) /* 3128 */
                {
                  char *line = text;

                  /* Set end_command - used below. */
                  end_command = read_command_name (&line);

                  /* Check argument meets format of a Texinfo command
                     (alphanumberic character followed by alphanumeric 
                     characters or hyphens. */

                  /* Check if argument is a block Texinfo command. */
                  end_id = lookup_command (end_command);
                  if (end_id == -1 || !(command_data(end_id).flags & CF_block))
                    {
                      /* error - unknown @end */
                    }
                  else
                    {
                      debug ("END BLOCK %s", end_command);
                      /* 3140 Handle conditional block commands (e.g.  
                         @ifinfo) */

                      /* If we are in a non-ignored conditional, there is not
                         an element for the block in the tree; it is recorded 
                         in the conditional stack.  Pop it and check it is the 
                         same as the one given in the @end line. */

                      if (command_data(end_id).data == BLOCK_conditional)
                        {
                          if (conditional_number > 0)
                            {
                              enum command_id popped;
                              popped = pop_conditional_stack ();
                              if (popped != end_id)
                                abort ();
                            }
                        }
                    }
                }
              else if (current->cmd == CM_include) /* 3166 */
                {
                  debug ("Include %s", text);
                  input_push_file (text);
                }
              else if (current->cmd == CM_documentencoding)
                /* 3190 */
                {
                }
              else if (current->cmd == CM_documentlanguage)
                /* 3223 */
                {
                }
            }
        }
      else if (current->cmd == CM_node) /* 3235 */
        {
          int i;
          ELEMENT *arg;
          ELEMENT *first_arg;
          /* Construct 'nodes_manuals' array.  This would be an 'extra' 
             reference to an array that doesn't exist anywhere else. */

          /* This sets the 'node_content' and 'normalized' keys on each element 
             in 'nodes_manuals'. */
          //parse_node_manual ();
          
          /* In Perl a copy of the argument list is taken and the empty space 
             arguments are removed with trim_spaces_comment_from_content. */
          first_arg = current->args.list[0];
          arg = new_element (ET_NONE);
          arg->parent_type = route_not_in_tree;
          for (i = 0; i < first_arg->contents.number; i++)
            {
              if (first_arg->contents.list[i]->type
                    != ET_empty_spaces_after_command
                  && first_arg->contents.list[i]->type != ET_spaces_at_end)
                {
                  /* FIXME: Is this safe to serialize? */
                  /* For example, if there are extra keys in the elements under 
                     each argument?  They may not be set in a copy.
                     Hopefully there aren't many extra keys set on commands in 
                     node names. */
                  add_to_element_contents (arg, first_arg->contents.list[i]);
                }
            }
          add_extra_key_contents (current, "node_content", arg);

          /* Also set 'normalized' here.  The normalized labels are actually 
             the keys of "labels_information($parser)". */

          /*Check that the node name doesn't have a filename element for 
            referring to an external manual (_check_internal_node), and that it 
            is not empty (_check_empty_node).  */
          //check_node_label ();

          /* This sets 'node_content' and 'normalized' on the node, among
             other things (which were already set in parse_node_manual). */
          register_label (current, arg);

          current_node = current;
        }
      else if (current->cmd == CM_listoffloats) /* 3248 */
        {
        }
      else
        {
          /* All the other "line" commands" */
        }

      current = current->parent; /* 3285 */
      if (end_command) /* Set above */
        {
          /* more processing of @end */
          ELEMENT *end_elt;

          debug ("END COMMAND %s", end_command);

          /* Reparent the "@end" element to be a child of the block element. */
          end_elt = pop_element_from_contents (current);

          /* 3289 If not a conditional */
          if (command_data(end_id).data != BLOCK_conditional)
            {
              ELEMENT *closed_command;
              /* This closes tree elements (e.g. paragraphs) until we reach
                 end_command.  It can print an error if another block command
                 is found first. */
              current = close_commands (current, end_id,
                              &closed_command, 0); /* 3292 */
              if (!closed_command)
                abort (); // 3335

              close_command_cleanup (closed_command);
              // 3301 INLINE_INSERTCOPYING
              add_to_element_contents (closed_command, end_elt); // 3321
              // 3324 ET_menu_comment
              if (close_preformatted_command (end_id))
                current = begin_preformatted (current);
            }
        } /* 3340 */
      else
        {
          if (close_preformatted_command (cmd_id))
            current = begin_preformatted (current);
        }

      /* 3346 included file */

      /* 3350 */
      if (cmd_id == CM_setfilename && (current_node || current_section))
        {
          /* warning */
          abort ();
        }
      /* 3355 columnfractions */
      else if (cmd_id == CM_columnfractions)
        {
          ELEMENT *before_item;
          // check if in multitable

          // pop and check context stack

          current = current->parent;
          before_item = new_element (ET_before_item);
          add_to_element_contents (current, before_item);
          current = before_item;
        }
      else if (command_data(cmd_id).flags & CF_root) /* 3380 */
        {
          current = last_contents_child (current);
          
          /* 3383 Destroy all contents (why do we do this?) */
          while (last_contents_child (current))
            destroy_element (pop_element_from_contents (current));

          /* Set 'associated_section' extra key for a node. */
          if (cmd_id != CM_node && cmd_id != CM_part)
            {
              if (current_node)
                {
                  if (!lookup_extra_key (current_node, "associated_section"))
                    {
                      add_extra_key_element
                        (current_node, "associated_section", current);
                      add_extra_key_element
                        (current, "associated_node", current_node);
                    }
                }

              // "current parts" - 3394

              current_section = current;
            }
        } /* 3416 */
    }


  // something to do with an empty line /* 3419 */

  //if () /* 'line' or 'def' at top of "context stack" */
    {
      /* Recurse. */
    }
  return current;
} /* end_line 3487 */