コード例 #1
0
static int chkwd(struct rnc_source *sp) {
  if(0<=CUR(sp).sym&&CUR(sp).sym<=SYM_IDENT) {
    return 1;
  } else {
    error(0,sp,RNC_ER_SEXP,sp->fn,CUR(sp).line,CUR(sp).col,"identifier or keyword",sym2str(CUR(sp).sym));
    return 0;
  }
}
コード例 #2
0
static int chkskip(struct rnc_source *sp,int symc,int syms) {
  if(CUR(sp).sym!=symc) {
    error(0,sp,RNC_ER_SEXP,sp->fn,CUR(sp).line,CUR(sp).col,sym2str(symc),sym2str(CUR(sp).sym));
    skipto(sp,syms);
    return 0;
  } else {
    return 1;
  }
}
コード例 #3
0
ファイル: cpptrad.c プロジェクト: Fokycnuk/gcc
/* Analyze and save the replacement text of a macro.  Returns true on
   success.  */
bool
_cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro)
{
  const uchar *cur;
  uchar *limit;
  cpp_context *context = pfile->context;

  /* The context has not been set up for command line defines, and CUR
     has not been updated for the macro name for in-file defines.  */
  pfile->out.cur = pfile->out.base;
  CUR (context) = pfile->buffer->cur;
  RLIMIT (context) = pfile->buffer->rlimit;
  check_output_buffer (pfile, RLIMIT (context) - CUR (context));

  /* Is this a function-like macro?  */
  if (* CUR (context) == '(')
    {
      bool ok = scan_parameters (pfile, macro);

      /* Remember the params so we can clear NODE_MACRO_ARG flags.  */
      macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);

      /* Setting macro to NULL indicates an error occurred, and
	 prevents unnecessary work in _cpp_scan_out_logical_line.  */
      if (!ok)
	macro = NULL;
      else
	{
	  BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
	  macro->fun_like = 1;
	}
    }

  /* Skip leading whitespace in the replacement text.  */
  pfile->buffer->cur
    = skip_whitespace (pfile, CUR (context),
		       CPP_OPTION (pfile, discard_comments_in_macro_exp));

  pfile->state.prevent_expansion++;
  _cpp_scan_out_logical_line (pfile, macro);
  pfile->state.prevent_expansion--;

  if (!macro)
    return false;

  /* Skip trailing white space.  */
  cur = pfile->out.base;
  limit = pfile->out.cur;
  while (limit > cur && is_space (limit[-1]))
    limit--;
  pfile->out.cur = limit;
  save_replacement_text (pfile, macro, 0);

  return true;
}
コード例 #4
0
static int nsuri(struct rnc_source *sp) {
  int uri=-1;
  switch(CUR(sp).sym) {
  case SYM_LITERAL: uri=rn_newString(CUR(sp).s); break;
  case SYM_INHERIT: uri=nss.tab[(sc_find(&nss,-1))][1]; break;
  default:
    error(0,sp,RNC_ER_SEXP,sp->fn,CUR(sp).line,CUR(sp).col,"literal or 'inherit'");	
    break;
  }
  getsym(sp);
  return uri;
}
コード例 #5
0
ファイル: cpptrad.c プロジェクト: Fokycnuk/gcc
/* Read and record the parameters, if any, of a function-like macro
   definition.  Destroys pfile->out.cur.

   Returns true on success, false on failure (syntax error or a
   duplicate parameter).  On success, CUR (pfile->context) is just
   past the closing parenthesis.  */
