예제 #1
0
파일: regcomp.c 프로젝트: OPSF/uClinux
/*
 - p_b_term - parse one term of a bracketed character list
 */
static void
p_b_term(struct parse *p, cset *cs)
{
	char c;
	char start, finish;
	int i;

	/* classify what we've got */
	switch ((MORE()) ? PEEK() : '\0') {
	case '[':
		c = (MORE2()) ? PEEK2() : '\0';
		break;
	case '-':
		SETERROR(REG_ERANGE);
		return;			/* NOTE RETURN */
		break;
	default:
		c = '\0';
		break;
	}

	switch (c) {
	case ':':		/* character class */
		NEXT2();
		REQUIRE(MORE(), REG_EBRACK);
		c = PEEK();
		REQUIRE(c != '-' && c != ']', REG_ECTYPE);
		p_b_cclass(p, cs);
		REQUIRE(MORE(), REG_EBRACK);
		REQUIRE(EATTWO(':', ']'), REG_ECTYPE);
		break;
	case '=':		/* equivalence class */
		NEXT2();
		REQUIRE(MORE(), REG_EBRACK);
		c = PEEK();
		REQUIRE(c != '-' && c != ']', REG_ECOLLATE);
		p_b_eclass(p, cs);
		REQUIRE(MORE(), REG_EBRACK);
		REQUIRE(EATTWO('=', ']'), REG_ECOLLATE);
		break;
	default:		/* symbol, ordinary character, or range */
/* xxx revision needed for multichar stuff */
		start = p_b_symbol(p);
		if (SEE('-') && MORE2() && PEEK2() != ']') {
			/* range */
			NEXT();
			if (EAT('-'))
				finish = '-';
			else
				finish = p_b_symbol(p);
		} else
			finish = start;
/* xxx what about signed chars here... */
		REQUIRE(start <= finish, REG_ERANGE);
		for (i = start; i <= finish; i++)
			CHadd(cs, i);
		break;
	}
}
예제 #2
0
파일: conio.c 프로젝트: Arkuda/rpc8e-cc65
/* Output one character at the current cursor position */
void __fastcall__ cputc( char c )
{
	unsigned char x;
	unsigned char y;
	unsigned char i;
	
	// FIXME: Call MMU to the make sure screen is the enabled device......
	
	// Set or unset reverse video bit, if needed.
	if( __conio_reverseVideo )
		c += 128;
	
	// Read the current cursor position.
	x = PEEK( 0x301 );
	y = PEEK( 0x302 );
	
	// Set the display memory window to the line the cursor is on.
	POKE( 0x300, y );

	// Write the character the the column the cursor is in, within the display
	//	memory window.
	if ( c != '\n')
		POKE( 0x310+x, c );
	
	// Advance the cursor, moving to the next line and scrolling the screen
	//	if needed.
	++x;
	if( x > 79 || c == '\n' )
	{
		x = 0;
		if( y >= 49 )
		{
			// Scroll...
			blit_shift(0,1,0,0,80,49);

			for (i = 0; i<80; i++)
				POKE( 0x310 + i, 0x20 );
				
		}
		else
		{	// no need to set if Y was 49. 
			++y;
			POKE( 0x302, y );
			POKE( 0x300, y );	// set row too
		}
	}
	
	// Set the cursor to the new position.
	POKE( 0x301, x );
}
예제 #3
0
파일: socket.c 프로젝트: Ugnis/Far-NetBox
/* readline()s mingled with other operations: buffering tests. */
static int line_mingle(void)
{
    ne_socket *sock;
    DECL(oneline, "alpha\nbeta\ndelta\ngamma\n");

    CALL(begin(&sock, serve_sstring, &oneline));
    
    READ("a"); LINE("lpha\n");
    READ("beta"); LINE("\n");
    PEEK("d"); PEEK("delt");
    LINE("delta\n");
    READ("gam"); LINE("ma\n");
    
    return finish(sock, 1);
}
예제 #4
0
파일: regcomp.c 프로젝트: OPSF/uClinux
/*
 - p_b_cclass - parse a character-class name and deal with it
 */
static void
p_b_cclass(struct parse *p, cset *cs)
{
	char *sp = p->next;
	struct cclass *cp;
	size_t len;
	const char *u;
	char c;

	while (MORE() && isalpha(PEEK()))
		NEXT();
	len = p->next - sp;
	for (cp = cclasses; cp->name != NULL; cp++)
		if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
			break;
	if (cp->name == NULL) {
		/* oops, didn't find it */
		SETERROR(REG_ECTYPE);
		return;
	}

	u = cp->chars;
	while ((c = *u++) != '\0')
		CHadd(cs, c);
	for (u = cp->multis; *u != '\0'; u += strlen(u) + 1)
		MCadd(p, cs, u);
}
예제 #5
0
파일: socket.c 프로젝트: Ugnis/Far-NetBox
static int blocking(void)
{
    ne_socket *sock;
    int ret;
    
    CALL(begin(&sock, echo_server, NULL));
    CALL(expect_block_timeout(sock, 1, "with non-zero timeout"));
         
    WRITEL("Hello, world.\n");
    
    /* poll for data */
    do {
        ret = ne_sock_block(sock, 1);
    } while (ret == NE_SOCK_TIMEOUT);

    ONV(ret != 0, ("ne_sock_block never got data: %d", ret));

    PEEK("Hello,");
    ret = ne_sock_block(sock, 1);
    ONV(ret != 0, ("ne_sock_block failed after peek: %d", ret));

    LINE("Hello, world.\n");

    return finish(sock, 0);
}
예제 #6
0
파일: ext.c 프로젝트: infoburp/gawk
NODE *
get_argument(int i)
{
	NODE *t;
	int arg_count, pcount;
	INSTRUCTION *pc;
	
	pc = TOP()->code_ptr;		/* Op_ext_builtin instruction */
	pcount = (pc + 1)->expr_count;	/* max # of arguments */
	arg_count = pc->expr_count;	/* # of arguments supplied */

	if (i < 0 || i >= pcount || i >= arg_count)
		return NULL;

	t = PEEK(arg_count - i);
	if (t->type == Node_param_list)
		t = GET_PARAM(t->param_cnt);

	if (t->type == Node_array_ref) {
		if (t->orig_array->type == Node_var) {
			/* already a scalar, can no longer use it as array */ 
			t->type = Node_var;
			t->var_value = Nnull_string;
			return t;
		}
		return t->orig_array; 	/* Node_var_new or Node_var_array */
	}
	if (t->type == Node_var)	/* See Case Node_var in setup_frame(), eval.c */
		return Nnull_string;
	/* Node_var_new, Node_var_array or Node_val */
	return t;
}
예제 #7
0
파일: summary.c 프로젝트: Kweepa/vicdoom
void __fastcall__ summaryScreen(void)
{
  // display kills, items, secrets, time
  // like this
  // MAP NAME
  // FINISHED
  // KILLS %
  // ITEMS %
  // SECRET %
  // TIME 00:00
  // PAR 00:00
  
  char kills = p_enemy_getKillPercentage();
  char items = getItemPercentage();
  char secret = (100*getNumVisitedSecrets())/getNumSecrets();
  int time = getMapTime();
  int par = getParTime();

  // clear screen
  clearScreen();
  
  textcolor(1);
  printCentered(caLevelNames[level-1], 1);
  textcolor(2);
  printCentered("finished", 2);
  cputsxy(4, 5, "kills");
  cputsxy(4, 7, "items");
  cputsxy(4, 9, "secret");
  cputsxy(4, 12, "time");
  cputsxy(4, 14, "par");

  setTextColor(2);
  POKE(198, 0);
  rollInPercentage(kills, 0x1000+22*5+14);
  waitASecond();
  rollInPercentage(items, 0x1000+22*7+14);
  waitASecond();
  rollInPercentage(secret, 0x1000+22*9+14);
  waitASecond();
  if (time > 10*60-1)
  {
    cputsxy(13,12,"sucks");
    playSound(SOUND_PISTOL);
  }
  else
  {
    rollInTime(time, 0x1000+22*12+13);
  }
  waitASecond();
  rollInTime(par, 0x1000+22*14+13);
  waitASecond();
  printCentered("press a key", 20);
  POKE(198, 0);
  while (PEEK(198) == 0) ;

  // clear screen
  clearScreen();
}
예제 #8
0
파일: conio.c 프로젝트: Arkuda/rpc8e-cc65
/* Return a character from the keyboard. If there is no character available,
 * the function waits until the user does press a key. If cursor is set to
 * 1 (see below), a blinking cursor is displayed while waiting.
 */
char cgetc( void )
{
        unsigned char key;
	unsigned char pos;

	while (!kbhit())
	{
		// WAI
	}

	key = PEEK(0x306);
	pos = PEEK(0x304)+1;
	if (pos > 0x10)
		pos = 0;
	POKE(0x304,pos);
	
	return key;
}
예제 #9
0
파일: conio.c 프로젝트: Arkuda/rpc8e-cc65
/* If onoff is 1, a cursor is displayed when waiting for keyboard input. If
 * onoff is 0, the cursor is hidden when waiting for keyboard input. The
 * function returns the old cursor setting.
 */
unsigned char __fastcall__ cursor( unsigned char onoff )
{
	// FIXME: Call MMU to the make sure screen is the enabled device......
	unsigned char oldStatus = PEEK( 0x303 );
	if( onoff )
		POKE( 0x303, 2 );
	else
		POKE( 0x303, 0 );
	return oldStatus;
}
예제 #10
0
파일: summary.c 프로젝트: Kweepa/vicdoom
void __fastcall__ waitASecond(void)
{
  char i = 60;
  do
  {
	  if (PEEK(198) == 0)
	  {
		  waitForRaster(1);
	  }
  	--i;
  }
  while (i > 0);
}
예제 #11
0
파일: regcomp.c 프로젝트: OPSF/uClinux
/*
 - p_count - parse a repetition count
 */
static int			/* the value */
p_count(struct parse *p)
{
	int count = 0;
	int ndigits = 0;

	while (MORE() && isdigit((uch)PEEK()) && count <= DUPMAX) {
		count = count*10 + (GETNEXT() - '0');
		ndigits++;
	}

	REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR);
	return(count);
}
예제 #12
0
/*
 - p_ere - ERE parser top level, concatenation and alternation
 == static void p_ere(struct parse *p, int stop, size_t reclimit);
 */
