예제 #1
0
/*
 * Close out block partial/full explicit.
 */
static void
blk_exp_close(MACRO_PROT_ARGS)
{
	struct mdoc_node *body;		/* Our own body. */
	struct mdoc_node *endbody;	/* Our own end marker. */
	struct mdoc_node *itblk;	/* An It block starting later. */
	struct mdoc_node *later;	/* A sub-block starting later. */
	struct mdoc_node *n;		/* Search back to our block. */

	int		 j, lastarg, maxargs, nl;
	enum margserr	 ac;
	enum mdoct	 atok, ntok;
	char		*p;

	nl = MDOC_NEWLINE & mdoc->flags;

	switch (tok) {
	case MDOC_Ec:
		maxargs = 1;
		break;
	case MDOC_Ek:
		mdoc->flags &= ~MDOC_KEEP;
		/* FALLTHROUGH */
	default:
		maxargs = 0;
		break;
	}

	/*
	 * Search backwards for beginnings of blocks,
	 * both of our own and of pending sub-blocks.
	 */

	atok = rew_alt(tok);
	body = endbody = itblk = later = NULL;
	for (n = mdoc->last; n; n = n->parent) {
		if (n->flags & MDOC_ENDED) {
			if ( ! (n->flags & MDOC_VALID))
				n->flags |= MDOC_BROKEN;
			continue;
		}

		/* Remember the start of our own body. */

		if (n->type == MDOC_BODY && atok == n->tok) {
			if (n->end == ENDBODY_NOT)
				body = n;
			continue;
		}

		if (n->type != MDOC_BLOCK || n->tok == MDOC_Nm)
			continue;

		if (n->tok == MDOC_It) {
			itblk = n;
			continue;
		}

		if (atok == n->tok) {
			assert(body);

			/*
			 * Found the start of our own block.
			 * When there is no pending sub block,
			 * just proceed to closing out.
			 */

			if (later == NULL ||
			    (tok == MDOC_El && itblk == NULL))
				break;

			/*
			 * When there is a pending sub block, postpone
			 * closing out the current block until the
			 * rew_pending() closing out the sub-block.
			 * Mark the place where the formatting - but not
			 * the scope - of the current block ends.
			 */

			mandoc_vmsg(MANDOCERR_BLK_NEST, mdoc->parse,
			    line, ppos, "%s breaks %s",
			    mdoc_macronames[atok],
			    mdoc_macronames[later->tok]);

			endbody = mdoc_endbody_alloc(mdoc, line, ppos,
			    atok, body, ENDBODY_SPACE);

			if (tok == MDOC_El)
				itblk->flags |= MDOC_ENDED | MDOC_BROKEN;

			/*
			 * If a block closing macro taking arguments
			 * breaks another block, put the arguments
			 * into the end marker.
			 */

			if (maxargs)
				mdoc->next = MDOC_NEXT_CHILD;
			break;
		}

		/* Explicit blocks close out description lines. */

		if (n->tok == MDOC_Nd) {
			rew_last(mdoc, n);
			continue;
		}

		/* Breaking an open sub block. */

		n->flags |= MDOC_BROKEN;
		if (later == NULL)
			later = n;
	}

	if (body == NULL) {
		mandoc_msg(MANDOCERR_BLK_NOTOPEN, mdoc->parse,
		    line, ppos, mdoc_macronames[tok]);
		if (maxargs && endbody == NULL) {
			/*
			 * Stray .Ec without previous .Eo:
			 * Break the output line, keep the arguments.
			 */
			mdoc_elem_alloc(mdoc, line, ppos, MDOC_br, NULL);
			rew_elem(mdoc, MDOC_br);
		}
	} else if (endbody == NULL) {
		rew_last(mdoc, body);
		if (maxargs)
			mdoc_tail_alloc(mdoc, line, ppos, atok);
	}

	if ( ! (mdoc_macros[tok].flags & MDOC_PARSED)) {
		if (buf[*pos] != '\0')
			mandoc_vmsg(MANDOCERR_ARG_SKIP,
			    mdoc->parse, line, ppos,
			    "%s %s", mdoc_macronames[tok],
			    buf + *pos);
		if (endbody == NULL && n != NULL)
			rew_pending(mdoc, n);
		return;
	}

	if (endbody != NULL)
		n = endbody;
	for (j = 0; ; j++) {
		lastarg = *pos;

		if (j == maxargs && n != NULL) {
			rew_pending(mdoc, n);
			n = NULL;
		}

		ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
		if (ac == ARGS_PUNCT || ac == ARGS_EOLN)
			break;

		ntok = ac == ARGS_QWORD ? MDOC_MAX :
		    lookup(mdoc, tok, line, lastarg, p);

		if (ntok == MDOC_MAX) {
			dword(mdoc, line, lastarg, p, DELIM_MAX,
			    MDOC_JOIN & mdoc_macros[tok].flags);
			continue;
		}

		if (n != NULL) {
			rew_pending(mdoc, n);
			n = NULL;
		}
		mdoc->flags &= ~MDOC_NEWLINE;
		mdoc_macro(mdoc, ntok, line, lastarg, pos, buf);
		break;
	}

	if (n != NULL)
		rew_pending(mdoc, n);
	if (nl)
		append_delims(mdoc, line, pos, buf);
}
예제 #2
0
static void
in_line(MACRO_PROT_ARGS)
{
	int		 la, scope, cnt, firstarg, mayopen, nc, nl;
	enum mdoct	 ntok;
	enum margserr	 ac;
	enum mdelim	 d;
	struct mdoc_arg	*arg;
	char		*p;

	nl = MDOC_NEWLINE & mdoc->flags;

	/*
	 * Whether we allow ignored elements (those without content,
	 * usually because of reserved words) to squeak by.
	 */

	switch (tok) {
	case MDOC_An:
		/* FALLTHROUGH */
	case MDOC_Ar:
		/* FALLTHROUGH */
	case MDOC_Fl:
		/* FALLTHROUGH */
	case MDOC_Mt:
		/* FALLTHROUGH */
	case MDOC_Nm:
		/* FALLTHROUGH */
	case MDOC_Pa:
		nc = 1;
		break;
	default:
		nc = 0;
		break;
	}

	mdoc_argv(mdoc, line, tok, &arg, pos, buf);

	d = DELIM_NONE;
	firstarg = 1;
	mayopen = 1;
	for (cnt = scope = 0;; ) {
		la = *pos;
		ac = mdoc_args(mdoc, line, pos, buf, tok, &p);

		/*
		 * At the end of a macro line,
		 * opening delimiters do not suppress spacing.
		 */

		if (ac == ARGS_EOLN) {
			if (d == DELIM_OPEN)
				mdoc->last->flags &= ~MDOC_DELIMO;
			break;
		}

		/*
		 * The rest of the macro line is only punctuation,
		 * to be handled by append_delims().
		 * If there were no other arguments,
		 * do not allow the first one to suppress spacing,
		 * even if it turns out to be a closing one.
		 */

		if (ac == ARGS_PUNCT) {
			if (cnt == 0 && (nc == 0 || tok == MDOC_An))
				mdoc->flags |= MDOC_NODELIMC;
			break;
		}

		ntok = (ac == ARGS_QWORD || (tok == MDOC_Fn && !cnt)) ?
		    MDOC_MAX : lookup(mdoc, tok, line, la, p);

		/*
		 * In this case, we've located a submacro and must
		 * execute it.  Close out scope, if open.  If no
		 * elements have been generated, either create one (nc)
		 * or raise a warning.
		 */

		if (ntok != MDOC_MAX) {
			if (scope)
				rew_elem(mdoc, tok);
			if (nc && ! cnt) {
				mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
				rew_last(mdoc, mdoc->last);
			} else if ( ! nc && ! cnt) {
				mdoc_argv_free(arg);
				mandoc_msg(MANDOCERR_MACRO_EMPTY,
				    mdoc->parse, line, ppos,
				    mdoc_macronames[tok]);
			}
			mdoc_macro(mdoc, ntok, line, la, pos, buf);
			if (nl)
				append_delims(mdoc, line, pos, buf);
			return;
		}

		/*
		 * Non-quote-enclosed punctuation.  Set up our scope, if
		 * a word; rewind the scope, if a delimiter; then append
		 * the word.
		 */

		d = ac == ARGS_QWORD ? DELIM_NONE : mdoc_isdelim(p);

		if (DELIM_NONE != d) {
			/*
			 * If we encounter closing punctuation, no word
			 * has been emitted, no scope is open, and we're
			 * allowed to have an empty element, then start
			 * a new scope.
			 */
			if ((d == DELIM_CLOSE ||
			     (d == DELIM_MIDDLE && tok == MDOC_Fl)) &&
			    !cnt && !scope && nc && mayopen) {
				mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
				scope = 1;
				cnt++;
				if (tok == MDOC_Nm)
					mayopen = 0;
			}
			/*
			 * Close out our scope, if one is open, before
			 * any punctuation.
			 */
			if (scope)
				rew_elem(mdoc, tok);
			scope = 0;
			if (tok == MDOC_Fn)
				mayopen = 0;
		} else if (mayopen && !scope) {
			mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
			scope = 1;
			cnt++;
		}

		dword(mdoc, line, la, p, d,
		    MDOC_JOIN & mdoc_macros[tok].flags);

		/*
		 * If the first argument is a closing delimiter,
		 * do not suppress spacing before it.
		 */

		if (firstarg && d == DELIM_CLOSE && !nc)
			mdoc->last->flags &= ~MDOC_DELIMC;
		firstarg = 0;

		/*
		 * `Fl' macros have their scope re-opened with each new
		 * word so that the `-' can be added to each one without
		 * having to parse out spaces.
		 */
		if (scope && tok == MDOC_Fl) {
			rew_elem(mdoc, tok);
			scope = 0;
		}
	}

	if (scope)
		rew_elem(mdoc, tok);

	/*
	 * If no elements have been collected and we're allowed to have
	 * empties (nc), open a scope and close it out.  Otherwise,
	 * raise a warning.
	 */

	if ( ! cnt) {
		if (nc) {
			mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
			rew_last(mdoc, mdoc->last);
		} else {
			mdoc_argv_free(arg);
			mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse,
			    line, ppos, mdoc_macronames[tok]);
		}
	}
	if (nl)
		append_delims(mdoc, line, pos, buf);
}
예제 #3
0
static void
blk_part_imp(MACRO_PROT_ARGS)
{
	int		  la, nl;
	enum margserr	  ac;
	char		 *p;
	struct mdoc_node *blk; /* saved block context */
	struct mdoc_node *body; /* saved body context */
	struct mdoc_node *n;

	nl = MDOC_NEWLINE & mdoc->flags;

	/*
	 * A macro that spans to the end of the line.  This is generally
	 * (but not necessarily) called as the first macro.  The block
	 * has a head as the immediate child, which is always empty,
	 * followed by zero or more opening punctuation nodes, then the
	 * body (which may be empty, depending on the macro), then zero
	 * or more closing punctuation nodes.
	 */

	blk = mdoc_block_alloc(mdoc, line, ppos, tok, NULL);
	rew_last(mdoc, mdoc_head_alloc(mdoc, line, ppos, tok));

	/*
	 * Open the body scope "on-demand", that is, after we've
	 * processed all our the leading delimiters (open parenthesis,
	 * etc.).
	 */

	for (body = NULL; ; ) {
		la = *pos;
		ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
		if (ac == ARGS_EOLN || ac == ARGS_PUNCT)
			break;

		if (body == NULL && ac != ARGS_QWORD &&
		    mdoc_isdelim(p) == DELIM_OPEN) {
			dword(mdoc, line, la, p, DELIM_OPEN, 0);
			continue;
		}

		if (body == NULL)
			body = mdoc_body_alloc(mdoc, line, ppos, tok);

		if (macro_or_word(mdoc, tok, line, la, pos, buf, 1))
			break;
	}
	if (body == NULL)
		body = mdoc_body_alloc(mdoc, line, ppos, tok);

	/*
	 * If there is an open sub-block requiring explicit close-out,
	 * postpone closing out the current block until the
	 * rew_pending() call closing out the sub-block.
	 */

	for (n = mdoc->last; n && n != body && n != blk->parent;
	     n = n->parent) {
		if (n->flags & MDOC_ENDED) {
			if ( ! (n->flags & MDOC_VALID))
				n->flags |= MDOC_BROKEN;
			continue;
		}
		if (n->type == MDOC_BLOCK &&
		    mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
			n->flags |= MDOC_BROKEN;
			if ( ! (body->flags & MDOC_ENDED)) {
				mandoc_vmsg(MANDOCERR_BLK_NEST,
				    mdoc->parse, line, ppos,
				    "%s breaks %s", mdoc_macronames[tok],
				    mdoc_macronames[n->tok]);
				mdoc_endbody_alloc(mdoc, line, ppos,
				    tok, body, ENDBODY_NOSPACE);
			}
		}
	}
	assert(n == body);
	if (body->flags & MDOC_ENDED)
		return;

	rew_last(mdoc, body);
	if (nl)
		append_delims(mdoc, line, pos, buf);
	rew_pending(mdoc, blk);

	/* Move trailing .Ns out of scope. */

	for (n = body->child; n && n->next; n = n->next)
		/* Do nothing. */ ;
	if (n && n->tok == MDOC_Ns)
		mdoc_node_relink(mdoc, n);
}
예제 #4
0
static void
in_line_argn(MACRO_PROT_ARGS)
{
	struct mdoc_arg	*arg;
	char		*p;
	enum margserr	 ac;
	enum mdoct	 ntok;
	int		 state; /* arg#; -1: not yet open; -2: closed */
	int		 la, maxargs, nl;

	nl = mdoc->flags & MDOC_NEWLINE;

	/*
	 * A line macro that has a fixed number of arguments (maxargs).
	 * Only open the scope once the first non-leading-punctuation is
	 * found (unless MDOC_IGNDELIM is noted, like in `Pf'), then
	 * keep it open until the maximum number of arguments are
	 * exhausted.
	 */

	switch (tok) {
	case MDOC_Ap:
		/* FALLTHROUGH */
	case MDOC_Ns:
		/* FALLTHROUGH */
	case MDOC_Ux:
		maxargs = 0;
		break;
	case MDOC_Bx:
		/* FALLTHROUGH */
	case MDOC_Es:
		/* FALLTHROUGH */
	case MDOC_Xr:
		maxargs = 2;
		break;
	default:
		maxargs = 1;
		break;
	}

	mdoc_argv(mdoc, line, tok, &arg, pos, buf);

	state = -1;
	p = NULL;
	for (;;) {
		la = *pos;
		ac = mdoc_args(mdoc, line, pos, buf, tok, &p);

		if (ac == ARGS_WORD && state == -1 &&
		    ! (mdoc_macros[tok].flags & MDOC_IGNDELIM) &&
		    mdoc_isdelim(p) == DELIM_OPEN) {
			dword(mdoc, line, la, p, DELIM_OPEN, 0);
			continue;
		}

		if (state == -1 && tok != MDOC_In &&
		    tok != MDOC_St && tok != MDOC_Xr) {
			mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
			state = 0;
		}

		if (ac == ARGS_PUNCT || ac == ARGS_EOLN) {
			if (abs(state) < 2 && tok == MDOC_Pf)
				mandoc_vmsg(MANDOCERR_PF_SKIP,
				    mdoc->parse, line, ppos, "Pf %s",
				    p == NULL ? "at eol" : p);
			break;
		}

		if (state == maxargs) {
			rew_elem(mdoc, tok);
			state = -2;
		}

		ntok = (ac == ARGS_QWORD || (tok == MDOC_Pf && state == 0)) ?
		    MDOC_MAX : lookup(mdoc, tok, line, la, p);

		if (ntok != MDOC_MAX) {
			if (state >= 0) {
				rew_elem(mdoc, tok);
				state = -2;
			}
			mdoc_macro(mdoc, ntok, line, la, pos, buf);
			break;
		}

		if (ac == ARGS_QWORD ||
		    mdoc_macros[tok].flags & MDOC_IGNDELIM ||
		    mdoc_isdelim(p) == DELIM_NONE) {
			if (state == -1) {
				mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
				state = 1;
			} else if (state >= 0)
				state++;
		} else if (state >= 0) {
			rew_elem(mdoc, tok);
			state = -2;
		}

		dword(mdoc, line, la, p, DELIM_MAX,
		    MDOC_JOIN & mdoc_macros[tok].flags);
	}

	if (state == -1) {
		mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse,
		    line, ppos, mdoc_macronames[tok]);
		return;
	}

	if (state == 0 && tok == MDOC_Pf)
		append_delims(mdoc, line, pos, buf);
	if (state >= 0)
		rew_elem(mdoc, tok);
	if (nl)
		append_delims(mdoc, line, pos, buf);
}
예제 #5
0
파일: ProcInfo.cpp 프로젝트: Vort/VortOS
	CProcInfo()
	{
		KeWaitForSymbol(Sm_InitStage2);

		m_TickCount = 0;
		m_KernelTime = 0;
		m_VisualProgressIndex = 6;
		m_SurfaceActivated = true;

		m_X = 20;
		m_Y = 20;

		m_Width = 236;
		m_Height = m_Margin * 4 + (m_VisibleProcCount + 4) * m_FontH;

		char Digit = '0';
		KeRequestCall(ClFont_GetTextWidth, PB(&Digit), 1, PB(&m_DigitW), 4);

		m_SurfaceID = CreateSurface(m_X, m_Y, m_Width, m_Height);
		DrawActiveBorder();
		DrawRect(m_SurfaceID, 1, 1, m_Width - 2, m_Margin * 3 + m_FontH * 4 - 1, m_BGColor);
		OutText(m_SurfaceID, m_Margin, m_Margin + m_FontH * 0, 0xFFA020A0, "Page Usage:");
		OutText(m_SurfaceID, m_Margin, m_Margin + m_FontH * 1, 0xFFA020A0, "Heap Usage:");
		OutText(m_SurfaceID, m_Margin, m_Margin + m_FontH * 2, 0xFFA020A0, "Kernel Time:");

		OutText(m_SurfaceID, m_Margin+4, m_Margin*2 + m_FontH * 3, 0xFF2020A0, "ID");
		OutText(m_SurfaceID, m_Margin+18, m_Margin*2 + m_FontH * 3, 0xFF20A020, "Mem");
		OutText(m_SurfaceID, m_Margin+52, m_Margin*2 + m_FontH * 3, 0xFFA0A020, "Nf");
		OutText(m_SurfaceID, m_Margin+74, m_Margin*2 + m_FontH * 3, 0xFF20A0A0, "Usr");
		OutText(m_SurfaceID, m_Margin+104, m_Margin*2 + m_FontH * 3, 0xFF20A0A0, "Krn");
		OutText(m_SurfaceID, m_Margin+128, m_Margin*2 + m_FontH * 3, 0xFFA02020, "Name");

		KeEnableNotification(NfKe_TimerTick);
		KeEnableNotification(Nf_SurfaceActivated);
		KeEnableNotification(NfKe_TerminateProcess);

		CNotification<4> N;
		for (;;)
		{
			KeWaitFor(1);
			N.Recv();

			if (N.GetID() == Nf_SurfaceActivated)
			{
				dword activatedSurfaceID = N.GetDword(0);

				if (activatedSurfaceID == m_SurfaceID)
				{
					if (!m_SurfaceActivated)
					{
						m_SurfaceActivated = true;
						DrawActiveBorder();
					}
				}
				else
				{
					if (m_SurfaceActivated)
					{
						m_SurfaceActivated = false;
						DrawActiveBorder();
					}
				}
			}
			else if (N.GetID() == NfKe_TimerTick)
			{
				if (m_TickCount % 144 == 0)
				{
					m_ProcList.Clear();

					CProcData PD;
					char Name[128];
					dword PrevPID = 0;
					for (;;)
					{
						dword PID = KeGetNextProcessInfo(PrevPID,
							PD.m_UsedPageCount, PD.m_NotificationCount,
							PD.m_UserPerfData, PD.m_KernelPerfData, Name);
						if (PID == 0xFFFFFFFF)
							break;
						PD.m_PID = PID;
						PD.m_Name = CStringA(Name);
						m_ProcList.PushBack(PD);
						PrevPID = PID;
					}

					qword UserTotalG = 0;
					qword KernelTotalG = 0;
					for (dword i = 0; i < m_ProcList.Size(); i++)
					{
						qword UserTotalL = 0;
						qword KernelTotalL = 0;
						for (dword j = 0; j < 128; j++)
						{
							UserTotalL += m_ProcList[i].m_UserPerfData[j];
							KernelTotalL += m_ProcList[i].m_KernelPerfData[j];
						}
						m_ProcList[i].m_UserTotal = UserTotalL;
						m_ProcList[i].m_KernelTotal = KernelTotalL;

						UserTotalG += UserTotalL;
						KernelTotalG += KernelTotalL;
					}

					for (dword i = 0; i < m_ProcList.Size(); i++)
					{
						m_ProcList[i].m_UserPercent = (m_ProcList[i].m_UserTotal << 16) / UserTotalG;
						m_ProcList[i].m_KernelPercent = (m_ProcList[i].m_KernelTotal << 16) / KernelTotalG;
					}

					m_KernelTime = (KernelTotalG << 16) / (KernelTotalG + UserTotalG);


					DrawRect(m_SurfaceID, 1, m_Margin * 3 + m_FontH * 4,
						m_Width - 2, m_Height - (m_Margin * 3 + m_FontH * 4) - 1, m_BGColor);

					dword VisibleProcCount = m_ProcList.Size();
					if (VisibleProcCount > m_VisibleProcCount)
						VisibleProcCount = m_VisibleProcCount;

					for (dword i = 0; i < VisibleProcCount; i++)
					{
						char CharBuf[5] = {0};
						dword XOffset = m_Margin + 14;
						dword YOffset = m_Margin * 3 + m_FontH * (4 + i);

						OutDecimal(XOffset, YOffset, m_ProcList[i].m_PID, 0xFF2020A0);
						XOffset += 24;

						OutDecimal(XOffset, YOffset, m_ProcList[i].m_UsedPageCount, 0xFF20A020);
						XOffset += 22;

						OutDecimal(XOffset, YOffset, m_ProcList[i].m_NotificationCount, 0xFFA0A020);
						XOffset += 0;

						OutPercent(XOffset, YOffset, m_ProcList[i].m_UserPercent, 0xFF20A0A0);
						XOffset += 32;

						OutPercent(XOffset, YOffset, m_ProcList[i].m_KernelPercent, 0xFF20A0A0);
						XOffset += 36;

						OutText(m_SurfaceID, XOffset, YOffset, 0xFFA02020, m_ProcList[i].m_Name._ptr());
					}
				}

				if (m_TickCount % 24 == 0)
				{
					dword HeapUsed;
					dword HeapTotal;
					dword PageUsed;
					dword PageTotal;
					KeGetMemInfo(HeapUsed, HeapTotal, PageUsed, PageTotal);

					dword PageUsage = dword((qword(PageUsed) * 0x10000) / PageTotal);
					dword HeapUsage = dword((qword(HeapUsed) * 0x10000) / HeapTotal);

					dword KernelTime = 0;
					dword HeapColor = 0xFF20A0A0;

					if (HeapUsage > 0x9999)
						HeapColor = 0xFFF8BF16;
					if (HeapUsage > 0xB333)
						HeapColor = 0xFFFA5914;

					DrawRect(m_SurfaceID, m_Margin + 74, m_Margin, 48, m_FontH * 3, m_BGColor);
					OutPercent(m_Margin + 74, m_Margin + m_FontH * 0, PageUsage, 0xFF20A0A0, true);
					OutPercent(m_Margin + 74, m_Margin + m_FontH * 1, HeapUsage, HeapColor, true);
					OutPercent(m_Margin + 74, m_Margin + m_FontH * 2, m_KernelTime, 0xFF20A0A0, true);

					dword PrevVP = m_VisualProgressIndex;

					m_VisualProgressIndex++;
					if (m_VisualProgressIndex >= 6)
						m_VisualProgressIndex = 0;

					dword C1 = 0xFFB0B8FF;
					dword C2 = 0xFFD0D4FF;
					if (m_VisualProgressIndex == 0)
					{
						C1 = 0xFFFFA393;
						C2 = 0xFFFFCCC4;
					}
					DrawRect(m_SurfaceID, 140 + PrevVP * 12,
						m_FontH + m_Margin + 4, 8, 8, m_BGColor);
					DrawRect(m_SurfaceID, 140 + m_VisualProgressIndex * 12,
						m_FontH + m_Margin + 4, 8, 8, C1);
					DrawRect(m_SurfaceID, 140 + m_VisualProgressIndex * 12 + 1,
						m_FontH + m_Margin + 4 + 1, 6, 6, C2);
				}

				if (m_TickCount == 0)
				{
					ShowSurface(m_SurfaceID);
				}

				m_TickCount++;
			}
			else if (N.GetID() == NfKe_TerminateProcess)
			{
				return;
			}
		}
	}