static bool
scan_parameters (cpp_reader *pfile, cpp_macro *macro)
{
  const uchar *cur = CUR (pfile->context) + 1;
  bool ok;

  for (;;)
    {
      cur = skip_whitespace (pfile, cur, true /* skip_comments */);

      if (is_idstart (*cur))
	{
	  ok = false;
	  if (_cpp_save_parameter (pfile, macro, lex_identifier (pfile, cur)))
	    break;
	  cur = skip_whitespace (pfile, CUR (pfile->context),
				 true /* skip_comments */);
	  if (*cur == ',')
	    {
	      cur++;
	      continue;
	    }
	  ok = (*cur == ')');
	  break;
	}

      ok = (*cur == ')' && macro->paramc == 0);
      break;
    }

  if (!ok)
    cpp_error (pfile, CPP_DL_ERROR, "syntax error in macro parameter list");

  CUR (pfile->context) = cur + (*cur == ')');

  return ok;
}
コード例 #6
0
ファイル: board.c プロジェクト: moon-watcher/Mega-Swirl
void drawBoard() {
	int x, y;
	char score_string[11];
	for (y = 0; y != BOARD_Y; y++) {
		for (x = 0; x != BOARD_X; x++) {
			if (board[y][x].id) {
				if (board[y][x].selected)
					VDP_fillTileMapRectInc(VDP_PLAN_A, TILE_ATTR_FULL(PAL2, PRIORITY_LOW, FALSE, FALSE, TILE_USERINDEX + (4 * board[y][x].id)), CUR(x), CUR(y), SWIRL_WIDTH, SWIRL_HEIGHT);
				else
					VDP_fillTileMapRectInc(VDP_PLAN_A, TILE_ATTR_FULL(PAL1, PRIORITY_LOW, FALSE, FALSE, TILE_USERINDEX + (4 * board[y][x].id)), CUR(x), CUR(y), SWIRL_WIDTH, SWIRL_HEIGHT);
			} else {
				VDP_clearTileMapRect(VDP_PLAN_A, CUR(x), CUR(y), SWIRL_WIDTH, SWIRL_HEIGHT);
			}
		}
	}
	VDP_drawText("Level 1", 31, 3);
	//VDP_drawText("Goals:", 32, 5);
	//VDP_drawText("0 / 0", 32, 6);
	VDP_drawText("Score:", 30, 26);
	intToStr((s32)score, score_string, 1);
	VDP_clearTileMapRect(VDP_PLAN_A, 30, 27, 10, 1);
	VDP_drawText(score_string, 30, 27);
	VDP_updateSprites();
}
コード例 #7
0
ファイル: cpptrad.c プロジェクト: Fokycnuk/gcc
/* Lexes and outputs an identifier starting at CUR, which is assumed
   to point to a valid first character of an identifier.  Returns
   the hashnode, and updates out.cur.  */
