Commit 089c540a authored by rdubner's avatar rdubner

Improved COBOL/b_xx cross mapping by eliminating some long-standing errors and misconceptions

parent 71f90474
...@@ -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)
...@@ -354,9 +354,7 @@ main(int argc, char *argv[]) ...@@ -354,9 +354,7 @@ main(int argc, char *argv[])
// The Consolidate() routine puts them together. // The Consolidate() routine puts them together.
variable_tree.Dump(); variable_tree.Consolidate(data_description,cob_data);
variable_tree.Consolidate(data_description);
variable_tree.Dump();
#if defined(DUMPING) #if defined(DUMPING)
variable_tree.Dump(); variable_tree.Dump();
variable_tree.DumpFlatList(); variable_tree.DumpFlatList();
......
...@@ -664,6 +664,17 @@ ScanForLinkage(ifstream &ifs, ...@@ -664,6 +664,17 @@ ScanForLinkage(ifstream &ifs,
} }
} }
cob_fields.Modify(f_symbol,base,offset); cob_fields.Modify(f_symbol,base,offset);
} else {
size_t nfound = param2.find(" + ");
if( nfound != string::npos ) {
offset += STOI( param2.substr(nfound+3) );
nfound = param2.find(" + ",nfound+3);
if( nfound != string::npos ) {
offset += STOI( param2.substr(nfound+3) );
nfound = param2.find(" + ",nfound+3);
}
}
cob_fields.Modify(f_symbol,base,offset);
} }
// Go see if there are more on this line // Go see if there are more on this line
...@@ -734,7 +745,7 @@ DATA_DESCRIPTIONS::Flatten(const COB_FIELDS &cob_fields, ...@@ -734,7 +745,7 @@ DATA_DESCRIPTIONS::Flatten(const COB_FIELDS &cob_fields,
it++ it++
) { ) {
COB_DATUM cob_data = *it; COB_DATUM cob_data = *it;
if( !IsInDs(cob_data.program_id,cob_data.cbl_name) ) { if( !IsInDs(cob_data.program_id,cob_data.name) ) {
// It's not already there. So, put it there. // It's not already there. So, put it there.
DATA_DESCRIPTION ds; DATA_DESCRIPTION ds;
ds.program_id = cob_data.program_id; ds.program_id = cob_data.program_id;
...@@ -804,7 +815,8 @@ DATA_DESCRIPTIONS::Dump() const ...@@ -804,7 +815,8 @@ DATA_DESCRIPTIONS::Dump() const
cout << "DATA_DESCRIPTION:" << endl ; cout << "DATA_DESCRIPTION:" << endl ;
cout << setw(20) << "program_id" ; cout << setw(20) << "program_id" ;
cout << setw(20) << "cbl_symbol" ; cout << setw(20) << "cbl_symbol" ;
cout << setw(20) << "c_symbol" ; cout << setw( 9) << "c_symbol" ;
cout << setw( 9) << "f_symbol" ;
cout << setw( 7) << "offset" ; cout << setw( 7) << "offset" ;
cout << setw(13) << "storage_type" ; cout << setw(13) << "storage_type" ;
cout << setw(16) << "picture" ; cout << setw(16) << "picture" ;
...@@ -822,7 +834,8 @@ DATA_DESCRIPTIONS::Dump() const ...@@ -822,7 +834,8 @@ DATA_DESCRIPTIONS::Dump() const
DATA_DESCRIPTION symbol = *it; DATA_DESCRIPTION symbol = *it;
cout << setw(20) << symbol.program_id ; cout << setw(20) << symbol.program_id ;
cout << setw(20) << symbol.cbl_symbol ; cout << setw(20) << symbol.cbl_symbol ;
cout << setw(20) << symbol.c_symbol ; cout << setw( 9) << symbol.c_symbol ;
cout << setw( 9) << symbol.field_data_name ;
cout << setw( 7) << symbol.field_data_offset ; cout << setw( 7) << symbol.field_data_offset ;
cout << setw(13) << symbol.storage_type ; cout << setw(13) << symbol.storage_type ;
cout << setw(16) << symbol.picture_string ; cout << setw(16) << symbol.picture_string ;
......
...@@ -169,8 +169,9 @@ typedef std::map<std::string,size_t> M_COB_DATUM; ...@@ -169,8 +169,9 @@ typedef std::map<std::string,size_t> M_COB_DATUM;
class COB_DATA class COB_DATA
{ {
public: public:
V_COB_DATUM v_data; V_COB_DATUM v_data; // The list of elements
M_COB_DATUM m_data; M_COB_DATUM m_data_from_b_field;
M_COB_DATUM m_data_from_cbl_name;
public: public:
COB_DATA() COB_DATA()
...@@ -183,14 +184,20 @@ public: ...@@ -183,14 +184,20 @@ public:
const std::string &storage, const std::string &storage,
const std::string &cbl_name) const std::string &cbl_name)
{ {
M_COB_DATUM::const_iterator it = m_data.find(name); M_COB_DATUM::const_iterator it = m_data_from_b_field.find(name);
if( it != m_data.end() ) { if( it != m_data_from_b_field.end() ) {
std::cout << "Creating the symbol " << name << " more than once in COB_DATA::Insert()\n" ; std::cout << "Creating the symbol " << name << " more than once in COB_DATA::Insert()\n" ;
exit(1); exit(1);
} }
COB_DATUM cd(name, size, program_id, storage, cbl_name); COB_DATUM cd(name, size, program_id, storage, cbl_name);
m_data[name] = v_data.size(); m_data_from_b_field[name] = v_data.size();
std::string cobol_name = program_id;
cobol_name += "|";
cobol_name += cbl_name;
m_data_from_cbl_name[cobol_name] = v_data.size();
v_data.push_back(cd); v_data.push_back(cd);
} }
...@@ -199,9 +206,9 @@ public: ...@@ -199,9 +206,9 @@ public:
{ {
std::cout << "COB_DATA:" << std::endl; std::cout << "COB_DATA:" << std::endl;
std::cout << std::setw(20) << "name" ; std::cout << std::setw(20) << "name" ;
std::cout << std::setw(20) << "storage";
std::cout << std::setw(20) << "size"; std::cout << std::setw(20) << "size";
std::cout << std::setw(20) << "program_id"; std::cout << std::setw(20) << "program_id";
std::cout << std::setw(20) << "storage";
std::cout << std::setw(20) << "cbl_name"; std::cout << std::setw(20) << "cbl_name";
std::cout << std::endl; std::cout << std::endl;
...@@ -211,9 +218,9 @@ public: ...@@ -211,9 +218,9 @@ public:
it++) { it++) {
COB_DATUM symbol = *it; COB_DATUM symbol = *it;
std::cout << std::setw(20) << symbol.name ; std::cout << std::setw(20) << symbol.name ;
std::cout << std::setw(20) << symbol.storage_type;
std::cout << std::setw(20) << symbol.size; std::cout << std::setw(20) << symbol.size;
std::cout << std::setw(20) << symbol.program_id; std::cout << std::setw(20) << symbol.program_id;
std::cout << std::setw(20) << symbol.storage_type;
std::cout << std::setw(20) << symbol.cbl_name; std::cout << std::setw(20) << symbol.cbl_name;
std::cout << std::endl; std::cout << std::endl;
} }
...@@ -224,14 +231,32 @@ public: ...@@ -224,14 +231,32 @@ public:
GetCobDatum(const std::string &b_name) const GetCobDatum(const std::string &b_name) const
{ {
const COB_DATUM *retval = nullptr; const COB_DATUM *retval = nullptr;
M_COB_DATUM::const_iterator it = m_data.find(b_name); M_COB_DATUM::const_iterator it = m_data_from_b_field.find(b_name);
if( it != m_data.end() ) { if( it != m_data_from_b_field.end() ) {
retval = &v_data[it->second]; retval = &v_data[it->second];
} }
return retval; return retval;
} }
const COB_DATUM *
GetCobDatumFromProgAndName(const std::string &prog,
const std::string &name) const
{
std::string cobol_name = prog;
cobol_name += "|";
cobol_name += name;
const COB_DATUM *retval = nullptr;
M_COB_DATUM::const_iterator it = m_data_from_cbl_name.find(cobol_name);
if( it != m_data_from_cbl_name.end() ) {
retval = &v_data[it->second];
}
return retval;
}
}; };
class COB_FIELD_ATTRIBUTES; class COB_FIELD_ATTRIBUTES;
...@@ -566,7 +591,6 @@ class DATA_DESCRIPTION ...@@ -566,7 +591,6 @@ class DATA_DESCRIPTION
{ {
public: public:
std::string program_id; std::string program_id;
int level;
std::string storage_type; std::string storage_type;
std::string cbl_symbol; std::string cbl_symbol;
std::string c_symbol; std::string c_symbol;
...@@ -591,7 +615,6 @@ public: ...@@ -591,7 +615,6 @@ public:
public: public:
DATA_DESCRIPTION() DATA_DESCRIPTION()
{ {
level = 0;
storage_size = 0; storage_size = 0;
attr_type = 0; attr_type = 0;
attr_digits = 0; attr_digits = 0;
...@@ -642,33 +665,33 @@ public: ...@@ -642,33 +665,33 @@ public:
} }
std::string std::string
MakeVKey(std::string const &program_id, std::string const &cbl_identifier,int offset) const MakeVKey(std::string const &program_id, std::string const &c_symbol,int offset) const
{ {
char ach[20]; char ach[20];
sprintf(ach,"%d",offset); sprintf(ach,"%d",offset);
return program_id + "|" + cbl_identifier + "|" + ach; return program_id + "|" + c_symbol + "|" + ach;
} }
void void
DsInsert(const DATA_DESCRIPTION &ds ) DsInsert(const DATA_DESCRIPTION &ds )
{ {
symbols_key[MakeVKey(ds.program_id,ds.cbl_symbol,ds.field_data_offset)] = symbols.size(); symbols_key[MakeVKey(ds.program_id,ds.c_symbol,ds.field_data_offset)] = symbols.size();
symbols_index[MakeVKey(ds.program_id,ds.cbl_symbol,-1)] = symbols.size(); symbols_index[MakeVKey(ds.program_id,ds.c_symbol,-1)] = symbols.size();
symbols.push_back(ds); symbols.push_back(ds);
} }
bool bool
IsInDs(std::string const &program_id, std::string const &cbl_identifier,int offset) const IsInDs(std::string const &program_id, std::string const &c_symbol,int offset) const
{ {
std::string dskey=MakeVKey(program_id,cbl_identifier,offset); std::string dskey=MakeVKey(program_id,c_symbol,offset);
M_VKEY::const_iterator it = symbols_key.find(dskey); M_VKEY::const_iterator it = symbols_key.find(dskey);
return it != symbols_key.end(); return it != symbols_key.end();
} }
size_t size_t
GetIndex(std::string const &program_id, std::string const &cbl_identifier,int offset) const GetIndex(std::string const &program_id, std::string const &c_symbol,int offset) const
{ {
size_t retval = (size_t)(-1); size_t retval = (size_t)(-1);
std::string dskey=MakeVKey(program_id,cbl_identifier,offset); std::string dskey=MakeVKey(program_id,c_symbol,offset);
M_VKEY::const_iterator it = symbols_key.find(dskey); M_VKEY::const_iterator it = symbols_key.find(dskey);
if(it != symbols_key.end()) { if(it != symbols_key.end()) {
retval = it->second; retval = it->second;
...@@ -677,17 +700,17 @@ public: ...@@ -677,17 +700,17 @@ public:
} }
bool bool
IsInDs(std::string const &program_id, std::string const &cbl_identifier) const IsInDs(std::string const &program_id, std::string const &c_symbol) const
{ {
std::string dskey=MakeVKey(program_id,cbl_identifier,-1); std::string dskey=MakeVKey(program_id,c_symbol,-1);
M_VKEY::const_iterator it = symbols_index.find(dskey); M_VKEY::const_iterator it = symbols_index.find(dskey);
return it != symbols_index.end(); return it != symbols_index.end();
} }
size_t size_t
GetIndex(std::string const &program_id, std::string const &cbl_identifier) const GetIndex(std::string const &program_id, std::string const &c_symbol) const
{ {
size_t retval = (size_t)(-1); size_t retval = (size_t)(-1);
std::string dskey=MakeVKey(program_id,cbl_identifier,-1); std::string dskey=MakeVKey(program_id,c_symbol,-1);
M_VKEY::const_iterator it = symbols_index.find(dskey); M_VKEY::const_iterator it = symbols_index.find(dskey);
if(it != symbols_index.end()) { if(it != symbols_index.end()) {
retval = it->second; retval = it->second;
...@@ -702,7 +725,6 @@ public: ...@@ -702,7 +725,6 @@ public:
const COB_PIC_SYMBOLS &cob_pic_symbols, const COB_PIC_SYMBOLS &cob_pic_symbols,
const COB_DATA &cob_data const COB_DATA &cob_data
); );
void FormatVariablesInfo(std::stringstream &ss) const;
}; };
......
...@@ -1108,146 +1108,51 @@ VARIABLE_TREE::AdjustFlatList() ...@@ -1108,146 +1108,51 @@ VARIABLE_TREE::AdjustFlatList()
} }
void void
VARIABLE_TREE::Consolidive(VAR_NODE *node,const DATA_DESCRIPTIONS &data_description,string &base_symbol) VARIABLE_TREE::Consolidive(VAR_NODE *node,const DATA_DESCRIPTIONS &data_description,string &base_symbol,const COB_DATA &cob_data)
{ {
// This routine was once more complicated; now it just propogates the top node b_xxx down through
// the whole branch:
if( node ) { if( node ) {
cout << "DEBUG0 " << node->level << " " << node->canonical_name << " " << base_symbol << endl;
VSTRING tokens = Split(node->GetCanonicalName(),"/"); VSTRING tokens = Split(node->GetCanonicalName(),"/");
if( tokens.size() >= 2 ) { if( tokens.size() >= 2 ) {
if( node->level <= 1 OR node->level EQ 77 ) {
// We're starting work on a brand-new level-one(ish) variable. We need to
// clear out the base_symbol:
base_symbol = "" ;
}
string program_id = tokens.back(); string program_id = tokens.back();
string cbl_symbol = tokens[0]; string cbl_symbol = tokens[0];
int offset = node->GetOffset(); int offset = node->GetOffset();
// See if we have a data_descriptions entry for that cbl_symbol
size_t index = NO_INDEX; size_t index = NO_INDEX;
if( data_description.IsInDs(program_id,cbl_symbol,offset) ) {
// We do! Save the index
index = data_description.GetIndex(program_id,cbl_symbol,offset);
node->data_description_index = index;
}
//else if( data_description.IsInDs(program_id,cbl_symbol) )
// {
// // We didn't find one specifically at that offset, but there is
// // non-specific entry (which happens when COBOL code doesn't
// // actually reference the variable
// index = data_description.GetIndex(program_id,cbl_symbol);
// node->data_description_index = index;
// }
if( index EQ NO_INDEX AND !node->redefines.empty() ) {
// We couldn't find ourself with our own name. Perhaps we
// can borrow our base_symbol from an older sibling.
VSTRING tokes = Split(node->redefines,"/");
if( data_description.IsInDs(program_id,tokes[0],offset) ) {
// We can! Save the index
index = data_description.GetIndex(program_id,tokes[0],offset);
} else if ( data_description.IsInDs(program_id,tokes[0]) ) {
index = data_description.GetIndex(program_id,tokes[0],offset);
}
if( index != NO_INDEX ) {
DATA_DESCRIPTION symbol = data_description[index];
if( base_symbol.empty() and !symbol.c_symbol.empty() ) {
// Replace our empty base_symbol with the one from data_descriptions
base_symbol = data_description[index].c_symbol;
}
node->base_symbol = data_description[index].c_symbol;
}
// We can't take anything except the base_symbol; none of the
// rest of our sibling's fields are relevant:
index = NO_INDEX;
}
if( index != NO_INDEX ) {
DATA_DESCRIPTION symbol = data_description[index];
if( base_symbol.empty() and !symbol.c_symbol.empty() ) {
// Replace our empty base_symbol with the one from data_descriptions
base_symbol = data_description[index].c_symbol;
}
// Here is where we combine the VARIABLE_TREE data with the DATA_DESCRIPTIONS
// data to create everything we need:
if( symbol.storage_size EQ 0 ) {
node->best_size = symbol.field_size;
} else if( symbol.field_size EQ 0 ) {
node->best_size = symbol.storage_size;
} else {
node->best_size = symbol.field_size;
}
if( node->picture.empty() ) {
node->best_picture = symbol.picture_string;
} else if ( symbol.picture_string.empty() ) {
node->best_picture = node->picture;
} else {
// If they're both on, go with the one from the listing file
node->best_picture = node->picture;
}
if( node->level EQ 66 ) { if( node->level <= 1 OR node->level EQ 77 ) {
// The .cbl.lst file doesn't have good offset information // We're starting work on a brand-new level-one(ish) variable.
// for 66 REDEFINES. But the symbol *might* have good information, // Let's check to see if there is a b_ buffer for this 01/77 symbol
// which it gets from the f_ field_attribute record when the 66 const COB_DATUM *pdatum = cob_data.GetCobDatumFromProgAndName(program_id,cbl_symbol);
// variable is referenced in the code. if( pdatum ) {
// Pick up the base symbol
node->offset = symbol.field_data_offset ; base_symbol = pdatum->name;
} }
node->base_symbol = symbol.c_symbol ;
node->attr_type = symbol.attr_type ;
node->attr_digits = symbol.attr_digits ;
node->attr_scale = symbol.attr_scale ;
node->attr_flags = symbol.attr_flags ;
} else {
node->best_size = node->size;
node->best_picture = node->picture;
} }
// We might have a new base_symbol at this point; if we do, apply it to if( !base_symbol.empty() ) {
// this node: // See if we have a data_descriptions entry for that cbl_symbol
if( data_description.IsInDs(program_id,base_symbol,offset) ) {
if( node->base_symbol.empty() AND !base_symbol.empty() ) { // We do! Save the index
cout << "DEBUG1 " << node->canonical_name << " " << base_symbol << endl ; index = data_description.GetIndex(program_id,base_symbol,offset);
node->base_symbol = base_symbol; node->data_description_index = index;
node->base_symbol = data_description[index].c_symbol;
}
} }
// And our work here is done:
} }
for(VVAR_NODES::const_iterator it=node->children.begin(); for(VVAR_NODES::const_iterator it=node->children.begin();
it!=node->children.end(); it!=node->children.end();
it++) { it++) {
VAR_NODE *child = *it; VAR_NODE *child = *it;
// Check our children // Check our children
Consolidive(child,data_description,base_symbol); Consolidive(child,data_description,base_symbol,cob_data);
if( !base_symbol.empty() AND node->base_symbol.empty() ) {
// One of our descendents has a base_address, and we don't. I'm not really
// sure that can happen, but just in case, propogate that base_symbol
// upward:
cout << "DEBUG2 " << node->canonical_name << " " << base_symbol << endl ;
node->base_symbol = base_symbol;
if( node->level <= 1 OR node->level EQ 77 ) {
// We're starting work on a brand-new level-one(ish) variable. We need to
// clear out the base_symbol:
base_symbol = "" ;
}
}
} }
base_symbol = "" ;
} }
} }
void void
VARIABLE_TREE::Consolidate(const DATA_DESCRIPTIONS &data_description) VARIABLE_TREE::Consolidate(const DATA_DESCRIPTIONS &data_description,const COB_DATA &cob_data)
{ {
// data_description has f_ and b_ entries for working-storage and linkage // data_description has f_ and b_ entries for working-storage and linkage
// variables that are referenced in the COBOL code // variables that are referenced in the COBOL code
...@@ -1266,7 +1171,7 @@ VARIABLE_TREE::Consolidate(const DATA_DESCRIPTIONS &data_description) ...@@ -1266,7 +1171,7 @@ VARIABLE_TREE::Consolidate(const DATA_DESCRIPTIONS &data_description)
// data_description. // data_description.
string base_symbol=""; string base_symbol="";
Consolidive(root,data_description,base_symbol); Consolidive(root,data_description,base_symbol,cob_data);
BuildFlatList(root,flat_list); BuildFlatList(root,flat_list);
AdjustFlatList(); AdjustFlatList();
......
...@@ -36,8 +36,9 @@ ...@@ -36,8 +36,9 @@
#include <iostream> #include <iostream>
#include <set> #include <set>
#include <map> #include <map>
#include "input_scan.h"
#include "vartree.h" #include "vartree.h"
#include "input_scan.h"
/* These objects are for keeping track of the parsed storage section /* These objects are for keeping track of the parsed storage section
...@@ -215,6 +216,7 @@ public: ...@@ -215,6 +216,7 @@ public:
}; };
typedef std::vector<VAR_NODE *>VVAR_NODES; typedef std::vector<VAR_NODE *>VVAR_NODES;
class COB_DATA;
class DATA_DESCRIPTIONS; class DATA_DESCRIPTIONS;
class VARIABLE_TREE class VARIABLE_TREE
{ {
...@@ -236,7 +238,8 @@ private: ...@@ -236,7 +238,8 @@ private:
void Consolidive(VAR_NODE *node, void Consolidive(VAR_NODE *node,
const DATA_DESCRIPTIONS &data_description, const DATA_DESCRIPTIONS &data_description,
std::string &base_symbol); std::string &base_symbol,
const COB_DATA &cob_data);
public: public:
VARIABLE_TREE(); VARIABLE_TREE();
...@@ -245,7 +248,7 @@ public: ...@@ -245,7 +248,7 @@ public:
void ReadFromFile(std::ifstream &ifs); void ReadFromFile(std::ifstream &ifs);
void BuildCanonicalName(); void BuildCanonicalName();
void Dump(std::ostream &s = std::cout); void Dump(std::ostream &s = std::cout);
void Consolidate(const DATA_DESCRIPTIONS &data_description); void Consolidate(const DATA_DESCRIPTIONS &data_description,const COB_DATA &cob_data);
void DumpFlatList() const; void DumpFlatList() const;
void FormatVariablesInfo(std::stringstream &ss) const; void FormatVariablesInfo(std::stringstream &ss) const;
......
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