Commit 033950f8 authored by rdubner's avatar rdubner

Remove O(N-squared) characteristic of BuildCanonicalName

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