static cpp_hashnode *
lex_identifier (cpp_reader *pfile, const uchar *cur)
{
  size_t len;
  uchar *out = pfile->out.cur;
  cpp_hashnode *result;

  do
    *out++ = *cur++;
  while (is_numchar (*cur));

  CUR (pfile->context) = cur;
  len = out - pfile->out.cur;
  result = (cpp_hashnode *) ht_lookup (pfile->hash_table, pfile->out.cur,
				       len, HT_ALLOC);
  pfile->out.cur = out;
  return result;
}
コード例 #8
0
ファイル: ed.c プロジェクト: ISLEcode/kornshell
static void
substitute(int inglob)
{
	register Line_t*	a1;
	char*			s;
	char*			e;
	int			n;

	n = getnum();
	compile();
	splice();
	if (n = regsubcomp(&ed.re, input(0), submap, n, 0))
		regfatal(&ed.re, 2, n);
	else {
		if (!(ed.re.re_sub->re_flags & REG_SUB_FULL))
			ed.re.re_sub->re_flags |= REG_SUB_PRINT;
		if ((n = *input(ed.re.re_npat)) && n != '\r' && n != '\n')
			error(2, "extra characters at end of command");
		ed.print = ed.re.re_sub->re_flags;
	}
	eat();
	for (a1 = ed.addr1; a1 <= ed.addr2; a1++) {
		if (execute(a1, 0)) {
			if (!regsubexec(&ed.re, CUR(), elementsof(ed.match), ed.match)) {
				inglob = 1;
				s = ed.re.re_sub->re_buf;
				SET(s, ed.re.re_sub->re_len);
				if (e = strchr(s, '\n'))
					*e++ = 0;
				replace(a1, s);
				if (e) {
					ed.linebreak = e;
					a1 = append(getbreak, a1, &ed.addr2);
				}
			}
		}
	}
	if (!inglob)
		error(2, "global pattern not found");
	ed.dot = ed.addr2;
}
コード例 #9
0
ファイル: ed.c プロジェクト: ISLEcode/kornshell
static int
execute(Line_t* addr, regflags_t flags)
{
	register char*	s;
	register int	c;

	trap();
	if (!addr)
		s = CUR();
	else if (addr == ed.zero)
		return 0;
	else {
		s = lineget(addr->offset);
		SET(s, 0);
	}
	if (c = regexec(&ed.re, s, elementsof(ed.match), ed.match, ed.reflags|flags)) {
		if (c != REG_NOMATCH)
			regfatal(&ed.re, 2, c);
		return 0;
	}
	return 1;
}
コード例 #10
0
static void skipAnnotationContent(struct rnc_source *sp) {
 /* syntax of annotations is not checked; it is not a purpose of this parser to handle them anyway */
  if(CUR(sp).sym==SYM_LSQU) {
    advance(sp);
    for(;;) {
      switch(CUR(sp).sym) {
      case SYM_RSQU: advance(sp); return;
      case SYM_LSQU: skipAnnotationContent(sp); break;
      case SYM_IDENT: case SYM_QNAME: /* keywords are in the default: clause */
      case SYM_ASGN:
      case SYM_LITERAL: case SYM_CONCAT: advance(sp); break;
      default:
	if(0<=CUR(sp).sym&&CUR(sp).sym<NKWD) { /* keywords */
	  advance(sp);
	  break;
	} else {
	  error(0,sp,RNC_ER_SILL,sp->fn,CUR(sp).line,CUR(sp).col,sym2str(CUR(sp).sym));
	  return;
	}
      }
    }
  }
}
コード例 #11
0
ファイル: cpptrad.c プロジェクト: Fokycnuk/gcc
/* Copies the next logical line in the current buffer (starting at
   buffer->cur) to the output buffer.  The output is guaranteed to
   terminate with a NUL character.  buffer->cur is updated.

   If MACRO is non-NULL, then we are scanning the replacement list of
   MACRO, and we call save_replacement_text() every time we meet an
   argument.  */
