Ejemplo n.º 1
0
void TPpContext::setInput(TInputScanner& input, bool versionWillBeError)
{
    assert(inputStack.size() == 0);

    pushInput(new tStringInput(this, input));

    errorOnVersion = versionWillBeError;
    versionSeen = false;
}
Ejemplo n.º 2
0
Archivo: Pp.cpp Proyecto: Alprog/Judy
// Handle #include
int TPpContext::CPPinclude(TPpToken* ppToken)
{
    const TSourceLoc directiveLoc = ppToken->loc;
    int token = scanToken(ppToken);
    if (token != PpAtomConstString) {
        // TODO: handle angle brackets.
        parseContext.ppError(directiveLoc, "must be followed by a file designation", "#include", "");
    } else {
        // Make a copy of the name because it will be overwritten by the next token scan.
        const std::string filename = ppToken->name;
        token = scanToken(ppToken);
        if (token != '\n' && token != EndOfInput) {
            parseContext.ppError(ppToken->loc, "extra content after file designation", "#include", "");
        } else {
            TShader::Includer::IncludeResult* res = includer.include(filename.c_str(), TShader::Includer::EIncludeRelative, currentSourceFile.c_str(), includeStack.size() + 1);
            if (res && !res->file_name.empty()) {
                if (res->file_data && res->file_length) {
                    const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
                    std::ostringstream prologue;
                    std::ostringstream epilogue;
                    prologue << "#line " << forNextLine << " " << "\"" << res->file_name << "\"\n";
                    epilogue << (res->file_data[res->file_length - 1] == '\n'? "" : "\n") << "#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n";
                    pushInput(new TokenizableIncludeFile(directiveLoc, prologue.str(), res, epilogue.str(), this));
                }
                // At EOF, there's no "current" location anymore.
                if (token != EndOfInput) parseContext.setCurrentColumn(0);
                // Don't accidentally return EndOfInput, which will end all preprocessing.
                return '\n';
            } else {
                std::string message =
                    res ? std::string(res->file_data, res->file_length)
                        : std::string("Could not process include directive");
                parseContext.ppError(directiveLoc, message.c_str(), "#include", "");
                if (res) {
                    includer.releaseInclude(res);
                }
            }
        }
    }
    return token;
}
Ejemplo n.º 3
0
// Handle #include
int TPpContext::CPPinclude(TPpToken* ppToken)
{
    const TSourceLoc directiveLoc = ppToken->loc;
    int token = scanToken(ppToken);
    if (token != PpAtomConstString) {
        // TODO: handle angle brackets.
        parseContext.ppError(directiveLoc, "must be followed by a file designation", "#include", "");
    } else {
        // Make a copy of the name because it will be overwritten by the next token scan.
        const std::string filename = ppToken->name;
        token = scanToken(ppToken);
        if (token != '\n' && token != EndOfInput) {
            parseContext.ppError(ppToken->loc, "extra content after file designation", "#include", "");
        } else {
            std::string sourceName;
            std::string replacement;
            std::tie(sourceName, replacement) = includer.include(filename.c_str());
            if (!sourceName.empty()) {
                if (!replacement.empty()) {
                    const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
                    std::ostringstream content;
                    content << "#line " << forNextLine << " " << "\"" << sourceName << "\"\n";
                    content << replacement << (replacement.back() == '\n' ? "" : "\n");
                    content << "#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n";
                    pushInput(new TokenizableString(directiveLoc, content.str(), this));
                }
                // At EOF, there's no "current" location anymore.
                if (token != EndOfInput) parseContext.setCurrentColumn(0);
                // Don't accidentally return EndOfInput, which will end all preprocessing.
                return '\n';
            } else {
                parseContext.ppError(directiveLoc, replacement.c_str(), "#include", "");
            }
        }
    }
    return token;
}
Ejemplo n.º 4
0
// Macro-expand a macro argument 'arg' to create 'expandedArg'.
// Does not replace 'arg'.
// Returns nullptr if no expanded argument is created.
TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken* ppToken, bool newLineOkay)
{
    // expand the argument
    TokenStream* expandedArg = new TokenStream;
    pushInput(new tMarkerInput(this));
    pushTokenStreamInput(arg);
    int token;
    while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) {
        token = tokenPaste(token, *ppToken);
        if (token == PpAtomIdentifier) {
            switch (MacroExpand(ppToken, false, newLineOkay)) {
            case MacroExpandNotStarted:
                break;
            case MacroExpandError:
                // toss the rest of the pushed-input argument by scanning until tMarkerInput
                while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput)
                    ;
                break;
            case MacroExpandStarted:
            case MacroExpandUndef:
                continue;
            }
        }
        if (token == tMarkerInput::marker || token == EndOfInput)
            break;
        expandedArg->putToken(token, ppToken);
    }

    if (token != tMarkerInput::marker) {
        // Error, or MacroExpand ate the marker, so had bad input, recover
        delete expandedArg;
        expandedArg = nullptr;
    }

    return expandedArg;
}
Ejemplo n.º 5
0
void TPpContext::UngetToken(int token, TPpToken* ppToken)
{
    pushInput(new tUngotTokenInput(this, token, ppToken));
}
Ejemplo n.º 6
0
void TPpContext::pushTokenStreamInput(TokenStream& ts, bool prepasting)
{
    pushInput(new tTokenInput(this, &ts, prepasting));
    ts.reset();
}
Ejemplo n.º 7
0
int main(int argc, char **argv){	
	int inputsNumber = 0;
	int stdIn = 0;//stdIn pas utilise
	input* listOfInputs = NULL;// liste des entrees a traiter
	int maxThreads = 0;
	
	
	int  i;
	//Parcoure tous les arguments de lancement du programme
	for(i = 1; i < argc; i++){
		char* in = argv[i];
		if(strcmp(in, MAX_THREADS_TK) == 0){ //maxthreads
			maxThreads = atoi(argv[i+1]);
			i++;
			//on passe 2 arguments puisqu'on a deja utilise le nombre
			// de threads max
			printf("Maxthreads set to %d\n",maxThreads);
		}
		else if (strcmp(in, STDIN_TK) == 0){ //stdIn
			stdIn = 1; // stdIn utilise
			inputsNumber++;
			printf("Stdin set \n");
		}
		else if (strcmp(in, FILE_TK) == 0){ //fichier
			if(pushInput(&listOfInputs, argv[i+1]) != 0){
				//probleme de malloc, arrete le programme
				exit(errno);
			}
			else{
				printf("Added %s to inputs\n", argv[i+1]);
				i++;
				inputsNumber++;
			}
		}
		else if(strstr(in, URL_TK) != NULL){ //URL
			if(pushInput(&listOfInputs, argv[i]) != 0){
				//probleme de malloc, arrete le programme
				exit(errno);
			}
			else{
				printf("Added %s to inputs\n", argv[i]);
				inputsNumber++;
			}
		}
		else{ //erreur de format
			fprintf(stderr, "Erreur: mauvais format");
			exit(-1);
		}
	}
	
	printf("Number of inputs %d\n", inputsNumber);
	
	if(maxThreads == 0){ /// a voir
		maxThreads = 10;
		printf("maxthread was 0, assigned to %d\n", maxThreads);
	}
	
	//initialisation des threads et semaphores
	pthread_t* threads; //threads utilises
	threads = (pthread_t*) malloc(sizeof(pthread_t) * maxThreads);
	sem_init(&available_switching, 0, 1); //switching disponible 
	sem_init(&available_thread, 0, 0); // aucun thread n'a termine
	available_thread_index = -1;
	
	
	//lance tous les threads
	int err = launchAllThreads(maxThreads, &stdIn, &inputsNumber, &listOfInputs, &threads);
	if(err){
		fprintf(stderr, "Erreur dans launchAllThreads: %d\n", err);
		exit(err);
	}
	printf("All threads launched, inputs left: %d\n", inputsNumber);
	
	setbuf(stdout, NULL); // stoppe le buffer
	
	while(inputsNumber > 0){
		printf("Rentre ici \n");
		sem_wait(&available_thread); // attend qu'un thread ait termine
		//zone critique
		printf("Zone critique\n");
		err = pthread_join(threads[available_thread_index], NULL);
		if(err){
			fprintf(stderr, "Erreur dans pthread_join: %d\n", err);
			exit(err);
		}
		char* file = popInput(&listOfInputs);
		printf("filename: %s\n", file);
		if (file == NULL){
			fprintf(stderr, "Erreur dans popInput\n");
			exit(-1);
		}
		thread_arg t_arg;
		t_arg.file = file;
		t_arg.fileType = getFileType(file);
		t_arg.threadIndex = available_thread_index;
		printf("switching producer number: %d , now on %s \n", available_thread_index, file);
		err = pthread_create(&threads[available_thread_index], NULL, &threadLauncher, &t_arg);
		if(err){
			fprintf(stderr, "Erreur dans pthread_create: %d\n", errno);
			exit(errno);
		}
		available_thread_index = -1; // pas necessaire mais plus prudent
		inputsNumber--;
		sem_post(&available_switching); //permet aux thread de signaler 
		//qu'ils ont fini
	}	
	
	///TODO every producer to consumer
	//free(threads); //ne pas oublier !	
	exit(EXIT_SUCCESS);
}
Ejemplo n.º 8
0
void TPpContext::pushTokenStreamInput(TokenStream* ts)
{
    pushInput(new tTokenInput(this, ts));
    RewindTokenStream(ts);
}
Ejemplo n.º 9
0
//
// Check an identifier (atom) to see if it is a macro that should be expanded.
// If it is, and defined, push a tInput that will produce the appropriate expansion
// and return 1.
// If it is, but undefined, and expandUndef is requested, push a tInput that will 
// expand to 0 and return -1.
// Otherwise, return 0 to indicate no expansion, which is not necessarily an error.
//
int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool newLineOkay)
{
    ppToken->space = false;
    switch (atom) {
    case PpAtomLineMacro:
        ppToken->ival = parseContext.getCurrentLoc().line;
        sprintf(ppToken->name, "%d", ppToken->ival);
        UngetToken(PpAtomConstInt, ppToken);
        return 1;

    case PpAtomFileMacro: {
        if (parseContext.getCurrentLoc().name)
            parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based __FILE__");
        ppToken->ival = parseContext.getCurrentLoc().string;
        sprintf(ppToken->name, "%s", ppToken->loc.getStringNameOrNum().c_str());
        UngetToken(PpAtomConstInt, ppToken);
        return 1;
    }

    case PpAtomVersionMacro:
        ppToken->ival = parseContext.version;
        sprintf(ppToken->name, "%d", ppToken->ival);
        UngetToken(PpAtomConstInt, ppToken);
        return 1;

    default:
        break;
    }

    Symbol *sym = LookUpSymbol(atom);
    int token;
    int depth = 0;

    // no recursive expansions
    if (sym && sym->mac.busy)
        return 0;

    // not expanding undefined macros
    if ((! sym || sym->mac.undef) && ! expandUndef)
        return 0;

    // 0 is the value of an undefined macro
    if ((! sym || sym->mac.undef) && expandUndef) {
        pushInput(new tZeroInput(this));
        return -1;
    }

    tMacroInput *in = new tMacroInput(this);

    TSourceLoc loc = ppToken->loc;  // in case we go to the next line before discovering the error
    in->mac = &sym->mac;
    if (sym->mac.args) {
        token = scanToken(ppToken);
        if (newLineOkay) {
            while (token == '\n')                
                token = scanToken(ppToken);
        }
        if (token != '(') {
            parseContext.ppError(loc, "expected '(' following", "macro expansion", GetAtomString(atom));
            UngetToken(token, ppToken);
            ppToken->atom = atom;

            delete in;
            return 0;
        }
        in->args.resize(in->mac->argc);
        for (int i = 0; i < in->mac->argc; i++)
            in->args[i] = new TokenStream;
        int arg = 0;
        bool tokenRecorded = false;
        do {
            depth = 0;
            while (1) {
                token = scanToken(ppToken);
                if (token == EndOfInput) {
                    parseContext.ppError(loc, "End of input in macro", "macro expansion", GetAtomString(atom));
                    delete in;
                    return 0;
                }
                if (token == '\n') {
                    if (! newLineOkay) {
                        parseContext.ppError(loc, "End of line in macro substitution:", "macro expansion", GetAtomString(atom));
                        delete in;
                        return 0;
                    }
                    continue;
                }
                if (token == '#') {
                    parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", GetAtomString(atom));
                    delete in;
                    return 0;
                }
                if (in->mac->argc == 0 && token != ')')
                    break;
                if (depth == 0 && (token == ',' || token == ')'))
                    break;
                if (token == '(')
                    depth++;
                if (token == ')')
                    depth--;
                RecordToken(in->args[arg], token, ppToken);
                tokenRecorded = true;
            }
            if (token == ')') {
                if (in->mac->argc == 1 && tokenRecorded == 0)
                    break;
                arg++;
                break;
            }
            arg++;
        } while (arg < in->mac->argc);

        if (arg < in->mac->argc)
            parseContext.ppError(loc, "Too few args in Macro", "macro expansion", GetAtomString(atom));
        else if (token != ')') {
            depth=0;
            while (token != EndOfInput && (depth > 0 || token != ')')) {
                if (token == ')')
                    depth--;
                token = scanToken(ppToken);
                if (token == '(')
                    depth++;
            }

            if (token == EndOfInput) {
                parseContext.ppError(loc, "End of input in macro", "macro expansion", GetAtomString(atom));
                delete in;
                return 0;
            }
            parseContext.ppError(loc, "Too many args in macro", "macro expansion", GetAtomString(atom));
        }
        for (int i = 0; i < in->mac->argc; i++)
            in->args[i] = PrescanMacroArg(in->args[i], ppToken, newLineOkay);
    }

    pushInput(in);
    sym->mac.busy = 1;
    RewindTokenStream(sym->mac.body);

    return 1;
}
Ejemplo n.º 10
0
void DeviceFilter::handleInput(const std::string& device, const DataGroup& inputData)
{
	filterInput(device, inputData, &getInputData());
	pushInput();
}
Ejemplo n.º 11
0
// Handle #include ...
// TODO: Handle macro expansions for the header name
int TPpContext::CPPinclude(TPpToken* ppToken)
{
    const TSourceLoc directiveLoc = ppToken->loc;
    bool startWithLocalSearch = true; // to additionally include the extra "" paths
    int token = scanToken(ppToken);

    // handle <header-name>-style #include
    if (token == '<') {
        startWithLocalSearch = false;
        token = scanHeaderName(ppToken, '>');
    }
    // otherwise ppToken already has the header name and it was "header-name" style

    if (token != PpAtomConstString) {
        parseContext.ppError(directiveLoc, "must be followed by a header name", "#include", "");
        return token;
    }

    // Make a copy of the name because it will be overwritten by the next token scan.
    const std::string filename = ppToken->name;

    // See if the directive was well formed
    token = scanToken(ppToken);
    if (token != '\n') {
        if (token == EndOfInput)
            parseContext.ppError(ppToken->loc, "expected newline after header name:", "#include", "%s", filename.c_str());
        else
            parseContext.ppError(ppToken->loc, "extra content after header name:", "#include", "%s", filename.c_str());
        return token;
    }

    // Process well-formed directive

    // Find the inclusion, first look in "Local" ("") paths, if requested,
    // otherwise, only search the "System" (<>) paths.
    TShader::Includer::IncludeResult* res = nullptr;
    if (startWithLocalSearch)
        res = includer.includeLocal(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
    if (res == nullptr || res->headerName.empty()) {
        includer.releaseInclude(res);
        res = includer.includeSystem(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
    }

    // Process the results
    if (res != nullptr && !res->headerName.empty()) {
        if (res->headerData != nullptr && res->headerLength > 0) {
            // path for processing one or more tokens from an included header, hand off 'res'
            const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
            std::ostringstream prologue;
            std::ostringstream epilogue;
            prologue << "#line " << forNextLine << " " << "\"" << res->headerName << "\"\n";
            epilogue << (res->headerData[res->headerLength - 1] == '\n'? "" : "\n") <<
                "#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n";
            pushInput(new TokenizableIncludeFile(directiveLoc, prologue.str(), res, epilogue.str(), this));
            // There's no "current" location anymore.
            parseContext.setCurrentColumn(0);
        } else {
            // things are okay, but there is nothing to process
            includer.releaseInclude(res);
        }
    } else {
        // error path, clean up
        std::string message =
            res != nullptr ? std::string(res->headerData, res->headerLength)
                           : std::string("Could not process include directive");
        parseContext.ppError(directiveLoc, message.c_str(), "#include", "for header name: %s", filename.c_str());
        includer.releaseInclude(res);
    }

    return token;
}
Ejemplo n.º 12
0
//
// Check a token to see if it is a macro that should be expanded.
// If it is, and defined, push a tInput that will produce the appropriate expansion
// and return 1.
// If it is, but undefined, and expandUndef is requested, push a tInput that will
// expand to 0 and return -1.
// Otherwise, return 0 to indicate no expansion, which is not necessarily an error.
//
int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay)
{
    ppToken->space = false;
    int macroAtom = atomStrings.getAtom(ppToken->name);
    switch (macroAtom) {
    case PpAtomLineMacro:
        ppToken->ival = parseContext.getCurrentLoc().line;
        snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
        UngetToken(PpAtomConstInt, ppToken);
        return 1;

    case PpAtomFileMacro: {
        if (parseContext.getCurrentLoc().name)
            parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based __FILE__");
        ppToken->ival = parseContext.getCurrentLoc().string;
        snprintf(ppToken->name, sizeof(ppToken->name), "%s", ppToken->loc.getStringNameOrNum().c_str());
        UngetToken(PpAtomConstInt, ppToken);
        return 1;
    }

    case PpAtomVersionMacro:
        ppToken->ival = parseContext.version;
        snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
        UngetToken(PpAtomConstInt, ppToken);
        return 1;

    default:
        break;
    }

    MacroSymbol* macro = macroAtom == 0 ? nullptr : lookupMacroDef(macroAtom);
    int token;
    int depth = 0;

    // no recursive expansions
    if (macro != nullptr && macro->busy)
        return 0;

    // not expanding undefined macros
    if ((macro == nullptr || macro->undef) && ! expandUndef)
        return 0;

    // 0 is the value of an undefined macro
    if ((macro == nullptr || macro->undef) && expandUndef) {
        pushInput(new tZeroInput(this));
        return -1;
    }

    tMacroInput *in = new tMacroInput(this);

    TSourceLoc loc = ppToken->loc;  // in case we go to the next line before discovering the error
    in->mac = macro;
    if (macro->args.size() > 0 || macro->emptyArgs) {
        token = scanToken(ppToken);
        if (newLineOkay) {
            while (token == '\n')
                token = scanToken(ppToken);
        }
        if (token != '(') {
            parseContext.ppError(loc, "expected '(' following", "macro expansion", atomStrings.getString(macroAtom));
            UngetToken(token, ppToken);
            delete in;
            return 0;
        }
        in->args.resize(in->mac->args.size());
        for (size_t i = 0; i < in->mac->args.size(); i++)
            in->args[i] = new TokenStream;
        in->expandedArgs.resize(in->mac->args.size());
        for (size_t i = 0; i < in->mac->args.size(); i++)
            in->expandedArgs[i] = nullptr;
        size_t arg = 0;
        bool tokenRecorded = false;
        do {
            depth = 0;
            while (1) {
                token = scanToken(ppToken);
                if (token == EndOfInput || token == tMarkerInput::marker) {
                    parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom));
                    delete in;
                    return 0;
                }
                if (token == '\n') {
                    if (! newLineOkay) {
                        parseContext.ppError(loc, "End of line in macro substitution:", "macro expansion", atomStrings.getString(macroAtom));
                        delete in;
                        return 0;
                    }
                    continue;
                }
                if (token == '#') {
                    parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", atomStrings.getString(macroAtom));
                    delete in;
                    return 0;
                }
                if (in->mac->args.size() == 0 && token != ')')
                    break;
                if (depth == 0 && (token == ',' || token == ')'))
                    break;
                if (token == '(')
                    depth++;
                if (token == ')')
                    depth--;
                in->args[arg]->putToken(token, ppToken);
                tokenRecorded = true;
            }
            if (token == ')') {
                if (in->mac->args.size() == 1 && tokenRecorded == 0)
                    break;
                arg++;
                break;
            }
            arg++;
        } while (arg < in->mac->args.size());

        if (arg < in->mac->args.size())
            parseContext.ppError(loc, "Too few args in Macro", "macro expansion", atomStrings.getString(macroAtom));
        else if (token != ')') {
            depth=0;
            while (token != EndOfInput && (depth > 0 || token != ')')) {
                if (token == ')')
                    depth--;
                token = scanToken(ppToken);
                if (token == '(')
                    depth++;
            }

            if (token == EndOfInput) {
                parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom));
                delete in;
                return 0;
            }
            parseContext.ppError(loc, "Too many args in macro", "macro expansion", atomStrings.getString(macroAtom));
        }

        // We need both expanded and non-expanded forms of the argument, for whether or
        // not token pasting will be applied later when the argument is consumed next to ##.
        for (size_t i = 0; i < in->mac->args.size(); i++)
            in->expandedArgs[i] = PrescanMacroArg(*in->args[i], ppToken, newLineOkay);
    }

    pushInput(in);
    macro->busy = 1;
    macro->body.reset();

    return 1;
}
Ejemplo n.º 13
0
/*****************************************************************************
* First character of command id should be second char of line
* Lexer returns a full line of data, needs to be parsed if .ce
* In version 1.0, valid commands are:
* .* (comment) followed by text to '\n'
* .br (new line), nothing else allowed on line
* .im (include file) 'filename'
* .nameit (define text macro) symbol=[a-zA-Z0-9]+ (10 max) text='text string'
*     text may contain entity references, nameit references and tags
* .ce (center) no tags, but text and both entity types
* Version 2.0 only supports .*, .br, .im
*/
Lexer::Token Document::processCommand( Lexer* lexer, Tag* parent )
{
    if( lexer->cmdId() == Lexer::COMMENT )
        ;//do nothing
    else if( lexer->cmdId() == Lexer::BREAK )
        parent->appendChild( new BrCmd( this, parent, dataName(), dataLine(), dataCol() ) );
    else if( lexer->cmdId() == Lexer::CENTER ) {
        CeCmd* cecmd( new CeCmd( this, parent, dataName(), dataLine(), dataCol() ) );
        parent->appendChild( cecmd );
        return cecmd->parse( lexer );
    }
    else if( lexer->cmdId() == Lexer::IMBED ) {
        std::string env( Environment.value( "IPFCIMBED" ) );
        std::vector< std::wstring > paths;
        std::wstring cwd;   //empty string for current directory
        paths.push_back( cwd );
#ifdef __UNIX__
        std::string separators( ":;" );
        char slash( '/' );
#else
        std::string separators( ";" );
        char slash( '\\' );
#endif
        std::string::size_type idx1( 0 );
        std::string::size_type idx2( env.find_first_of( separators, idx1 ) );
        std::wstring fbuffer;
        mbtowstring( env.substr( idx1, idx2 - idx1 ), fbuffer );
        paths.push_back( fbuffer );
        while( idx2 != std::string::npos ) {
            idx1 = idx2 + 1;
            idx2 = env.find_first_of( separators, idx1 );
            fbuffer.clear();
            mbtowstring( env.substr( idx1, idx2 - idx1 ), fbuffer );
            paths.push_back( fbuffer );
        }
        for( size_t count = 0; count < paths.size(); ++count ) {
            std::wstring* fname( new std::wstring( paths[ count ] ) );
            if( !fname->empty() )
                *fname += slash;
            *fname += lexer->text();
#ifndef __UNIX__
            if( fname->size() > PATH_MAX ) {
                throw FatalError( ERR_PATH_MAX );
            }
#endif
            try {
                IpfFile* ipff( new IpfFile( fname ) );
                fname = addFileName( fname );
                pushInput( ipff );
                break;
            }
            catch( FatalError& e ) {
                delete fname;
                if( count == paths.size() - 1 )
                    throw e;
            }
            catch( FatalIOError& e ) {
                delete fname;
                if( count == paths.size() - 1 )
                    throw e;
            }
        }
    }
    else if( lexer->cmdId() == Lexer::NAMEIT ) {
        std::wstring::size_type idx1( lexer->text().find( L"symbol=" ) );
        std::wstring::size_type idx2( lexer->text().find( L' ', idx1 ) );
        std::wstring sym( lexer->text().substr( idx1 + 7, idx2 - idx1 - 7 ) );
        killQuotes( sym );
        sym.insert( sym.begin(), L'&' );
        sym += L'.';
        std::wstring::size_type idx3( lexer->text().find( L"text=" ) );
        //check for single quotes
        std::wstring::size_type idx4( lexer->text()[ idx3 + 5 ] == L'\'' ? \
            lexer->text().find( L'\'', idx3  + 6 ) : \
            lexer->text().find( L' ', idx3 + 5 ) );
        std::wstring txt( lexer->text().substr( idx3 + 5, idx4 - idx3 - 5 ) );
        killQuotes( txt );
        if( !nls->isEntity( sym ) && nameIts.find( sym ) == nameIts.end() ) //add it to the list
            nameIts.insert( std::map< std::wstring, std::wstring >::value_type( sym, txt ) );
        else
            printError( ERR3_DUPSYMBOL );
    }
    else
        printError( ERR1_CMDNOTDEF );
    return getNextToken();
}
Ejemplo n.º 14
0
void TextManager::input(int lin,int col, int code){
  setInputPool(code);
  getInput(lin,col);
  pushInput(code);
}
Ejemplo n.º 15
0
void TestDevice::pushInput(const std::string& data)
{
	getInputData().strings().set("helloWorld", data);
	pushInput();
}
Ejemplo n.º 16
0
//
// Check a token to see if it is a macro that should be expanded:
// - If it is, and defined, push a tInput that will produce the appropriate
//   expansion and return MacroExpandStarted.
// - If it is, but undefined, and expandUndef is requested, push a tInput
//   that will expand to 0 and return MacroExpandUndef.
// - Otherwise, there is no expansion, and there are two cases:
//   * It might be okay there is no expansion, and no specific error was
//     detected. Returns MacroExpandNotStarted.
//   * The expansion was started, but could not be completed, due to an error
//     that cannot be recovered from. Returns MacroExpandError.
//
MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay)
{
    ppToken->space = false;
    int macroAtom = atomStrings.getAtom(ppToken->name);
    switch (macroAtom) {
    case PpAtomLineMacro:
        ppToken->ival = parseContext.getCurrentLoc().line;
        snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
        UngetToken(PpAtomConstInt, ppToken);
        return MacroExpandStarted;

    case PpAtomFileMacro: {
        if (parseContext.getCurrentLoc().name)
            parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based __FILE__");
        ppToken->ival = parseContext.getCurrentLoc().string;
        snprintf(ppToken->name, sizeof(ppToken->name), "%s", ppToken->loc.getStringNameOrNum().c_str());
        UngetToken(PpAtomConstInt, ppToken);
        return MacroExpandStarted;
    }

    case PpAtomVersionMacro:
        ppToken->ival = parseContext.version;
        snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
        UngetToken(PpAtomConstInt, ppToken);
        return MacroExpandStarted;

    default:
        break;
    }

    MacroSymbol* macro = macroAtom == 0 ? nullptr : lookupMacroDef(macroAtom);

    // no recursive expansions
    if (macro != nullptr && macro->busy)
        return MacroExpandNotStarted;

    // not expanding undefined macros
    if ((macro == nullptr || macro->undef) && ! expandUndef)
        return MacroExpandNotStarted;

    // 0 is the value of an undefined macro
    if ((macro == nullptr || macro->undef) && expandUndef) {
        pushInput(new tZeroInput(this));
        return MacroExpandUndef;
    }

    tMacroInput *in = new tMacroInput(this);

    TSourceLoc loc = ppToken->loc;  // in case we go to the next line before discovering the error
    in->mac = macro;
    if (macro->functionLike) {
        // We don't know yet if this will be a successful call of a
        // function-like macro; need to look for a '(', but without trashing
        // the passed in ppToken, until we know we are no longer speculative.
        TPpToken parenToken;
        int token = scanToken(&parenToken);
        if (newLineOkay) {
            while (token == '\n')
                token = scanToken(&parenToken);
        }
        if (token != '(') {
            // Function-like macro called with object-like syntax: okay, don't expand.
            // (We ate exactly one token that might not be white space; put it back.
            UngetToken(token, &parenToken);
            delete in;
            return MacroExpandNotStarted;
        }
        in->args.resize(in->mac->args.size());
        for (size_t i = 0; i < in->mac->args.size(); i++)
            in->args[i] = new TokenStream;
        in->expandedArgs.resize(in->mac->args.size());
        for (size_t i = 0; i < in->mac->args.size(); i++)
            in->expandedArgs[i] = nullptr;
        size_t arg = 0;
        bool tokenRecorded = false;
        do {
            TVector<char> nestStack;
            while (true) {
                token = scanToken(ppToken);
                if (token == EndOfInput || token == tMarkerInput::marker) {
                    parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom));
                    delete in;
                    return MacroExpandError;
                }
                if (token == '\n') {
                    if (! newLineOkay) {
                        parseContext.ppError(loc, "End of line in macro substitution:", "macro expansion", atomStrings.getString(macroAtom));
                        delete in;
                        return MacroExpandError;
                    }
                    continue;
                }
                if (token == '#') {
                    parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", atomStrings.getString(macroAtom));
                    delete in;
                    return MacroExpandError;
                }
                if (in->mac->args.size() == 0 && token != ')')
                    break;
                if (nestStack.size() == 0 && (token == ',' || token == ')'))
                    break;
                if (token == '(')
                    nestStack.push_back(')');
                else if (token == '{' && parseContext.isReadingHLSL())
                    nestStack.push_back('}');
                else if (nestStack.size() > 0 && token == nestStack.back())
                    nestStack.pop_back();
                in->args[arg]->putToken(token, ppToken);
                tokenRecorded = true;
            }
            // end of single argument scan

            if (token == ')') {
                // closing paren of call
                if (in->mac->args.size() == 1 && !tokenRecorded)
                    break;
                arg++;
                break;
            }
            arg++;
        } while (arg < in->mac->args.size());
        // end of all arguments scan

        if (arg < in->mac->args.size())
            parseContext.ppError(loc, "Too few args in Macro", "macro expansion", atomStrings.getString(macroAtom));
        else if (token != ')') {
            // Error recover code; find end of call, if possible
            int depth = 0;
            while (token != EndOfInput && (depth > 0 || token != ')')) {
                if (token == ')' || token == '}')
                    depth--;
                token = scanToken(ppToken);
                if (token == '(' || token == '{')
                    depth++;
            }

            if (token == EndOfInput) {
                parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom));
                delete in;
                return MacroExpandError;
            }
            parseContext.ppError(loc, "Too many args in macro", "macro expansion", atomStrings.getString(macroAtom));
        }

        // We need both expanded and non-expanded forms of the argument, for whether or
        // not token pasting will be applied later when the argument is consumed next to ##.
        for (size_t i = 0; i < in->mac->args.size(); i++)
            in->expandedArgs[i] = PrescanMacroArg(*in->args[i], ppToken, newLineOkay);
    }

    pushInput(in);
    macro->busy = 1;
    macro->body.reset();

    return MacroExpandStarted;
}