static void
p_ere(
    struct parse *p,
    int stop,			/* character this ERE should end at */
    size_t reclimit)
{
	char c;
	sopno prevback = 0;	/* pacify gcc */
	sopno prevfwd = 0; 	/* pacify gcc */
	sopno conc;
	int first = 1;		/* is this the first alternative? */

	_DIAGASSERT(p != NULL);

	if (reclimit++ > RECLIMIT || p->error == REG_ESPACE) {
		p->error = REG_ESPACE;
		return;
	}

	for (;;) {
		/* do a bunch of concatenated expressions */
		conc = HERE();
		while (MORE() && (c = PEEK()) != '|' && c != stop)
			p_ere_exp(p, reclimit);
		REQUIRE(HERE() != conc, REG_EMPTY);	/* require nonempty */

		if (!EAT('|'))
			break;		/* NOTE BREAK OUT */

		if (first) {
			INSERT(OCH_, conc);	/* offset is wrong */
			prevfwd = conc;
			prevback = conc;
			first = 0;
		}
		ASTERN(OOR1, prevback);
		prevback = THERE();
		AHEAD(prevfwd);			/* fix previous offset */
		prevfwd = HERE();
		EMIT(OOR2, 0);			/* offset is very wrong */
	}

	if (!first) {		/* tail-end fixups */
		AHEAD(prevfwd);
		ASTERN(O_CH, prevback);
	}

	assert(!MORE() || SEE(stop));
}
예제 #13
0
/* Mark resource as initialized */
static void
init_usage( ldap_debug_usage_info_t *usage, const char *msg )
{
	if( !options_done )
		get_options();
	if( !nomem ) {
		if( !noreinit ) {
			MEMERROR_IF( debug_already_initialized( usage ), msg, {
				/* Provoke malloc debuggers */
				unsigned char *dummy = DUMMY_ADDR( usage );
				PEEK( dummy );
				free( dummy );
				free( dummy );
			} );
		}
예제 #14
0
/*
 * create a bunch of random live cells in the requested
 * graphics page
 */
void randomize(uint16_t baseaddr[], uint16_t count)
{
    uint16_t r;
    uint8_t  row, col;
    static uint8_t resetcount = 0;

    // The Apple zero page has some semi-random garbage
    // suitable for seeding our PRNG
    uint16_t seed = PEEK(RSEED1) + PEEK(RSEED2) * 256;
    ++resetcount;
    srand(resetcount + seed);
    lo_clear(gr_page[0], TGI_COLOR_BLACK);

    while (count--) {
        r = rand();
        // use the high bit to determine which nibble we turn on
        row = r & ROWRANDMASK;
        col = (r & COLRANDMASK) >> 8;
        row %= MAXROWCNT;
        col %= MAXCOLCNT;
        //printf("turning on %d,%d with %04x\n", row, col, r);
        lo_plot(baseaddr, row, col, 0xf);
    }
}
예제 #15
0
파일: socket.c 프로젝트: Ugnis/Far-NetBox
static int line_overflow(void)
{
    ne_socket *sock;
    ssize_t ret;
    DECL_LONG(line, 'A', OVERLEN);

    CALL(begin(&sock, serve_sstring, &line));

    PEEK("A"); /* fill the read buffer */
    ret = ne_sock_readline(sock, buffer, OVERLEN);
    ONV(ret != NE_SOCK_ERROR,
        ("readline should fail on overlong line: %" NE_FMT_SSIZE_T, ret));

    ne_free(line.data);
    return finish(sock, 0);
}
예제 #16
0
파일: summary.c 프로젝트: Kweepa/vicdoom
void __fastcall__ rollInPercentage(char pc, int scr)
{
  signed char i = -4;
  POKE(scr + 3,'%');
  do
  {
    i += 4;
    if (i > pc) i = pc;
    print3DigitNumToScreen(i, scr);
    playSound(SOUND_PISTOL);
    if (PEEK(198) == 0)
    {
		  waitForRaster(2);
    }
  }
  while (i < pc);
}
예제 #17
0
파일: conio.c 프로젝트: Arkuda/rpc8e-cc65
void blit_shift(unsigned char sx, unsigned char sy, unsigned char dx, unsigned char dy, unsigned char width, unsigned char height)
{
	// FIXME: Call MMU to the make sure screen is the enabled device......

	POKE( 0x30a, dx);
	POKE( 0x30b, dy);
	
	POKE( 0x308, sx );
	POKE( 0x309, sy );

	POKE( 0x30c, width );
	POKE( 0x30d, height );

	POKE( 0x307, 3 );		// blitter SHIFT command
	while ( PEEK( 0x307 ) == 3 )
	{
		// WAI
	}
	
}
예제 #18
0
//---------------------------------------------------------------------------
void OGWriteSector(int Side,int Track,int Sector,int Bytes)
{
  FILE *f=fopen(WriteDir+SLASH+"hiscores","r+b");
  if (f==NULL) return;

  int SavePos;
  for(;;){
    int SavedSide=-1,SavedTrack=-1,SavedSector=-1,SavedBytes=-1;
    SavePos=ftell(f);
    fread(&SavedSide,1,sizeof(int),f);
    fread(&SavedTrack,1,sizeof(int),f);
    fread(&SavedSector,1,sizeof(int),f);
    fread(&SavedBytes,1,sizeof(int),f);
    if (SavedSide==-1 || SavedTrack==-1 || SavedSector==-1 || SavedBytes==-1) break;
    if (SavedSide==Side && SavedTrack==Track && SavedSector==Sector){
      if (SavedBytes==Bytes){
        // Can save over here
        break;
      }else{
        fseek(f,SavePos+sizeof(int)*2,SEEK_SET);
        SavedSector=256; // Clear this one
        fwrite(&SavedSector,1,sizeof(int),f);
        fseek(f,SavePos+sizeof(int)*4+SavedBytes,SEEK_SET);
      }
    }else{
      fseek(f,SavedBytes,SEEK_CUR);
    }
  }
  fseek(f,SavePos,SEEK_SET);
  fwrite(&Side,1,sizeof(int),f);
  fwrite(&Track,1,sizeof(int),f);
  fwrite(&Sector,1,sizeof(int),f);
  fwrite(&Bytes,1,sizeof(int),f);
  for (int n=0;n<Bytes;n++){
    if (dma_address+n < mem_len){
      BYTE b=PEEK(dma_address+n);
      fwrite(&b,1,1,f);
    }
  }
  fclose(f);
}
예제 #19
0
파일: summary.c 프로젝트: Kweepa/vicdoom
void __fastcall__ rollInTime(int t, int scr)
{
  int i = -5;
  char ih, il;
  POKE(scr + 2,':');
  do
  {
    i += 5;
    if (i > t) i = t;
    ih = i / 60;
    il = i - 60 * ih;
    print2DigitNumToScreen(ih, scr);
    print2DigitNumToScreen(il, scr + 3);
    playSound(SOUND_PISTOL);
    if (PEEK(198) == 0)
    {
		  waitForRaster(2);
    }
  }
  while (i < t);
}
예제 #20
0
파일: socket.c 프로젝트: Ugnis/Far-NetBox
/* Stress out the read buffer handling a little. */
static int read_and_peek(void)
{
    ne_socket *sock;
    DECL(hello, STR);

    CALL(begin(&sock, serve_sstring, &hello));

    PEEK("Hello");
    PEEK("Hell");
    PEEK(STR);
    READ("He");
    PEEK("llo, ");
    READ("l");
    PEEK("lo, World.");
    READ("lo, Worl");
    PEEK("d."); PEEK("d");
    READ("d.");

    return finish(sock, 1);
}
예제 #21
0
파일: regcomp.c 프로젝트: OPSF/uClinux
/*
 - p_ere - ERE parser top level, concatenation and alternation
 */
static void
p_ere(struct parse *p, int stop)	/* character this ERE should end at */
{
	char c;
	sopno prevback;
	sopno prevfwd;
	sopno conc;
	int first = 1;		/* is this the first alternative? */

	for (;;) {
		/* do a bunch of concatenated expressions */
		conc = HERE();
		while (MORE() && (c = PEEK()) != '|' && c != stop)
			p_ere_exp(p);
		REQUIRE(HERE() != conc, REG_EMPTY);	/* require nonempty */

		if (!EAT('|'))
			break;		/* NOTE BREAK OUT */

		if (first) {
			INSERT(OCH_, conc);	/* offset is wrong */
			prevfwd = conc;
			prevback = conc;
			first = 0;
		}
		ASTERN(OOR1, prevback);
		prevback = THERE();
		AHEAD(prevfwd);			/* fix previous offset */
		prevfwd = HERE();
		EMIT(OOR2, 0);			/* offset is very wrong */
	}

	if (!first) {		/* tail-end fixups */
		AHEAD(prevfwd);
		ASTERN(O_CH, prevback);
	}

	assert(!MORE() || SEE(stop));
}
예제 #22
0
int			parse_exp_redir(struct s_iterator *i,
					struct s_btree *node)
{
  struct s_token	*t;

  if (HAS_NEXT(i))
    {
      t = PEEK(i);
      if (t->type == TT_RREDIR)
	return (parse_exp_rredir(i, node));
      else if (t->type == TT_DRREDIR)
	return (parse_exp_drredir(i, node));
      else if (t->type == TT_LREDIR)
	return (parse_exp_lredir(i, node));
      else if (t->type == TT_DLREDIR)
	return (parse_exp_dlredir(i, node));
      else if (t->type == TT_TLREDIR)
	return (parse_exp_tlredir(i, node));
      else
	return (fprintf(stderr, "error: unexpected token \"%s\"\n",
			t->string._string), -1);
    }
  return (0);
}
예제 #23
0
파일: conio.c 프로젝트: Arkuda/rpc8e-cc65
void blit_fill(unsigned char x, unsigned char y, unsigned char width, unsigned char height, unsigned char fillchar)
{
	// FIXME: Call MMU to the make sure screen is the enabled device......
	
	POKE( 0x308, fillchar);
	POKE( 0x30a, x);
	POKE( 0x30b, y);
	
	POKE( 0x30c, width );
	POKE( 0x30d, height );
	
	POKE( 0x307, 1);			// blitter FILL command
	while ( PEEK( 0x307 ) == 1)
	{
		// WAI
	}

	// reset blit size to 0
	
	POKE( 0x300, 0 ); // set row to 0
	POKE( 0x301, 0 );
	POKE( 0x302, 0 );
	
}
예제 #24
0
/*
 * determine which graphics page is active
 */
uint8_t find_page(void)
{
    return (PEEK(ACTIVEPAGE) & 0x80 ? 1 : 0);
}
예제 #25
0
//---------------------------------------------------------------------------
void OGIntercept()
{
  MEM_ADDRESS OGTitleAd=0,OGPalAd=0;
  int OGBmpNum=0;
  switch (pc){
#if ONEGAME_IDX==OG_NM1_IDX
    case 0x21AA: // Title screen routine
      areg[0]=0x249E;
      SET_PC(0x21B0);
      OGTitleAd=xbios2;
      break;
#elif ONEGAME_IDX==OG_NM2_IDX
    case 0x216E: // Title screen routine
      areg[0]=0x8AB4;
      SET_PC(0x2174);

      OGTitleAd=xbios2;
      OGPalAd=areg[0];
      for (int i=0;i<16;i++) OGStorePal[i]=m68k_dpeek(OGPalAd + i*2);
      break;
    case 0x2178: // Restore palette
      m68k_lpoke(0x12E80,0x006A0098);
      SET_PC(0x2182);

      for (int i=0;i<16;i++) m68k_dpoke(0x8AB4 + i*2,OGStorePal[i]);
      break;
    case 0x387E: // Skip "Get ready.."
      SET_PC(0x389E);
      break;
#elif ONEGAME_IDX==OG_SAT1_IDX
    case 0x153E: // Title screen routine
      areg[0]=0xA67E;
      SET_PC(0x1544);

      OGTitleAd=xbios2;
      OGPalAd=areg[0];
      for (int i=0;i<16;i++) OGStorePal[i]=m68k_dpeek(OGPalAd + i*2);
      break;
    case 0x154A: // Restore palette
      m68k_dpoke(0x16ea,0x36B0);
      SET_PC(0x1552);

      for (int i=0;i<16;i++) m68k_dpoke(0xA67E + i*2,OGStorePal[i]);
      break;
    case 0x1984: // "Get ready for battle"
    case 0x1278: // "Time Over"
    case 0x17E8: // "Well done warrior"
    case 0x1802: // "The way to the magic"
    case 0x181C: // "Kingdom is closer"
    case 0x18E0: // "You got it"
      areg[0]=OG_TEXT_ADDRESS+m68k_dpeek(pc+2);
      SET_PC(pc+4);
      break;
#elif ONEGAME_IDX==OG_SAT2_IDX
    case 0x11c4: // Title screen routine
      areg[0]=0xD8C2;
      SET_PC(0x11ca);

      OGTitleAd=0x77300;
      OGPalAd=areg[0];
      for (int i=0;i<16;i++) OGStorePal[i]=m68k_dpeek(OGPalAd + i*2);
      break;
    case 0x11CE: // Restore palette
      m68k_dpoke(0x9758,0x64);
      SET_PC(0x11d6);
      for (int i=0;i<16;i++) m68k_dpoke(0xD8C2 + i*2,OGStorePal[i]);
      break;
    case 0x35BE: // Draw description of item in shop
      m68k_dpoke(0x93A6,0xe6);
      SET_PC(0x35C6);
      if (areg[0]==0x95DE) areg[0]=OG_TEXT_ADDRESS+m68k_dpeek(0x35BE+2);
      break;
#elif ONEGAME_IDX==OG_AW1_IDX
    case 0xa0aa: // Title screen routine
      areg[7]-=4;
      m68k_lpoke(areg[7],0xA0b0);
      SET_PC(0xA678);

      OGTitleAd=0x78000;
      OGPalAd=0x18832;
      for (int i=0;i<16;i++) OGStorePal[i]=m68k_dpeek(OGPalAd + i*2);
      break;
    case 0xA0b0: // Restore palette
      areg[0]=0x187CE;
      SET_PC(0xA0b6);

      for (int i=0;i<16;i++) m68k_dpoke(0x18832 + i*2,OGStorePal[i]);
      break;
    case 0x8986: // Load screen fade up
      areg[7]-=4;
      m68k_lpoke(areg[7],0x8988);
      SET_PC(0xA670);

      OGTitleAd=xbios2;
      OGPalAd=0x18812;
      OGBmpNum=1;
      for (int i=0;i<16;i++) OGStorePal[i]=m68k_dpeek(OGPalAd + i*2);
      break;
    case 0x8988: // Load screen restore pal
      SET_PC(0x898a);
      for (int i=0;i<16;i++) m68k_dpoke(0x18812 + i*2,OGStorePal[i]);
      break;

    case 0x8CEC: // End screen fade up
      areg[7]-=4;
      m68k_lpoke(areg[7],0x8CEE);
      SET_PC(0xA678);

      OGTitleAd=xbios2;
      OGPalAd=0x18832;
      OGBmpNum=2;
      for (int i=0;i<16;i++) OGStorePal[i]=m68k_dpeek(OGPalAd + i*2);
      break;
    case 0x8CEE: // End screen restore pal
      SET_PC(0x8CF2);
      for (int i=0;i<16;i++) m68k_dpoke(0x18832 + i*2,OGStorePal[i]);
      break;

    case 0x8996: // Fade out before load hook
      areg[7]-=4;
      m68k_lpoke(areg[7],0x8998); // return address
      SET_PC(0x17976);
      break;
    case 0x8998: // Do what above instruction should hook
      areg[7]-=4;
      m68k_lpoke(areg[7],0x899a); // return address
      SET_PC(0x8e24);
      break;

#elif ONEGAME_IDX==OG_AW2_IDX
    case 0xCFDC: // Title screen routine
      areg[7]-=4;
      m68k_lpoke(areg[7],0xCFE0); // return address
      SET_PC(0xfdf4);

      OGTitleAd=0x78000;
      OGPalAd=0x14312;
      for (int i=0;i<16;i++) OGStorePal[i]=m68k_dpeek(OGPalAd + i*2);
      break;
    case 0xCFE0: // Restore palette
      areg[0]=0x125B2;
      SET_PC(0xCFE4);

      for (int i=0;i<16;i++) m68k_dpoke(0x14312 + i*2,OGStorePal[i]);
      break;
    case 0x01198E: // Load enemy at end of level 2
      SET_PC(m68k_lpeek(r[15]));
      r[15]+=4;

      OGDrawSprite(10,0x69a62);
      OGDrawSprite(11,0x69B62);
      OGDrawSprite(12,0x69C22);
      OGDrawSprite(13,0x69CA2);
      break;
#endif
  }
  if (pOGTitle && OGTitleAd){
    MEM_ADDRESS ad=OGTitleAd & 0xffffff;
    MEM_ADDRESS ad_end=ad+32000;
    WORD *p=pOGTitle;
    if (OGBmpNum) if (pOGExtraScreen[OGBmpNum-1]) p=pOGExtraScreen[OGBmpNum-1];
    if (ad_end<=mem_len){
      while (ad<ad_end){
        DPEEK(ad)=*(p++);
        ad+=2;
      }
      if (OGBmpNum==0){
#if ONEGAME_IDX==OG_SAT2_IDX
        MEM_ADDRESS ad2=0x2B500;
#elif ONEGAME_IDX==OG_AW1_IDX
        MEM_ADDRESS ad2=0x3CE00;
#elif ONEGAME_IDX==OG_AW2_IDX
        MEM_ADDRESS ad2=0x70300;
#else
        MEM_ADDRESS ad2=0;
#endif
        if (ad2){
          ad=OGTitleAd & 0xffffff;
          while (ad<ad_end) PEEK((ad2++))=PEEK((ad++));
        }
      }
      if (OGPalAd){
        for (int i=0;i<16;i++){
          DPEEK(OGPalAd)=*(p++);
          OGPalAd+=2;
        }
      }else{
        for (int i=0;i<16;i++) STpal[i]=*(p++);
        palette_convert_all();
      }
    }
  }
}
예제 #26
0
파일: regcomp.c 프로젝트: OPSF/uClinux
/*
 - p_bracket - parse a bracketed character list
 *
 * Note a significant property of this code:  if the allocset() did SETERROR,
 * no set operations are done.
 */
static void
p_bracket(struct parse *p)
{
	cset *cs;
	int invert = 0;

	/* Dept of Truly Sickening Special-Case Kludges */
	if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) {
		EMIT(OBOW, 0);
		NEXTn(6);
		return;
	}
	if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) {
		EMIT(OEOW, 0);
		NEXTn(6);
		return;
	}

	if ((cs = allocset(p)) == NULL) {
		/* allocset did set error status in p */
		return;
	}

	if (EAT('^'))
		invert++;	/* make note to invert set at end */
	if (EAT(']'))
		CHadd(cs, ']');
	else if (EAT('-'))
		CHadd(cs, '-');
	while (MORE() && PEEK() != ']' && !SEETWO('-', ']'))
		p_b_term(p, cs);
	if (EAT('-'))
		CHadd(cs, '-');
	MUSTEAT(']', REG_EBRACK);

	if (p->error != 0) {	/* don't mess things up further */
		freeset(p, cs);
		return;
	}

	if (p->g->cflags&REG_ICASE) {
		int i;
		int ci;

		for (i = p->g->csetsize - 1; i >= 0; i--)
			if (CHIN(cs, i) && isalpha(i)) {
				ci = othercase(i);
				if (ci != i)
					CHadd(cs, ci);
			}
		if (cs->multis != NULL)
			mccase(p, cs);
	}
	if (invert) {
		int i;

		for (i = p->g->csetsize - 1; i >= 0; i--)
			if (CHIN(cs, i))
				CHsub(cs, i);
			else
				CHadd(cs, i);
		if (p->g->cflags&REG_NEWLINE)
			CHsub(cs, '\n');
		if (cs->multis != NULL)
			mcinvert(p, cs);
	}

	assert(cs->multis == NULL);		/* xxx */

	if (nch(p, cs) == 1) {		/* optimize singleton sets */
		ordinary(p, firstch(p, cs));
		freeset(p, cs);
	} else
		EMIT(OANYOF, freezeset(p, cs));
}
예제 #27
0
파일: vm.c 프로젝트: giantfishy/3-move
PUBLIC int run_vm(VMSTATE vms) {
  OBJ vm_hold;	/* Holding register. NOT SEEN BY GC */
  int ticks_left = VM_TIMESLICE_TICKS;

  while (vms->c.vm_state != VM_STATE_DYING && ticks_left-- && vms->r->vm_acc != yield_thread) {
    if (vms->c.vm_state > 0) {
      vms->c.vm_state--;
      if (vms->c.vm_state == 0) {
	/* Quota expired. Warn. */
	vms->c.vm_state = VM_DEFAULT_CPU_QUOTA;
	vm_raise(vms, (OBJ) newsym("quota-expired"), NULL);
	/* Make sure we don't recurse :-) */
	vms->r->vm_trap_closure = NULL;
      }
    }

    gc_reach_safepoint();

#ifdef DEBUG
    debug_dump_instr( vms->r->vm_code->vec , vms->c.vm_ip );
#endif

    switch (CODEAT(vms->c.vm_ip)) {
      case OP_AT: {
	int index = CODEAT(vms->c.vm_ip + 1);

	if (index < 0 || index >= vms->r->vm_acc->length) {
	  vm_raise(vms, (OBJ) newsym("range-check-error"), vms->r->vm_acc);
	  break;
	}

	if (!VECTORP(vms->r->vm_acc)) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}

	vms->r->vm_acc = AT((VECTOR) vms->r->vm_acc, index);
	vms->c.vm_ip += 2;
	break;
      }

      case OP_ATPUT: {
	int index = CODEAT(vms->c.vm_ip + 1);

	vm_hold = PEEK();

	if (index < 0 || index >= vm_hold->length) {
	  vm_raise(vms, (OBJ) newsym("range-check-error"), vm_hold);
	  break;
	}

	if (!VECTORP(vm_hold)) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vm_hold);
	  break;
	}

	ATPUT((VECTOR) vm_hold, index, vms->r->vm_acc);
	vms->c.vm_ip += 2;
	break;
      }

      case OP_MOV_A_LOCL: {
	int i = CODEAT(vms->c.vm_ip + 1);
	vm_hold = (OBJ) vms->r->vm_env;
	while (i-- > 0) vm_hold = AT((VECTOR) vm_hold, 0);
	vms->r->vm_acc = AT((VECTOR) vm_hold, CODEAT(vms->c.vm_ip + 2) + 1);
	vms->c.vm_ip += 3;
	break;
      }

      case OP_MOV_A_GLOB:
	vm_hold = AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));
	vms->r->vm_acc = AT((OVECTOR) vm_hold, SY_VALUE);
	vms->c.vm_ip += 2;
	break;

      case OP_MOV_A_SLOT: {
	OVECTOR slot, slotname;

	if (!OBJECTP(vms->r->vm_acc)) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}

	slotname = (OVECTOR) AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));

	if (!O_CAN_X((OBJECT) vms->r->vm_acc, vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) slotname);
	}

	slot = findslot((OBJECT) vms->r->vm_acc, slotname, NULL);

	if (slot == NULL) {
	  vm_raise(vms, (OBJ) newsym("slot-not-found"), (OBJ) slotname);
	  break;
	}

	if (!MS_CAN_R(slot, vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) slotname);
	}

	vms->r->vm_acc = AT(slot, SL_VALUE);
	vms->c.vm_ip += 2;
	break;
      }

      case OP_MOV_A_LITL:
	vms->r->vm_acc = AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));
	vms->c.vm_ip += 2;
	break;

      case OP_MOV_A_SELF: vms->r->vm_acc = (OBJ) vms->r->vm_self; vms->c.vm_ip++; break;
      case OP_MOV_A_FRAM: vms->r->vm_acc = (OBJ) vms->r->vm_frame; vms->c.vm_ip++; break;

      case OP_MOV_LOCL_A: {
	int i = CODEAT(vms->c.vm_ip + 1);
	vm_hold = (OBJ) vms->r->vm_env;
	while (i-- > 0) vm_hold = AT((VECTOR) vm_hold, 0);
	ATPUT((VECTOR) vm_hold, CODEAT(vms->c.vm_ip + 2) + 1, vms->r->vm_acc);
	vms->c.vm_ip += 3;
	break;
      }

      case OP_MOV_GLOB_A:
	if (!PRIVILEGEDP(vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) newsym("setting-global-value"));
	}
	vm_hold = AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));
	ATPUT((OVECTOR) vm_hold, SY_VALUE, vms->r->vm_acc);
	vms->c.vm_ip += 2;
	break;

      case OP_MOV_SLOT_A: {
	OVECTOR slot, slotname;
	OBJECT target = (OBJECT) POP();
	OBJECT foundin;

	if (!OBJECTP(target)) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), (OBJ) target);
	  break;
	}

	slotname = (OVECTOR) AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));

	if (!O_CAN_X(target, vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) slotname);
	}

	slot = findslot(target, slotname, &foundin);

	if (slot == NULL) {
	  vm_raise(vms, (OBJ) newsym("slot-not-found"), (OBJ) slotname);
	  break;
	}

	if (!MS_CAN_W(slot, vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) slotname);
	}

	if (foundin == target) {
	  ATPUT(slot, SL_VALUE, vms->r->vm_acc);
	} else {
	  OVECTOR newslot = addslot(target, slotname, (OBJECT) AT(slot, SL_OWNER));
	  ATPUT(newslot, SL_FLAGS, AT(slot, SL_FLAGS));
	  ATPUT(newslot, SL_VALUE, vms->r->vm_acc);
	}

	vms->c.vm_ip += 2;
	break;
      }

      case OP_MOV_FRAM_A:
	if (!PRIVILEGEDP(vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) newsym("restoring-vm-frame-pointer"));
	}

	if (!OVECTORP(vms->r->vm_acc) || ((OVECTOR) vms->r->vm_acc)->type != T_FRAME) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}

	vms->r->vm_frame = (OVECTOR) vms->r->vm_acc;
	vms->c.vm_ip++;
	break;

      case OP_PUSH: PUSH(vms->r->vm_acc); vms->c.vm_ip++; break;
      case OP_POP: vms->r->vm_acc = POP(); vms->c.vm_ip++; break;
      case OP_SWAP:
	vm_hold = POP();
	PUSH(vms->r->vm_acc);
	vms->r->vm_acc = vm_hold;
	vms->c.vm_ip++;
	break;

      case OP_VECTOR:
	vms->r->vm_acc = (OBJ) newvector(CODEAT(vms->c.vm_ip+1));
	vms->c.vm_ip += 2;
	break;
	
      case OP_ENTER_SCOPE:
	vm_hold = (OBJ) newvector(CODEAT(vms->c.vm_ip+1) + 1);
	ATPUT((VECTOR) vm_hold, 0, (OBJ) vms->r->vm_env);
	vms->r->vm_env = (VECTOR) vm_hold;
	vms->c.vm_ip += 2;
	break;

      case OP_LEAVE_SCOPE:
	vms->r->vm_env = (VECTOR) AT(vms->r->vm_env, 0);
	vms->c.vm_ip++;
	break;

      case OP_MAKE_VECTOR: {
	int i = 0;
	int len = CODEAT(vms->c.vm_ip+1);
	VECTOR vec = newvector_noinit(len);

	for (i = len - 1; i >= 0; i--)
	  ATPUT(vec, i, POP());

	vms->r->vm_acc = (OBJ) vec;
	vms->c.vm_ip += 2;
	break;
      }

      case OP_CLOSURE:
	vms->r->vm_acc = make_closure_from((OVECTOR) vms->r->vm_acc,
					   vms->r->vm_self,
					   vms->r->vm_env,
					   vms->r->vm_effuid);
	vms->c.vm_ip++;
	break;

      case OP_METHOD_CLOSURE: {
	OVECTOR methname = (OVECTOR) AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));
	OVECTOR method;

	if (!OBJECTP(vms->r->vm_acc)) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}

	method = findmethod((OBJECT) vms->r->vm_acc, methname);

	if (method == NULL) {
	  vm_raise(vms, (OBJ) newsym("method-not-found"), (OBJ) methname);
	  break;
	}

	if (!MS_CAN_R(method, vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) methname);
	}

	vm_hold = (OBJ) newovector(CL_MAXSLOTINDEX, T_CLOSURE);
	ATPUT((OVECTOR) vm_hold, CL_METHOD, (OBJ) method);
	ATPUT((OVECTOR) vm_hold, CL_SELF, vms->r->vm_acc);
	vms->r->vm_acc = vm_hold;

	vms->c.vm_ip += 2;
	break;
      }

      case OP_RET:
	if (vms->r->vm_frame != NULL) {
	  restoreframe(vms, vms->r->vm_frame);
	  if (vms->r->vm_code != NULL)
	    break;
	}

	vms->c.vm_state = VM_STATE_DYING;
	return 1;	/* finished, nothing more to run! */
	
      case OP_CALL: {
	OVECTOR methname = (OVECTOR) AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));
	OVECTOR method;

	if (vms->r->vm_acc == NULL || TAGGEDP(vms->r->vm_acc)) {
	  vm_raise(vms,
		   (OBJ) newsym("null-call-error"),
		   AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip+1)));
	  break;
	}

	if (!OBJECTP(vms->r->vm_acc)) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}

	method = findmethod((OBJECT) vms->r->vm_acc, methname);

	if (method == NULL) {
	  vm_raise(vms, (OBJ) newsym("method-not-found"), (OBJ) methname);
	  break;
	}

	if (!MS_CAN_X(method, vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) methname);
	}

	vm_hold = POP();
	if (vm_hold->length-1 != NUM(AT(method, ME_ARGC))) {
	  vm_raise(vms, (OBJ) newsym("wrong-argc"), (OBJ) methname);
	  break;
	}

	vms->c.vm_ip += 2;
	push_frame(vms);

	vms->r->vm_env = (VECTOR) vm_hold;
	ATPUT(vms->r->vm_env, 0, AT(method, ME_ENV));
	vms->r->vm_code = (BVECTOR) AT(method, ME_CODE);
	vms->r->vm_lits = (VECTOR) AT(method, ME_LITS);
	vms->r->vm_self = (OBJECT) vms->r->vm_acc;
	if (NUM(AT(method, ME_FLAGS)) & O_SETUID)
	  vms->r->vm_effuid = (OBJECT) AT(method, ME_OWNER);
	vms->r->vm_method = method;
	vms->c.vm_ip = 0;
	break;
      }

      case OP_CALL_AS: {
	OVECTOR methname = (OVECTOR) AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));
	OVECTOR method;

	if (vms->r->vm_self == NULL ||
	    vms->r->vm_acc == NULL || TAGGEDP(vms->r->vm_acc)) {
	  vm_raise(vms,
		   (OBJ) newsym("null-call-error"),
		   AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip+1)));
	  break;
	}

	if (!OBJECTP(vms->r->vm_acc)) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}

	method = findmethod((OBJECT) vms->r->vm_acc, methname);

	if (method == NULL) {
	  vm_raise(vms, (OBJ) newsym("method-not-found"), (OBJ) methname);
	  break;
	}

	if (!MS_CAN_X(method, vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) methname);
	}

	vm_hold = POP();
	if (vm_hold->length-1 != NUM(AT(method, ME_ARGC))) {
	  vm_raise(vms, (OBJ) newsym("wrong-argc"), (OBJ) methname);
	  break;
	}

	vms->c.vm_ip += 2;
	push_frame(vms);

	vms->r->vm_env = (VECTOR) vm_hold;
	ATPUT(vms->r->vm_env, 0, AT(method, ME_ENV));
	vms->r->vm_code = (BVECTOR) AT(method, ME_CODE);
	vms->r->vm_lits = (VECTOR) AT(method, ME_LITS);

	/* don't set vm_self, this is OP_CALL_AS. */
	/* vms->r->vm_self = vms->r->vm_acc; */

	if (NUM(AT(method, ME_FLAGS)) & O_SETUID)
	  vms->r->vm_effuid = (OBJECT) AT(method, ME_OWNER);
	vms->r->vm_method = method;
	vms->c.vm_ip = 0;
	break;
      }

      case OP_APPLY:
	vms->c.vm_ip++;
	apply_closure(vms, (OVECTOR) vms->r->vm_acc, (VECTOR) POP());
	break;

      case OP_JUMP: vms->c.vm_ip += 3 + ((int16_t) CODE16AT(vms->c.vm_ip+1)); break;

      case OP_JUMP_TRUE:
	vms->c.vm_ip += (vms->r->vm_acc == false) ? 3 :
						    3 + ((int16_t) CODE16AT(vms->c.vm_ip+1));
	break;

      case OP_JUMP_FALSE:
	vms->c.vm_ip += (vms->r->vm_acc != false) ? 3 :
						    3 + ((int16_t) CODE16AT(vms->c.vm_ip+1));
	break;

      case OP_NOT:
	vms->r->vm_acc = (vms->r->vm_acc == false) ? true : false;
	vms->c.vm_ip++;
	break;

      case OP_EQ:
	vms->r->vm_acc = (vms->r->vm_acc == POP()) ? true : false;
	vms->c.vm_ip++;
	break;

      case OP_NE:
	vms->r->vm_acc = (vms->r->vm_acc != POP()) ? true : false;
	vms->c.vm_ip++;
	break;

      NUMOP(OP_GT, vms->r->vm_acc = (NUM(vms->r->vm_acc) < NUM(POP())) ? true : false);
      NUMOP(OP_LT, vms->r->vm_acc = (NUM(vms->r->vm_acc) > NUM(POP())) ? true : false);
      NUMOP(OP_GE, vms->r->vm_acc = (NUM(vms->r->vm_acc) <= NUM(POP())) ? true : false);
      NUMOP(OP_LE, vms->r->vm_acc = (NUM(vms->r->vm_acc) >= NUM(POP())) ? true : false);

      NUMOP(OP_NEG, vms->r->vm_acc = MKNUM(-NUM(vms->r->vm_acc)));
      NUMOP(OP_BNOT, vms->r->vm_acc = MKNUM(~NUM(vms->r->vm_acc)));
      NUMOP(OP_BOR, vms->r->vm_acc = MKNUM(NUM(vms->r->vm_acc)|NUM(POP())));
      NUMOP(OP_BAND, vms->r->vm_acc = MKNUM(NUM(vms->r->vm_acc)&NUM(POP())));

      case OP_PLUS:
	if (vms->r->vm_acc == NULL || PEEK() == NULL) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}
	if (NUMP(vms->r->vm_acc) && NUMP(PEEK()))
	  vms->r->vm_acc = MKNUM(NUM(vms->r->vm_acc)+NUM(POP()));
	else if (TAGGEDP(vms->r->vm_acc) || TAGGEDP(PEEK())) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	} else if (BVECTORP(vms->r->vm_acc) && BVECTORP(PEEK()))
	  vms->r->vm_acc = (OBJ) bvector_concat((BVECTOR) POP(), (BVECTOR) vms->r->vm_acc);
	else if (VECTORP(vms->r->vm_acc) && VECTORP(PEEK()))
	  vms->r->vm_acc = (OBJ) vector_concat((VECTOR) POP(), (VECTOR) vms->r->vm_acc);
	else {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}
	vms->c.vm_ip++;
	break;

      NUMOP(OP_MINUS, vms->r->vm_acc = MKNUM(NUM(POP())-NUM(vms->r->vm_acc)));
      NUMOP(OP_STAR, vms->r->vm_acc = MKNUM(NUM(POP())*NUM(vms->r->vm_acc)));
      NUMOP(OP_SLASH,
	    if (vms->r->vm_acc == MKNUM(0))
	      vm_raise(vms, (OBJ) newsym("divide-by-zero"), NULL);
	    else
	      vms->r->vm_acc = MKNUM(NUM(POP())/NUM(vms->r->vm_acc)));
      NUMOP(OP_PERCENT,
	    if (vms->r->vm_acc == MKNUM(0))
	      vm_raise(vms, (OBJ) newsym("divide-by-zero"), NULL);
	    else
	      vms->r->vm_acc = MKNUM(NUM(POP())%NUM(vms->r->vm_acc)));

      default:
	fprintf(stderr, "Unknown bytecode reached (%d == 0x%x).\n",
		CODEAT(vms->c.vm_ip),
		CODEAT(vms->c.vm_ip));
	exit(MOVE_EXIT_PROGRAMMER_FUCKUP);
    }
  }

  return vms->c.vm_state == VM_STATE_DYING;
}
예제 #28
0
파일: regcomp.c 프로젝트: OPSF/uClinux
/*
 - p_simp_re - parse a simple RE, an atom possibly followed by a repetition
 */