예제 #6
0
파일: branfuck.c 프로젝트: nyuichi/xjit
void
codegen(xJIT *xjit)
{
  xOperand *pputc, *pgetc, *stack;
  char c;
  const void *code;
  int lstack[100], *lcur = lstack, lno = 0;

  pputc = rbx;
  pgetc = rbp;
  stack = r12;

  push(rbx);
  push(rbp);
  push(r12);
  mov(pputc, rdi);                /* putchar */
  mov(pgetc, rsi);                /* getchar */
  mov(stack, rdx);                /* stack */

  while (~(c = getchar())) {
    switch (c) {
    case '+':
    case '-':
      {
        int cnt;

        cnt = countc(c);
        if (cnt == 1) {
          c == '+'
            ? inc(dword(stack))
            : dec(dword(stack));
        }
        else {
          addi(dword(stack), c == '+' ? cnt : -cnt);
        }
      }
      break;
    case '>':
    case '<':
      {
        int cnt;

        cnt = countc(c);
        addi(stack, 4 * (c == '>' ? cnt : -cnt));
      }
      break;
    case '.':
      {
        mov(rdi, dword(stack));
        call(pputc,XJIT_CALL_OPERAND);
      }
      break;
    case ',':
      {
        call(pgetc,XJIT_CALL_OPERAND);
        mov(dword(stack), eax);
      }
      break;
    case '[':
      {
        L(numl(lno, 'B'));      /* backward label */
        mov(eax, dword(stack));
        test(eax, eax);
        jz(numl(lno, 'F'), XJIT_LABEL_NEAR);
        *lcur++ = lno++;
      }
      break;
    case ']':
      {
        int no;

        no = *--lcur;
        jmp(numl(no, 'B'), XJIT_JMP_LABEL);
        L(numl(no, 'F'));       /* forward label */
      }
      break;
    default:
      break;
    }
  }

  pop(r12);
  pop(rbp);
  pop(rbx);
  ret();
}
void rbBytecode::ParseFunc( dword token )
{
	rbToken* t = new rbToken(NULL,token);
	wxString& name = t->Name;
	wxString& output = t->Output;
	wxString code;
	dword flags = 0;

	

	try{
	//wxLogMessage( wxT("%sFUNC %x"), GetPrefix(), dword(token) );

	PrintPreOutput(t);

	switch( token )
	{

	case 0x0070:	// $ 
	{
		RB_TOKEN_CODE("29A001000029A10100000B53");
		RB_TOKEN_NAME("$");
		flags=0x00023401;
		break;
	}

	case 0x0071:	// GotoState 
	{
		RB_TOKEN_CODE("299D000000299E000000299F00000029A00000000B53");
		RB_TOKEN_NAME("GotoState");
		flags=0x00020401;
		break;
	}

	case 0x0072:	// == 
	{
		RB_TOKEN_CODE("293B010000293C0100000B53");
		RB_TOKEN_NAME("==");
		flags=0x00023401;
		break;
	}

	case 0x0073:	// < 
	{
		RB_TOKEN_CODE("299801000029990100000B53");
		RB_TOKEN_NAME("<");
		flags=0x00023401;
		break;
	}

	case 0x0074:	// > 
	{
		RB_TOKEN_CODE("299401000029950100000B53");
		RB_TOKEN_NAME(">");
		flags=0x00023401;
		break;
	}

	case 0x0075:	// Enable 
	{
		RB_TOKEN_CODE("29830000000B53");
		RB_TOKEN_NAME("Enable");
		flags=0x00020401;
		break;
	}

	case 0x0076:	// Disable 
	{
		RB_TOKEN_CODE("29810000000B53");
		RB_TOKEN_NAME("Disable");
		flags=0x00020401;
		break;
	}

	case 0x0077:	// != 
	{
		RB_TOKEN_CODE("293701000029380100000B53");
		RB_TOKEN_NAME("!=");
		flags=0x00023401;
		break;
	}

	case 0x0078:	// <= 
	{
		RB_TOKEN_CODE("299001000029910100000B53");
		RB_TOKEN_NAME("<=");
		flags=0x00023401;
		break;
	}

	case 0x0079:	// >= 
	{
		RB_TOKEN_CODE("298C010000298D0100000B53");
		RB_TOKEN_NAME(">=");
		flags=0x00023401;
		break;
	}

	case 0x007A:	// == 
	{
		RB_TOKEN_CODE("298801000029890100000B53");
		RB_TOKEN_NAME("==");
		flags=0x00023401;
		break;
	}

	case 0x007B:	// != 
	{
		RB_TOKEN_CODE("298401000029850100000B53");
		RB_TOKEN_NAME("!=");
		flags=0x00023401;
		break;
	}

	case 0x007C:	// ~= 
	{
		RB_TOKEN_CODE("298001000029810100000B53");
		RB_TOKEN_NAME("~=");
		flags=0x00023401;
		break;
	}

	case 0x007D:	// Len 
	{
		RB_TOKEN_CODE("29730100000B53");
		RB_TOKEN_NAME("Len");
		flags=0x00022401;
		break;
	}

	case 0x007E:	// InStr 
	{
		RB_TOKEN_CODE("296F01000029700100000B53");
		RB_TOKEN_NAME("InStr");
		flags=0x00022401;
		break;
	}

	case 0x007F:	// Mid 
	{
		RB_TOKEN_CODE("296A010000296B010000296C0100000B53");
		RB_TOKEN_NAME("Mid");
		flags=0x00022401;
		break;
	}

	case 0x0080:	// Left 
	{
		RB_TOKEN_CODE("296601000029670100000B53");
		RB_TOKEN_NAME("Left");
		flags=0x00022401;
		break;
	}

	case 0x0081:	// ! 
	{
		RB_TOKEN_CODE("29B70300000B53");
		RB_TOKEN_NAME("!");
		flags=0x00023411;
		break;
	}

	case 0x0082:	// && 
	{
		RB_TOKEN_CODE("29AB03000029AC0300000B53");
		RB_TOKEN_NAME("&&");
		flags=0x00023401;
		break;
	}

	case 0x0083:	// ^^ 
	{
		RB_TOKEN_CODE("29A703000029A80300000B53");
		RB_TOKEN_NAME("^^");
		flags=0x00023401;
		break;
	}

	case 0x0084:	// || 
	{
		RB_TOKEN_CODE("29A303000029A40300000B53");
		RB_TOKEN_NAME("||");
		flags=0x00023401;
		break;
	}

	case 0x0085:	// *= 
	{
		RB_TOKEN_CODE("299F03000029A00300000B53");
		RB_TOKEN_NAME("*=");
		flags=0x00423401;
		break;
	}

	case 0x0086:	// /= 
	{
		RB_TOKEN_CODE("299B030000299C0300000B53");
		RB_TOKEN_NAME("/=");
		flags=0x00423401;
		break;
	}

	case 0x0087:	// += 
	{
		RB_TOKEN_CODE("299703000029980300000B53");
		RB_TOKEN_NAME("+=");
		flags=0x00423401;
		break;
	}

	case 0x0088:	// -= 
	{
		RB_TOKEN_CODE("299303000029940300000B53");
		RB_TOKEN_NAME("-=");
		flags=0x00423401;
		break;
	}

	case 0x0089:	// ++ 
	{
		RB_TOKEN_CODE("29900300000B53");
		RB_TOKEN_NAME("++");
		flags=0x00423411;
		break;
	}

	case 0x008A:	// -- 
	{
		RB_TOKEN_CODE("298D0300000B53");
		RB_TOKEN_NAME("--");
		flags=0x00423411;
		break;
	}

	case 0x008B:	// ++ 
	{
		RB_TOKEN_CODE("298A0300000B53");
		RB_TOKEN_NAME("++");
		flags=0x00423401;
		break;
	}

	case 0x008C:	// -- 
	{
		RB_TOKEN_CODE("29870300000B53");
		RB_TOKEN_NAME("--");
		flags=0x00423401;
		break;
	}

	case 0x008D:	// ~ 
	{
		RB_TOKEN_CODE("29840300000B53");
		RB_TOKEN_NAME("~");
		flags=0x00023411;
		break;
	}

	case 0x008E:	// == 
	{
		RB_TOKEN_CODE("290D020000290E0200000B53");
		RB_TOKEN_NAME("==");
		flags=0x00023401;
		break;
	}

	case 0x008F:	// - 
	{
		RB_TOKEN_CODE("29810300000B53");
		RB_TOKEN_NAME("-");
		flags=0x00023411;
		break;
	}

	case 0x0090:	// * 
	{
		RB_TOKEN_CODE("297D030000297E0300000B53");
		RB_TOKEN_NAME("*");
		flags=0x00023401;
		break;
	}

	case 0x0091:	// / 
	{
		RB_TOKEN_CODE("2979030000297A0300000B53");
		RB_TOKEN_NAME("/");
		flags=0x00023401;
		break;
	}

	case 0x0092:	// + 
	{
		RB_TOKEN_CODE("297503000029760300000B53");
		RB_TOKEN_NAME("+");
		flags=0x00023401;
		break;
	}

	case 0x0093:	// - 
	{
		RB_TOKEN_CODE("297103000029720300000B53");
		RB_TOKEN_NAME("-");
		flags=0x00023401;
		break;
	}

	case 0x0094:	// << 
	{
		RB_TOKEN_CODE("296D030000296E0300000B53");
		RB_TOKEN_NAME("<<");
		flags=0x00023401;
		break;
	}

	case 0x0095:	// >> 
	{
		RB_TOKEN_CODE("2969030000296A0300000B53");
		RB_TOKEN_NAME(">>");
		flags=0x00023401;
		break;
	}

	case 0x0096:	// < 
	{
		RB_TOKEN_CODE("296103000029620300000B53");
		RB_TOKEN_NAME("<");
		flags=0x00023401;
		break;
	}

	case 0x0097:	// > 
	{
		RB_TOKEN_CODE("295D030000295E0300000B53");
		RB_TOKEN_NAME(">");
		flags=0x00023401;
		break;
	}

	case 0x0098:	// <= 
	{
		RB_TOKEN_CODE("2959030000295A0300000B53");
		RB_TOKEN_NAME("<=");
		flags=0x00023401;
		break;
	}

	case 0x0099:	// >= 
	{
		RB_TOKEN_CODE("295503000029560300000B53");
		RB_TOKEN_NAME(">=");
		flags=0x00023401;
		break;
	}

	case 0x009A:	// == 
	{
		RB_TOKEN_CODE("295103000029520300000B53");
		RB_TOKEN_NAME("==");
		flags=0x00023401;
		break;
	}

	case 0x009B:	// != 
	{
		RB_TOKEN_CODE("294D030000294E0300000B53");
		RB_TOKEN_NAME("!=");
		flags=0x00023401;
		break;
	}

	case 0x009C:	// & 
	{
		RB_TOKEN_CODE("2949030000294A0300000B53");
		RB_TOKEN_NAME("&");
		flags=0x00023401;
		break;
	}

	case 0x009D:	// ^ 
	{
		RB_TOKEN_CODE("294503000029460300000B53");
		RB_TOKEN_NAME("^");
		flags=0x00023401;
		break;
	}

	case 0x009E:	// | 
	{
		RB_TOKEN_CODE("294103000029420300000B53");
		RB_TOKEN_NAME("|");
		flags=0x00023401;
		break;
	}

	case 0x009F:	// *= 
	{
		RB_TOKEN_CODE("293D030000293E0300000B53");
		RB_TOKEN_NAME("*=");
		flags=0x00423401;
		break;
	}

	case 0x00A0:	// /= 
	{
		RB_TOKEN_CODE("2939030000293A0300000B53");
		RB_TOKEN_NAME("/=");
		flags=0x00423401;
		break;
	}

	case 0x00A1:	// += 
	{
		RB_TOKEN_CODE("293503000029360300000B53");
		RB_TOKEN_NAME("+=");
		flags=0x00423401;
		break;
	}

	case 0x00A2:	// -= 
	{
		RB_TOKEN_CODE("293103000029320300000B53");
		RB_TOKEN_NAME("-=");
		flags=0x00423401;
		break;
	}

	case 0x00A3:	// ++ 
	{
		RB_TOKEN_CODE("292E0300000B53");
		RB_TOKEN_NAME("++");
		flags=0x00423411;
		break;
	}

	case 0x00A4:	// -- 
	{
		RB_TOKEN_CODE("292B0300000B53");
		RB_TOKEN_NAME("--");
		flags=0x00423411;
		break;
	}

	case 0x00A5:	// ++ 
	{
		RB_TOKEN_CODE("29280300000B53");
		RB_TOKEN_NAME("++");
		flags=0x00423401;
		break;
	}

	case 0x00A6:	// -- 
	{
		RB_TOKEN_CODE("29250300000B53");
		RB_TOKEN_NAME("--");
		flags=0x00423401;
		break;
	}

	case 0x00A7:	// Rand 
	{
		RB_TOKEN_CODE("29220300000B53");
		RB_TOKEN_NAME("Rand");
		flags=0x00022401;
		break;
	}

	case 0x00A8:	// @ 
	{
		RB_TOKEN_CODE("299C010000299D0100000B53");
		RB_TOKEN_NAME("@");
		flags=0x00023401;
		break;
	}

	case 0x00A9:	// - 
	{
		RB_TOKEN_CODE("29120300000B53");
		RB_TOKEN_NAME("-");
		flags=0x00023411;
		break;
	}

	case 0x00AA:	// ** 
	{
		RB_TOKEN_CODE("290E030000290F0300000B53");
		RB_TOKEN_NAME("**");
		flags=0x00023401;
		break;
	}

	case 0x00AB:	// * 
	{
		RB_TOKEN_CODE("290A030000290B0300000B53");
		RB_TOKEN_NAME("*");
		flags=0x00023401;
		break;
	}

	case 0x00AC:	// / 
	{
		RB_TOKEN_CODE("290603000029070300000B53");
		RB_TOKEN_NAME("/");
		flags=0x00023401;
		break;
	}

	case 0x00AD:	// % 
	{
		RB_TOKEN_CODE("290203000029030300000B53");
		RB_TOKEN_NAME("%");
		flags=0x00023401;
		break;
	}

	case 0x00AE:	// + 
	{
		RB_TOKEN_CODE("29FE02000029FF0200000B53");
		RB_TOKEN_NAME("+");
		flags=0x00023401;
		break;
	}

	case 0x00AF:	// - 
	{
		RB_TOKEN_CODE("29FA02000029FB0200000B53");
		RB_TOKEN_NAME("-");
		flags=0x00023401;
		break;
	}

	case 0x00B0:	// < 
	{
		RB_TOKEN_CODE("29F602000029F70200000B53");
		RB_TOKEN_NAME("<");
		flags=0x00023401;
		break;
	}

	case 0x00B1:	// > 
	{
		RB_TOKEN_CODE("29F202000029F30200000B53");
		RB_TOKEN_NAME(">");
		flags=0x00023401;
		break;
	}

	case 0x00B2:	// <= 
	{
		RB_TOKEN_CODE("29EE02000029EF0200000B53");
		RB_TOKEN_NAME("<=");
		flags=0x00023401;
		break;
	}

	case 0x00B3:	// >= 
	{
		RB_TOKEN_CODE("29EA02000029EB0200000B53");
		RB_TOKEN_NAME(">=");
		flags=0x00023401;
		break;
	}

	case 0x00B4:	// == 
	{
		RB_TOKEN_CODE("29E602000029E70200000B53");
		RB_TOKEN_NAME("==");
		flags=0x00023401;
		break;
	}

	case 0x00B5:	// != 
	{
		RB_TOKEN_CODE("29DE02000029DF0200000B53");
		RB_TOKEN_NAME("!=");
		flags=0x00023401;
		break;
	}

	case 0x00B6:	// *= 
	{
		RB_TOKEN_CODE("29DA02000029DB0200000B53");
		RB_TOKEN_NAME("*=");
		flags=0x00423401;
		break;
	}

	case 0x00B7:	// /= 
	{
		RB_TOKEN_CODE("29D602000029D70200000B53");
		RB_TOKEN_NAME("/=");
		flags=0x00423401;
		break;
	}

	case 0x00B8:	// += 
	{
		RB_TOKEN_CODE("29D202000029D30200000B53");
		RB_TOKEN_NAME("+=");
		flags=0x00423401;
		break;
	}

	case 0x00B9:	// -= 
	{
		RB_TOKEN_CODE("29CE02000029CF0200000B53");
		RB_TOKEN_NAME("-=");
		flags=0x00423401;
		break;
	}

	case 0x00BA:	// Abs 
	{
		RB_TOKEN_CODE("29CB0200000B53");
		RB_TOKEN_NAME("Abs");
		flags=0x00022401;
		break;
	}

	case 0x00BB:	// Sin 
	{
		RB_TOKEN_CODE("29C80200000B53");
		RB_TOKEN_NAME("Sin");
		flags=0x00022401;
		break;
	}

	case 0x00BC:	// Cos 
	{
		RB_TOKEN_CODE("29C20200000B53");
		RB_TOKEN_NAME("Cos");
		flags=0x00022401;
		break;
	}

	case 0x00BD:	// Tan 
	{
		RB_TOKEN_CODE("29BC0200000B53");
		RB_TOKEN_NAME("Tan");
		flags=0x00022401;
		break;
	}

	case 0x00BE:	// Atan 
	{
		RB_TOKEN_CODE("29B902000029BA0200000B53");
		RB_TOKEN_NAME("Atan");
		flags=0x00022401;
		break;
	}

	case 0x00BF:	// Exp 
	{
		RB_TOKEN_CODE("29B60200000B53");
		RB_TOKEN_NAME("Exp");
		flags=0x00022401;
		break;
	}

	case 0x00C0:	// Loge 
	{
		RB_TOKEN_CODE("29B30200000B53");
		RB_TOKEN_NAME("Loge");
		flags=0x00022401;
		break;
	}

	case 0x00C1:	// Sqrt 
	{
		RB_TOKEN_CODE("29B00200000B53");
		RB_TOKEN_NAME("Sqrt");
		flags=0x00022401;
		break;
	}

	case 0x00C2:	// Square 
	{
		RB_TOKEN_CODE("29AD0200000B53");
		RB_TOKEN_NAME("Square");
		flags=0x00022401;
		break;
	}

	case 0x00C3:	// FRand 
	{
		RB_TOKEN_CODE("0B53");
		RB_TOKEN_NAME("FRand");
		flags=0x00022401;
		break;
	}

	case 0x00C4:	// >>> 
	{
		RB_TOKEN_CODE("296503000029660300000B53");
		RB_TOKEN_NAME(">>>");
		flags=0x00023401;
		break;
	}

	case 0x00C5:	// IsA 
	{
		RB_TOKEN_CODE("29280100000B53");
		RB_TOKEN_NAME("IsA");
		flags=0x00020401;
		break;
	}

	case 0x00C9:	// Repl 
	{
		RB_TOKEN_CODE("29500100002951010000295201000029530100000B53");
		RB_TOKEN_NAME("Repl");
		flags=0x00022401;
		break;
	}

	case 0x00CB:	// != 
	{
		RB_TOKEN_CODE("2909020000290A0200000B53");
		RB_TOKEN_NAME("!=");
		flags=0x00023401;
		break;
	}

	case 0x00D2:	// ~= 
	{
		RB_TOKEN_CODE("29E202000029E30200000B53");
		RB_TOKEN_NAME("~=");
		flags=0x00023401;
		break;
	}

	case 0x00D3:	// - 
	{
		RB_TOKEN_CODE("29800200000B53");
		RB_TOKEN_NAME("-");
		flags=0x00023411;
		break;
	}

	case 0x00D4:	// * 
	{
		RB_TOKEN_CODE("297D020000297E0200000B53");
		RB_TOKEN_NAME("*");
		flags=0x00023401;
		break;
	}

	case 0x00D5:	// * 
	{
		RB_TOKEN_CODE("2979020000297A0200000B53");
		RB_TOKEN_NAME("*");
		flags=0x00023401;
		break;
	}

	case 0x00D6:	// / 
	{
		RB_TOKEN_CODE("297102000029720200000B53");
		RB_TOKEN_NAME("/");
		flags=0x00023401;
		break;
	}

	case 0x00D7:	// + 
	{
		RB_TOKEN_CODE("296D020000296E0200000B53");
		RB_TOKEN_NAME("+");
		flags=0x00023401;
		break;
	}

	case 0x00D8:	// - 
	{
		RB_TOKEN_CODE("2969020000296A0200000B53");
		RB_TOKEN_NAME("-");
		flags=0x00023401;
		break;
	}

	case 0x00D9:	// == 
	{
		RB_TOKEN_CODE("295D020000295E0200000B53");
		RB_TOKEN_NAME("==");
		flags=0x00023401;
		break;
	}

	case 0x00DA:	// != 
	{
		RB_TOKEN_CODE("2959020000295A0200000B53");
		RB_TOKEN_NAME("!=");
		flags=0x00023401;
		break;
	}

	case 0x00DB:	// Dot 
	{
		RB_TOKEN_CODE("295502000029560200000B53");
		RB_TOKEN_NAME("Dot");
		flags=0x00023401;
		break;
	}

	case 0x00DC:	// Cross 
	{
		RB_TOKEN_CODE("295102000029520200000B53");
		RB_TOKEN_NAME("Cross");
		flags=0x00023401;
		break;
	}

	case 0x00DD:	// *= 
	{
		RB_TOKEN_CODE("294D020000294E0200000B53");
		RB_TOKEN_NAME("*=");
		flags=0x00423401;
		break;
	}

	case 0x00DE:	// /= 
	{
		RB_TOKEN_CODE("294502000029460200000B53");
		RB_TOKEN_NAME("/=");
		flags=0x00423401;
		break;
	}

	case 0x00DF:	// += 
	{
		RB_TOKEN_CODE("294102000029420200000B53");
		RB_TOKEN_NAME("+=");
		flags=0x00423401;
		break;
	}

	case 0x00E0:	// -= 
	{
		RB_TOKEN_CODE("293D020000293E0200000B53");
		RB_TOKEN_NAME("-=");
		flags=0x00423401;
		break;
	}

	case 0x00E1:	// VSize 
	{
		RB_TOKEN_CODE("293A0200000B53");
		RB_TOKEN_NAME("VSize");
		flags=0x00022401;
		break;
	}

	case 0x00E2:	// Normal 
	{
		RB_TOKEN_CODE("292E0200000B53");
		RB_TOKEN_NAME("Normal");
		flags=0x00022401;
		break;
	}

	case 0x00E5:	// GetAxes 
	{
		RB_TOKEN_CODE("29DC01000029DD01000029DE01000029DF0100000B53");
		RB_TOKEN_NAME("GetAxes");
		flags=0x00422401;
		break;
	}

	case 0x00E6:	// GetUnAxes 
	{
		RB_TOKEN_CODE("29D701000029D801000029D901000029DA0100000B53");
		RB_TOKEN_NAME("GetUnAxes");
		flags=0x00422401;
		break;
	}

	case 0x00E7:	// LogInternal 
	{
		RB_TOKEN_CODE("29AC00000029AD0000000B53");
		RB_TOKEN_NAME("LogInternal");
		flags=0x00022401;
		break;
	}

	case 0x00E8:	// WarnInternal 
	{
		RB_TOKEN_CODE("29AA0000000B53");
		RB_TOKEN_NAME("WarnInternal");
		flags=0x00022401;
		break;
	}

	case 0x00EA:	// Right 
	{
		RB_TOKEN_CODE("296201000029630100000B53");
		RB_TOKEN_NAME("Right");
		flags=0x00022401;
		break;
	}

	case 0x00EB:	// Caps 
	{
		RB_TOKEN_CODE("295F0100000B53");
		RB_TOKEN_NAME("Caps");
		flags=0x00022401;
		break;
	}

	case 0x00EC:	// Chr 
	{
		RB_TOKEN_CODE("29590100000B53");
		RB_TOKEN_NAME("Chr");
		flags=0x00022401;
		break;
	}

	case 0x00ED:	// Asc 
	{
		RB_TOKEN_CODE("29560100000B53");
		RB_TOKEN_NAME("Asc");
		flags=0x00022401;
		break;
	}

	case 0x00EE:	// Locs 
	{
		RB_TOKEN_CODE("295C0100000B53");
		RB_TOKEN_NAME("Locs");
		flags=0x00022401;
		break;
	}

	case 0x00F2:	// == 
	{
		RB_TOKEN_CODE("29B303000029B40300000B53");
		RB_TOKEN_NAME("==");
		flags=0x00023401;
		break;
	}

	case 0x00F3:	// != 
	{
		RB_TOKEN_CODE("29AF03000029B00300000B53");
		RB_TOKEN_NAME("!=");
		flags=0x00023401;
		break;
	}

	case 0x00F4:	// FMin 
	{
		RB_TOKEN_CODE("29A702000029A80200000B53");
		RB_TOKEN_NAME("FMin");
		flags=0x00022401;
		break;
	}

	case 0x00F5:	// FMax 
	{
		RB_TOKEN_CODE("29A302000029A40200000B53");
		RB_TOKEN_NAME("FMax");
		flags=0x00022401;
		break;
	}

	case 0x00F6:	// FClamp 
	{
		RB_TOKEN_CODE("299E020000299F02000029A00200000B53");
		RB_TOKEN_NAME("FClamp");
		flags=0x00022401;
		break;
	}

	case 0x00F7:	// Lerp 
	{
		RB_TOKEN_CODE("2999020000299A020000299B0200000B53");
		RB_TOKEN_NAME("Lerp");
		flags=0x00022401;
		break;
	}

	case 0x00F9:	// Min 
	{
		RB_TOKEN_CODE("291E030000291F0300000B53");
		RB_TOKEN_NAME("Min");
		flags=0x00022401;
		break;
	}

	case 0x00FA:	// Max 
	{
		RB_TOKEN_CODE("291A030000291B0300000B53");
		RB_TOKEN_NAME("Max");
		flags=0x00022401;
		break;
	}

	case 0x00FB:	// Clamp 
	{
		RB_TOKEN_CODE("2915030000291603000029170300000B53");
		RB_TOKEN_NAME("Clamp");
		flags=0x00022401;
		break;
	}

	case 0x00FC:	// VRand 
	{
		RB_TOKEN_CODE("0B53");
		RB_TOKEN_NAME("VRand");
		flags=0x00022401;
		break;
	}

	case 0x00FE:	// == 
	{
		RB_TOKEN_CODE("292401000029250100000B53");
		RB_TOKEN_NAME("==");
		flags=0x00023401;
		break;
	}

	case 0x00FF:	// != 
	{
		RB_TOKEN_CODE("292001000029210100000B53");
		RB_TOKEN_NAME("!=");
		flags=0x00023401;
		break;
	}

	case 0x0100:	// Sleep 
	{
		RB_TOKEN_CODE("294C0D00000B53");
		RB_TOKEN_NAME("Sleep");
		flags=0x00020409;
		break;
	}

	case 0x0102:	// ClassIsChildOf 
	{
		RB_TOKEN_CODE("292B010000292C0100000B53");
		RB_TOKEN_NAME("ClassIsChildOf");
		flags=0x00022401;
		break;
	}

	case 0x0105:	// FinishAnim 
	{
		RB_TOKEN_CODE("294B0D00000B53");
		RB_TOKEN_NAME("FinishAnim");
		flags=0x00020409;
		break;
	}

	case 0x0106:	// SetCollision 
	{
		RB_TOKEN_CODE("29470D000029480D000029490D00000B53");
		RB_TOKEN_NAME("SetCollision");
		flags=0x00020401;
		break;
	}

	case 0x010A:	// Move 
	{
		RB_TOKEN_CODE("293D0D00000B53");
		RB_TOKEN_NAME("Move");
		flags=0x00020401;
		break;
	}

	case 0x010B:	// SetLocation 
	{
		RB_TOKEN_CODE("293A0D00000B53");
		RB_TOKEN_NAME("SetLocation");
		flags=0x00020401;
		break;
	}

	case 0x010E:	// + 
	{
		RB_TOKEN_CODE("29F900000029FA0000000B53");
		RB_TOKEN_NAME("+");
		flags=0x00023401;
		break;
	}

	case 0x010F:	// - 
	{
		RB_TOKEN_CODE("29F000000029F10000000B53");
		RB_TOKEN_NAME("-");
		flags=0x00023401;
		break;
	}

	case 0x0110:	// SetOwner 
	{
		RB_TOKEN_CODE("29230D00000B53");
		RB_TOKEN_NAME("SetOwner");
		flags=0x00020401;
		break;
	}

	case 0x0113:	// << 
	{
		RB_TOKEN_CODE("296502000029660200000B53");
		RB_TOKEN_NAME("<<");
		flags=0x00023401;
		break;
	}

	case 0x0114:	// >> 
	{
		RB_TOKEN_CODE("296102000029620200000B53");
		RB_TOKEN_NAME(">>");
		flags=0x00023401;
		break;
	}

	case 0x0115:	// Trace 
	{
		RB_TOKEN_CODE("29940C000029950C000029960C000029970C000029980C000029990C0000299A0C0000299B0C00000B53");
		RB_TOKEN_NAME("Trace");
		flags=0x00420401;
		break;
	}

	case 0x0116:	// Spawn 
	{
		RB_TOKEN_CODE("29730C000029740C000029750C000029760C000029770C000029780C000029790C00000B53");
		RB_TOKEN_NAME("Spawn");
		flags=0x00020401;
		break;
	}

	case 0x0117:	// Destroy 
	{
		RB_TOKEN_CODE("0B53");
		RB_TOKEN_NAME("Destroy");
		flags=0x00020401;
		break;
	}

	case 0x0118:	// SetTimer 
	{
		RB_TOKEN_CODE("296B0C0000296C0C0000296D0C0000296E0C00000B53");
		RB_TOKEN_NAME("SetTimer");
		flags=0x00020401;
		break;
	}

	case 0x0119:	// IsInState 
	{
		RB_TOKEN_CODE("2999000000299A0000000B53");
		RB_TOKEN_NAME("IsInState");
		flags=0x00020401;
		break;
	}

	case 0x011B:	// SetCollisionSize 
	{
		RB_TOKEN_CODE("29440D000029450D00000B53");
		RB_TOKEN_NAME("SetCollisionSize");
		flags=0x00020401;
		break;
	}

	case 0x011C:	// GetStateName 
	{
		RB_TOKEN_CODE("0B53");
		RB_TOKEN_NAME("GetStateName");
		flags=0x00020401;
		break;
	}

	case 0x011F:	// * 
	{
		RB_TOKEN_CODE("290502000029060200000B53");
		RB_TOKEN_NAME("*");
		flags=0x00023401;
		break;
	}

	case 0x0120:	// * 
	{
		RB_TOKEN_CODE("290102000029020200000B53");
		RB_TOKEN_NAME("*");
		flags=0x00023401;
		break;
	}

	case 0x0121:	// / 
	{
		RB_TOKEN_CODE("29FD01000029FE0100000B53");
		RB_TOKEN_NAME("/");
		flags=0x00023401;
		break;
	}

	case 0x0122:	// *= 
	{
		RB_TOKEN_CODE("29F901000029FA0100000B53");
		RB_TOKEN_NAME("*=");
		flags=0x00423401;
		break;
	}

	case 0x0123:	// /= 
	{
		RB_TOKEN_CODE("29F501000029F60100000B53");
		RB_TOKEN_NAME("/=");
		flags=0x00423401;
		break;
	}

	case 0x0128:	// * 
	{
		RB_TOKEN_CODE("297502000029760200000B53");
		RB_TOKEN_NAME("*");
		flags=0x00023401;
		break;
	}

	case 0x0129:	// *= 
	{
		RB_TOKEN_CODE("2949020000294A0200000B53");
		RB_TOKEN_NAME("*=");
		flags=0x00423401;
		break;
	}

	case 0x012A:	// SetBase 
	{
		RB_TOKEN_CODE("29250D000029260D000029270D000029280D00000B53");
		RB_TOKEN_NAME("SetBase");
		flags=0x00020401;
		break;
	}

	case 0x012B:	// SetRotation 
	{
		RB_TOKEN_CODE("29370D00000B53");
		RB_TOKEN_NAME("SetRotation");
		flags=0x00020401;
		break;
	}

	case 0x012C:	// MirrorVectorByNormal 
	{
		RB_TOKEN_CODE("291E020000291F0200000B53");
		RB_TOKEN_NAME("MirrorVectorByNormal");
		flags=0x00022401;
		break;
	}

	case 0x0130:	// AllActors 
	{
		RB_TOKEN_CODE("29360C000029370C00000B53");
		RB_TOKEN_NAME("AllActors");
		flags=0x00420405;
		break;
	}

	case 0x0131:	// ChildActors 
	{
		RB_TOKEN_CODE("29300C000029310C00000B53");
		RB_TOKEN_NAME("ChildActors");
		flags=0x00420405;
		break;
	}

	case 0x0132:	// BasedActors 
	{
		RB_TOKEN_CODE("292D0C0000292E0C00000B53");
		RB_TOKEN_NAME("BasedActors");
		flags=0x00420405;
		break;
	}

	case 0x0133:	// TouchingActors 
	{
		RB_TOKEN_CODE("292A0C0000292B0C00000B53");
		RB_TOKEN_NAME("TouchingActors");
		flags=0x00420405;
		break;
	}

	case 0x0135:	// TraceActors 
	{
		RB_TOKEN_CODE("29210C000029220C000029230C000029240C000029250C000029260C000029270C000029280C00000B53");
		RB_TOKEN_NAME("TraceActors");
		flags=0x00420405;
		break;
	}

	case 0x0137:	// VisibleActors 
	{
		RB_TOKEN_CODE("291C0C0000291D0C0000291E0C0000291F0C00000B53");
		RB_TOKEN_NAME("VisibleActors");
		flags=0x00420405;
		break;
	}

	case 0x0138:	// VisibleCollidingActors 
	{
		RB_TOKEN_CODE("29160C000029170C000029180C000029190C0000291A0C00000B53");
		RB_TOKEN_NAME("VisibleCollidingActors");
		flags=0x00420405;
		break;
	}

	case 0x0139:	// DynamicActors 
	{
		RB_TOKEN_CODE("29330C000029340C00000B53");
		RB_TOKEN_NAME("DynamicActors");
		flags=0x00420405;
		break;
	}

	case 0x013C:	// + 
	{
		RB_TOKEN_CODE("29F101000029F20100000B53");
		RB_TOKEN_NAME("+");
		flags=0x00023401;
		break;
	}

	case 0x013D:	// - 
	{
		RB_TOKEN_CODE("29ED01000029EE0100000B53");
		RB_TOKEN_NAME("-");
		flags=0x00023401;
		break;
	}

	case 0x013E:	// += 
	{
		RB_TOKEN_CODE("29E901000029EA0100000B53");
		RB_TOKEN_NAME("+=");
		flags=0x00423401;
		break;
	}

	case 0x013F:	// -= 
	{
		RB_TOKEN_CODE("29E501000029E60100000B53");
		RB_TOKEN_NAME("-=");
		flags=0x00423401;
		break;
	}

	case 0x0140:	// RotRand 
	{
		RB_TOKEN_CODE("29D40100000B53");
		RB_TOKEN_NAME("RotRand");
		flags=0x00022401;
		break;
	}

	case 0x0141:	// CollidingActors 
	{
		RB_TOKEN_CODE("29100C000029110C000029120C000029130C000029140C00000B53");
		RB_TOKEN_NAME("CollidingActors");
		flags=0x00420405;
		break;
	}

	case 0x0142:	// $= 
	{
		RB_TOKEN_CODE("297D010000297E0100000B53");
		RB_TOKEN_NAME("$=");
		flags=0x00423401;
		break;
	}

	case 0x0143:	// @= 
	{
		RB_TOKEN_CODE("2979010000297A0100000B53");
		RB_TOKEN_NAME("@=");
		flags=0x00423401;
		break;
	}

	case 0x0144:	// -= 
	{
		RB_TOKEN_CODE("297601000029770100000B53");
		RB_TOKEN_NAME("-=");
		flags=0x00423401;
		break;
	}

	case 0x01D0:	// StrLen 
	{
		RB_TOKEN_CODE("29262C000029272C000029282C00000B53");
		RB_TOKEN_NAME("StrLen");
		flags=0x00420401;
		break;
	}

	case 0x01D1:	// DrawText 
	{
		RB_TOKEN_CODE("291F2C000029202C00000B53");
		RB_TOKEN_NAME("DrawText");
		flags=0x00020401;
		break;
	}

	case 0x01D2:	// DrawTile 
	{
		RB_TOKEN_CODE("29312C000029322C000029332C000029342C000029352C000029362C000029372C00000B53");
		RB_TOKEN_NAME("DrawTile");
		flags=0x00020401;
		break;
	}

	case 0x01D5:	// DrawTextClipped 
	{
		RB_TOKEN_CODE("291C2C0000291D2C00000B53");
		RB_TOKEN_NAME("DrawTextClipped");
		flags=0x00020401;
		break;
	}

	case 0x01D6:	// TextSize 
	{
		RB_TOKEN_CODE("29222C000029232C000029242C00000B53");
		RB_TOKEN_NAME("TextSize");
		flags=0x00420401;
		break;
	}

	case 0x01F4:	// MoveTo 
	{
		RB_TOKEN_CODE("2916260000291726000029182600000B53");
		RB_TOKEN_NAME("MoveTo");
		flags=0x00020409;
		break;
	}

	case 0x01F6:	// MoveToward 
	{
		RB_TOKEN_CODE("291026000029112600002912260000291326000029142600000B53");
		RB_TOKEN_NAME("MoveToward");
		flags=0x00020409;
		break;
	}

	case 0x01FC:	// FinishRotation 
	{
		RB_TOKEN_CODE("0B53");
		RB_TOKEN_NAME("FinishRotation");
		flags=0x00020409;
		break;
	}

	case 0x0200:	// MakeNoise 
	{
		RB_TOKEN_CODE("294F0C000029500C00000B53");
		RB_TOKEN_NAME("MakeNoise");
		flags=0x00020401;
		break;
	}

	case 0x0202:	// LineOfSightTo 
	{
		RB_TOKEN_CODE("293326000029342600000B53");
		RB_TOKEN_NAME("LineOfSightTo");
		flags=0x00020401;
		break;
	}

	case 0x0205:	// FindPathToward 
	{
		RB_TOKEN_CODE("29032600002904260000290526000029062600000B53");
		RB_TOKEN_NAME("FindPathToward");
		flags=0x00020401;
		break;
	}

	case 0x0206:	// FindPathTo 
	{
		RB_TOKEN_CODE("2909260000290A260000290B2600000B53");
		RB_TOKEN_NAME("FindPathTo");
		flags=0x00020401;
		break;
	}

	case 0x0208:	// ActorReachable 
	{
		RB_TOKEN_CODE("29EE2500000B53");
		RB_TOKEN_NAME("ActorReachable");
		flags=0x00020401;
		break;
	}

	case 0x0209:	// PointReachable 
	{
		RB_TOKEN_CODE("29F12500000B53");
		RB_TOKEN_NAME("PointReachable");
		flags=0x00020401;
		break;
	}

	case 0x020C:	// FindStairRotation 
	{
		RB_TOKEN_CODE("294F2B00000B53");
		RB_TOKEN_NAME("FindStairRotation");
		flags=0x00020401;
		break;
	}

	case 0x020D:	// FindRandomDest 
	{
		RB_TOKEN_CODE("0B53");
		RB_TOKEN_NAME("FindRandomDest");
		flags=0x00020401;
		break;
	}

	case 0x020E:	// PickWallAdjust 
	{
		RB_TOKEN_CODE("29E82500000B53");
		RB_TOKEN_NAME("PickWallAdjust");
		flags=0x00020401;
		break;
	}

	case 0x020F:	// WaitForLanding 
	{
		RB_TOKEN_CODE("29E62500000B53");
		RB_TOKEN_NAME("WaitForLanding");
		flags=0x00020409;
		break;
	}

	case 0x0213:	// PickTarget 
	{
		RB_TOKEN_CODE("2923260000292426000029252600002926260000292726000029282600000B53");
		RB_TOKEN_NAME("PickTarget");
		flags=0x00420401;
		break;
	}

	case 0x0214:	// PlayerCanSeeMe 
	{
		RB_TOKEN_CODE("0B53");
		RB_TOKEN_NAME("PlayerCanSeeMe");
		flags=0x00020401;
		break;
	}

	case 0x0215:	// CanSee 
	{
		RB_TOKEN_CODE("29302600000B53");
		RB_TOKEN_NAME("CanSee");
		flags=0x00020401;
		break;
	}

	case 0x0218:	// SaveConfig 
	{
		RB_TOKEN_CODE("0B53");
		RB_TOKEN_NAME("SaveConfig");
		flags=0x00020401;
		break;
	}

	case 0x0219:	// CanSeeByPoints 
	{
		RB_TOKEN_CODE("292B260000292C260000292D2600000B53");
		RB_TOKEN_NAME("CanSeeByPoints");
		flags=0x00020401;
		break;
	}

	case 0x0222:	// UpdateURL 
	{
		RB_TOKEN_CODE("29642B000029652B000029662B00000B53");
		RB_TOKEN_NAME("UpdateURL");
		flags=0x00020401;
		break;
	}

	case 0x0223:	// GetURLMap 
	{
		RB_TOKEN_CODE("0B53");
		RB_TOKEN_NAME("GetURLMap");
		flags=0x00020401;
		break;
	}

	case 0x0224:	// FastTrace 
	{
		RB_TOKEN_CODE("29860C000029870C000029880C00000B53");
		RB_TOKEN_NAME("FastTrace");
		flags=0x00020401;
		break;
	}

	case 0x05DC:	// ProjectOnTo 
	{
		RB_TOKEN_CODE("291A020000291B0200000B53");
		RB_TOKEN_NAME("ProjectOnTo");
		flags=0x00022401;
		break;
	}

	case 0x05DD:	// IsZero 
	{
		RB_TOKEN_CODE("29170200000B53");
		RB_TOKEN_NAME("IsZero");
		flags=0x00022401;
		break;
	}

	case 0x0F81:	// MoveSmooth 
	{
		RB_TOKEN_CODE("292D0D00000B53");
		RB_TOKEN_NAME("MoveSmooth");
		flags=0x00020401;
		break;
	}

	case 0x0F82:	// SetPhysics 
	{
		RB_TOKEN_CODE("29E20C00000B53");
		RB_TOKEN_NAME("SetPhysics");
		flags=0x00020401;
		break;
	}

	case 0x0F83:	// AutonomousPhysics 
	{
		RB_TOKEN_CODE("292C0D00000B53");
		RB_TOKEN_NAME("AutonomousPhysics");
		flags=0x00020401;
		break;
	}




	default:
	{
		throw upexception(wxString::Format(wxT("Unknown Function Token %x at %s"),dword(token),Arc.DebugInfo().c_str()));
	}


	}

	output = name;
	AddToken(t);
	PushStack(t);


	if( rbHasFlag(flags,0x1000) )
	{
		if( rbHasFlag(flags,0x10) )
		{
			// preoperator
			//wxLogMessage( wxT("%x %x preoperator"),token,flags);
			output = name;
			PrintOutput(output);	
			for( dword x=0; x!=0xFF; ++x )
				if( LoadToken() == 0x16 )
					break;
		}
		else
		{
			// post/operator
			//wxLogMessage( wxT("%x %x post/operator"),token,flags);
			output = wxString::Format( wxT(" %s "), PF_SAFESTR(name) );

			for( dword x=0; x!=0xFF; ++x )
			{
				if( LoadToken() == 0x16 )
					break;

				if( x == 0 )
				{
					PrintOutput(output);	
				}
			}
		}
	}
	else
	{
		output = wxString::Format( wxT("%s"), PF_SAFESTR(name) );
		ParseAndOutputFunction( output );
	}

	PopStack();

	PrintPostOutput(t);


/*
static final preoperator byte #(byte a){return a;}          
// 00000000000000100011000000010010

static final postoperator byte #(byte a){return a;}         
// 00000000000000100011000000000011

static final operator(1) byte #(byte a, byte b){return a;}  
// 00000000000000100011000000000011

// 0072 ==
// 00000000000000100011010000000001

// 00000000000000000001000000000000


	FUNC_Operator       = 0x00001000,   // Operator function.
	FUNC_PreOperator	= 0x00000010,	// Unary operator is a prefix operator.


	FUNC_Final			= 0x00000001,	// Function is final (prebindable, non-overridable function).
	FUNC_Defined		= 0x00000002,	// Function has been defined (not just declared).
	FUNC_Iterator		= 0x00000004,	// Function is an iterator.
	FUNC_Latent		    = 0x00000008,	// Function is a latent state function.
	FUNC_Singular       = 0x00000020,   // Function cannot be reentered.
	FUNC_Net            = 0x00000040,   // Function is network-replicated.
	FUNC_NetReliable    = 0x00000080,   // Function should be sent reliably on the network.
	FUNC_Simulated		= 0x00000100,	// Function executed on the client side.
	FUNC_Exec		    = 0x00000200,	// Executable from command line.
	FUNC_Native			= 0x00000400,	// Native function.
	FUNC_Event          = 0x00000800,   // Event function.
	FUNC_Static         = 0x00002000,   // Static function.
	FUNC_NoExport       = 0x00004000,   // Don't export intrinsic function to C++.
	FUNC_Const          = 0x00008000,   // Function doesn't modify this object.
	FUNC_Invariant      = 0x00010000,   // Return value is purely dependent on parameters; no state dependencies or internal state changes.
	FUNC_Public			= 0x00020000,	// Function is accessible in all classes (if overridden, parameters much remain unchanged).
	FUNC_Private		= 0x00040000,	// Function is accessible only in the class it is defined in (cannot be overriden, but function name may be reused in subclasses.  IOW: if overridden, parameters don't need to match, and Super.Func() cannot be accessed since it's private.)
	FUNC_Protected		= 0x00080000,	// Function is accessible only in the class it is defined in and subclasses (if overridden, parameters much remain unchanged).
	FUNC_Delegate		= 0x00100000,	// Function is actually a delegate.
*/
	
	/*if( !t )
	{ 
		t = new rbToken(token,name,output); 
		AddToken(t); 
	}

	dword idx = 0;
	dword param = 0;
	while( idx < code.Length() )
	{
		unsigned long val;
		if( !code.Mid(idx,2).ToULong(&val,16) )
			throw upexception(wxString::Format(wxT("Unknown Function Token code %x at %s"),dword(token),Arc.DebugInfo().c_str()));

		idx += 2;
		if( val == 0x29 )
		{
			++param;
			if( !code.Mid(idx,4).ToULong(&val,16) )
				throw upexception(wxString::Format(wxT("Unknown Function Token code 2 %x at %s"),dword(token),Arc.DebugInfo().c_str()));

			//val = wxUINT32_SWAP_ALWAYS(val);
			idx += 4;
			wxLogMessage( wxString::Format(wxT("LOAD param %d for %s"),param,PF_SAFESTR(name)));
			AddToken(LoadToken(true));
		}
		else if( val == 0x0b )
		{
			// should be 0x16 = endparams
			AddToken(LoadToken(true));
			wxLogMessage( wxString::Format(wxT("END param for %s"),PF_SAFESTR(name)));
		}
	}

*/
	} 
	catch( upexception& e ) { throw upexception( wxString::Format(wxT(" [%.4x]%s -- %s"), token, PF_SAFESTR(name), e.wwhat().c_str() )); }
	catch( exception& e ) { throw exception( wxString::Format(wxT(" [%.4x]%s -- %hs"), token, PF_SAFESTR(name), e.what()).ToAscii()); }

}
static int
blk_part_exp(MACRO_PROT_ARGS)
{
	int		  la, nl;
	enum margserr	  ac;
	struct mdoc_node *head; /* keep track of head */
	struct mdoc_node *body; /* keep track of body */
	char		 *p;
	enum mdoct	  ntok;

	nl = MDOC_NEWLINE & mdoc->flags;

	/*
	 * The opening of an explicit macro having zero or more leading
	 * punctuation nodes; a head with optional single element (the
	 * case of `Eo'); and a body that may be empty.
	 */

	if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, NULL))
		return(0); 

	for (head = body = NULL; ; ) {
		la = *pos;
		ac = mdoc_args(mdoc, line, pos, buf, tok, &p);

		if (ARGS_ERROR == ac)
			return(0);
		if (ARGS_PUNCT == ac)
			break;
		if (ARGS_EOLN == ac)
			break;

		/* Flush out leading punctuation. */

		if (NULL == head && ARGS_QWORD != ac &&
				DELIM_OPEN == mdoc_isdelim(p)) {
			assert(NULL == body);
			if ( ! dword(mdoc, line, la, p, DELIM_OPEN, 0))
				return(0);
			continue;
		}

		if (NULL == head) {
			assert(NULL == body);
			if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
				return(0);
			head = mdoc->last;
		}

		/*
		 * `Eo' gobbles any data into the head, but most other
		 * macros just immediately close out and begin the body.
		 */

		if (NULL == body) {
			assert(head);
			/* No check whether it's a macro! */
			if (MDOC_Eo == tok)
				if ( ! dword(mdoc, line, la, p, DELIM_MAX, 0))
					return(0);

			if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos))
				return(0);
			if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
				return(0);
			body = mdoc->last;

			if (MDOC_Eo == tok)
				continue;
		}

		assert(NULL != head && NULL != body);

		ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);

		if (MDOC_MAX == ntok) {
			if ( ! dword(mdoc, line, la, p, DELIM_MAX,
			    MDOC_JOIN & mdoc_macros[tok].flags))
				return(0);
			continue;
		}

		if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
			return(0);
		break;
	}

	/* Clean-up to leave in a consistent state. */

	if (NULL == head)
		if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
			return(0);

	if (NULL == body) {
		if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos))
			return(0);
		if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
			return(0);
	}

	/* Standard appending of delimiters. */

	if ( ! nl)
		return(1);
	return(append_delims(mdoc, line, pos, buf));
}
static int
in_line(MACRO_PROT_ARGS)
{
	int		 la, scope, cnt, nc, nl;
	enum margverr	 av;
	enum mdoct	 ntok;
	enum margserr	 ac;
	enum mdelim	 d;
	struct mdoc_arg	*arg;
	char		*p;

	nl = MDOC_NEWLINE & mdoc->flags;

	/*
	 * Whether we allow ignored elements (those without content,
	 * usually because of reserved words) to squeak by.
	 */

	switch (tok) {
	case (MDOC_An):
		/* FALLTHROUGH */
	case (MDOC_Ar):
		/* FALLTHROUGH */
	case (MDOC_Fl):
		/* FALLTHROUGH */
	case (MDOC_Mt):
		/* FALLTHROUGH */
	case (MDOC_Nm):
		/* FALLTHROUGH */
	case (MDOC_Pa):
		nc = 1;
		break;
	default:
		nc = 0;
		break;
	}

	for (arg = NULL;; ) {
		la = *pos;
		av = mdoc_argv(mdoc, line, tok, &arg, pos, buf);

		if (ARGV_WORD == av) {
			*pos = la;
			break;
		} 
		if (ARGV_EOLN == av)
			break;
		if (ARGV_ARG == av)
			continue;

		mdoc_argv_free(arg);
		return(0);
	}

	for (cnt = scope = 0;; ) {
		la = *pos;
		ac = mdoc_args(mdoc, line, pos, buf, tok, &p);

		if (ARGS_ERROR == ac)
			return(0);
		if (ARGS_EOLN == ac)
			break;
		if (ARGS_PUNCT == ac)
			break;

		ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);

		/* 
		 * In this case, we've located a submacro and must
		 * execute it.  Close out scope, if open.  If no
		 * elements have been generated, either create one (nc)
		 * or raise a warning.
		 */

		if (MDOC_MAX != ntok) {
			if (scope && ! rew_elem(mdoc, tok))
				return(0);
			if (nc && 0 == cnt) {
				if ( ! mdoc_elem_alloc(mdoc, line,
						ppos, tok, arg))
					return(0);
				if ( ! rew_last(mdoc, mdoc->last))
					return(0);
			} else if ( ! nc && 0 == cnt) {
				mdoc_argv_free(arg);
				mdoc_pmsg(mdoc, line, ppos,
					MANDOCERR_MACROEMPTY);
			}

			if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
				return(0);
			if ( ! nl)
				return(1);
			return(append_delims(mdoc, line, pos, buf));
		} 

		/* 
		 * Non-quote-enclosed punctuation.  Set up our scope, if
		 * a word; rewind the scope, if a delimiter; then append
		 * the word. 
		 */

		d = ARGS_QWORD == ac ? DELIM_NONE : mdoc_isdelim(p);

		if (DELIM_NONE != d) {
			/*
			 * If we encounter closing punctuation, no word
			 * has been omitted, no scope is open, and we're
			 * allowed to have an empty element, then start
			 * a new scope.  `Ar', `Fl', and `Li', only do
			 * this once per invocation.  There may be more
			 * of these (all of them?).
			 */
			if (0 == cnt && (nc || MDOC_Li == tok) && 
					DELIM_CLOSE == d && ! scope) {
				if ( ! mdoc_elem_alloc(mdoc, line,
						ppos, tok, arg))
					return(0);
				if (MDOC_Ar == tok || MDOC_Li == tok || 
						MDOC_Fl == tok)
					cnt++;
				scope = 1;
			}
			/*
			 * Close out our scope, if one is open, before
			 * any punctuation.
			 */
			if (scope && ! rew_elem(mdoc, tok))
				return(0);
			scope = 0;
		} else if ( ! scope) {
			if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg))
				return(0);
			scope = 1;
		}

		if (DELIM_NONE == d)
			cnt++;

		if ( ! dword(mdoc, line, la, p, d,
		    MDOC_JOIN & mdoc_macros[tok].flags))
			return(0);

		/*
		 * `Fl' macros have their scope re-opened with each new
		 * word so that the `-' can be added to each one without
		 * having to parse out spaces.
		 */
		if (scope && MDOC_Fl == tok) {
			if ( ! rew_elem(mdoc, tok))
				return(0);
			scope = 0;
		}
	}

	if (scope && ! rew_elem(mdoc, tok))
		return(0);

	/*
	 * If no elements have been collected and we're allowed to have
	 * empties (nc), open a scope and close it out.  Otherwise,
	 * raise a warning.
	 */

	if (nc && 0 == cnt) {
		if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg))
			return(0);
		if ( ! rew_last(mdoc, mdoc->last))
			return(0);
	} else if ( ! nc && 0 == cnt) {
		mdoc_argv_free(arg);
		mdoc_pmsg(mdoc, line, ppos, MANDOCERR_MACROEMPTY);
	}

	if ( ! nl)
		return(1);
	return(append_delims(mdoc, line, pos, buf));
}
예제 #10
0
			dword In::Read32()
			{
				byte data[4];
				Read( data, 4 );
				return data[0] | uint(data[1]) << 8 | dword(data[2]) << 16 | dword(data[3]) << 24;
			}
