Commit 033950f8 authored by rdubner's avatar rdubner

Remove O(N-squared) characteristic of BuildCanonicalName

parent b5c969ca
......@@ -48,7 +48,7 @@
using namespace std;
//#define DUMPING
// #define DUMPING
void
scan_test(const string &filename)
......
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerCommandArguments>-f C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest\rtest.cbl</LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>-f C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest.cbl</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerCommandArguments>-f C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest\rtest.cbl</LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>-f C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest.cbl</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommandArguments>-f C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest\rtest.cbl</LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>-f C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest.cbl</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerCommandArguments>-f C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest\rtest.cbl</LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>-f C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest C:\Users\Bob\repos\cbl-gdb-samples\ref_test_2\rtest.cbl</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>
\ No newline at end of file
......@@ -277,6 +277,9 @@ ProcessDataStorage(ifstream &ifs,
// static cob_field f_294 = {5, b_291 + 15, &a_10}; /* LOW-VAL */
static const char SZ_COB_FIELD_F[] = "cob_field f_";
nfound = input.find(SZ_COB_FIELD_F);
// we can be fooled at this point. For example, if there is an EBCDIC
// alphabet involved, then we can have cob_field f_native.
if( nfound != string::npos ) {
nfound += strlen(SZ_COB_FIELD_F);
......@@ -290,116 +293,119 @@ ProcessDataStorage(ifstream &ifs,
f_name += ch;
}
// Skip past the '{'
while( nfound < input.length() ) {
char ch = input[nfound++];
if( ch EQ '{' ) {
break;
// Let's refuse to be fooled:
if( f_name != "f_" ) {
// Skip past the '{'
while( nfound < input.length() ) {
char ch = input[nfound++];
if( ch EQ '{' ) {
break;
}
}
}
// Pick up the size:
int size = STOI(input.substr(nfound));
// Pick up the size:
int size = STOI(input.substr(nfound));
// Skip past the next space:
while( nfound < input.length() ) {
char ch = input[nfound++];
if( ch EQ ' ' ) {
break;
// Skip past the next space:
while( nfound < input.length() ) {
char ch = input[nfound++];
if( ch EQ ' ' ) {
break;
}
}
}
// Skip to the name_of_data
string b_name;
if( nfound < input.length() ) {
// Pick up the b
b_name += input[nfound++];
}
if( nfound < input.length() ) {
// Pick up the _
b_name += input[nfound++];
}
while( nfound < input.length() ) {
char ch = input[nfound++];
if( !isdigit(ch) ) {
break;
// Skip to the name_of_data
string b_name;
if( nfound < input.length() ) {
// Pick up the b
b_name += input[nfound++];
}
if( nfound < input.length() ) {
// Pick up the _
b_name += input[nfound++];
}
while( nfound < input.length() ) {
char ch = input[nfound++];
if( !isdigit(ch) ) {
break;
}
b_name += ch;
}
b_name += ch;
}
if(b_name EQ "NU") {
b_name = "";
}
if(b_name EQ "NU") {
b_name = "";
}
// Skip past the ampersand:
while( nfound < input.length() ) {
char ch = input[nfound++];
if( ch EQ '&' ) {
break;
// Skip past the ampersand:
while( nfound < input.length() ) {
char ch = input[nfound++];
if( ch EQ '&' ) {
break;
}
}
}
// Pick up the pointer to the attribute
string a_name;
if( nfound < input.length() ) {
// Pick up the a
a_name += input[nfound++];
}
if( nfound < input.length() ) {
// Pick up the _
a_name += input[nfound++];
}
while( nfound < input.length() ) {
char ch = input[nfound++];
if( !isdigit(ch) ) {
break;
// Pick up the pointer to the attribute
string a_name;
if( nfound < input.length() ) {
// Pick up the a
a_name += input[nfound++];
}
if( nfound < input.length() ) {
// Pick up the _
a_name += input[nfound++];
}
while( nfound < input.length() ) {
char ch = input[nfound++];
if( !isdigit(ch) ) {
break;
}
a_name += ch;
}
a_name += ch;
}
// See if there is an offset:
int offset = 0;
nfound = input.find(" + ");
if( nfound != string::npos ) {
offset = STOI( input.substr(nfound+3) );
}
// See if there is an offset:
int offset = 0;
nfound = input.find(" + ");
if( nfound != string::npos ) {
offset = STOI( input.substr(nfound+3) );
}
string cbl_name = GetCommentText(input);
string cbl_name = GetCommentText(input);
size_t nfound = cbl_name.find(" Record");
if( nfound != string::npos ) {
cbl_name = cbl_name.substr(0,nfound);
}
size_t nfound = cbl_name.find(" Record");
if( nfound != string::npos ) {
cbl_name = cbl_name.substr(0,nfound);
}
string mapped_program_id = program_id;
// As mentioned in the b_ processing, the program_id at
// this point can be a lie. When a b_ is declared GLOBAL,
// its definition is in one program-id. But if it's
// accessed in program-id2, that's where the .h file says
// the f_ variable that references b_ is. We built a map
// to get around that, which we have to do to get these
// variables lined up with the .cbl.lst variable list.
map<string,string>::const_iterator it =
b_symbol_to_program_id.find(b_name);
if(it != b_symbol_to_program_id.end()) {
mapped_program_id = it->second;
}
string mapped_program_id = program_id;
// As mentioned in the b_ processing, the program_id at
// this point can be a lie. When a b_ is declared GLOBAL,
// its definition is in one program-id. But if it's
// accessed in program-id2, that's where the .h file says
// the f_ variable that references b_ is. We built a map
// to get around that, which we have to do to get these
// variables lined up with the .cbl.lst variable list.
map<string,string>::const_iterator it =
b_symbol_to_program_id.find(b_name);
if(it != b_symbol_to_program_id.end()) {
mapped_program_id = it->second;
}
string parent;
const COB_DATUM *pdatum = cob_data.GetCobDatum(b_name);
if( pdatum ) {
parent = pdatum->cbl_name;
}
string parent;
const COB_DATUM *pdatum = cob_data.GetCobDatum(b_name);
if( pdatum ) {
parent = pdatum->cbl_name;
}
cob_fields.Insert(f_name,
b_name,
offset,
size,
a_name,
mapped_program_id,
parent,
cbl_name); // And this the child
continue;
cob_fields.Insert(f_name,
b_name,
offset,
size,
a_name,
mapped_program_id,
parent,
cbl_name);
continue;
}
}
// Check for a PICTURE symbol
......
......@@ -273,7 +273,7 @@ PARAMETERS::GetParameters(int argc, char *argv[])
Usage();
exit(1);
}
if( optind >= argc ) {
Usage();
exit(1);
......
......@@ -49,6 +49,7 @@ VAR_NODE::VAR_NODE()
is_external = false;
is_global = false;
parent = nullptr;
birth_order = (size_t)(-1);
}
void
......@@ -98,6 +99,7 @@ VAR_NODE::AddChild(VAR_NODE *new_node)
// And link in the new node
new_node->parent = this;
new_node->birth_order = this->children.size();
this->children.push_back(new_node);
}
......@@ -830,17 +832,7 @@ VARIABLE_TREE::BuildCanonicalName(VAR_NODE *var_node)
if(var_node->level >= LEVEL_FILE) {
VAR_NODE *parent = var_node->parent;
int brother_index = -1;
// Check all of dad's children
for(int i=1; i<(int)parent->children.size(); i++) {
// When we find ourself, then we've also found our immediately
// older sibling:
if(parent->children[i] EQ var_node) {
brother_index = i-1 ;
break;
}
}
int brother_index = (int)(var_node->birth_order-1);
if( var_node->level EQ LEVEL_66 ) {
// A level 66 variable is like an 01 or 77: it's a top-level
......@@ -911,6 +903,7 @@ VARIABLE_TREE::BuildCanonicalName(VAR_NODE *var_node)
// the same level that grampa is on.
var_node->parent = grampa->parent;
var_node->birth_order = grampa->parent->children.size();
grampa->parent->children.push_back(var_node);
// We need to eliminate ourself from our parent's level.
......
......@@ -126,6 +126,9 @@ private:
std::string b_name; // b_name is imputed from the f_name
std::string f_name;
size_t birth_order; // This is our position in the roll call of siblings
// // (starts from zero)
public:
VAR_NODE();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment