Example #1
0
File *Parser::GetIncludedFile(sym_t preprocessor, const char *line, FILE **outf, bool& in_compiler_dir)
{
	bool quoted = true;
	CC_STRING ifpath, itoken, iline;
	File *retval = NULL;

	iline = ExpandLine(intab, true, line, errmsg);
	if(!errmsg.isnull())
		goto done;

	itoken = GetIncludeFileName(iline, quoted);
	iline.clear();
	if( itoken.isnull() ) {
		errmsg.Format("Invalid include preprocessor: %s", pline.from.c_str());
		goto done;
	}

	if(!rtc->get_include_file_path(itoken, GetCurrentFileName(), quoted, preprocessor == SSID_SHARP_INCLUDE_NEXT, ifpath, &in_compiler_dir)) {
		errmsg.Format("Cannot find include file \"%s\"", itoken.c_str());
		goto done;
	}

	RealFile *file;
	pline.to = pline.from;
	file = new RealFile;
	file->SetFileName(ifpath);
	retval = file;
	*outf = NULL;

	if(has_dep_file() && ! in_compiler_dir)
		AddDependency("  ", ifpath.c_str());
done:
	return retval;
}
Example #2
0
/*------------------------------*
 * Paste n characters to a line *
 *------------------------------*/
BOOL PasteChars(LONG x, struct line_node *line, LONG length, const char *characters, struct UserAction *buffer, struct InstData *data)
{
  ENTER();

  if(line->line.Styles != NULL)
  {
    if(*line->line.Styles != EOS)
    {
      ULONG c = 0;

      while(*(line->line.Styles+c) <= x+1)
        c += 2;
      while(*(line->line.Styles+c) != EOS)
      {
        *(line->line.Styles+c) += length;
        c += 2;
      }
    }
  }

  if(line->line.Colors != NULL)
  {
    if(*line->line.Colors != 0xffff)
    {
        ULONG c = 0;

      while(*(line->line.Colors+c) <= x+1)
        c += 2;
      while(*(line->line.Colors+c) != 0xffff)
      {
        *(line->line.Colors+c) += length;
        c += 2;
      }
    }
  }

  if((*((long *)line->line.Contents-1))-4 < (LONG)(line->line.Length + length + 1))
  {
    if(ExpandLine(line, length, data) == FALSE)
    {
      RETURN(FALSE);
      return(FALSE);
    }
  }

  UpdateChange(x, line, length, characters, buffer, data);

  RETURN(TRUE);
  return(TRUE);
}
Example #3
0
/* PreprocessLine() is the "preprocessor".
 * 1. the line is tokenized with Tokenize(), Token_Count set
 * 2. (text) macros are expanded by ExpandLine()
 * 3. "preprocessor" directives are executed
 */
int PreprocessLine( char *line, struct asm_tok tokenarray[] )
/***********************************************************/
{
    int i;

    /* v2.11: GetTextLine() removed - this is now done in ProcessFile() */

    /* v2.08: moved here from GetTextLine() */
    ModuleInfo.CurrComment = NULL;
    /* v2.06: moved here from Tokenize() */
    ModuleInfo.line_flags = 0;
    /* Token_Count is the number of tokens scanned */
    Token_Count = Tokenize( line, 0, tokenarray, TOK_DEFAULT );

#ifdef DEBUG_OUT
    cntppl0++;
    if ( ModuleInfo.GeneratedCode )
        DebugMsg1(("PreprocessLine: >%s<\n", line ));
    else
        DebugMsg1(("PreprocessLine(%s): >%s< cmt=%s\n", GetTopSrcName(), line, ModuleInfo.CurrComment ? ModuleInfo.CurrComment : "" ));
#endif

#if REMOVECOMENT == 0
    if ( Token_Count == 0 && ( CurrIfState == BLOCK_ACTIVE || ModuleInfo.listif ) )
        LstWriteSrcLine();
#endif

    if ( Token_Count == 0 )
        return( 0 );

#ifdef DEBUG_OUT
    /* option -np, skip preprocessor? */
    if ( Options.skip_preprocessor )
        return( Token_Count );
#endif

    /* CurrIfState != BLOCK_ACTIVE && Token_Count == 1 | 3 may happen
     * if a conditional assembly directive has been detected by Tokenize().
     * However, it's important NOT to expand then */
    if ( CurrIfState == BLOCK_ACTIVE ) {
        if ( ( tokenarray[Token_Count].bytval & TF3_EXPANSION ? ExpandText( line, tokenarray, TRUE ) : ExpandLine( line, tokenarray ) ) < NOT_ERROR )
            return( 0 );
    }

    DebugCmd( cntppl1++ );

    i = 0;
    if ( Token_Count > 2 && ( tokenarray[1].token == T_COLON || tokenarray[1].token == T_DBL_COLON ) )
        i = 2;

    /* handle "preprocessor" directives:
     * IF, ELSE, ENDIF, ...
     * FOR, REPEAT, WHILE, ...
     * PURGE
     * INCLUDE
     * since v2.05, error directives are no longer handled here!
     */
    if ( tokenarray[i].token == T_DIRECTIVE &&
        tokenarray[i].dirtype <= DRT_INCLUDE ) {

        /* if i != 0, then a code label is located before the directive */
        if ( i > 1 ) {
            if ( ERROR == WriteCodeLabel( line, tokenarray ) )
                return( 0 );
        }
        directive_tab[tokenarray[i].dirtype]( i, tokenarray );
        return( 0 );
    }

    /* handle preprocessor directives which need a label */

    if ( tokenarray[0].token == T_ID && tokenarray[1].token == T_DIRECTIVE ) {
        struct asym *sym;
        switch ( tokenarray[1].dirtype ) {
        case DRT_EQU:
            /*
             * EQU is a special case:
             * If an EQU directive defines a text equate
             * it MUST be handled HERE and 0 must be returned to the caller.
             * This will prevent further processing, nothing will be stored
             * if FASTPASS is on.
             * Since one cannot decide whether EQU defines a text equate or
             * a number before it has scanned its argument, we'll have to
             * handle it in ANY case and if it defines a number, the line
             * must be stored and, if -EP is set, written to stdout.
             */
            if ( sym = CreateConstant( tokenarray ) ) {
                if ( sym->state != SYM_TMACRO ) {
#if FASTPASS
                    if ( StoreState ) FStoreLine( 0 );
#endif
                    if ( Options.preprocessor_stdout == TRUE )
                        WritePreprocessedLine( line );
                }
                /* v2.03: LstWrite() must be called AFTER StoreLine()! */
                if ( ModuleInfo.list == TRUE ) {
                    LstWrite( sym->state == SYM_INTERNAL ? LSTTYPE_EQUATE : LSTTYPE_TMACRO, 0, sym );
                }
            }
            return( 0 );
        case DRT_MACRO:
        case DRT_CATSTR: /* CATSTR + TEXTEQU directives */
        case DRT_SUBSTR:
            directive_tab[tokenarray[1].dirtype]( 1, tokenarray );
            return( 0 );
        }
    }

    DebugCmd( cntppl2++ );
    return( Token_Count );
}
/************************************************************************
* Function: BYTE GFXTransition(SHORT left, SHORT top, SHORT right, 
*                              SHORT bottom, GFX_TRANSITION_TYPE type, 
*                              DWORD srcpageaddr, DWORD destpageaddr,
*                              WORD delay_ms, WORD param1, WORD param2)
*                                                                       
* Overview: This function saves the parameters to be used and marks the 
*           transition to be pending which is executed when 
*           GFXExecutePendingTransition() is called
*                                                                       
* Input:    left         ->  left x coordinate
*           top          ->  top y coordinate
*           right        ->  right x coordinate
*           bottom       ->  bottom y coordinate
*           type         ->  Transition type
*           srcpageaddr  ->  Source page address for the transition
*           destpageaddr ->  Destination page address for the transition
*           delay_ms     ->  Delay in milli seconds between redraws in the 
*                            screen while executing the transition
*           param1       ->  Transition-type specific parameter
*           param2       ->  Transition-type specific parameter
*                                                                       
* Output:   0       ->  Transition executed successfully
*           -1      ->  Transition not executed
*                                                                       
************************************************************************/
BYTE GFXTransition(SHORT left, SHORT top, SHORT right, SHORT bottom, GFX_TRANSITION_TYPE type, DWORD srcpageaddr, DWORD destpageaddr, WORD delay_ms, WORD param1, WORD param2)
{
    BYTE retval = 0;
    SHORT width, height;

    if(left > right)
    {
        return (-1); /* Don't draw */
    }

    if(top > bottom)
    {
        return (-1); /* Don't draw */
    }
    
    left    = (left < 0)    ? 0: (left > GetMaxX())  ? GetMaxX(): left;
    top     = (top < 0)     ? 0: (top > GetMaxY())   ? GetMaxY(): top;
    right   = (right < 0)   ? 0: (right > GetMaxX()) ? GetMaxX(): right;
    bottom  = (bottom < 0)  ? 0: (bottom > GetMaxY())? GetMaxY(): bottom;

    #if (DISP_ORIENTATION == 0) || (DISP_ORIENTATION == 180)

        width   =   right - left + 1;
        height  =   bottom - top + 1;

    #elif (DISP_ORIENTATION == 90) || (DISP_ORIENTATION == 270)

        height  =   right - left + 1;
        width   =   bottom - top + 1;

    #endif

    #if (DISP_ORIENTATION == 90)

        bottom  =   DISP_VER_RESOLUTION - left;
        left    =   top;
        right   =   left + width;
        top     =   bottom - height;

    #elif (DISP_ORIENTATION == 180)

        right   =   DISP_HOR_RESOLUTION - left;
        bottom  =   DISP_VER_RESOLUTION - top;
        left    =   right - width;
        top     =   bottom - height;

    #elif (DISP_ORIENTATION == 270)

        right   =   DISP_HOR_RESOLUTION - top;
        top     =   left;
        bottom  =   top + height;
        left    =   right - width;

    #endif

    Startx = left;
    Starty = top;
    Width = width;
    Height = height;

    _delay_ms = delay_ms;
    _srcpageaddr = srcpageaddr;
    _destpageaddr = destpageaddr;
    _param1 = param1;
    _param2 = param2;

    switch(type)
    {
    
        case EXPANDING_RECTANGLE:
                                ExpandRectangle();
                                break;
        
        case CONTRACTING_RECTANGLE:
                                ContractRectangle();
                                break;

        case SLIDE:
                                SlideRectangle();
                                break;

        case PUSH:
                                PushRectangle();
                                break;

        case EXPANDING_LINE:
                                ExpandLine();
                                break;

        case CONTRACTING_LINE:
                                ContractLine();
                                break;

        default:
                                PlainCopyRectangle();
                                retval = 0xFF;
                                break;
    };

   return (retval);
}
Example #5
0
bool Parser::SM_Run()
{
	FILE *out_fp = included_files.top()->ofile;
	const char *pos;
	TRI_STATE result = TSV_0;
	const char *output = pline.from.c_str();
	sym_t preprocessor;
	CC_STRING expanded_line;

	do {
		pos = pline.parsed.c_str();
		preprocessor = GetPreprocessor(pos, &pos);
		if(preprocessor != pline.pp_id || (pline.content != -1 && pline.content + pline.parsed.c_str() != pos) ) {
			fprintf(stderr, "%s:%zu\n", dv_current_file, dv_current_line);
			fprintf(stderr, "  (%d) %s\n", pline.content, pline.parsed.c_str());
			fprintf(stderr, "  %d vs %d\n", preprocessor, pline.pp_id);
			exit(1);
		}
	} while(0);

	pos = pline.parsed.c_str() + pline.content;

	dv_current_file = GetCurrentFileName().c_str();
	dv_current_line = GetCurrentLineNumber();

//	GDB_TRAP2(strstr(dv_current_file,"makeint.h"), (dv_current_line==30));
//	GDB_TRAP2(strstr(dv_current_file,"/usr/include/features.h"), dv_current_line==131);
	switch(pline.pp_id) {
	case SSID_SHARP_IF:
		if( superior_conditional_value(true) != TSV_0 )
			result = (TRI_STATE) Compute(pos);
		goto handle_if_branch;

	case SSID_SHARP_IFNDEF:
		if( superior_conditional_value(true) != TSV_0 )
			result = (TRI_STATE) CheckSymbolDefined(pos, true, NULL);
		goto handle_if_branch;

	case SSID_SHARP_IFDEF:
		if( superior_conditional_value(true) != TSV_0 )
			result = (TRI_STATE) CheckSymbolDefined(pos, false, NULL);

handle_if_branch:
		if( result == TSV_X ) {
			if( gvar_preprocess_mode ) {
				if(errmsg.isnull())
					errmsg = "Error on processing conditional";
				goto done;
			}
		}

		conditionals.push(new CConditionalChain());

		upper_chain()->enter_if(result);
		upper_chain()->filename = dv_current_file;
		upper_chain()->line = dv_current_line;
		if(eval_current_conditional() != TSV_X)
			output = NULL;
		included_files.top()->add_if(result);
		break;

	case SSID_SHARP_ELIF:
		if( superior_conditional_value(false) == TSV_0 ) {
			included_files.top()->add_elif(false);
			goto done;
		}
		if( upper_chain()->has_true() ) {
			upper_chain()->enter_elif(TSV_0);
			included_files.top()->add_elif(false);
			goto done;
		}
		result = (TRI_STATE) Compute(pos);
		if( gvar_preprocess_mode && result == TSV_X)
			goto done;

		/*
		 *  Transformation on the condition of:
		 *
		 *  1) #if   0
		 *     #elif X --> #if   X
		 *
		 *  2) #elif X
		 *     #elif 1 --> #else
		 */
		if( eval_current_conditional() == TSV_0 ) {
			if(result == TSV_X) {
				pline.to = do_elif(1);
				output = pline.to.c_str();
			} else
				output = NULL;
		} else {
			if(result == TSV_1) {
				pline.to = do_elif(2);
				output = pline.to.c_str();
			} else if(result == TSV_0)
				output = NULL;
		}
		upper_chain()->enter_elif(result);
		included_files.top()->add_elif(result);
		break;

	case SSID_SHARP_ELSE:
		if( superior_conditional_value(false) == TSV_0 ) {
			included_files.top()->add_else(false);
			goto done;
		}
		result = upper_chain()->enter_else();
		included_files.top()->add_else(result);
		if( eval_current_conditional() != TSV_X )
			output = NULL;
		break;

	case SSID_SHARP_ENDIF:
		included_files.top()->add_endif();
		CConditionalChain *c;
		if( ! upper_chain()->keep_endif() )
			output = NULL;
		if( conditionals.size() == 0 ) {
			errmsg = "Unmatched #endif";
			goto done;
		}
		conditionals.pop(c);
		delete c;
		break;

	default:
		if(eval_current_conditional() == TSV_0)
			goto done;
		if(eval_current_conditional() == TSV_X)
			goto print_and_exit;

		switch(pline.pp_id) {
		  case SSID_SHARP_DEFINE:
			if(!do_define(pos))
				goto error_out;
			break;
		  case SSID_SHARP_UNDEF:
			handle_undef(intab, pos);
			break;
		  case SSID_SHARP_INCLUDE:
		  case SSID_SHARP_INCLUDE_NEXT:
			if( gvar_preprocess_mode )
				do_include(pline.pp_id, pos, &output);
			break;
		  default:
			if(gvar_expand_macros) {
				pos = pline.parsed.c_str();
				expanded_line = ExpandLine(intab, false, pos, errmsg);
				if(!errmsg.isnull())
					goto error_out;
				if(included_files.size() == 1) {
					expanded_line += '\n';
					output = expanded_line.c_str();
				}
			}
		}
	}

print_and_exit:
	if( out_fp != NULL && output != NULL )
		fprintf(out_fp, "%s", output);
done:
	pline.comment_start = -1;
	if(gvar_preprocess_mode && GetError()) {
		IncludedFile *tmp;
		CC_STRING pmsg, ts;
		while(included_files.size() > 0) {
			included_files.pop(tmp);
			ts.Format("  %s:%u\n", tmp->ifile->name.c_str(), tmp->ifile->line);
			pmsg += ts;
		}
		if( !pmsg.isnull() ) {
			errmsg = pmsg + errmsg;
		}
	}
	return gvar_preprocess_mode ? (GetError() == NULL) : true;

error_out:
	return false;
}
Example #6
0
int Parser::Compute(const char *line)
{
	static const char opp[] = { '<', '=', '>', 'X'};
	enum {
		STAT_INIT,
		STAT_OPR1,
		STAT_OPR2,
		STAT_OPND,
		STAT_DEFINED,  /* defined    */
		STAT_DEFINED1, /* defined(   */
		STAT_DEFINED2, /* defined(X  */
	} state;
	CC_STACK<sym_t>  opr_stack;
	CC_STACK<SynToken>  opnd_stack;
	sym_t last_opr = SSID_SHARP;
	SynToken last_token;
	char sign;
	const char *symbol = NULL;
	LOG_VERB dml = LOGV_DEBUG;
	CC_STRING expansion;

	if(!gvar_preprocess_mode) {
		/*
		 *  Keep `#if 0' blocks which are usually user comments.
		 */
		char *copied_line = strdup(line);
		const char *first = strtok(copied_line, " \t");
		int ignore = 0;
		/* Simple code and work properly in most cases */
		if(first && first[0] == '0')
			ignore = 1;
		free(copied_line);
		if(ignore)
			return TSV_X;
	}

	expansion = ExpandLine(intab, false, line, errmsg);
	if( !errmsg.isnull() ) {
		return TSV_X;
	}

	ReadReq req(expansion.c_str());
	SynToken& token = req.token;
	opr_stack.push(SSID_SHARP);
	log(dml, "PUSH OPR: #\n");
	sign = 0;
	state = STAT_OPR1;
	while(1) {
		sym_t  opr;
		const char *last_pos = req.cp;
		int ret;

		ret = ReadToken(intab, &req, false);
		if( ret == 0 )
			break;
		else if( ret < 0 )
			goto error;

		if( token.attr == SynToken::TA_CHAR )
			token.attr = SynToken::TA_INT;
		if( sign != 0 ) {
			if(token.attr != SynToken::TA_UINT && token.id != SSID_DEFINED) {
				errmsg.Format("%s following %c", TR(intab,token.id), sign);
				goto error;
			}
			if(sign == '-') {
				token.attr = SynToken::TA_INT;
				token.i32_val = -token.i32_val;
			}
			sign = 0;
		} else if( (token.id == SSID_ADDITION || token.id == SSID_SUBTRACTION) &&  CheckPrevOperator(last_opr)) {
			sign = token.id == SSID_ADDITION ? '+' : '-';
			goto next;
		}

		switch(state) {
		case STAT_INIT:
			if(IsOperator(token.id))
				state = STAT_OPR1;
			else if(token.id == SSID_DEFINED)
				state = STAT_DEFINED;
			else if(token.attr == SynToken::TA_IDENT)
				state = STAT_OPND;
			break;
		case STAT_OPND:
			if(IsOperator(token.id))
				state = STAT_OPR1;
			else {
				errmsg = "Adjacent operands";
				goto error;
			}
			break;
		case STAT_OPR1:
			if(IsOperator(token.id))
				state = STAT_OPR2;
			else if(token.id == SSID_DEFINED)
				state = STAT_DEFINED;
			else
				state= STAT_INIT;
			break;
		case STAT_OPR2:
			if(IsOperator(token.id)) {
			} else if(token.id == SSID_DEFINED)
				state = STAT_DEFINED;
			else
				state = STAT_INIT;
			break;
		case STAT_DEFINED:
			if(token.id == SSID_LEFT_PARENTHESIS)
				state = STAT_DEFINED1;
			else if(token.attr == SynToken::TA_IDENT) {
				CheckSymbolDefined(last_pos, false, &token);
				if(!errmsg.isnull())
					goto error;
				state = STAT_INIT;
			}
			break;
		case STAT_DEFINED1:
			if(token.attr == SynToken::TA_IDENT) {
				state = STAT_DEFINED2;
				symbol = last_pos;
			} else {
				errmsg = "Syntax error: ";
				goto error;
			}
			break;
		case STAT_DEFINED2:
			if(token.id == SSID_RIGHT_PARENTHESIS) {
				CheckSymbolDefined(symbol, false, &token);
				if(!errmsg.isnull())
					goto error;
				state = STAT_INIT;
				opnd_stack.push(token);
				opr = token.id;
				goto next;
			} else {
				errmsg = "Unmatched (";
				goto error;
			}
			break;
		}
		if(state == STAT_DEFINED || state == STAT_DEFINED1 || state == STAT_DEFINED2)
			goto next;

		if( token.id == SynToken::TA_UINT || token.id == SynToken::TA_INT )
			log(dml, "Current: %u\n", token.u32_val);
		else
			log(dml, "Current: %s\n", TR(intab,token.id));
//		log(dml, "OPR  Stack: \n", opr_stack);
//		log(dml, "OPND Stack: \n", opnd_stack);
		opr = token.id;
		if( IsOperator(opr) ) {
			sym_t opr0;
			int result;
again:
			opr0 = opr_stack.top();
			result = intab->opMat.Compare(opr0, opr);
			log(dml, "Compare: %s %c %s\n", TR(intab,opr0),opp[1+result],TR(intab,opr));
			switch(result) {
			case _EQ:
				opr_stack.pop(opr0);
				break;
			case _GT:
				opr_stack.pop(opr0);
				if( ! CalculateOnStackTop(opr0, opnd_stack, opr_stack) ) {
					goto error;
				}
				goto again;
			case _LT:
				opr_stack.push(opr);
				break;
			case _XX:
				errmsg.Format("Cannot compare \"%s\" and \"%s\"", TR(intab,opr0), TR(intab,opr));
				log(LOGV_ERROR, "*ERROR* %s\n", errmsg.c_str());
				goto error;
			}
		} else {
			opnd_stack.push(token);
		}

	next:
		last_opr = opr;
	}

	do {
		sym_t opr0;
		int result;

		if( ! opr_stack.pop(opr0) )
			goto error;
		result = intab->opMat.Compare(opr0, SSID_SHARP);
		log(dml, "Compare: %s %c #\n", TR(intab,opr0),opp[result]);
		switch(result) {
		case _EQ:
			break;
		case _GT:
			if( ! CalculateOnStackTop(opr0, opnd_stack, opr_stack) ) {
				goto error;
			}
			break;
		default:
			log(LOGV_ERROR, "%s:%u: Bad expression\n", __func__,  __LINE__);
			errmsg = "[1] Bad expression";
			goto error;
		}
	} while( opr_stack.size() != 0 );

	if( opnd_stack.size() != 1 ) {
		log(LOGV_ERROR, "%s:%u: Bad expression\n", __func__,  __LINE__);
		errmsg = "[2] Bad expression";
		goto error;
	}

	if( opnd_stack.top().attr == SynToken::TA_IDENT ) {
		if( gvar_preprocess_mode ) {
			return TSV_0;
		}
		return TSV_X;
	}
	log(dml, "Numberic Value: %u\n", opnd_stack.top().i32_val);;
	return !!opnd_stack.top().i32_val;

error:
	log(LOGV_ERROR, "*Error* %s\n", errmsg.c_str());
	return gvar_preprocess_mode ? TSV_0 : TSV_X;
}