bool
_cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro)
{
  bool result = true;
  cpp_context *context;
  const uchar *cur;
  uchar *out;
  struct fun_macro fmacro;
  unsigned int c, paren_depth = 0, quote;
  enum ls lex_state = ls_none;
  bool header_ok;
  const uchar *start_of_input_line;

  fmacro.buff = NULL;

  quote = 0;
  header_ok = pfile->state.angled_headers;
  CUR (pfile->context) = pfile->buffer->cur;
  RLIMIT (pfile->context) = pfile->buffer->rlimit;
  pfile->out.cur = pfile->out.base;
  pfile->out.first_line = pfile->line;
  /* start_of_input_line is needed to make sure that directives really,
     really start at the first character of the line.  */
  start_of_input_line = pfile->buffer->cur;
 new_context:
  context = pfile->context;
  cur = CUR (context);
  check_output_buffer (pfile, RLIMIT (context) - cur);
  out = pfile->out.cur;

  for (;;)
    {
      if (!context->prev
	  && cur >= pfile->buffer->notes[pfile->buffer->cur_note].pos)
	{
	  pfile->buffer->cur = cur;
	  _cpp_process_line_notes (pfile, false);
	}
      c = *cur++;
      *out++ = c;

      /* Whitespace should "continue" out of the switch,
	 non-whitespace should "break" out of it.  */
      switch (c)
	{
	case ' ':
	case '\t':
	case '\f':
	case '\v':
	case '\0':
	  continue;

	case '\n':
	  /* If this is a macro's expansion, pop it.  */
	  if (context->prev)
	    {
	      pfile->out.cur = out - 1;
	      _cpp_pop_context (pfile);
	      goto new_context;
	    }

	  /* Omit the newline from the output buffer.  */
	  pfile->out.cur = out - 1;
	  pfile->buffer->cur = cur;
	  pfile->buffer->need_line = true;
	  pfile->line++;

	  if ((lex_state == ls_fun_open || lex_state == ls_fun_close)
	      && !pfile->state.in_directive
	      && _cpp_get_fresh_line (pfile))
	    {
	      /* Newlines in arguments become a space, but we don't
		 clear any in-progress quote.  */
	      if (lex_state == ls_fun_close)
		out[-1] = ' ';
	      cur = pfile->buffer->cur;
	      continue;
	    }
	  goto done;

	case '<':
	  if (header_ok)
	    quote = '>';
	  break;
	case '>':
	  if (c == quote)
	    quote = 0;
	  break;

	case '"':
	case '\'':
	  if (c == quote)
	    quote = 0;
	  else if (!quote)
	    quote = c;
	  break;

	case '\\':
	  /* Skip escaped quotes here, it's easier than above.  */
	  if (*cur == '\\' || *cur == '"' || *cur == '\'')
	    *out++ = *cur++;
	  break;

	case '/':
	  /* Traditional CPP does not recognize comments within
	     literals.  */
	  if (!quote && *cur == '*')
	    {
	      pfile->out.cur = out;
	      cur = copy_comment (pfile, cur, macro != 0);
	      out = pfile->out.cur;
	      continue;
	    }
	  break;

	case '_':
	case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
	case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
	case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
	case 's': case 't': case 'u': case 'v': case 'w': case 'x':
	case 'y': case 'z':
	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
	case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
	case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
	case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
	case 'Y': case 'Z':
	  if (!pfile->state.skipping && (quote == 0 || macro))
	    {
	      cpp_hashnode *node;
	      uchar *out_start = out - 1;

	      pfile->out.cur = out_start;
	      node = lex_identifier (pfile, cur - 1);
	      out = pfile->out.cur;
	      cur = CUR (context);

	      if (node->type == NT_MACRO
		  /* Should we expand for ls_answer?  */
		  && (lex_state == ls_none || lex_state == ls_fun_open)
		  && !pfile->state.prevent_expansion)
		{
		  /* Macros invalidate MI optimization.  */
		  pfile->mi_valid = false;
		  if (! (node->flags & NODE_BUILTIN)
		      && node->value.macro->fun_like)
		    {
		      maybe_start_funlike (pfile, node, out_start, &fmacro);
		      lex_state = ls_fun_open;
		      fmacro.line = pfile->line;
		      continue;
		    }
		  else if (!recursive_macro (pfile, node))
		    {
		      /* Remove the object-like macro's name from the
			 output, and push its replacement text.  */
		      pfile->out.cur = out_start;
		      push_replacement_text (pfile, node);
		      lex_state = ls_none;
		      goto new_context;
		    }
		}
	      else if (macro && (node->flags & NODE_MACRO_ARG) != 0)
		{
		  /* Found a parameter in the replacement text of a
		     #define.  Remove its name from the output.  */
		  pfile->out.cur = out_start;
		  save_replacement_text (pfile, macro, node->value.arg_index);
		  out = pfile->out.base;
		}
	      else if (lex_state == ls_hash)
		{
		  lex_state = ls_predicate;
		  continue;
		}
	      else if (pfile->state.in_expression
		       && node == pfile->spec_nodes.n_defined)
		{
		  lex_state = ls_defined;
		  continue;
		}
	    }
	  break;

	case '(':
	  if (quote == 0)
	    {
	      paren_depth++;
	      if (lex_state == ls_fun_open)
		{
		  if (recursive_macro (pfile, fmacro.node))
		    lex_state = ls_none;
		  else
		    {
		      lex_state = ls_fun_close;
		      paren_depth = 1;
		      out = pfile->out.base + fmacro.offset;
		      fmacro.args[0] = fmacro.offset;
		    }
		}
	      else if (lex_state == ls_predicate)
		lex_state = ls_answer;
	      else if (lex_state == ls_defined)
		lex_state = ls_defined_close;
	    }
	  break;

	case ',':
	  if (quote == 0 && lex_state == ls_fun_close && paren_depth == 1)
	    save_argument (&fmacro, out - pfile->out.base);
	  break;

	case ')':
	  if (quote == 0)
	    {
	      paren_depth--;
	      if (lex_state == ls_fun_close && paren_depth == 0)
		{
		  cpp_macro *m = fmacro.node->value.macro;

		  m->used = 1;
		  lex_state = ls_none;
		  save_argument (&fmacro, out - pfile->out.base);

		  /* A single zero-length argument is no argument.  */
		  if (fmacro.argc == 1
		      && m->paramc == 0
		      && out == pfile->out.base + fmacro.offset + 1)
		    fmacro.argc = 0;

		  if (_cpp_arguments_ok (pfile, m, fmacro.node, fmacro.argc))
		    {
		      /* Remove the macro's invocation from the
			 output, and push its replacement text.  */
		      pfile->out.cur = (pfile->out.base
					     + fmacro.offset);
		      CUR (context) = cur;
		      replace_args_and_push (pfile, &fmacro);
		      goto new_context;
		    }
		}
	      else if (lex_state == ls_answer || lex_state == ls_defined_close)
		lex_state = ls_none;
	    }
	  break;

	case '#':
	  if (cur - 1 == start_of_input_line
	      /* A '#' from a macro doesn't start a directive.  */
	      && !pfile->context->prev
	      && !pfile->state.in_directive)
	    {
	      /* A directive.  With the way _cpp_handle_directive
		 currently works, we only want to call it if either we
		 know the directive is OK, or we want it to fail and
		 be removed from the output.  If we want it to be
		 passed through (the assembler case) then we must not
		 call _cpp_handle_directive.  */
	      pfile->out.cur = out;
	      cur = skip_whitespace (pfile, cur, true /* skip_comments */);
	      out = pfile->out.cur;

	      if (*cur == '\n')
		{
		  /* Null directive.  Ignore it and don't invalidate
		     the MI optimization.  */
		  pfile->buffer->need_line = true;
		  pfile->line++;
		  result = false;
		  goto done;
		}
	      else
		{
		  bool do_it = false;

		  if (is_numstart (*cur)
		      && CPP_OPTION (pfile, lang) != CLK_ASM)
		    do_it = true;
		  else if (is_idstart (*cur))
		    /* Check whether we know this directive, but don't
		       advance.  */
		    do_it = lex_identifier (pfile, cur)->is_directive;

		  if (do_it || CPP_OPTION (pfile, lang) != CLK_ASM)
		    {
		      /* This is a kludge.  We want to have the ISO
			 preprocessor lex the next token.  */
		      pfile->buffer->cur = cur;
		      _cpp_handle_directive (pfile, false /* indented */);
		      result = false;
		      goto done;
		    }
		}
	    }

	  if (pfile->state.in_expression)
	    {
	      lex_state = ls_hash;
	      continue;
	    }
	  break;

	default:
	  break;
	}

      /* Non-whitespace disables MI optimization and stops treating
	 '<' as a quote in #include.  */
      header_ok = false;
      if (!pfile->state.in_directive)
	pfile->mi_valid = false;

      if (lex_state == ls_none)
	continue;

      /* Some of these transitions of state are syntax errors.  The
	 ISO preprocessor will issue errors later.  */
      if (lex_state == ls_fun_open)
	/* Missing '('.  */
	lex_state = ls_none;
      else if (lex_state == ls_hash
	       || lex_state == ls_predicate
	       || lex_state == ls_defined)
	lex_state = ls_none;

      /* ls_answer and ls_defined_close keep going until ')'.  */
    }

 done:
  if (fmacro.buff)
    _cpp_release_buff (pfile, fmacro.buff);

  if (lex_state == ls_fun_close)
    cpp_error_with_line (pfile, CPP_DL_ERROR, fmacro.line, 0,
			 "unterminated argument list invoking macro \"%s\"",
			 NODE_NAME (fmacro.node));
  return result;
}
コード例 #12
0
static int chksym(struct rnc_source *sp,int sym) {
  return chkskip(sp,sym,CUR(sp).sym);
}
コード例 #13
0
/* parser helpers: weak symbols, syntax errors */
static void skipto(struct rnc_source *sp,int sym) {
  while(CUR(sp).sym!=sym&&CUR(sp).sym!=SYM_EOF) getsym(sp);
}
コード例 #14
0
/* advance, join literal fragments and skip annotations and documentation comments */
static void getsym(struct rnc_source *sp) {
  advance(sp);
  for(;;) {
    switch(CUR(sp).sym) {
    case SYM_DOCUMENTATION:
      advance(sp);
      continue;
    case SYM_FOLLOW_ANNOTATION: advance(sp);
      if(CUR(sp).sym<0||CUR(sp).sym>SYM_QNAME) {
	error(0,sp,RNC_ER_SEXP,sp->fn,CUR(sp).line,CUR(sp).col,"identifier, prefixed name or keyword",sym2str(CUR(sp).sym));
	while(CUR(sp).sym!=SYM_LSQU&&CUR(sp).sym!=SYM_EOF) advance(sp);
      } else {
	advance(sp);
	if(CUR(sp).sym!=SYM_LSQU) error(0,sp,RNC_ER_SEXP,sp->fn,CUR(sp).line,CUR(sp).col,sym2str(SYM_LSQU),sym2str(CUR(sp).sym));
      }
    case SYM_LSQU:
      skipAnnotationContent(sp);
      continue;
    case SYM_LITERAL:
     /* alternatively, either a non-terminal, or a separate filter;
      - one more filtering layer is not worth the effort,
      - the non-terminal would later need extra buffer for concatenated strings.
      Since the concatenation is only applied to constants anyway, merging them
      into a single terminal looks appropriate.
      */
      if(NXT(sp).sym==SYM_CONCAT) {
	sp->cur=!sp->cur; advance(sp);
	if(NXT(sp).sym!=SYM_LITERAL) {
	  error(0,sp,RNC_ER_SEXP,sp->fn,NXT(sp).line,NXT(sp).col,sym2str(SYM_LITERAL),sym2str(NXT(sp).sym));
	  break;
	}
	{ int newslen=strlen(CUR(sp).s)+strlen(NXT(sp).s)+1;
	  if(newslen>CUR(sp).slen) realloc_s(&CUR(sp),newslen);
	}
	strcat(CUR(sp).s,NXT(sp).s);
	sp->cur=!sp->cur; advance(sp);
	continue;
      }
      break;
    }
    return;
  }
}
コード例 #15
0
/* newlines are replaced with \0; \x{<hex>+} are unescaped.
the result is in sp->v
*/
static void getv(struct rnc_source *sp) {
  if(sp->nx>0) {
    sp->v='x'; --sp->nx;
  } else if(sp->nx==0) {
    sp->v=sp->w;
    sp->nx=-1;
  } else {
    getu(sp);
    switch(sp->u) {
    case '\r': case '\n': sp->v=0; break;
    case '\\':
      getu(sp);
      if(sp->u=='x') {
	sp->nx=0;
	do {
	  ++sp->nx;
	  getu(sp);
	} while(sp->u=='x');
	if(sp->u=='{') {
	  sp->nx=-1;
	  sp->v=0;
	  for(;;) {
	    getu(sp);
	    if(sp->u=='}') goto END_OF_HEX_DIGITS;
	    sp->v<<=4;
	    switch(sp->u) {
	    case '0': break;
	    case '1': sp->v+=1; break;
	    case '2': sp->v+=2; break;
	    case '3': sp->v+=3; break;
	    case '4': sp->v+=4; break;
	    case '5': sp->v+=5; break;
	    case '6': sp->v+=6; break;
	    case '7': sp->v+=7; break;
	    case '8': sp->v+=8; break;
	    case '9': sp->v+=9; break;
	    case 'A': case 'a': sp->v+=10; break;
	    case 'B': case 'b': sp->v+=11; break;
	    case 'C': case 'c': sp->v+=12; break;
	    case 'D': case 'd': sp->v+=13; break;
	    case 'E': case 'e': sp->v+=14; break;
	    case 'F': case 'f': sp->v+=15; break;
	    default:
	      error(0,sp,RNC_ER_XESC,sp->fn,CUR(sp).line,CUR(sp).col);
	      goto END_OF_HEX_DIGITS;
	    }
	  } END_OF_HEX_DIGITS:;
	} else {
	  sp->v='\\'; sp->w=sp->u;
	}
      } else {
	sp->nx=0;
	sp->v='\\'; sp->w=sp->u;
      }
      break;
    default:
      sp->v=sp->u;
      break;
    }
  }
}