static int			/* was the simple RE an unbackslashed $? */
p_simp_re(struct parse *p,
    int starordinary)		/* is a leading * an ordinary character? */
{
	int c;
	int count;
	int count2;
	sopno pos;
	int i;
	sopno subno;
#	define	BACKSL	(1<<CHAR_BIT)

	pos = HERE();		/* repetion op, if any, covers from here */

	assert(MORE());		/* caller should have ensured this */
	c = GETNEXT();
	if (c == '\\') {
		REQUIRE(MORE(), REG_EESCAPE);
		c = BACKSL | GETNEXT();
	}
	switch (c) {
	case '.':
		if (p->g->cflags&REG_NEWLINE)
			nonnewline(p);
		else
			EMIT(OANY, 0);
		break;
	case '[':
		p_bracket(p);
		break;
	case BACKSL|'{':
		SETERROR(REG_BADRPT);
		break;
	case BACKSL|'(':
		p->g->nsub++;
		subno = p->g->nsub;
		if (subno < NPAREN)
			p->pbegin[subno] = HERE();
		EMIT(OLPAREN, subno);
		/* the MORE here is an error heuristic */
		if (MORE() && !SEETWO('\\', ')'))
			p_bre(p, '\\', ')');
		if (subno < NPAREN) {
			p->pend[subno] = HERE();
			assert(p->pend[subno] != 0);
		}
		EMIT(ORPAREN, subno);
		REQUIRE(EATTWO('\\', ')'), REG_EPAREN);
		break;
	case BACKSL|')':	/* should not get here -- must be user */
	case BACKSL|'}':
		SETERROR(REG_EPAREN);
		break;
	case BACKSL|'1':
	case BACKSL|'2':
	case BACKSL|'3':
	case BACKSL|'4':
	case BACKSL|'5':
	case BACKSL|'6':
	case BACKSL|'7':
	case BACKSL|'8':
	case BACKSL|'9':
		i = (c&~BACKSL) - '0';
		assert(i < NPAREN);
		if (p->pend[i] != 0) {
			assert(i <= p->g->nsub);
			EMIT(OBACK_, i);
			assert(p->pbegin[i] != 0);
			assert(OP(p->strip[p->pbegin[i]]) == OLPAREN);
			assert(OP(p->strip[p->pend[i]]) == ORPAREN);
			(void) dupl(p, p->pbegin[i]+1, p->pend[i]);
			EMIT(O_BACK, i);
		} else
			SETERROR(REG_ESUBREG);
		p->g->backrefs = 1;
		break;
	case '*':
		REQUIRE(starordinary, REG_BADRPT);
		/* FALLTHROUGH */
	default:
		ordinary(p, (char)c);
		break;
	}

	if (EAT('*')) {		/* implemented as +? */
		/* this case does not require the (y|) trick, noKLUDGE */
		INSERT(OPLUS_, pos);
		ASTERN(O_PLUS, pos);
		INSERT(OQUEST_, pos);
		ASTERN(O_QUEST, pos);
	} else if (EATTWO('\\', '{')) {
		count = p_count(p);
		if (EAT(',')) {
			if (MORE() && isdigit((uch)PEEK())) {
				count2 = p_count(p);
				REQUIRE(count <= count2, REG_BADBR);
			} else		/* single number with comma */
				count2 = INFINITY;
		} else		/* just a single number */
			count2 = count;
		repeat(p, pos, count, count2);
		if (!EATTWO('\\', '}')) {	/* error heuristics */
			while (MORE() && !SEETWO('\\', '}'))
				NEXT();
			REQUIRE(MORE(), REG_EBRACE);
			SETERROR(REG_BADBR);
		}
	} else if (c == '$')	/* $ (but not \$) ends it */
		return(1);

	return(0);
}
예제 #29
0
파일: regcomp.c 프로젝트: OPSF/uClinux
/*
 - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op
 */
static void
p_ere_exp(struct parse *p)
{
	char c;
	sopno pos;
	int count;
	int count2;
	sopno subno;
	int wascaret = 0;

	assert(MORE());		/* caller should have ensured this */
	c = GETNEXT();

	pos = HERE();
	switch (c) {
	case '(':
		REQUIRE(MORE(), REG_EPAREN);
		p->g->nsub++;
		subno = p->g->nsub;
		if (subno < NPAREN)
			p->pbegin[subno] = HERE();
		EMIT(OLPAREN, subno);
		if (!SEE(')'))
			p_ere(p, ')');
		if (subno < NPAREN) {
			p->pend[subno] = HERE();
			assert(p->pend[subno] != 0);
		}
		EMIT(ORPAREN, subno);
		MUSTEAT(')', REG_EPAREN);
		break;
#ifndef POSIX_MISTAKE
	case ')':		/* happens only if no current unmatched ( */
		/*
		 * You may ask, why the ifndef?  Because I didn't notice
		 * this until slightly too late for 1003.2, and none of the
		 * other 1003.2 regular-expression reviewers noticed it at
		 * all.  So an unmatched ) is legal POSIX, at least until
		 * we can get it fixed.
		 */
		SETERROR(REG_EPAREN);
		break;
#endif
	case '^':
		EMIT(OBOL, 0);
		p->g->iflags |= USEBOL;
		p->g->nbol++;
		wascaret = 1;
		break;
	case '$':
		EMIT(OEOL, 0);
		p->g->iflags |= USEEOL;
		p->g->neol++;
		break;
	case '|':
		SETERROR(REG_EMPTY);
		break;
	case '*':
	case '+':
	case '?':
		SETERROR(REG_BADRPT);
		break;
	case '.':
		if (p->g->cflags&REG_NEWLINE)
			nonnewline(p);
		else
			EMIT(OANY, 0);
		break;
	case '[':
		p_bracket(p);
		break;
	case '\\':
		REQUIRE(MORE(), REG_EESCAPE);
		c = GETNEXT();
		ordinary(p, c);
		break;
	case '{':		/* okay as ordinary except if digit follows */
		REQUIRE(!MORE() || !isdigit((uch)PEEK()), REG_BADRPT);
		/* FALLTHROUGH */
	default:
		ordinary(p, c);
		break;
	}

	if (!MORE())
		return;
	c = PEEK();
	/* we call { a repetition if followed by a digit */
	if (!( c == '*' || c == '+' || c == '?' ||
				(c == '{' && MORE2() && isdigit((uch)PEEK2())) ))
		return;		/* no repetition, we're done */
	NEXT();

	REQUIRE(!wascaret, REG_BADRPT);
	switch (c) {
	case '*':	/* implemented as +? */
		/* this case does not require the (y|) trick, noKLUDGE */
		INSERT(OPLUS_, pos);
		ASTERN(O_PLUS, pos);
		INSERT(OQUEST_, pos);
		ASTERN(O_QUEST, pos);
		break;
	case '+':
		INSERT(OPLUS_, pos);
		ASTERN(O_PLUS, pos);
		break;
	case '?':
		/* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
		INSERT(OCH_, pos);		/* offset slightly wrong */
		ASTERN(OOR1, pos);		/* this one's right */
		AHEAD(pos);			/* fix the OCH_ */
		EMIT(OOR2, 0);			/* offset very wrong... */
		AHEAD(THERE());			/* ...so fix it */
		ASTERN(O_CH, THERETHERE());
		break;
	case '{':
		count = p_count(p);
		if (EAT(',')) {
			if (isdigit((uch)PEEK())) {
				count2 = p_count(p);
				REQUIRE(count <= count2, REG_BADBR);
			} else		/* single number with comma */
				count2 = INFINITY;
		} else		/* just a single number */
			count2 = count;
		repeat(p, pos, count, count2);
		if (!EAT('}')) {	/* error heuristics */
			while (MORE() && PEEK() != '}')
				NEXT();
			REQUIRE(MORE(), REG_EBRACE);
			SETERROR(REG_BADBR);
		}
		break;
	}

	if (!MORE())
		return;
	c = PEEK();
	if (!( c == '*' || c == '+' || c == '?' ||
				(c == '{' && MORE2() && isdigit((uch)PEEK2())) ) )
		return;
	SETERROR(REG_BADRPT);
}
예제 #30
0
void
ppbuiltin(void)
{
	register int		c;
	register char*		p;
	register char*		a;

	int			n;
	int			op;
	char*			token;
	char*			t;
	long			number;
	long			onumber;
	struct ppinstk*		in;
	struct pplist*		list;
	struct ppsymbol*	sym;
	Sfio_t*			sp;

	number = pp.state;
	pp.state |= DISABLE|FILEPOP|NOSPACE;
	token = pp.token;
	p = pp.token = pp.tmpbuf;
	*(a = pp.args) = 0;
	if ((c = pplex()) != T_ID)
	{
		error(2, "%s: #(<identifier>...) expected", p);
		*p = 0;
	}
	switch (op = (int)hashget(pp.strtab, p))
	{
	case V_DEFAULT:
		n = 0;
		p = pp.token = pp.valbuf;
		if ((c = pplex()) == ',')
		{
			op = -1;
			c = pplex();
		}
		pp.state &= ~NOSPACE;
		for (;;)
		{
			if (!c)
			{
				error(2, "%s in #(...) argument", pptokchr(c));
				break;
			}
			if (c == '(') n++;
			else if (c == ')' && !n--) break;
			else if (c == ',' && !n && op > 0) op = 0;
			if (op) pp.token = pp.toknxt;
			c = pplex();
		}
		*pp.token = 0;
		pp.token = token;
		pp.state = number;
		break;
	case V_EMPTY:
		p = pp.valbuf;
		if ((c = pplex()) == ')') *p = '1';
		else
		{
			*p = '0';
			n = 0;
			for (;;)
			{
				if (!c)
				{
					error(2, "%s in #(...) argument", pptokchr(c));
					break;
				}
				if (c == '(') n++;
				else if (c == ')' && !n--) break;
				c = pplex();
			}
		}
		*(p + 1) = 0;
		pp.token = token;
		pp.state = number;
		break;
	case V_ITERATE:
		n = 0;
		pp.token = pp.valbuf;
		if ((c = pplex()) != T_ID || !(sym = ppsymref(pp.symtab, pp.token)) || !sym->macro || sym->macro->arity != 1 || (c = pplex()) != ',')
		{
			error(2, "#(%s <macro(x)>, ...) expected", p);
			for (;;)
			{
				if (!c)
				{
					error(2, "%s in #(...) argument", pptokchr(c));
					break;
				}
				if (c == '(') n++;
				else if (c == ')' && !n--) break;
				c = pplex();
			}
			*pp.valbuf = 0;
		}
		else while (c != ')')
		{
			p = pp.token;
			if (pp.token > pp.valbuf) *pp.token++ = ' ';
			STRCOPY(pp.token, sym->name, a);
			*pp.token++ = '(';
			if (!c || !(c = pplex()))
			{
				pp.token = p;
				error(2, "%s in #(...) argument", pptokchr(c));
				break;
			}
			pp.state &= ~NOSPACE;
			while (c)
			{
				if (c == '(') n++;
				else if (c == ')' && !n--) break;
				else if (c == ',' && !n) break;
				pp.token = pp.toknxt;
				c = pplex();
			}
			*pp.token++ = ')';
			pp.state |= NOSPACE;
		}
		p = pp.valbuf;
		pp.token = token;
		pp.state = number;
		break;
	default:
		pp.token = token;
		while (c != ')')
		{
			if (!c)
			{
				error(2, "%s in #(...) argument", pptokchr(c));
				break;
			}
			if ((c = pplex()) == T_ID && !*a)
				strcpy(a, pp.token);
		}
		pp.state = number;
		switch (op)
		{
		case V_ARGC:
			c = -1;
			for (in = pp.in; in; in = in->prev)
				if ((in->type == IN_MACRO || in->type == IN_MULTILINE) && (in->symbol->flags & SYM_FUNCTION))
				{
					c = *((unsigned char*)(pp.macp->arg[0] - 2));
					break;
				}
			sfsprintf(p = pp.valbuf, MAXTOKEN, "%d", c);
			break;
		case V_BASE:
			p = (a = strrchr(error_info.file, '/')) ? a + 1 : error_info.file;
			break;
		case V_DATE:
			if (!(p = pp.date))
			{
				time_t	tm;

				time(&tm);
				a = p = ctime(&tm) + 4;
				*(p + 20) = 0;
				for (p += 7; *p = *(p + 9); p++);
				pp.date = p = strdup(a);
			}
			break;
		case V_FILE:
			p = error_info.file;
			break;
		case V_LINE:
			sfsprintf(p = pp.valbuf, MAXTOKEN, "%d", error_info.line);
			break;
		case V_PATH:
			p = pp.path;
			break;
		case V_SOURCE:
			p = error_info.file;
			for (in = pp.in; in->prev; in = in->prev)
				if (in->prev->type == IN_FILE && in->file)
					p = in->file;
			break;
		case V_STDC:
			p = pp.valbuf;
			p[0] = ((pp.state & (COMPATIBILITY|TRANSITION)) || (pp.mode & (HOSTED|HOSTEDTRANSITION)) == (HOSTED|HOSTEDTRANSITION)) ? '0' : '1';
			p[1] = 0;
			break;
		case V_TIME:
			if (!(p = pp.time))
			{
				time_t	tm;

				time(&tm);
				p = ctime(&tm) + 11;
				*(p + 8) = 0;
				pp.time = p = strdup(p);
			}
			break;
		case V_VERSION:
			p = (char*)pp.version;
			break;
		case V_DIRECTIVE:
			pp.state |= NEWLINE;
			pp.mode |= RELAX;
			strcpy(p = pp.valbuf, "#");
			break;
		case V_GETENV:
			if (!(p = getenv(a))) p = "";
			break;
		case V_GETMAC:
			p = (sym = pprefmac(a, REF_NORMAL)) ? sym->macro->value : "";
			break;
		case V_GETOPT:
			sfsprintf(p = pp.valbuf, MAXTOKEN, "%ld", ppoption(a));
			break;
		case V_GETPRD:
			p = (list = (struct pplist*)hashget(pp.prdtab, a)) ? list->value : "";
			break;
		case V__PRAGMA:
			if ((c = pplex()) == '(')
			{
				number = pp.state;
				pp.state |= NOSPACE|STRIP;
				c = pplex();
				pp.state = number;
				if (c == T_STRING || c == T_WSTRING)
				{
					if (!(sp = sfstropen()))
						error(3, "temporary buffer allocation error");
					sfprintf(sp, "#%s %s\n", dirname(PRAGMA), pp.token);
					a = sfstruse(sp);
					if ((c = pplex()) == ')')
					{
						pp.state |= NEWLINE;
						PUSH_BUFFER(p, a, 1);
					}
					sfstrclose(sp);
				}
			}
			if (c != ')')
				error(2, "%s: (\"...\") expected", p);
			return;
		case V_FUNCTION:

#define BACK(a,p)	((a>p)?*--a:(number++?0:((p=pp.outbuf+PPBUFSIZ),(a=pp.outbuf+2*PPBUFSIZ),*--a)))
#define PEEK(a,p)	((a>p)?*(a-1):(number?0:*(pp.outbuf+2*PPBUFSIZ-1)))

			number = pp.outbuf != pp.outb;
			a = pp.outp;
			p = pp.outb;
			op = 0;
			while (c = BACK(a, p))
			{
				if (c == '"' || c == '\'')
				{
					op = 0;
					while ((n = BACK(a, p)) && n != c || PEEK(a, p) == '\\');
				}
				else if (c == '\n')
				{
					token = a;
					while (c = BACK(a, p))
						if (c == '\n')
						{
							a = token;
							break;
						}
						else if (c == '#' && PEEK(a, p) == '\n')
							break;
				}
				else if (c == ' ')
					/*ignore*/;
				else if (c == '{') /* '}' */
					op = 1;
				else if (op == 1)
				{
					if (c == ')')
					{
						op = 2;
						n = 1;
					}
					else
						op = 0;
				}
				else if (op == 2)
				{
					if (c == ')')
						n++;
					else if (c == '(' && !--n)
						op = 3;
				}
				else if (op == 3)
				{
					if (ppisidig(c))
					{
						for (t = p, token = a, onumber = number; ppisidig(PEEK(a, p)) && a >= p; BACK(a, p));
						p = pp.valbuf + 1;
						if (a > token)
						{
							for (; a < pp.outbuf+2*PPBUFSIZ; *p++ = *a++);
							a = pp.outbuf;
						}
						for (; a <= token; *p++ = *a++);
						*p = 0;
						p = pp.valbuf + 1;
						if (streq(p, "for") || streq(p, "if") || streq(p, "switch") || streq(p, "while"))
						{
							op = 0;
							p = t;
							number = onumber;
							continue;
						}
					}
					else
						op = 0;
					break;
				}
			}
			if (op == 3)
				p = strncpy(pp.funbuf, p, sizeof(pp.funbuf) - 1);
			else if (*pp.funbuf)
				p = pp.funbuf;
			else
				p = "__FUNCTION__";
			break;
		default:
			if (pp.builtin && (a = (*pp.builtin)(pp.valbuf, p, a)))
				p = a;
			break;
		}
		break;
	}
	if (strchr(p, MARK))
	{
		a = pp.tmpbuf;
		strcpy(a, p);
		c = p != pp.valbuf;
		p = pp.valbuf + c;
		for (;;)
		{
			if (p < pp.valbuf + MAXTOKEN - 2)
				switch (*p++ = *a++)
				{
				case 0:
					break;
				case MARK:
					*p++ = MARK;
					/*FALLTHROUGH*/
				default:
					continue;
				}
			break;
		}
		p = pp.valbuf + c;
	}
	if (p == pp.valbuf)
		PUSH_STRING(p);
	else
	{
		if (p == pp.valbuf + 1)
			*pp.valbuf = '"';
		else
		{
			if (strlen(p) > MAXTOKEN - 2)
				error(1, "%-.16s: builtin value truncated", p);
			sfsprintf(pp.valbuf, MAXTOKEN, "\"%-.*s", MAXTOKEN - 2, p);
		}
		PUSH_QUOTE(pp.valbuf, 1);
	}
}