Esempio n. 1
0
bool opDriver::CodeCurrent() {
    // foreach dialect we have...
    // and all dependencies, are we up to date?
    // are we up to date?
    opSet<path>::iterator it = OhFiles.begin();
    opSet<path>::iterator end = OhFiles.end();

    time_t opcpptime = opPlatform::GetOpCppTimeStamp();

    while (it != end) {
        const path& ohfilepath = *it;

        // get the output path
        opString filestring = GetOutputPath(opParameters::Get(), ohfilepath);

        path oohfilepath = (filestring + ".ooh").GetString();
        path ocppfilepath = (filestring + ".ocpp").GetString();

        if (!exists(oohfilepath)) return false;

        if (!exists(ocppfilepath)) return false;

        time_t ohtime = last_write_time(ohfilepath);
        time_t oohtime = last_write_time(oohfilepath);
        time_t ocpptime = last_write_time(ocppfilepath);

        if (ohtime > oohtime || ohtime > ocpptime || opcpptime > oohtime ||
            opcpptime > ocpptime)
            return false;

        // now check dependencies
        FileNode file;
        file.LoadDependencies(filestring + ".depend");

        if (file.IsDependencyNewer(oohtime)) return false;

        ++it;
    }

    return true;
}
Esempio n. 2
0
// compiles a file in normal mode
bool opDriver::NormalModeFile(const opParameters& p, const path& filename) {
    double totaltimestart = opTimer::GetTimeSeconds();

    // build the output filename strings...
    // fix this for ../ case (convert to string and find & replace...)
    opString sfile = GetOutputPath(p, filename);

    path oohpath = (sfile + ".ooh").GetString();
    path ocpppath = (sfile + ".ocpp").GetString();

    path outputpath = oohpath.branch_path();

    if (!exists(outputpath)) create_directories(outputpath);

    // lets check the timestamp...
    if (!p.Force) {
        time_t ohtime = last_write_time(filename);

        // we want to rebuild upon upgrades / new builds
        time_t opcpptime = opPlatform::GetOpCppTimeStamp();

        if (exists(oohpath) && exists(ocpppath)) {
            time_t oohtime = last_write_time(oohpath);
            time_t ocpptime = last_write_time(ocpppath);

            time_t dohtime = GetGeneratedDialectTimestamp(p);

            FileNode tempfile;
            tempfile.LoadDependencies(sfile + ".depend");
            bool bNewDepend = tempfile.IsDependencyNewer(oohtime);

            if (bNewDepend) {
                if (p.Verbose) {
                    Log("Included file newer than generated file, forcing "
                        "recompile ...");
                    Log("");
                }
            }
            // up to date if ooh newer than oh, and ooh newer than opcpp build
            else if (oohtime < opcpptime || ocpptime < opcpptime) {
                if (p.Verbose) {
                    Log(opPlatform::GetOpCppExecutableName() +
                        " newer than generated file, forcing recompile ...");
                    Log("");
                }
            } else if (oohtime <= dohtime || ocpptime <= dohtime) {
                if (p.Verbose) {
                    Log("Dialect newer than generated file, forcing recompile "
                        "...");
                    Log("");
                }
            } else if (oohtime > ohtime && ocpptime > ohtime) {
                if (p.Verbose) Log(filename.string() + " is up to date");

                return true;
            }
        }
    }

    opError::Clear();

    // output compiling -file- to std out
    if (!p.Silent) {
        Log(opString("Compiling ") + filename.string() + " ...");
    }

    // load the oh file, it will be tracked elsewhere
    OPFileNode* filenode =
        FileNode::Load<OPFileNode>(filename.string(), opScanner::SM_NormalMode);

    // filenode should be non-null even if there were errors
    assert(filenode);

    if (opError::HasErrors()) {
        if (p.PrintTree) filenode->PrintTree(filename.string());

        opError::Print();
        return false;
    }

    // no errors, let's print the output files
    try {
        // Save dependencies file.
        opString dependpath = sfile + ".depend";
        filenode->SaveDependencies(dependpath);

        // open the output files for the generated code...
        FileWriteStream hfile(oohpath.string());
        FileWriteStream sfile(ocpppath.string());

        if (hfile.is_open() && sfile.is_open()) {
            filenode->SetFiles(oohpath.string(), ocpppath.string());

            opFileStream filestream(hfile, sfile);

            // add the pre-pend path (for relative #lines)
            filestream.SetDepths(oohpath.string());

            // files are open, now print to them
            filenode->PrintNode(filestream);

            filestream.Output();
        } else {
            Log("Could not open output file(s)!");
            return false;
        }
    } catch (opException::opCPP_Exception&) {
        //??? ever
    }

    // print xml!
    if (p.PrintXml) {
        try {
            path xmlpath = (sfile + ".xml").GetString();

            // open the output files for the generated code...
            boost::filesystem::ofstream xfile(xmlpath);

            if (xfile.is_open()) {
                opXmlStream filestream(xfile);

                // files are open, now print to them
                filenode->PrintXml(filestream);
            } else {
                Log("Could not open output xml file!");
                return false;
            }
        } catch (opException::opCPP_Exception&) {
            //??? ever
        }
    }

    // any errors left?
    // shouldn't be really
    opError::Print();

    double totaltimeend = opTimer::GetTimeSeconds();
    double totaltimeMs = (totaltimeend - totaltimestart) * 1000.0;

    // TODO: allow PrintTree to any stream
    //		and add support for PrintTree to file
    // print the AST to stdout
    if (p.PrintTree) filenode->PrintTree(filename.string());

    // write the verbose compilation notice
    if (p.Verbose) {
        Log("");
        Log(opString("Compilation successful ... took ") + totaltimeMs +
            " ms (" + filenode->GetScanMs() + " scan ms, " +
            filenode->GetParseMs() + " parse ms)");
    }

    return true;
}