/*
 * Close out block partial/full explicit.  
 */
static int
blk_exp_close(MACRO_PROT_ARGS)
{
	struct mdoc_node *body;		/* Our own body. */
	struct mdoc_node *later;	/* A sub-block starting later. */
	struct mdoc_node *n;		/* For searching backwards. */

	int	 	 j, lastarg, maxargs, flushed, nl;
	enum margserr	 ac;
	enum mdoct	 atok, ntok;
	char		*p;

	nl = MDOC_NEWLINE & mdoc->flags;

	switch (tok) {
	case (MDOC_Ec):
		maxargs = 1;
		break;
	case (MDOC_Ek):
		mdoc->flags &= ~MDOC_KEEP;
	default:
		maxargs = 0;
		break;
	}

	/*
	 * Search backwards for beginnings of blocks,
	 * both of our own and of pending sub-blocks.
	 */
	atok = rew_alt(tok);
	body = later = NULL;
	for (n = mdoc->last; n; n = n->parent) {
		if (MDOC_VALID & n->flags)
			continue;

		/* Remember the start of our own body. */
		if (MDOC_BODY == n->type && atok == n->tok) {
			if (ENDBODY_NOT == n->end)
				body = n;
			continue;
		}

		if (MDOC_BLOCK != n->type || MDOC_Nm == n->tok)
			continue;
		if (atok == n->tok) {
			assert(body);

			/*
			 * Found the start of our own block.
			 * When there is no pending sub block,
			 * just proceed to closing out.
			 */
			if (NULL == later)
				break;

			/* 
			 * When there is a pending sub block,
			 * postpone closing out the current block
			 * until the rew_sub() closing out the sub-block.
			 */
			make_pending(later, tok, mdoc, line, ppos);

			/*
			 * Mark the place where the formatting - but not
			 * the scope - of the current block ends.
			 */
			if ( ! mdoc_endbody_alloc(mdoc, line, ppos,
			    atok, body, ENDBODY_SPACE))
				return(0);
			break;
		}

		/*
		 * When finding an open sub block, remember the last
		 * open explicit block, or, in case there are only
		 * implicit ones, the first open implicit block.
		 */
		if (later &&
		    MDOC_EXPLICIT & mdoc_macros[later->tok].flags)
			continue;
		if (MDOC_It != n->tok)
			later = n;
	}

	if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) {
		/* FIXME: do this in validate */
		if (buf[*pos]) 
			mdoc_pmsg(mdoc, line, ppos, MANDOCERR_ARGSLOST);

		if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
			return(0);
		return(rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos));
	}

	if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
		return(0);

	if (NULL == later && maxargs > 0) 
		if ( ! mdoc_tail_alloc(mdoc, line, ppos, rew_alt(tok)))
			return(0);

	for (flushed = j = 0; ; j++) {
		lastarg = *pos;

		if (j == maxargs && ! flushed) {
			if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
				return(0);
			flushed = 1;
		}

		ac = mdoc_args(mdoc, line, pos, buf, tok, &p);

		if (ARGS_ERROR == ac)
			return(0);
		if (ARGS_PUNCT == ac)
			break;
		if (ARGS_EOLN == ac)
			break;

		ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);

		if (MDOC_MAX == ntok) {
			if ( ! dword(mdoc, line, lastarg, p, DELIM_MAX,
			    MDOC_JOIN & mdoc_macros[tok].flags))
				return(0);
			continue;
		}

		if ( ! flushed) {
			if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
				return(0);
			flushed = 1;
		}

		mdoc->flags &= ~MDOC_NEWLINE;

		if ( ! mdoc_macro(mdoc, ntok, line, lastarg, pos, buf))
			return(0);
		break;
	}

	if ( ! flushed && ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
		return(0);

	if ( ! nl)
		return(1);
	return(append_delims(mdoc, line, pos, buf));
}
static int
in_line_eoln(MACRO_PROT_ARGS)
{
	int		 la;
	enum margserr	 ac;
	enum margverr	 av;
	struct mdoc_arg	*arg;
	char		*p;
	enum mdoct	 ntok;

	assert( ! (MDOC_PARSED & mdoc_macros[tok].flags));

	if (tok == MDOC_Pp)
		rew_sub(MDOC_BLOCK, mdoc, MDOC_Nm, line, ppos);

	/* Parse macro arguments. */

	for (arg = NULL; ; ) {
		la = *pos;
		av = mdoc_argv(mdoc, line, tok, &arg, pos, buf);

		if (ARGV_WORD == av) {
			*pos = la;
			break;
		}
		if (ARGV_EOLN == av) 
			break;
		if (ARGV_ARG == av)
			continue;

		mdoc_argv_free(arg);
		return(0);
	}

	/* Open element scope. */

	if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg))
		return(0);

	/* Parse argument terms. */

	for (;;) {
		la = *pos;
		ac = mdoc_args(mdoc, line, pos, buf, tok, &p);

		if (ARGS_ERROR == ac)
			return(0);
		if (ARGS_EOLN == ac)
			break;

		ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);

		if (MDOC_MAX == ntok) {
			if ( ! dword(mdoc, line, la, p, DELIM_MAX,
			    MDOC_JOIN & mdoc_macros[tok].flags))
				return(0);
			continue;
		}

		if ( ! rew_elem(mdoc, tok))
			return(0);
		return(mdoc_macro(mdoc, ntok, line, la, pos, buf));
	}

	/* Close out (no delimiters). */

	return(rew_elem(mdoc, tok));
}
/* ARGSUSED */
static int
in_line_argn(MACRO_PROT_ARGS)
{
	int		 la, flushed, j, maxargs, nl;
	enum margserr	 ac;
	enum margverr	 av;
	struct mdoc_arg	*arg;
	char		*p;
	enum mdoct	 ntok;

	nl = MDOC_NEWLINE & mdoc->flags;

	/*
	 * A line macro that has a fixed number of arguments (maxargs).
	 * Only open the scope once the first non-leading-punctuation is
	 * found (unless MDOC_IGNDELIM is noted, like in `Pf'), then
	 * keep it open until the maximum number of arguments are
	 * exhausted.
	 */

	switch (tok) {
	case (MDOC_Ap):
		/* FALLTHROUGH */
	case (MDOC_No):
		/* FALLTHROUGH */
	case (MDOC_Ns):
		/* FALLTHROUGH */
	case (MDOC_Ux):
		maxargs = 0;
		break;
	case (MDOC_Bx):
		/* FALLTHROUGH */
	case (MDOC_Xr):
		maxargs = 2;
		break;
	default:
		maxargs = 1;
		break;
	}

	for (arg = NULL; ; ) {
		la = *pos;
		av = mdoc_argv(mdoc, line, tok, &arg, pos, buf);

		if (ARGV_WORD == av) {
			*pos = la;
			break;
		} 

		if (ARGV_EOLN == av)
			break;
		if (ARGV_ARG == av)
			continue;

		mdoc_argv_free(arg);
		return(0);
	}

	for (flushed = j = 0; ; ) {
		la = *pos;
		ac = mdoc_args(mdoc, line, pos, buf, tok, &p);

		if (ARGS_ERROR == ac)
			return(0);
		if (ARGS_PUNCT == ac)
			break;
		if (ARGS_EOLN == ac)
			break;

		if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) && 
				ARGS_QWORD != ac && 0 == j && 
				DELIM_OPEN == mdoc_isdelim(p)) {
			if ( ! dword(mdoc, line, la, p, DELIM_OPEN, 0))
				return(0);
			continue;
		} else if (0 == j)
		       if ( ! mdoc_elem_alloc(mdoc, line, la, tok, arg))
			       return(0);

		if (j == maxargs && ! flushed) {
			if ( ! rew_elem(mdoc, tok))
				return(0);
			flushed = 1;
		}

		ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);

		if (MDOC_MAX != ntok) {
			if ( ! flushed && ! rew_elem(mdoc, tok))
				return(0);
			flushed = 1;
			if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
				return(0);
			j++;
			break;
		}

		if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) &&
				ARGS_QWORD != ac &&
				! flushed &&
				DELIM_NONE != mdoc_isdelim(p)) {
			if ( ! rew_elem(mdoc, tok))
				return(0);
			flushed = 1;
		}

		if ( ! dword(mdoc, line, la, p, DELIM_MAX,
		    MDOC_JOIN & mdoc_macros[tok].flags))
			return(0);
		j++;
	}

	if (0 == j && ! mdoc_elem_alloc(mdoc, line, la, tok, arg))
	       return(0);

	/* Close out in a consistent state. */

	if ( ! flushed && ! rew_elem(mdoc, tok))
		return(0);
	if ( ! nl)
		return(1);
	return(append_delims(mdoc, line, pos, buf));
}
예제 #14
0
static void
blk_full(MACRO_PROT_ARGS)
{
	int		  la, nl, parsed;
	struct mdoc_arg	 *arg;
	struct mdoc_node *blk; /* Our own or a broken block. */
	struct mdoc_node *head; /* Our own head. */
	struct mdoc_node *body; /* Our own body. */
	struct mdoc_node *n;
	enum margserr	  ac, lac;
	char		 *p;

	nl = MDOC_NEWLINE & mdoc->flags;

	if (buf[*pos] == '\0' && (tok == MDOC_Sh || tok == MDOC_Ss)) {
		mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse,
		    line, ppos, mdoc_macronames[tok]);
		return;
	}

	if ( ! (mdoc_macros[tok].flags & MDOC_EXPLICIT)) {

		/* Here, tok is one of Sh Ss Nm Nd It. */

		blk = NULL;
		for (n = mdoc->last; n != NULL; n = n->parent) {
			if (n->flags & MDOC_ENDED) {
				if ( ! (n->flags & MDOC_VALID))
					n->flags |= MDOC_BROKEN;
				continue;
			}
			if (n->type != MDOC_BLOCK)
				continue;

			if (tok == MDOC_It && n->tok == MDOC_Bl) {
				if (blk != NULL) {
					mandoc_vmsg(MANDOCERR_BLK_BROKEN,
					    mdoc->parse, line, ppos,
					    "It breaks %s",
					    mdoc_macronames[blk->tok]);
					rew_pending(mdoc, blk);
				}
				break;
			}

			if (mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
				switch (tok) {
				case MDOC_Sh:
					/* FALLTHROUGH */
				case MDOC_Ss:
					mandoc_vmsg(MANDOCERR_BLK_BROKEN,
					    mdoc->parse, line, ppos,
					    "%s breaks %s",
					    mdoc_macronames[tok],
					    mdoc_macronames[n->tok]);
					rew_pending(mdoc, n);
					n = mdoc->last;
					continue;
				case MDOC_It:
					/* Delay in case it's astray. */
					blk = n;
					continue;
				default:
					break;
				}
				break;
			}

			/* Here, n is one of Sh Ss Nm Nd It. */

			if (tok != MDOC_Sh && (n->tok == MDOC_Sh ||
			    (tok != MDOC_Ss && (n->tok == MDOC_Ss ||
			     (tok != MDOC_It && n->tok == MDOC_It)))))
				break;

			/* Item breaking an explicit block. */

			if (blk != NULL) {
				mandoc_vmsg(MANDOCERR_BLK_BROKEN,
				    mdoc->parse, line, ppos,
				    "It breaks %s",
				    mdoc_macronames[blk->tok]);
				rew_pending(mdoc, blk);
				blk = NULL;
			}

			/* Close out prior implicit scopes. */

			rew_last(mdoc, n);
		}

		/* Skip items outside lists. */

		if (tok == MDOC_It && (n == NULL || n->tok != MDOC_Bl)) {
			mandoc_vmsg(MANDOCERR_IT_STRAY, mdoc->parse,
			    line, ppos, "It %s", buf + *pos);
			mdoc_elem_alloc(mdoc, line, ppos, MDOC_br, NULL);
			rew_elem(mdoc, MDOC_br);
			return;
		}
	}

	/*
	 * This routine accommodates implicitly- and explicitly-scoped
	 * macro openings.  Implicit ones first close out prior scope
	 * (seen above).  Delay opening the head until necessary to
	 * allow leading punctuation to print.  Special consideration
	 * for `It -column', which has phrase-part syntax instead of
	 * regular child nodes.
	 */

	mdoc_argv(mdoc, line, tok, &arg, pos, buf);
	blk = mdoc_block_alloc(mdoc, line, ppos, tok, arg);
	head = body = NULL;

	/*
	 * Exception: Heads of `It' macros in `-diag' lists are not
	 * parsed, even though `It' macros in general are parsed.
	 */

	parsed = tok != MDOC_It ||
	    mdoc->last->parent->tok != MDOC_Bl ||
	    mdoc->last->parent->norm->Bl.type != LIST_diag;

	/*
	 * The `Nd' macro has all arguments in its body: it's a hybrid
	 * of block partial-explicit and full-implicit.  Stupid.
	 */

	if (tok == MDOC_Nd) {
		head = mdoc_head_alloc(mdoc, line, ppos, tok);
		rew_last(mdoc, head);
		body = mdoc_body_alloc(mdoc, line, ppos, tok);
	}

	if (tok == MDOC_Bk)
		mdoc->flags |= MDOC_KEEP;

	ac = ARGS_PEND;
	for (;;) {
		la = *pos;
		lac = ac;
		ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
		if (ac == ARGS_EOLN) {
			if (lac != ARGS_PPHRASE && lac != ARGS_PHRASE)
				break;
			/*
			 * This is necessary: if the last token on a
			 * line is a `Ta' or tab, then we'll get
			 * ARGS_EOLN, so we must be smart enough to
			 * reopen our scope if the last parse was a
			 * phrase or partial phrase.
			 */
			if (body != NULL)
				rew_last(mdoc, body);
			body = mdoc_body_alloc(mdoc, line, ppos, tok);
			break;
		}
		if (tok == MDOC_Bd || tok == MDOC_Bk) {
			mandoc_vmsg(MANDOCERR_ARG_EXCESS,
			    mdoc->parse, line, la, "%s ... %s",
			    mdoc_macronames[tok], buf + la);
			break;
		}
		if (tok == MDOC_Rs) {
			mandoc_vmsg(MANDOCERR_ARG_SKIP, mdoc->parse,
			    line, la, "Rs %s", buf + la);
			break;
		}
		if (ac == ARGS_PUNCT)
			break;

		/*
		 * Emit leading punctuation (i.e., punctuation before
		 * the MDOC_HEAD) for non-phrase types.
		 */

		if (head == NULL &&
		    ac != ARGS_PEND &&
		    ac != ARGS_PHRASE &&
		    ac != ARGS_PPHRASE &&
		    ac != ARGS_QWORD &&
		    mdoc_isdelim(p) == DELIM_OPEN) {
			dword(mdoc, line, la, p, DELIM_OPEN, 0);
			continue;
		}

		/* Open a head if one hasn't been opened. */

		if (head == NULL)
			head = mdoc_head_alloc(mdoc, line, ppos, tok);

		if (ac == ARGS_PHRASE ||
		    ac == ARGS_PEND ||
		    ac == ARGS_PPHRASE) {

			/*
			 * If we haven't opened a body yet, rewind the
			 * head; if we have, rewind that instead.
			 */

			rew_last(mdoc, body == NULL ? head : body);
			body = mdoc_body_alloc(mdoc, line, ppos, tok);

			/*
			 * Process phrases: set whether we're in a
			 * partial-phrase (this effects line handling)
			 * then call down into the phrase parser.
			 */

			if (ac == ARGS_PPHRASE)
				mdoc->flags |= MDOC_PPHRASE;
			if (ac == ARGS_PEND && lac == ARGS_PPHRASE)
				mdoc->flags |= MDOC_PPHRASE;
			parse_rest(mdoc, MDOC_MAX, line, &la, buf);
			mdoc->flags &= ~MDOC_PPHRASE;
			continue;
		}

		if (macro_or_word(mdoc, tok, line, la, pos, buf, parsed))
			break;
	}

	if (blk->flags & MDOC_VALID)
		return;
	if (head == NULL)
		head = mdoc_head_alloc(mdoc, line, ppos, tok);
	if (nl && tok != MDOC_Bd && tok != MDOC_Bl && tok != MDOC_Rs)
		append_delims(mdoc, line, pos, buf);
	if (body != NULL)
		goto out;

	/*
	 * If there is an open (i.e., unvalidated) sub-block requiring
	 * explicit close-out, postpone switching the current block from
	 * head to body until the rew_pending() call closing out that
	 * sub-block.
	 */
	for (n = mdoc->last; n && n != head; n = n->parent) {
		if (n->flags & MDOC_ENDED) {
			if ( ! (n->flags & MDOC_VALID))
				n->flags |= MDOC_BROKEN;
			continue;
		}
		if (n->type == MDOC_BLOCK &&
		    mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
			n->flags = MDOC_BROKEN;
			head->flags = MDOC_ENDED;
		}
	}
	if (head->flags & MDOC_ENDED)
		return;

	/* Close out scopes to remain in a consistent state. */

	rew_last(mdoc, head);
	body = mdoc_body_alloc(mdoc, line, ppos, tok);
