// ------------------------------------------------------------------ // Route Diagram Drawing Tool. // Copyright (C) 1999 Odinn Sorensen // Copyright (C) 1999-2001 Alexander S. Aganichev // Copyright (C) 2005 Stas Degteff // ------------------------------------------------------------------ // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // ------------------------------------------------------------------ // Designed to work with the Goldware library. May need some work.. // ------------------------------------------------------------------ // $Id$ // ------------------------------------------------------------------ #include #include #include #include #include #include using namespace std; #include #include #include #include int debug = false; // ------------------------------------------------------------------ // Config versions #define __GVER_NAME__ "Route Diagram Drawing Tool" #define __GVER_SHORTNAME__ "RDDT" #define __gver_name__ __GVER_NAME__ #define __gver_shortname__ __GVER_SHORTNAME__ // ------------------------------------------------------------------ class node { public: node() { order = 0; depth = 0; used = false; posts = 0; } bool used; int order; int depth; int posts; ftn_addr address; string name; vector links; string display; void add(const char* s) { ftn_addr n = s; add(n); } void add(ftn_addr& addr); node& operator=(const node& a); }; // ------------------------------------------------------------------ typedef list list_node; // ------------------------------------------------------------------ class nodetree { public: nodetree() { maxname = 0; maxdisp = 0; order = 0; indent = 2; posts = 0; } list_node nodes; int order; int maxname; int maxdisp; int indent; int posts; void prepare(ftn_addr& previous, ftn_addr& current, int depth); void sort(); void print(); void add(node& a); }; // ------------------------------------------------------------------ node& node::operator=(const node& a) { used = a.used; order = a.order; depth = a.depth; address = a.address; name = a.name; display = a.display; links = a.links; return *this; } // ------------------------------------------------------------------ bool equals2d(ftn_addr& a, ftn_addr& b) { if(a == b) return true; else if((a.net == b.net) and (a.node == b.node) and (a.point == b.point)) return true; return false; } // ------------------------------------------------------------------ void node::add(ftn_addr& addr) { if(equals2d(addr, address)) return; for(int l=0; lused) { if(equals2d(n->address, current)) { n->order = ++order; n->depth = depth; n->used = true; for(int l=0; llinks.size(); l++) { //if(not equals2d(n->links[l], previous)) if(n->links[l] != previous) prepare(current, n->links[l], depth+1); } break; } } } } // ------------------------------------------------------------------ bool _compare_nodes(const node& a, const node& b) { int cmp = compare_two(a.order ? 0 : 1, b.order ? 0 : 1); if(cmp) return (cmp < 0); cmp = compare_two(a.order, b.order); if(cmp) return (cmp < 0); return (a.address.compare(b.address) < 0); } #if defined(_MSC_VER) inline bool operator<(const node& A,const node& B){ return _compare_nodes(A,B); } #define compare_nodes #else #define compare_nodes _compare_nodes #endif // ------------------------------------------------------------------ void nodetree::sort() { nodes.sort(compare_nodes); } // ------------------------------------------------------------------ void nodetree::print() { list_node::iterator n; for(n=nodes.begin(); n != nodes.end(); n++) { char buf[100]; strsetsz(strcpy(buf, n->name.c_str()), maxname+indent); n->display = buf; list_node::iterator x; bool above, below; for(int d=1; ddepth; d++) { above = false; below = false; if(d > 0) { for(x=n; x-- != nodes.begin();) { if(x->depth < d) break; else if(x->depth == d) { above = true; break; } } for(x=n; ++x != nodes.end();) { if(x->depth < d) break; else if(x->depth == d) { below = true; break; } } } if(above and below) { #ifdef KOI8 strcpy(buf, ""); #else strcpy(buf, ""); #endif } else *buf = NUL; strsetsz(buf, indent); n->display += buf; } if(n->depth) { #ifdef KOI8 strcpy(buf, ""); #else strcpy(buf, ""); #endif strsetsz(buf, indent); #ifdef KOI8 strchg(buf, ' ', ''); #else strchg(buf, ' ', ''); #endif n->display += buf; } n->display += n->address.make_string(buf); maxdisp = maximum_of_two((size_t)maxdisp, n->display.length()); } for(n=nodes.begin(); n != nodes.end(); n++) { list_node::iterator x=n; if(++x != nodes.end()) { #ifdef KOI8 const char* p = strchr(n->display.c_str(), ''); #else const char* p = strchr(n->display.c_str(), ''); #endif if(p) { int len = p - n->display.c_str(); #ifdef KOI8 if((x->display[len] == '') or (x->display[len] == '')) n->display[len] = ''; #else if((x->display[len] == '') or (x->display[len] == '')) n->display[len] = ''; #endif } } n->display.resize(maxdisp, ' '); char buf[40]; sprintf(buf, "%*s[%i]", indent, "", n->depth); n->display += buf; } for(n=nodes.begin(); n != nodes.end(); n++) cout << n->display.c_str() << endl; } // ------------------------------------------------------------------ int main(int argc, char** argv) { throw_init(); // set locale setlocale(LC_CTYPE, ""); cout << __gver_name__ << " v." << __gver_preversion__ << __gver_shortver__ << __gver_platform__ << __gver_postversion__; #ifdef KOI8 cout << " (koi8)"; #endif cout << endl << "Copyright (C) 1999 Odinn Sorensen" << endl << "Copyright (C) 1999-2001 Alexander S. Aganichev" << endl << "Copyright (C) 2005 Stas Degteff & Golded+ team" << endl << "----------------------------------------------------------------------" << endl << endl; if(argc < 2) { cout << "Syntax: RDDT [options] [address or name]" << endl << "\twhere options may be:" << endl << "\t\t-d - Debug mode" << endl << "\t\t-p - Decode path" << endl << "\t\t-n ownaddress - Your own address" << endl << "\t\t-l ownuplink - Your own uplink" << endl << "\t\t-i num - indent spaces" << endl << endl; return 1; } #if defined(GUTLOS_FUNCS) g_init_os(0); #endif node anode; nodetree atree; ifstream fp(argv[1]); ftn_addr address; bool decode_path = false; char* top = NULL; ftn_addr ownaddress; ftn_addr ownuplink; for(int argn=2; argn 1) { anode.links.resize(0); strchg(&links[0][0], '_', ' '); anode.name = links[0]; atree.maxname = maximum_of_two(anode.name.length(), (size_t)atree.maxname); anode.address = links[1]; if(links.size() > 2) { if(decode_path) { anode.posts++; atree.posts++; int n; address = links[2]; if(not equals2d(address, anode.address)) anode.add(address); for(n=3; naddress.match(match)) { xnode = *n; address = n->address; break; } } } else { for(list_node::iterator n=atree.nodes.begin(); n != atree.nodes.end(); n++) { if(n->name.find(top) != n->name.npos) { xnode = *n; address = n->address; break; } } } if(address.valid()) { if(debug) { char buf[50]; for(list_node::iterator n=atree.nodes.begin(); n != atree.nodes.end(); n++) { xnode = *n; cout << xnode.address.make_string(buf) << endl; for(int l=0; l