From 27d132f87f7d6f0baeb382e69c2b1e6b88a40b55 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Thu, 7 Aug 2014 18:15:06 +1000 Subject: rtms-tld: Refactor the code to match a better configuration format. --- rld-config.cpp | 14 +- rld-config.h | 52 ++++-- rld-rap.cpp | 2 +- rld.h | 13 +- rtems-tld.cpp | 540 ++++++++++++++++++++++++++++++++------------------------- rtld-base.ini | 4 +- test-trace.ini | 34 ++-- 7 files changed, 374 insertions(+), 285 deletions(-) diff --git a/rld-config.cpp b/rld-config.cpp index af85f94..ee619c8 100644 --- a/rld-config.cpp +++ b/rld-config.cpp @@ -60,9 +60,9 @@ namespace rld section::get_record_item (const std::string& rec_name) const { const record& rec = get_record (rec_name); - if (rec.items.size () != 1) + if (rec.items_.size () != 1) throw rld::error ("duplicate", "record item: " + name + '/' + rec_name); - return rec.items[0].text; + return rec.items_[0].text; } void @@ -70,8 +70,8 @@ namespace rld { const record& rec = get_record (rec_name); items.clear (); - for (rld::config::items::const_iterator ii = rec.items.begin (); - ii != rec.items.end (); + for (rld::config::items::const_iterator ii = rec.items_.begin (); + ii != rec.items_.end (); ++ii) { items.push_back ((*ii).text); @@ -100,7 +100,7 @@ namespace rld if (ini.LoadFile (path.c_str ()) != SI_OK) throw rld::error (::strerror (errno), "load config: " + path); - paths.push_back (path); + paths_.push_back (path); /* * Merge the loaded configuration into our configuration. @@ -138,7 +138,7 @@ namespace rld vi != vals.end (); ++vi) { - rec.items.push_back (item ((*vi).pItem)); + rec.items_.push_back (item ((*vi).pItem)); } sec.recs.push_back (rec); @@ -205,7 +205,7 @@ namespace rld const paths& config::get_paths () const { - return paths; + return paths_; } } } diff --git a/rld-config.h b/rld-config.h index adf3a9e..b8bd495 100644 --- a/rld-config.h +++ b/rld-config.h @@ -62,13 +62,13 @@ namespace rld struct record { std::string name; //< Name of the record. - items items; //< The record's items. + items items_; //< The record's items. /** * Return true if there is only one item. */ bool single () const { - return items.size () == 1; + return items_.size () == 1; } }; @@ -100,7 +100,7 @@ namespace rld /** * Return the list of items in a record in a strings container. */ - void get_record_items (const std::string& name, rld::strings& items) const; + void get_record_items (const std::string& name, rld::strings& items_) const; }; /** @@ -154,24 +154,35 @@ namespace rld private: - paths paths; /**< The path's of the loaded files. */ - sections secs; /**< The sections loaded from configuration files */ + paths paths_; /**< The path's of the loaded files. */ + sections secs; /**< The sections loaded from configuration files */ }; /** * Return the items from a record. */ template < typename T > - void parse_items (const rld::config::record& record, T& items) + void parse_items (const rld::config::record& record, + T& items_, + bool clear = true, + bool split = true) { - items.clear (); - for (rld::config::items::const_iterator ii = record.items.begin (); - ii != record.items.end (); + if (clear) + items_.clear (); + for (rld::config::items::const_iterator ii = record.items_.begin (); + ii != record.items_.end (); ++ii) { - rld::strings ss; - rld::split (ss, (*ii).text, ','); - std::copy (ss.begin (), ss.end (), std::back_inserter (items)); + if (split) + { + rld::strings ss; + rld::split (ss, (*ii).text, ','); + std::copy (ss.begin (), ss.end (), std::back_inserter (items_)); + } + else + { + items_.push_back ((*ii).text); + } } } @@ -182,10 +193,13 @@ namespace rld template < typename T > void parse_items (const rld::config::section& section, const std::string& name, - T& items, - bool present = false) + T& items_, + bool present = false, + bool clear = true, + bool split = true) { - items.clear (); + if (clear) + items_.clear (); const rld::config::record* rec = 0; try { @@ -202,7 +216,7 @@ namespace rld } if (rec) - parse_items (*rec, items); + parse_items (*rec, items_, clear, split); } /** @@ -214,10 +228,10 @@ namespace rld void parse_items (const rld::config::config& config, const std::string& section, const std::string& record, - T& items, + T& items_, bool present = false) { - items.clear (); + items_.clear (); const rld::config::section* sec = 0; try { @@ -234,7 +248,7 @@ namespace rld } if (sec) - parse_items (*sec, record, items); + parse_items (*sec, record, items_); } } } diff --git a/rld-rap.cpp b/rld-rap.cpp index 500c2c3..9b87279 100644 --- a/rld-rap.cpp +++ b/rld-rap.cpp @@ -150,7 +150,7 @@ namespace rld * index. This is used when adding the external symbols so the symbol's * value can be adjusted by the offset of the section in the RAP section. */ - typedef std::map < const int, osection > osections; + typedef std::map < int, osection > osections; /** * An ordered container of object section indexes. We need the same diff --git a/rld.h b/rld.h index 36ab013..1f5e60b 100644 --- a/rld.h +++ b/rld.h @@ -156,11 +156,16 @@ namespace rld */ inline std::string dequote (const std::string& s) { - if ((s.front () == '"') || (s.front () == '\'')) + if (!s.empty ()) { - if (s.front () != s.back ()) - throw rld::error ("invalid quoting", "string: " + s); - return s.substr (1, s.length () - (1 + 1)); + char front = s[0]; + char back = s[s.length () - 1]; + if ((front == '"') || (front == '\'')) + { + if (front != back) + throw rld::error ("invalid quoting", "string: " + s); + return s.substr (1, s.length () - (1 + 1)); + } } return s; } diff --git a/rtems-tld.cpp b/rtems-tld.cpp index ec8ccb5..d206da7 100644 --- a/rtems-tld.cpp +++ b/rtems-tld.cpp @@ -70,7 +70,7 @@ namespace rld /** * A function's signature. */ - struct function_sig + struct signature { std::string name; /**< The function's name. */ function_args args; /**< The function's list of arguments. */ @@ -79,17 +79,12 @@ namespace rld /** * The default constructor. */ - function_sig (); + signature (); /** * Construct the signature loading it from the configuration. */ - function_sig (const rld::config::record& record); - - /** - * Copy constructor. - */ - function_sig (const function_sig& orig); + signature (const rld::config::record& record); /** * Return the function's declaration. @@ -98,60 +93,69 @@ namespace rld }; /** - * A container of function signatures. + * A container of signatures. */ - typedef std::map < std::string, function_sig > function_sigs; + typedef std::map < std::string, signature > signatures; /** - * Wrappers hold the data used when wrapping the code. It knows how to wrap - * a specific trace function. Wrapping a function requires specific defines - * and header files. + * A function is list of function signatures headers and defines that allow + * a function to be wrapped. */ - struct wrapper + struct function { - std::string name; /**< The name of this wrapper. */ - rld::strings headers; /**< Include statements. */ - rld::strings defines; /**< Define statements. */ - std::string map_sym_prefix; /**< Mapping symbol prefix. */ - std::string arg_trace; /**< Code template to trace an argument. */ - std::string ret_trace; /**< Code template to trace the return value. */ - rld::strings& code; /**< Code block inserted before the trace code. */ - function_sigs sigs; /**< The functions this wrapper wraps. */ + std::string name; /**< The name of this wrapper. */ + rld::strings headers; /**< Include statements. */ + rld::strings defines; /**< Define statements. */ + signatures signatures_; /**< Signatures in this function. */ /** - * Load the wrapper. + * Load the function. */ - wrapper (const std::string& name, - rld::strings& code, - rld::config::config& config); + function (rld::config::config& config, + const std::string& name); /** - * Parse the generator. + * Dump the function. */ - void parse_generator (rld::config::config& config, - const rld::config::section& section); + void dump (std::ostream& out) const; + }; + + /** + * A container of functions. + */ + typedef std::vector < function > functions; + + /** + * A generator and that contains the functions used to trace arguments and + * return values. It also provides the implementation of those functions. + */ + struct generator + { + std::string name; /**< The name of this wrapper. */ + rld::strings headers; /**< Include statements. */ + rld::strings defines; /**< Define statements. */ + std::string map_sym_prefix; /**< Mapping symbol prefix. */ + std::string arg_trace; /**< Code template to trace an argument. */ + std::string ret_trace; /**< Code template to trace the return value. */ + rld::strings code; /**< Code block inserted before the trace code. */ /** - * Recursive parser for strings. + * Default constructor. */ - void parse (rld::config::config& config, - const rld::config::section& section, - const std::string& sec_name, - const std::string& rec_name, - rld::strings& items, - int depth = 0); + generator (); /** - * Dump the wrapper. + * Load the generator. + */ + generator (rld::config::config& config, + const std::string& name); + + /** + * Dump the generator. */ void dump (std::ostream& out) const; }; - /** - * A container of wrappers. The order is the order we wrap. - */ - typedef std::vector < wrapper > wrappers; - /** * Tracer. */ @@ -166,6 +170,18 @@ namespace rld void load (rld::config::config& config, const std::string& section); + /** + * The the functions for the trace. + */ + void load_functions (rld::config::config& config, + const rld::config::section& section); + + /** + * The the traces for the tracer. + */ + void load_traces (rld::config::config& config, + const rld::config::section& section); + /** * Generate the wrapper object file. */ @@ -183,11 +199,11 @@ namespace rld private: - std::string name; /**< The name of the trace. */ - std::string bsp; /**< The BSP we are linking to. */ - rld::strings traces; /**< The functions to trace. */ - wrappers wrappers; /**< Wrappers wrap trace functions. */ - rld::strings code; /**< Wrapper code records. Must be unique. */ + std::string name; /**< The name of the trace. */ + std::string bsp; /**< The BSP we are linking to. */ + rld::strings traces; /**< The functions to trace. */ + functions functions_; /**< The functions that can be traced. */ + generator generator_; /**< The tracer's generator. */ }; /** @@ -217,25 +233,62 @@ namespace rld private: rld::config::config config; /**< User configuration. */ - tracer tracer; /**< The tracer */ + tracer tracer_; /**< The tracer */ }; - function_sig::function_sig () + /** + * Recursive parser for strings. + */ + void + parse (rld::config::config& config, + const rld::config::section& section, + const std::string& sec_name, + const std::string& rec_name, + rld::strings& items, + bool split = true, + int depth = 0) + { + if (depth > 32) + throw rld::error ("too deep", "parsing: " + sec_name + '/' + rec_name); + + rld::config::parse_items (section, rec_name, items, false, false, split); + + rld::strings sl; + + rld::config::parse_items (section, sec_name, sl); + + for (rld::strings::iterator sli = sl.begin (); + sli != sl.end (); + ++sli) + { + const rld::config::section& sec = config.get_section (*sli); + parse (config, sec, sec_name, rec_name, items, split, depth + 1); + } + + /* + * Make the items unique. + */ + rld::strings::iterator ii; + ii = std::unique (items.begin (), items.end ()); + items.resize (std::distance (items.begin (), ii)); + } + + signature::signature () { } - function_sig::function_sig (const rld::config::record& record) + signature::signature (const rld::config::record& record) { /* * There can only be one function signature in the configuration. */ if (!record.single ()) - throw rld::error ("duplicate", "function signature: " + record.name); + throw rld::error ("duplicate", "signature: " + record.name); name = record.name; /* - * Function signatures are defined as the return value then the arguments + * Signatures are defined as the return value then the arguments * delimited by a comma and white space. No checking is made of the * return value or arguments. */ @@ -243,24 +296,17 @@ namespace rld rld::config::parse_items (record, si); if (si.size () == 0) - throw rld::error ("no return value", "function signature: " + record.name); + throw rld::error ("no return value", "signature: " + record.name); if (si.size () == 1) - throw rld::error ("no arguments", "function signature: " + record.name); + throw rld::error ("no arguments", "signature: " + record.name); ret = si[0]; args.resize (si.size () - 1); std::copy (si.begin () + 1, si.end (), args.begin ()); } - function_sig::function_sig (const function_sig& orig) - : name (orig.name), - args (orig.args), - ret (orig.ret) - { - } - const std::string - function_sig::decl () const + signature::decl () const { std::string ds = ret + ' ' + name + '('; int arg = 0; @@ -276,129 +322,114 @@ namespace rld return ds; } - wrapper::wrapper (const std::string& name, - rld::strings& code, - rld::config::config& config) - : name (name), - code (code) + function::function (rld::config::config& config, + const std::string& name) + : name (name) { /* - * A wrapper section optionally contain one or more records of: + * A function section optionally contain one or more records of: * - * # trace A list of functions to trace. - * # generator The name of the generator section. Defaults if not present. - * # headers A list of sections containing headers or header records. - * # header A list of include string that are single or double quoted. - * # defines A list of sections containing defines or define record. - * # defines A list of define string that are single or double quoted. - * # signatures A list of section names of function signatures. + * # headers A list of sections containing headers or header records. + * # header A list of include string that are single or double quoted. + * # defines A list of sections containing defines or define record. + * # defines A list of define string that are single or double quoted. + * # signatures A list of section names of signatures. + * # includes A list of files to include. * * @note The quoting and list spliting is a little weak because a delimiter * in a quote should not be seen as a delimiter. */ const rld::config::section& section = config.get_section (name); + config.includes (section); + parse (config, section, "headers", "header", headers); parse (config, section, "defines", "define", defines); - parse_generator (config, section); - rld::strings sig_list; - - rld::config::parse_items (section, "signatures", sig_list); + section.get_record_items ("signatures", sig_list); for (rld::strings::const_iterator sli = sig_list.begin (); sli != sig_list.end (); ++sli) { const rld::config::section& sig_sec = config.get_section (*sli); - for (rld::config::records::const_iterator ri = sig_sec.recs.begin (); - ri != sig_sec.recs.end (); - ++ri) + for (rld::config::records::const_iterator si = sig_sec.recs.begin (); + si != sig_sec.recs.end (); + ++si) { - function_sig func (*ri); - sigs[func.name] = func; + signature sig (*si); + signatures_[sig.name] = sig; } } } void - wrapper::parse_generator (rld::config::config& config, - const rld::config::section& section) + function::dump (std::ostream& out) const { - const rld::config::record* rec = 0; - try - { - const rld::config::record& record = section.get_record ("generator"); - rec = &record; - } - catch (rld::error re) + out << " Function: " << name << std::endl + << " Headers: " << headers.size () << std::endl; + for (rld::strings::const_iterator hi = headers.begin (); + hi != headers.end (); + ++hi) { - /* - * No error, continue. - */ + out << " " << (*hi) << std::endl; } - - std::string gen_section; - - if (rec) + out << " Defines: " << defines.size () << std::endl; + for (rld::strings::const_iterator di = defines.begin (); + di != defines.end (); + ++di) { - if (!rec->single ()) - throw rld::error ("duplicate", "generator: " + section.name + "/generator"); - gen_section = rec->items[0].text; + out << " " << (*di) << std::endl; } - else + out << " Signatures: " << signatures_.size () << std::endl; + for (signatures::const_iterator si = signatures_.begin (); + si != signatures_.end (); + ++si) { - gen_section = config.get_section ("default-generator").get_record_item ("generator"); + const signature& sig = (*si).second; + out << " " << sig.name << ": " << sig.decl () << ';' << std::endl; } - - const rld::config::section& sec = config.get_section (gen_section); - - map_sym_prefix = sec.get_record_item ("map-sym-prefix"); - arg_trace = rld::dequote (sec.get_record_item ("arg-trace")); - ret_trace = rld::dequote (sec.get_record_item ("ret-trace")); - - /* - * The code block, if present is placed in the code conttainer if unique. - * If referenced by more than wrapper and duplicated a compiler error - * will be generated. - */ - rld::strings::iterator ci; - code.push_back (rld::dequote (sec.get_record_item ("code"))); - ci = std::unique (code.begin (), code.end ()); - code.resize (std::distance (code.begin (), ci)); } - void - wrapper::parse (rld::config::config& config, - const rld::config::section& section, - const std::string& sec_name, - const std::string& rec_name, - rld::strings& items, - int depth) + generator::generator () { - if (depth > 32) - throw rld::error ("too deep", "parsing: " + sec_name + '/' + rec_name); + } - rld::config::parse_items (section, rec_name, items); + generator::generator (rld::config::config& config, + const std::string& name) + : name (name) + { + /* + * A generator section optionally contain one or more records of: + * + * # headers A list of sections containing headers or header records. + * # header A list of include string that are single or double quoted. + * # defines A list of sections containing defines or define record. + * # defines A list of define string that are single or double quoted. + * # code-blocks A list of section names of code blocks. + * # includes A list of files to include. + * + * @note The quoting and list spliting is a little weak because a delimiter + * in a quote should not be seen as a delimiter. + */ + const rld::config::section& section = config.get_section (name); - rld::strings sl; + config.includes (section); - rld::config::parse_items (section, sec_name, sl); + parse (config, section, "headers", "header", headers); + parse (config, section, "defines", "define", defines); + parse (config, section, "code-blocks", "code", code, false); - for (rld::strings::const_iterator sli = sl.begin (); - sli != sl.end (); - ++sli) - { - const rld::config::section& sec = config.get_section (*sli); - parse (config, sec, sec_name, rec_name, items, depth + 1); - } + map_sym_prefix = section.get_record_item ("map-sym-prefix"); + arg_trace = rld::dequote (section.get_record_item ("arg-trace")); + ret_trace = rld::dequote (section.get_record_item ("ret-trace")); } void - wrapper::dump (std::ostream& out) const + generator::dump (std::ostream& out) const { - out << " Wrapper: " << name << std::endl + out << " Generator: " << name << std::endl << " Headers: " << headers.size () << std::endl; for (rld::strings::const_iterator hi = headers.begin (); hi != headers.end (); @@ -416,13 +447,13 @@ namespace rld out << " Mapping Symbol Prefix: " << map_sym_prefix << std::endl << " Arg Trace Code: " << arg_trace << std::endl << " Return Trace Code: " << ret_trace << std::endl - << " Function Signatures: " << sigs.size () << std::endl; - for (function_sigs::const_iterator si = sigs.begin (); - si != sigs.end (); - ++si) + << " Code blocks: " << std::endl; + for (rld::strings::const_iterator ci = code.begin (); + ci != code.end (); + ++ci) { - const function_sig& sig = (*si).second; - out << " " << sig.name << ": " << sig.decl () << ';' << std::endl; + out << " > " + << rld::find_replace (*ci, "\n", "\n | ") << std::endl; } } @@ -432,70 +463,76 @@ namespace rld void tracer::load (rld::config::config& config, - const std::string& section) + const std::string& tname) { /* - * The configuration must contain a "trace" section. This is the top level - * configuration and must the following fields: - * - * # name The name of trace being linked. - * # trace The list of sections containing functions to trace. - * # wrapper The list of sections containing wrapping details. + * The configuration must contain a "section" section. This is the top level + * configuration and may contain: * - * The following record are optional: + * # name The name of trace being linked. + * # bsp The architecture/bsp name of the BSP. + * # options A list of options as per the long command line args. + * # traces The list of sections containing function lists to trace. + * # functions The list of sections containing function details. + * # include The list of files to include. * - * # bdp The BSP the executable is for. Can be supplied on the command - * line. - * # include Include the INI file. + * The following records are required: * - * The following will throw an error is the section or records are not - * found. + * # name + * # bsp + * # trace + * # functions */ - rld::strings ss; + const rld::config::section& section = config.get_section (tname); - const rld::config::section& tsec = config.get_section (section); - const rld::config::record& nrec = tsec.get_record ("name"); - const rld::config::record& brec = tsec.get_record ("bsp"); - const rld::config::record& trec = tsec.get_record ("trace"); - const rld::config::record& wrec = tsec.get_record ("wrapper"); + config.includes (section); - if (!nrec.single ()) - throw rld::error ("duplicate", "trace names"); - name = nrec.items[0].text; + name = section.get_record_item ("name"); + bsp = section.get_record_item ("bsp"); - if (!brec.single ()) - throw rld::error ("duplicate", "trace bsp"); - bsp = brec.items[0].text; - - /* - * Include any files. - */ - config.includes (tsec); + load_functions (config, section); + load_traces (config, section); + } - /* - * Load the wrappers. - */ - rld::strings wi; - rld::config::parse_items (wrec, wi); - for (rld::strings::const_iterator wsi = wi.begin (); - wsi != wi.end (); - ++wsi) + void + tracer::load_functions (rld::config::config& config, + const rld::config::section& section) + { + rld::strings fl; + rld::config::parse_items (section, "functions", fl, true); + for (rld::strings::const_iterator fli = fl.begin (); + fli != fl.end (); + ++fli) { - wrappers.push_back (wrapper (*wsi, code, config)); + functions_.push_back (function (config, *fli)); } + } - /* - * Load the trace functions. - */ - rld::strings ti; - rld::config::parse_items (trec, ti); - for (rld::strings::const_iterator tsi = ti.begin (); - tsi != ti.end (); - ++tsi) + void + tracer::load_traces (rld::config::config& config, + const rld::config::section& section) + { + parse (config, section, "traces", "trace", traces); + + rld::strings gens; + std::string gen; + + parse (config, section, "traces", "generator", gens); + + if (gens.size () > 1) + throw rld::error ("duplicate generators", "tracer: " + section.name); + + if (gens.size () == 0) + { + gen = + config.get_section ("default-generator").get_record_item ("generator"); + } + else { - rld::config::parse_items (config, *tsi, "trace", traces, true); + gen = gens[0]; } + generator_ = generator (config, gen); } void @@ -515,24 +552,14 @@ namespace rld c.write_line (" * Automatically generated."); c.write_line (" */"); - for (wrappers::const_iterator wi = wrappers.begin (); - wi != wrappers.end (); - ++wi) - { - const wrapper& wrap = *wi; - c.write_line (""); - c.write_line ("/*"); - c.write_line (" * Wrapper: " + wrap.name); - c.write_line (" */"); - c.write_lines (wrap.defines); - c.write_lines (wrap.headers); - } - c.write_line (""); c.write_line ("/*"); - c.write_line (" * Code blocks"); + c.write_line (" * Generator: " + generator_.name); c.write_line (" */"); - c.write_lines (code); + c.write_lines (generator_.defines); + c.write_lines (generator_.headers); + c.write_line (""); + c.write_lines (generator_.code); generate_traces (c); } @@ -548,28 +575,59 @@ namespace rld void tracer::generate_traces (rld::process::tempfile& c) { + for (functions::const_iterator fi = functions_.begin (); + fi != functions_.end (); + ++fi) + { + const function& funcs = *fi; + + for (rld::strings::const_iterator ti = traces.begin (); + ti != traces.end (); + ++ti) + { + const std::string& trace = *ti; + signatures::const_iterator si = funcs.signatures_.find (trace); + + if (si != funcs.signatures_.end ()) + { + c.write_line (""); + c.write_line ("/*"); + c.write_line (" * Function: " + funcs.name); + c.write_line (" */"); + c.write_lines (funcs.defines); + c.write_lines (funcs.headers); + break; + } + } + } + + c.write_line (""); + c.write_line ("/*"); + c.write_line (" * Wrappers."); + c.write_line (" */"); + for (rld::strings::const_iterator ti = traces.begin (); ti != traces.end (); ++ti) { - const std::string& func = *ti; + const std::string& trace = *ti; bool found = false; - for (wrappers::const_iterator wi = wrappers.begin (); - wi != wrappers.end (); - ++wi) + for (functions::const_iterator fi = functions_.begin (); + fi != functions_.end (); + ++fi) { - const wrapper& wrap = *wi; - function_sigs::const_iterator fsi = wrap.sigs.find (func); + const function& funcs = *fi; + signatures::const_iterator si = funcs.signatures_.find (trace); - if (fsi != wrap.sigs.end ()) + if (si != funcs.signatures_.end ()) { found = true; - const function_sig& fs = (*fsi).second; + const signature& sig = (*si).second; c.write_line(""); - c.write_line(fs.decl ()); + c.write_line(sig.decl ()); c.write_line("{"); std::string l; @@ -578,14 +636,14 @@ namespace rld * @todo Need to define as part of the function signature if ret * processing is required. */ - if (fs.ret != "void") + if (sig.ret != "void") { - c.write_line(" " + fs.ret + " ret;"); + c.write_line(" " + sig.ret + " ret;"); l = " ret ="; } - l += " " + wrap.map_sym_prefix + fs.name + '('; - for (size_t a = 0; a < fs.args.size (); ++a) + l += " " + generator_.map_sym_prefix + sig.name + '('; + for (size_t a = 0; a < sig.args.size (); ++a) { if (a) l += ", "; @@ -594,7 +652,7 @@ namespace rld l += ");"; c.write_line(l); - if (fs.ret != "void") + if (sig.ret != "void") { c.write_line(" return ret;"); } @@ -604,7 +662,7 @@ namespace rld } if (!found) - throw rld::error ("not found", "trace function: " + func); + throw rld::error ("not found", "trace function: " + trace); } } @@ -612,21 +670,23 @@ namespace rld tracer::dump (std::ostream& out) const { out << " Tracer: " << name << std::endl - << " BSP: " << bsp << std::endl; - for (wrappers::const_iterator wi = wrappers.begin (); - wi != wrappers.end (); - ++wi) + << " BSP: " << bsp << std::endl + << " Traces: " << traces.size () << std::endl; + for (rld::strings::const_iterator ti = traces.begin (); + ti != traces.end (); + ++ti) { - (*wi).dump (out); + out << " " << (*ti) << std::endl; } - out << " Code blocks: " << std::endl; - for (rld::strings::const_iterator ci = code.begin (); - ci != code.end (); - ++ci) + out << " Functions: " << functions_.size () << std::endl; + for (functions::const_iterator fi = functions_.begin (); + fi != functions_.end (); + ++fi) { - out << " > " - << rld::find_replace (*ci, "\n", "\n | ") << std::endl; + (*fi).dump (out); } + out << " Generator: " << std::endl; + generator_.dump (out); } linker::linker () @@ -639,13 +699,13 @@ namespace rld { config.clear (); config.load (path); - tracer.load (config, trace); + tracer_.load (config, trace); } void linker::generate_wrapper () { - tracer.generate (); + tracer_.generate (); } void @@ -660,7 +720,7 @@ namespace rld out << " " << (*pi) << std::endl; } - tracer.dump (out); + tracer_.dump (out); } } } diff --git a/rtld-base.ini b/rtld-base.ini index 1ffc17e..b574e0b 100644 --- a/rtld-base.ini +++ b/rtld-base.ini @@ -5,7 +5,7 @@ ; ; -; The default generartor is used if a wrapper does provide a generator record. +; The default generartor is used if a function set does provide a generator record. ; [default-generator] generator = printf-generator @@ -32,5 +32,5 @@ static inline void rtld_pg_print_arg(int arg_num, } CODE -[base-generator-headers] +[printf-generator-headers] header = "#include " diff --git a/test-trace.ini b/test-trace.ini index ae0a2de..a6205d2 100644 --- a/test-trace.ini +++ b/test-trace.ini @@ -11,15 +11,20 @@ name = RTEMS Trace Linker Test ; ; The BSP. ; -bsp = sis +bsp = sparc/sis +; +; Options can be defined here or on the command line. +; +options = all-funcs, verbose ; ; Functions to trace. ; -trace = test-trace, test-trace-funcs, rtems-api-task +traces = test-trace, test-trace-funcs, rtems-api-task ; -; Define the wrapper. +; Define the function sets. These are the function's that can be +; added to the trace lists. ; -wrapper = test-trace, rtems-api +functions = test-trace-funcs, rtems-api ; ; Include RTEMS Trace support. ; @@ -28,21 +33,26 @@ include = rtems.ini, rtld-base.ini ; ; User application trace example. ; -[test-trace-funcs] -trace = test_trace_1, test_trace_2 - [test-trace] +generator = printf-generator +; Just here for testing. trace = test_trace_3 -header = '#include "test-trace.h"' -define = "#define TEST_TRACE 1" + +[test-trace-funcs] +; Parsed via the 'function-set', not parse as a 'trace'. +headers = test-headers +header = '#include "test-trace-2.h"' +defines = test-defines +define = "#define TEST_TRACE_2 2" signatures = test-signatures -generator = printf-generator +; Parsed via the 'trace', not parsed as a function-set +trace = test_trace_1, test_trace_2 [test-headers] -header = '#include "test-trace.h"' +header = '#include "test-trace-1.h"' [test-defines] -define = "#define TEST_TRACE 1" +define = "#define TEST_TRACE_1 1" [test-signatures] test_trace_1 = void, int -- cgit v1.2.3