diff options
Diffstat (limited to 'sbe/tools/ppetracepp/ppetracepp.C')
-rwxr-xr-x | sbe/tools/ppetracepp/ppetracepp.C | 949 |
1 files changed, 0 insertions, 949 deletions
diff --git a/sbe/tools/ppetracepp/ppetracepp.C b/sbe/tools/ppetracepp/ppetracepp.C deleted file mode 100755 index d0bf5c09..00000000 --- a/sbe/tools/ppetracepp/ppetracepp.C +++ /dev/null @@ -1,949 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: sbe/tools/ppetracepp/ppetracepp.C $ */ -/* */ -/* OpenPOWER sbe Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2016 */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -/* -# *** ppetracepp - a fsp/common Linux trace pre processor -# this one replaces the trace strings by the corresponding hash value -# (i.e. the complete call to trace_ppe_hash is replaced) - -# *** Usage -# -# prepend compiler call with the call of this pre processor, i.e if you have -# $(CC) $(CFLAGS) -o $@ $< -# in your Makefile change it to this: -# ppetracepp $(CC) $(CFLAGS) -o $@ $< -# ppetracepp will use "$(CC) -E" to call the C pre processor "cpp". -# you can set a env var "REALCPP" to the name of a program to select -# a different programm as cpp -# -# ppetracepp creates a file "$target.ppe.hash" with the trace strings and the hash values. -# -# to enable debug mode set envvar PPETRACEPPDEBUG to 1 or give '-d' as first arg - -# *** Change History -# -# 2003-02-26 RBa created from scratch -# 2003-02-28 RBa add C++ support (C++ interface uses own type for the hash) -# 2003-05-28 RBa if cc should link instead of compile just call compiler -# 2003-07-11 AGe Change search alg. slightly and put just format back -# 2003-07-25 RBa just call gcc if called to link instead to compile -# eat argument for option -x -# 2003-11-26 RBa fix c/c++ algo: compile as c++ if realcc=*g++ -# 2004-02-02 RBa remove explicit test whether source file is readable -# it is obsolete and might lead to an error if afs is used -# 2004-02-13 RBa add support for dependency generation (-MD/-MG, -MF) -# don't prepend './' to object filename -# 2006-04-19 RBa rewrite trace_ppe_write_all support, handle C and C++ the same -# 2006-05-24 RBa fix handling of missing -o ; add TRAC_PPVER for macro/API version -# 2006-09-15 RBa add handling of \" in trace format strings ; reduce non-error output -# put object file in current dir if no -o given -# 2007-03-22 RBa handle more gcc options (-i) ; protect " in call to shell -# store output of cpp as "unmodified" output for debug -# only write string/hash file if strings found -# 2012-09-24 hlava Rewritten as C program for better build performance (was perl) -*/ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <string> -#include <time.h> -#include <fcntl.h> -#include <map> -#include <vector> -#include <unistd.h> -#include <sys/types.h> -typedef u_int32_t u32 ; -typedef u_int8_t u8 ; -#include <jhash.h> - -using namespace std; - -static string version = "2.0"; -static string macro_version = "1"; - -static bool debug = false; -#define dprintf(format, ...) if (debug) { printf(format, ##__VA_ARGS__); fflush(stdout); } -static map<string,string> hashtab; -static string hashtype; -static string hashtype_suffix; - -static string tmp; -static string cmd; -static FILE* CPP = NULL; // pipe from preprocessor -static FILE* CC = NULL; // pipe to compiler -static FILE* DEBUG = NULL; -static FILE* DEBUGIN = NULL; - -//***************************************************************************** -// replace_substr -//***************************************************************************** -void replace_substr(std::string& str, const std::string& oldStr, const std::string& newStr) -{ - size_t pos = 0; - while((pos = str.find(oldStr, pos)) != std::string::npos) - { - str.replace(pos, oldStr.length(), newStr); - pos += newStr.length(); - } - -} - -//***************************************************************************** -// fileparse -//***************************************************************************** -void fileparse(const string& in_str, string& name, string& dir, string& suff) -{ - string str(in_str); - size_t pos; - name = ""; - dir = ""; - suff = ""; - pos = str.find_last_of('.'); - if (pos != string::npos) - { - suff = str.substr(pos); - str = str.substr(0, pos); - } - pos = str.find_last_of('/'); - if (pos != string::npos) - { - name = str.substr(pos+1); - str = str.substr(0, pos+1); - } - dir = str; -} - -static const size_t TRACE_PPE_HASH_LEN = 13; -//***************************************************************************** -// chop_up_line -//***************************************************************************** -bool chop_up_line(string& in_line, string& prefix, string& strings, string& salt, string& suffix) -{ - // First see if this line matches the pattern we're looking for - // Since this will return false 95%+ of the time this function it called, we do it - // before doing any other init for performance reasons. - size_t pos = in_line.find("trace_ppe_hash"); - if (pos == string::npos) { return(false); } - - // trace_ppe_hash ( "..." ".." "..." , 2 ) - // regex: PREFIX 'trace_ppe_hash' space '(' space STRINGS space ',' space NUMBER space ')' SUFFIX - // STRINGS: '"' .* '"' space? + - - // Original perl magic incantation: - // while($line =~ m/^(.*?)trace_ppe_hash\s*\(\s*((".*?(?<!\\)"\s*)+),\s*(-?\d+)\s*\)(.*)$/) { - // ($prefix, $strings, $salt, $suffix) = ($1, $2, $4, $5); - // - // Decrypting the magic pattern matching... - // (.*?) => $1 = everything up to the word "trace_ppe_hash" - // trace_ppe_hash = delimiter - // \s*\(\s* = delimiter = <0-n whitespace chars>, left paren, <0-n whitespace chars> - // ((".*?(?<!\\)"\s*)+) => $2 = double-quote, some chars up to last closing double-quote ($3 used for nested regex) - // ,\s* = delimiter = comma followed by some whitespace - // (-?\d+)\s*\)(.*) => $4 and $5 - // $/) = end of the line input string - string line(in_line); - prefix = ""; - strings = ""; - salt = ""; - suffix = ""; - size_t pos1; - size_t pos2; - size_t pos3; - - pos1 = pos + 14; // pos1 = after "trace_ppe_hash" - pos2 = line.find("(", pos1); - if (pos2 == string::npos) { return(false); } - ++pos2; - pos3 = line.find("\"", pos2); - if (pos3 == string::npos) { return(false); } - dprintf("--------\nchop_up_line: Passed basic checks. line= %s\n", line.c_str()); - dprintf("pos1=%d, pos2=%d, pos3=%d\n", pos1, pos2, pos3); - if ((pos1 != (pos2-1)) && (line.find_first_not_of(" \t", pos1, (pos2-pos1)+1) != string::npos)) { return(false); } //non-whitespace? - if ((pos2 != pos3) && (line.find_first_not_of(" \t", pos2, (pos3-pos2)) != string::npos)) { return(false); } //non-whitespace? - - // Get the prefix data - dprintf(">chop_up_line(\"%s\",...)\n", line.c_str()); - prefix = line.substr(0, pos); - line = line.substr(pos + TRACE_PPE_HASH_LEN); - dprintf(" prefix=\"%s\"\n", prefix.c_str()); - - // Get the strings and join/fix them: Store all strings between paired double-quotes up to the - // first comma not inside a string - pos = line.find_first_of('('); - if (pos == string::npos) { return(false); } - line = line.substr(pos + 1); - strings = ""; - while(!line.empty()) - { - pos = line.find_first_of(','); - pos1 = line.find_first_of('"'); - if ((pos1 == string::npos) || ((pos != string::npos) && (pos < pos1))) { break; } // found comma before next quote - pos2 = line.find_first_of('"', (pos1+1)); - if (pos2 == string::npos) { return(false); } // unbalanced quotes! - while(line[pos2-1] == '\\') // skip escaped quotes in the string (they're not the ending quote) - { - pos2 = line.find_first_of('"', (pos2+1)); - if (pos2 == string::npos) { return(false); } // unbalanced quotes! - } - if (!strings.empty()) { strings += " "; } - strings += line.substr(pos1, (pos2-pos1)+1); - line = line.substr(pos2+1); - } - replace_substr(strings, "\" \"", ""); - replace_substr(strings, "\\\"", "ESCAPEDQUOTE"); - replace_substr(strings, "\"", ""); - replace_substr(strings, "ESCAPEDQUOTE", "\""); - // Remove trailing whitespace ah20130717 - pos = strings.find_last_not_of(" \t\n"); - if ((pos != string::npos) && (pos < (strings.length()-1))) - { - strings = strings.substr(0, pos+1); - } - - dprintf(" strings>%s<\n", strings.c_str()); - - // Get the salt - pos = line.find(","); - if (pos != string::npos) { line = line.substr(pos+1); } - pos = line.find_first_of(')'); - if (pos == string::npos) { return(false); } - salt = line.substr(0, pos); - line = line.substr(pos+1); - //dprintf(" salt=\"%s\"\n", salt.c_str()); - pos = salt.find_first_not_of(" \t\n"); - if (pos == string::npos) { return(false); } - salt = salt.substr(pos); - pos = salt.find_last_not_of(" \t\n"); - if (pos == string::npos) { return(false); } - salt = salt.substr(0, pos+1); - dprintf(" salt=\"%s\"\n", salt.c_str()); - - // Get the suffix (i.e. the rest) - suffix = line; - if (suffix[suffix.length()-1] == '\n') { suffix = suffix.substr(0, suffix.length()-1); } - dprintf(" suffix=\"%s\"\n<chop_up_line() returning true\n", suffix.c_str()); - - return(true); -} - -//***************************************************************************** -// get_format_string -//***************************************************************************** -int get_format_string(const string& in_str, string& format) -{ - int format_salt = 0; - size_t pos; - size_t pos_end; - string str(in_str); - // (@format_param) = ($strings =~ /(%[#0\- +'I]*\d*(?:\.\d*)?[hlLqjzt]*[diouxXeEfFgGaAcsCSpn])/g); - // $format = join(',', @format_param); - // Decrypting the regular expression magic... - // (%[#0\- +'I]*\d*(?:\.\d*)?[hlLqjzt]*[diouxXeEfFgGaAcsCSpn]) - - format = ""; - while(!str.empty()) - { - pos = str.find("%"); - if (pos == string::npos) { break; } - if (pos == (str.length()-1)) { break; } // last char in string? just skip it - if (str[pos+1] == '%') // double percent sign? just skip first one - { - str = str.substr(pos+1); - continue; - } - pos_end = str.find_first_of("cdieEfgGosuxXpn", pos); // find formatting specifier - if (pos_end == string::npos) - { - fprintf(stderr, "ERROR: ppetracepp could not parse trace formatting string \"%s\" in \"%s\"\n", str.c_str(), in_str.c_str()); - break; - } - - if (!format.empty()) - format += ","; - format += str.substr(pos, (pos_end-pos)+1); - ++format_salt; - - str = str.substr(pos_end+1); - } - // Correct for escaped percent signs - string temp_str(in_str); - while((pos = temp_str.find("%%")) != string::npos) - { - if (pos < (temp_str.length()-2)) // Not the last thing in the string? - { - dprintf(" decrementing salt value %d\n", format_salt); - --format_salt; - temp_str = temp_str.substr(pos+2); - } - else - { - temp_str = ""; - } - } - - return(format_salt); -} - -#define BUF_SIZE 40 -//***************************************************************************** -// get_hash -//***************************************************************************** -void get_hash(const string& i_str, const unsigned int salt_num, string& hash32, string& hash16) -{ - string str(i_str); - unsigned int hash_num = 0; - char buf[BUF_SIZE]; - - hash16 = ""; - hash32 = ""; - dprintf(">get_hash(\"%s\",%d)\n", str.c_str(), salt_num); - - // Call jhash function to get the hash value - hash_num = jhash((void*)str.c_str(), str.length(), salt_num); - dprintf("jhash() returned: %u\n", hash_num); - sprintf(buf, "%u", hash_num & 0x0000ffff); - hash16 = buf; - sprintf(buf, "%u", ((salt_num << 16) | (hash_num & 0x0000ffff))); - hash32 = buf; - - // validate the hash value - size_t pos = hash32.find_first_not_of("0123456789"); - if (pos != string::npos) - { - fprintf(stderr, "trexhash error: %s\n", hash32.c_str()); - fprintf(stderr, "for call <<%s>>\n", cmd.c_str()); - exit(1); - } - -//removing this since it doesn't seem to have any affect on the output -#if 0 - // If hash is empty, use the sum of the ord values in the original string - if ((hash == "")||(hash == "0")) - { - unsigned int len = str.length(); - unsigned int hash_num = 0; - //unsigned char conv_buf[2] = { '\0', '\0' }; - u_int8_t conv_num; - for (unsigned int i=0; i < len; ++i) - { - //conv_buf[0] = str[i]; - conv_num = (u_int8_t)str[i]; - hash_num += (unsigned int)conv_num; - } - } -#endif - - dprintf("<get_hash(\"%s\",%d) returned hash: %s\n", str.c_str(), salt_num, hash32.c_str()); -} - -//***************************************************************************** -// parse_line -//***************************************************************************** -void parse_line(map<string,string>& rhash, string& line, string& out_line) -{ - // NOTE: "line" arg may get modified by this function! Caller must not assume it's unchanged. - string format; - string prefix; - string strings; - string tmp; - string salt; - string hash16; - string hash32; - int salt_num; - int format_salt; - string suffix; - string write_all_suffix; - size_t pos; - - out_line = ""; - // trace_ppe_hash ( "..." ".." "..." , 2 ) - // regex: PREFIX 'trace_ppe_hash' space '(' space STRINGS space ',' space NUMBER space ')' SUFFIX - // STRINGS: '"' .* '"' space? + - //while($line =~ m/^(.*?)trace_ppe_hash\s*\(\s*((".*?(?<!\\)"\s*)+),\s*(-?\d+)\s*\)(.*)$/) { - // Attempt to approximate the above amazing perl regex... - while( chop_up_line(line, prefix, strings, salt, suffix) ) - { - //dprintf("\n\nprefix = %s\nstrings = %s\nsalt = %s\nsuffix = %s\n", - // prefix.c_str(), strings.c_str(), salt.c_str(), suffix.c_str()); - // is this a trace_ppe_write_all call? - pos = prefix.find("trace_ppe_write_all"); - if (pos != string::npos) - { - // yes. replace trace_ppe_hash with hash value and reduced format string - format_salt = get_format_string(strings, format); - // reduced format string will be added after hash value - write_all_suffix = ",\" "; - write_all_suffix += format; - write_all_suffix += "\""; - - if (!salt.empty()) - { - salt_num = atoi(salt.c_str()); - } - else - { - salt_num = -1; - } - - if (salt_num == -1) - { - salt_num = format_salt; - } - else if (salt_num != format_salt) - { - fprintf(stderr, "ERROR: printf mismatch in '%s': TRACE says %d, format says %d args\n", - line.c_str(), salt_num, format_salt); - } - } - else - { - write_all_suffix = ""; - salt_num = atoi(salt.c_str()); - } - - // get the trex hash value for the strings - get_hash(strings, salt_num, hash32, hash16); - - // check for duplicate and store the mapping - if ((rhash.find(hash32) != rhash.end()) && (rhash[hash32] != strings)) - { - fprintf(stderr, "hash collision: two different strings give the same hash value '%s'\n", hash32.c_str()); - fprintf(stderr, "%s\n%s\n", strings.c_str(), rhash[hash32].c_str()); - // Not breaking the compilation here. This is same as if we get hash - // collision across files. As in SBE we are using mirroring, these - // hash collisions will take some time to resolve. Till that time, - // let us allow compilation of procedures. - //return; - } - rhash[hash32] = strings; - - // add the modified line to the output - tmp = prefix; - tmp += "("; - tmp += hashtype; - tmp += " "; - tmp += hash16; - tmp += hashtype_suffix; - tmp += ")"; - tmp += write_all_suffix; - out_line += tmp; - dprintf("changed call: %s...\n", tmp.c_str()); - line = suffix; - } - out_line += line; - if (out_line[out_line.length()-1] != '\n') - out_line += "\n"; -} - -//***************************************************************************** -// main -//***************************************************************************** -int main(int argc, char** argv) -{ - char* p_env = getenv("PPETRACEPPDEBUG"); - if (p_env) - debug = true; - - - int argi = 1; - string arg; - string optarg; - if (argc > 1) arg = argv[1]; - if ((argc < 2) || (arg == "-h")) - { - fprintf(stderr, "usage: %s realcompiler compileroptions -o target source\n", argv[0]); - exit(9); - } - string realcc(argv[argi++]); - string cctype("c++"); - bool optx_found = false; - - if (realcc == "-d") - { - debug = true; - realcc = argv[argi++]; - } - - // wait until -d options is handled before checking $debug - dprintf("ppetracepp version %s - API/macro version %s\n", version.c_str(), macro_version.c_str()); - - p_env = getenv("REALCPP"); - string realcpp; - if (p_env) - realcpp = p_env; - if (realcpp.empty()) - { - dprintf("cannot find cpp, using <realcompiler> -E\n"); - realcpp = realcc; - realcpp += " -E"; - } - dprintf("realcpp is %s\n", realcpp.c_str()); - -//------------------------------------------------------------------------------ -// parse all the arguments -//------------------------------------------------------------------------------ -string source; -string object; -vector<string> ccopts; -vector<string> cppopts; -bool dodeps = false; -string depfile; -string pfx; -string sfx; -int origargi = argi; -for( ; argi < argc; ++argi) -{ - arg = argv[argi]; - dprintf("Processing argv[%d]: \"%s\"\n", argi, arg.c_str()); - if (arg.length() > 2) - { - pfx = arg.substr(0,2); - sfx = arg.substr(arg.length()-2); - } - else - { - pfx = arg; - sfx = arg; - } - dprintf(" pfx: \"%s\" sfx: \"%s\"\n", pfx.c_str(), sfx.c_str()); - - if (pfx == "-o") - { - if (! object.empty()) - { - fprintf(stderr, "two -o options, aborting\n"); - exit(1); - } - if (arg.length() > 2) - { - object = sfx; - } - else - { - object = argv[++argi]; - } - dprintf("object is now %s\n", object.c_str()); - } - else if (arg == "-c") - { - // don't call cpp with -c, this is for the compiler - ccopts.push_back(arg); - dprintf("found -c option\n"); - } - else if (pfx == "-l") - { - // cpp doesn't need library arguments - cppopts.push_back(arg); - } - else if (pfx == "-i") - { - // option takes an argument, handle it too - optarg = argv[argi++]; - ccopts.push_back(arg); - ccopts.push_back(optarg); - cppopts.push_back(arg); - cppopts.push_back(optarg); - dprintf("found option '%s %s'\n", arg.c_str(), optarg.c_str()); - } - else if ((arg == "-L") || - (arg == "-I") || - (arg == "-x") || - (arg == "-b") || - (arg == "-B") || - (arg == "-V") || - (arg == "-D") || - (arg == "--param") || - (arg == "-MQ") || - (arg == "-MT")) - { - // option takes an argument, handle it too - optarg = argv[argi++]; - ccopts.push_back(arg); - ccopts.push_back(optarg); - cppopts.push_back(arg); - cppopts.push_back(optarg); - dprintf("found option '%s %s'\n", arg.c_str(), optarg.c_str()); - if (arg == "-x") - { - // option x sets the language - c or c++ - if ((optarg != "c") && (optarg != "c++") && (optarg != "assembler-with-cpp")) - { - fprintf(stderr, "cannot process language '%s', aborting\n", optarg.c_str()); - exit(1); - } - cctype = optarg; - optx_found = true; - } - } - else if ((arg == "-MD")||(arg == "-MG")) - { - // gen deps - dodeps = true; - dprintf("found %s, creating dependencies\n", arg.c_str()); - } - else if (arg == "-MF") - { - // set dependencies file - depfile = argv[argi++]; - dprintf("set dependencies file to '%s'\n", depfile.c_str()); - } - else if (arg[0] == '-') - { - // arg starts with - so it's an option - ccopts.push_back(arg); - cppopts.push_back(arg); - dprintf("found option '%s'\n", arg.c_str()); - } - else if ((sfx == ".a") || - (sfx == ".o")) - { - // an object or archive, ignore this but give it to cc - ccopts.push_back(arg); - dprintf("found object/archive '%s'\n", arg.c_str()); - } - else if ((sfx == ".c") || - (sfx == ".C") || - (sfx == ".S") || - (arg.substr(arg.length()-4) == ".cpp") || - (arg.substr(arg.length()-4) == ".cxx")) - { - // the source file(s). we should only get one - if (!source.empty()) - { - fprintf(stderr, "don't know to handle two source files, aborting\n"); - exit(1); - } - source = arg; - // put the - (for read-from-stdin) where the source file was - // (order is important!) - ccopts.push_back("-"); - dprintf("found source file %s\n", source.c_str()); - } - else if (access(arg.c_str(), F_OK)) - { - // option but not a file, an unknown option? - ccopts.push_back(arg); - cppopts.push_back(arg); - dprintf("found unknown option '%s'\n", arg.c_str()); - } -} - -//------------------------------------------------------------------------------ -// set other parameters based on arguments specified -//------------------------------------------------------------------------------ -if (source.empty()) -{ - // this might be a call to link a program instead of compile a source (or asm source) - dprintf("NOTME: starting as cc '%s ...'\n", realcc.c_str()); - execvp(realcc.c_str(), &(argv[origargi])); - fprintf(stderr, "ERROR: returned from execvp() call to run %s\n", realcc.c_str()); -} -if (object.empty()) -{ - dprintf("no object file given, default to source name\n"); - // gcc builds object name from source name if no -o given, replacing - // suffix with .o. The file is placed in the current directory, - // not in the source directory! - string n; - string d; - string s; - fileparse(source, n, d, s); - if (!n.empty() && !s.empty()) - { - object = n + ".o"; - dprintf("tracpp: guessing object name %s\n", object.c_str()); - dprintf(" from source name %s\n", source.c_str()); - } - else - { - fprintf(stderr, "Unable to determine Source File Name\n"); - exit(1);; - } -} - -// set value of trace hash according to language -// check source file extension if no explicit -x option given -if (!optx_found) -{ - if (realcc.find("g++") != string::npos) - { - dprintf("compiler language: C++ (from compiler name)\n"); - cctype = "c++"; - } - else - { - if (source.substr(source.length()-2) == ".c") - { - dprintf("compiler language: C (from source file extension)\n"); - cctype = "c"; - } - else if (source.substr(source.length()-2) == ".S") - { - dprintf("compiler language: assembly (from source file extension)\n"); - cctype = "assembler-with-cpp"; - } - else - { - dprintf("compiler language: C++ (default)\n"); - cctype = "c++"; - } - } -} -else -{ - dprintf("compiler language: %s (from option '-x')\n", cctype.c_str()); -} - -if (cctype == "c") -{ - hashtype = "(unsigned short)"; - hashtype_suffix = "U"; -} -else if (cctype == "assembler-with-cpp") -{ - hashtype = ""; - hashtype_suffix = ""; -} -else -{ - hashtype = "(trace_hash_val)"; - hashtype_suffix = "U"; -} -// define TRAC_PPETRACEPP for macros -tmp = "-DTRAC_PPETRACEPP -DTRAC_PPVER="; -tmp += macro_version; -cppopts.push_back(tmp); -if (dodeps) -{ - if (depfile.empty()) - { - if ((p_env = getenv("DEPENDENCIES_OUTPUT")) != NULL) - { - depfile = p_env; - } - else if ((p_env = getenv("SUNPRO_DEPENDENCIES")) != NULL) - { - depfile = p_env; - } - else - { - depfile = object; - if (depfile.substr(depfile.length()-2) == ".o") - { - depfile = depfile.substr(0, depfile.length()-2); - depfile += ".d"; - } - } - } - tmp = "-MD -MF "; - tmp += depfile; - cppopts.push_back(tmp); -} - -//------------------------------------------------------------------------------ -// start cpp -//------------------------------------------------------------------------------ -cmd = realcpp; -for(vector<string>::iterator p = cppopts.begin(); p != cppopts.end(); ++p) -{ - cmd += " "; - cmd += *p; -} -cmd += " "; -cmd += source; -cmd += " -o-"; -dprintf("starting as cpp '%s'\n", cmd.c_str()); -CPP = popen(cmd.c_str(), "r"); -if (CPP == NULL) -{ - fprintf(stderr, "cannot start cpp '%s'\n", realcpp.c_str()); - perror(""); - exit(1); -} - -//------------------------------------------------------------------------------ -// start cc. manually set language as source file extension not available to cc -//------------------------------------------------------------------------------ -string type_str = ""; -if (!optx_found) -{ - // no option -x given by caller, set manually - type_str = "-x "; - type_str += cctype; -} -cmd = realcc; -cmd += " "; -cmd += type_str; -for(vector<string>::iterator p = ccopts.begin(); p != ccopts.end(); ++p) -{ - cmd += " "; - cmd += *p; -} -cmd += " -o "; -cmd += object; -dprintf("starting as cc '%s'\n", cmd.c_str()); -CC = popen(cmd.c_str(), "w"); -if (CC == NULL) -{ - fprintf(stderr, "cannot start cc '%s'\n", realcc.c_str()); - perror(""); - exit(1); -} - -string modifiedfile; -string unmodifiedfile; -if (debug) -{ - modifiedfile = object + ".debug"; - DEBUG = fopen(modifiedfile.c_str(), "w"); - if (DEBUG == NULL) - { - string msg = "cannot open file "; - msg += modifiedfile; - perror(msg.c_str()); - modifiedfile = ""; - } - else - { - fprintf(stderr, "writing preprocessed source to %s\n", modifiedfile.c_str()); - } - unmodifiedfile = object + ".debug_in"; - DEBUGIN = fopen(unmodifiedfile.c_str(), "w"); - if (DEBUGIN == NULL) - { - string msg = "cannot open file "; - msg += unmodifiedfile; - perror(msg.c_str()); - unmodifiedfile = ""; - } - else - { - fprintf(stderr, "writing unprocessed source to %s\n", unmodifiedfile.c_str()); - } -} - -string oldline; -string newline; -static const int MAX_BUFFER = 51200; -char buf[MAX_BUFFER]; -while (!feof(CPP)) -{ - if (fgets(buf, MAX_BUFFER, CPP) != NULL) - { - oldline = buf; - if (DEBUGIN) { fprintf(DEBUGIN, "%s", oldline.c_str()); } - parse_line(hashtab, oldline, newline); - //#print "oldline = $oldline"; - //#print "newline = $newline"; - if (newline.empty()) - { - fprintf(stderr, "hash error in/with file %s\n", source.c_str()); - exit(1); - } - //#print "newline = $newline\n"; - fprintf(CC, "%s", newline.c_str()); - if (DEBUG) { fprintf(DEBUG, "%s", newline.c_str()); } - } -} -if (DEBUG) { fclose(DEBUG); } -if (DEBUGIN) { fclose(DEBUGIN); } -int cmd_rc = pclose(CPP); -if (cmd_rc) -{ - fprintf(stderr, "error from cpp\n"); - if (cmd_rc & 127) - { - fprintf(stderr, "cpp got signal %d\n", (cmd_rc & 127)); - exit(1); - } - else if (cmd_rc >> 8) - { - fprintf(stderr, "cpp returned %d\n", (cmd_rc >> 8)); - exit(cmd_rc >> 8); - } -} -cmd_rc = pclose(CC); -if (cmd_rc) -{ - fprintf(stderr, "error from cc\n"); - if (cmd_rc & 127) - { - fprintf(stderr, "cc got signal %d\n", (cmd_rc & 127)); - exit(1); - } - else if (cmd_rc >> 8) - { - fprintf(stderr, "cc returned %d\n", (cmd_rc >> 8)); - exit(cmd_rc >> 8); - } -} - -if (!hashtab.empty()) -{ - string stringfile = object; - stringfile += ".ppe.hash"; - // open trace string file - FILE* TRC = fopen(stringfile.c_str(), "w"); - if (TRC == NULL) - { - fprintf(stderr, "cannot write trace string file '%s'\n", stringfile.c_str()); - exit(1); - } - dprintf("Writing to file %s\n", stringfile.c_str()); - - string pwd; - FILE* PWD = popen("pwd", "r"); - fgets(buf, MAX_BUFFER, PWD); - pwd = buf; - pclose(PWD); - time_t tt = time(NULL); - sprintf(buf, "%s", asctime(localtime(&tt))); - buf[strlen(buf)-1] = '\0'; // chop off extra newline - fprintf(TRC, "#FSP_TRACE_v2|||%s|||BUILD:%s", buf, pwd.c_str()); - - string srch_str = "||"; - srch_str += source; - int srch_str_len = srch_str.length(); - size_t pos; - for(map<string,string>::iterator p = hashtab.begin(); p != hashtab.end(); ++p) - { - pos = (p->second).find(srch_str); - if ((pos != string::npos) && ((pos + srch_str_len) == (p->second).length())) - { - // source file name is already part of the string - fprintf(TRC, "%s||%s\n", (p->first).c_str(), (p->second).c_str()); - } - else - { - fprintf(TRC, "%s||%s||%s\n", (p->first).c_str(), (p->second).c_str(), source.c_str()); - } - //#print TRC "$key||$source||$hashtab{$key}\n"; - } - fclose(TRC); -} -else -{ - dprintf("No trace calls/strings found, not writing hash file\n"); -} -} // end main |