out:
	if (mdoc->flags & MDOC_FREECOL) {
		rew_last(mdoc, body);
		rew_last(mdoc, blk);
		mdoc->flags &= ~MDOC_FREECOL;
	}
}
예제 #15
0
/////////////////////////////////////////
// aes crypt
/////////////////////////////////////////
int process_aes_crypt(char *globalptr, char *data, int datalen, int usekey, int blkseq, int need_xor){	
	static u8 zero[32];
	static u32 ks[60];
	u32 blk[0x10];
	int j;
	int k;
	char *ptr;

	struct global_s *global;
	global=(struct global_s *)globalptr;


	memset(ks,0,sizeof(ks));

	// if no key, use zero
	memset(zero,0,sizeof(zero));

	// use real key
	if (usekey){
		memcpy(zero,global->AES_KEY,0x20);
	};

	// setup key
	aes_256_setkey (zero, ks);
	
	// for debug aes encoding
	// print key material
	if (0) {
		ptr=(char *)ks;
		show_memory(ptr, 60*4, "KeyMat");
	};

	// setup control block
	memset (blk, 0, 0x10);

	//if using key, control block have local and remote session id data.
	if (usekey){
		blk[0]=global->LOCAL_SESSION_ID * 0x10000 + global->REMOTE_SESSION_ID;
	};
	
	// need xor session id in control block
	if (need_xor){
		blk[0]=blk[0] ^ 0xFFFFFFFF;
	};

	blk[1]=blk[0];
	blk[3]=blk[3] + (blkseq * 0x10000);
	

	show_memory(data, datalen, "Before AES crypt");

	// process aes crypt
	for (j = 0; j+16 < datalen; j += 16){
		aes_256_encrypt (blk, blk+4, ks);
		dword(data+j+ 0) ^= bswap32(blk[4]);
		dword(data+j+ 4) ^= bswap32(blk[5]);
		dword(data+j+ 8) ^= bswap32(blk[6]);
		dword(data+j+12) ^= bswap32(blk[7]);
		blk[3]++;
	};
	if (j < datalen){
		aes_256_encrypt (blk, blk+4, ks);
		for (k = 0; j < datalen; j++, k++) data[j] ^= ((u8 *)(blk+4))[k^3];
	};

	show_memory(data, datalen, "After AES crypt");


	return 0;

};
예제 #16
0
static int
blk_part_imp(MACRO_PROT_ARGS)
{
	int		  la, nl;
	enum mdoct	  ntok;
	enum margserr	  ac;
	char		 *p;
	struct mdoc_node *blk; /* saved block context */
	struct mdoc_node *body; /* saved body context */
	struct mdoc_node *n;

	nl = MDOC_NEWLINE & mdoc->flags;

	/*
	 * A macro that spans to the end of the line.  This is generally
	 * (but not necessarily) called as the first macro.  The block
	 * has a head as the immediate child, which is always empty,
	 * followed by zero or more opening punctuation nodes, then the
	 * body (which may be empty, depending on the macro), then zero
	 * or more closing punctuation nodes.
	 */

	if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, NULL))
		return(0);

	blk = mdoc->last;

	if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
		return(0);
	if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos))
		return(0);

	/*
	 * Open the body scope "on-demand", that is, after we've
	 * processed all our the leading delimiters (open parenthesis,
	 * etc.).
	 */

	for (body = NULL; ; ) {
		la = *pos;
		ac = mdoc_args(mdoc, line, pos, buf, tok, &p);

		if (ARGS_ERROR == ac)
			return(0);
		if (ARGS_EOLN == ac)
			break;
		if (ARGS_PUNCT == ac)
			break;

		if (NULL == body && ARGS_QWORD != ac &&
				DELIM_OPEN == mdoc_isdelim(p)) {
			if ( ! dword(mdoc, line, la, p, DELIM_OPEN))
				return(0);
			continue;
		} 

		if (NULL == body) {
		       if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
			       return(0);
			body = mdoc->last;
		}

		ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p);

		if (MDOC_MAX == ntok) {
			if ( ! dword(mdoc, line, la, p, DELIM_MAX))
				return(0);
			continue;
		}

		if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
			return(0);
		break;
	}

	/* Clean-ups to leave in a consistent state. */

	if (NULL == body) {
		if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
			return(0);
		body = mdoc->last;
	}

	for (n = body->child; n && n->next; n = n->next)
		/* Do nothing. */ ;
	
	/* 
	 * End of sentence spacing: if the last node is a text node and
	 * has a trailing period, then mark it as being end-of-sentence.
	 */

	if (n && MDOC_TEXT == n->type && n->string)
		if (mandoc_eos(n->string, strlen(n->string), 1))
			n->flags |= MDOC_EOS;

	/* Up-propagate the end-of-space flag. */

	if (n && (MDOC_EOS & n->flags)) {
		body->flags |= MDOC_EOS;
		body->parent->flags |= MDOC_EOS;
	}

	/*
	 * If there is an open sub-block requiring explicit close-out,
	 * postpone closing out the current block
	 * until the rew_sub() call closing out the sub-block.
	 */
	for (n = mdoc->last; n && n != body && n != blk->parent;
			n = n->parent) {
		if (MDOC_BLOCK == n->type &&
		    MDOC_EXPLICIT & mdoc_macros[n->tok].flags &&
		    ! (MDOC_VALID & n->flags)) {
			make_pending(n, tok, mdoc, line, ppos);
			if ( ! mdoc_endbody_alloc(mdoc, line, ppos,
			    tok, body, ENDBODY_NOSPACE))
				return(0);
			return(1);
		}
	}

	/* 
	 * If we can't rewind to our body, then our scope has already
	 * been closed by another macro (like `Oc' closing `Op').  This
	 * is ugly behaviour nodding its head to OpenBSD's overwhelming
	 * crufty use of `Op' breakage.
	 */
	if (n != body)
		mandoc_vmsg(MANDOCERR_SCOPENEST, mdoc->parse, line, ppos, 
				"%s broken", mdoc_macronames[tok]);

	if (n && ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
		return(0);

	/* Standard appending of delimiters. */

	if (nl && ! append_delims(mdoc, line, pos, buf))
		return(0);

	/* Rewind scope, if applicable. */

	if (n && ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
		return(0);

	/* Move trailing .Ns out of scope. */

	for (n = body->child; n && n->next; n = n->next)
		/* Do nothing. */ ;
	if (n && MDOC_Ns == n->tok)
		mdoc_node_relink(mdoc, n);

	return(1);
}
static int
blk_full(MACRO_PROT_ARGS)
{
	int		  la, nl, nparsed;
	struct mdoc_arg	 *arg;
	struct mdoc_node *head; /* save of head macro */
	struct mdoc_node *body; /* save of body macro */
	struct mdoc_node *n;
	enum mdoc_type	  mtt;
	enum mdoct	  ntok;
	enum margserr	  ac, lac;
	enum margverr	  av;
	char		 *p;

	nl = MDOC_NEWLINE & mdoc->flags;

	/* Close out prior implicit scope. */

	if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) {
		if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
			return(0);
		if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
			return(0);
	}

	/*
	 * This routine accommodates implicitly- and explicitly-scoped
	 * macro openings.  Implicit ones first close out prior scope
	 * (seen above).  Delay opening the head until necessary to
	 * allow leading punctuation to print.  Special consideration
	 * for `It -column', which has phrase-part syntax instead of
	 * regular child nodes.
	 */

	for (arg = NULL;; ) {
		la = *pos;
		av = mdoc_argv(mdoc, line, tok, &arg, pos, buf);

		if (ARGV_WORD == av) {
			*pos = la;
			break;
		} 

		if (ARGV_EOLN == av)
			break;
		if (ARGV_ARG == av)
			continue;

		mdoc_argv_free(arg);
		return(0);
	}

	if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, arg))
		return(0);

	head = body = NULL;

	/*
	 * Exception: Heads of `It' macros in `-diag' lists are not
	 * parsed, even though `It' macros in general are parsed.
	 */
	nparsed = MDOC_It == tok &&
		MDOC_Bl == mdoc->last->parent->tok &&
		LIST_diag == mdoc->last->parent->norm->Bl.type;

	/*
	 * The `Nd' macro has all arguments in its body: it's a hybrid
	 * of block partial-explicit and full-implicit.  Stupid.
	 */

	if (MDOC_Nd == tok) {
		if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
			return(0);
		head = mdoc->last;
		if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos))
			return(0);
		if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
			return(0);
		body = mdoc->last;
	}

	if (MDOC_Bk == tok)
		mdoc->flags |= MDOC_KEEP;

	ac = ARGS_ERROR;

	for ( ; ; ) {
		la = *pos;
		/* Initialise last-phrase-type with ARGS_PEND. */
		lac = ARGS_ERROR == ac ? ARGS_PEND : ac;
		ac = mdoc_args(mdoc, line, pos, buf, tok, &p);

		if (ARGS_PUNCT == ac)
			break;

		if (ARGS_ERROR == ac)
			return(0);

		if (ARGS_EOLN == ac) {
			if (ARGS_PPHRASE != lac && ARGS_PHRASE != lac)
				break;
			/*
			 * This is necessary: if the last token on a
			 * line is a `Ta' or tab, then we'll get
			 * ARGS_EOLN, so we must be smart enough to
			 * reopen our scope if the last parse was a
			 * phrase or partial phrase.
			 */
			if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
				return(0);
			if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
				return(0);
			body = mdoc->last;
			break;
		}

		/* 
		 * Emit leading punctuation (i.e., punctuation before
		 * the MDOC_HEAD) for non-phrase types.
		 */

		if (NULL == head && 
				ARGS_PEND != ac &&
				ARGS_PHRASE != ac &&
				ARGS_PPHRASE != ac &&
				ARGS_QWORD != ac &&
				DELIM_OPEN == mdoc_isdelim(p)) {
			if ( ! dword(mdoc, line, la, p, DELIM_OPEN, 0))
				return(0);
			continue;
		}

		/* Open a head if one hasn't been opened. */

		if (NULL == head) {
			if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
				return(0);
			head = mdoc->last;
		}

		if (ARGS_PHRASE == ac || 
				ARGS_PEND == ac ||
				ARGS_PPHRASE == ac) {
			/*
			 * If we haven't opened a body yet, rewind the
			 * head; if we have, rewind that instead.
			 */

			mtt = body ? MDOC_BODY : MDOC_HEAD;
			if ( ! rew_sub(mtt, mdoc, tok, line, ppos))
				return(0);
			
			/* Then allocate our body context. */

			if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
				return(0);
			body = mdoc->last;

			/*
			 * Process phrases: set whether we're in a
			 * partial-phrase (this effects line handling)
			 * then call down into the phrase parser.
			 */

			if (ARGS_PPHRASE == ac)
				mdoc->flags |= MDOC_PPHRASE;
			if (ARGS_PEND == ac && ARGS_PPHRASE == lac)
				mdoc->flags |= MDOC_PPHRASE;

			if ( ! phrase(mdoc, line, la, buf))
				return(0);

			mdoc->flags &= ~MDOC_PPHRASE;
			continue;
		}

		ntok = nparsed || ARGS_QWORD == ac ? 
			MDOC_MAX : lookup(tok, p);

		if (MDOC_MAX == ntok) {
			if ( ! dword(mdoc, line, la, p, DELIM_MAX,
			    MDOC_JOIN & mdoc_macros[tok].flags))
				return(0);
			continue;
		}

		if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf))
			return(0);
		break;
	}

	if (NULL == head) {
		if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
			return(0);
		head = mdoc->last;
	}
	
	if (nl && ! append_delims(mdoc, line, pos, buf))
		return(0);

	/* If we've already opened our body, exit now. */

	if (NULL != body)
		goto out;

	/*
	 * If there is an open (i.e., unvalidated) sub-block requiring
	 * explicit close-out, postpone switching the current block from
	 * head to body until the rew_sub() call closing out that
	 * sub-block.
	 */
	for (n = mdoc->last; n && n != head; n = n->parent) {
		if (MDOC_BLOCK == n->type && 
				MDOC_EXPLICIT & mdoc_macros[n->tok].flags &&
				! (MDOC_VALID & n->flags)) {
			n->pending = head;
			return(1);
		}
	}

	/* Close out scopes to remain in a consistent state. */

	if ( ! rew_sub(MDOC_HEAD, mdoc, tok, line, ppos))
		return(0);
	if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
		return(0);

out:
	if ( ! (MDOC_FREECOL & mdoc->flags))
		return(1);

	if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
		return(0);
	if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
		return(0);

	mdoc->flags &= ~MDOC_FREECOL;
	return(1);
}