home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume35 / splash / patch01 < prev    next >
Encoding:
Text File  |  1993-01-19  |  31.0 KB  |  1,052 lines

  1. Newsgroups: comp.sources.misc
  2. From: morris@netcom.com (Jim Morris)
  3. Subject: v35i001:  splash - Small Perl-like List And String Handling class lib, v1.8, Patch01
  4. Message-ID: <1993Jan20.232429.21589@sparky.imd.sterling.com>
  5. X-Md4-Signature: 51012b5e6bde1eb23c063b463fe1e320
  6. Date: Wed, 20 Jan 1993 23:24:29 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: morris@netcom.com (Jim Morris)
  10. Posting-number: Volume 35, Issue 1
  11. Archive-name: splash/patch01
  12. Environment: C++
  13. Patch-To: splash: Volume 34, Issue 121-123
  14.  
  15. [ It seems that when I repackaged splash I left out the sample files that  ]
  16. [ were suppose to be in the sample directory.  This shar file contains the ]
  17. [ missing sample files.  To apply this "patch", cd to the splash top level ]
  18. [ source directory and unshar the following.  Sorry Jim, and to any others ]
  19. [ I have inconvenienced.                                                   ]
  20. [             -Kent+                                             ]
  21. -----------------------------
  22. #! /bin/sh
  23. # This is a shell archive.  Remove anything before this line, then feed it
  24. # into a shell via "sh file" or similar.  To overwrite existing files,
  25. # type "sh file -c".
  26. # Contents:  sample/README.sam sample/assoc.c++ sample/chgfnt.c++
  27. #   sample/cislog.c++ sample/justify.c++ sample/tracer.c++
  28. #   sample/tracer.h sample/tstio.c++ sample/xcl.c++
  29. # Wrapped by kent@sparky on Tue Jan 19 21:39:05 1993
  30. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  31. echo If this archive is complete, you will see the following message:
  32. echo '          "shar: End of archive 1 (of 1)."'
  33. if test -f 'sample/README.sam' -a "${1}" != "-c" ; then 
  34.   echo shar: Will not clobber existing file \"'sample/README.sam'\"
  35. else
  36.   echo shar: Extracting \"'sample/README.sam'\" \(714 characters\)
  37.   sed "s/^X//" >'sample/README.sam' <<'END_OF_FILE'
  38. XThe files in this directory are samples of programs I have written
  39. Xto use the SPLASH class library.
  40. X
  41. Xassoc.c++    - Shows hows to use the association arrays
  42. X
  43. Xchgfnt.c++    - Is a program that reads in an AmiPro style file
  44. X          and also the win.ini file. It replaces all
  45. X          non-truetype fonts with a user entered one
  46. X
  47. Xcislog.c++    - calculates the monthly charges from a log file
  48. X          generated by Procomm/win for Compuserve logins
  49. X
  50. Xtstio.c++    - Simple minded test of streams use with SPLASH
  51. X
  52. Xjustify.c++    - A filter program that justifies text to a given
  53. X          line width
  54. X
  55. Xxcl.c++        - A program that is used with the Tracer files that
  56. X          automatically inserts a TRACER macro at the start
  57. X          of all functions in a c++ program.
  58. END_OF_FILE
  59.   if test 714 -ne `wc -c <'sample/README.sam'`; then
  60.     echo shar: \"'sample/README.sam'\" unpacked with wrong size!
  61.   fi
  62.   # end of 'sample/README.sam'
  63. fi
  64. if test -f 'sample/assoc.c++' -a "${1}" != "-c" ; then 
  65.   echo shar: Will not clobber existing file \"'sample/assoc.c++'\"
  66. else
  67.   echo shar: Extracting \"'sample/assoc.c++'\" \(535 characters\)
  68.   sed "s/^X//" >'sample/assoc.c++' <<'END_OF_FILE'
  69. X#ifdef    TESTASSOC
  70. X
  71. X#include <iostream.h>
  72. X#include "splash.h"
  73. X#include "assoc.h"
  74. X
  75. Xmain()
  76. X{
  77. X    Assoc<int> a;
  78. X    a("one")= 1; a("two")= 2; a("three")= 3;
  79. X    cout << a << endl;
  80. X    
  81. X    cout << "Keys:" << endl << a.keys() << endl;
  82. X    cout << "Values:" << endl << a.values() << endl;
  83. X    
  84. X    cout << "a.isin(\"three\")= " << a.isin("three") << endl;
  85. X    cout << "a.isin(\"four\")= " << a.isin("four") << endl;
  86. X    
  87. X    int t= a.adelete("two");
  88. X    cout << "a.adelete(\"two\") returns: " << t << ", a= " << endl << a << endl;
  89. X
  90. X}
  91. X#endif
  92. X
  93. END_OF_FILE
  94.   if test 535 -ne `wc -c <'sample/assoc.c++'`; then
  95.     echo shar: \"'sample/assoc.c++'\" unpacked with wrong size!
  96.   fi
  97.   # end of 'sample/assoc.c++'
  98. fi
  99. if test -f 'sample/chgfnt.c++' -a "${1}" != "-c" ; then 
  100.   echo shar: Will not clobber existing file \"'sample/chgfnt.c++'\"
  101. else
  102.   echo shar: Extracting \"'sample/chgfnt.c++'\" \(3541 characters\)
  103.   sed "s/^X//" >'sample/chgfnt.c++' <<'END_OF_FILE'
  104. X#ifdef    TESTCHGFNT
  105. X// Read an AmiPro style sheet and change any unknown font
  106. X#include    <fstream.h>
  107. X#include    <stdlib.h>
  108. X
  109. X#ifdef    __TURBOC__
  110. X#pragma hdrstop
  111. X#endif
  112. X
  113. X#include    "splash.h"
  114. X#include    "assoc.h"
  115. X
  116. Xvoid main(int argc, char **argv)
  117. X{
  118. Xchar c, *infn;
  119. Xifstream ini("\\win3\\win.ini");
  120. Xofstream fout("t.sty");
  121. Xint ln= 0;
  122. XSPString w;
  123. XSPStringList l;
  124. XSPStringList ttfonts;
  125. XAssoc<SPString> repfnts("", "");  // saves font replacement names
  126. X
  127. X    if(argc < 2) infn= "test.sty";
  128. X    else infn= argv[1];
  129. X
  130. X    ifstream fin(infn);
  131. X
  132. X    if(!ini){
  133. X        cerr << "Can't open \\win3\\win.ini" << endl;
  134. X        exit(1);
  135. X    }
  136. X
  137. X    if(!fin){
  138. X        cerr << "Can't open " << infn << endl;
  139. X        exit(1);
  140. X    }
  141. X
  142. X    if(!fout){
  143. X        cerr << "Can't open t.sty for write" << endl;
  144. X        exit(1);
  145. X    }
  146. X
  147. X    cout << "Reading in truetype fonts" << endl;
  148. X
  149. X    while(ini >> w){ // find the [fonts] section
  150. X    if(w.m("\\[fonts\\]")) break;
  151. X    }
  152. X
  153. X//    cout << buf << endl;
  154. X
  155. X    if(!ini.good()){ // checks all file state
  156. X        cerr << "Couldn't find [fonts] section in win.ini" << endl;
  157. X        exit(1);
  158. X    }
  159. X
  160. X    // make a list of truetype fonts
  161. X    Regexp r1("^([a-zA-Z ]+) \\(([a-zA-Z ]+)\\)=");
  162. X    Regexp r2("^TrueType$");
  163. X    Regexp r3("\\[.*\\]");
  164. X
  165. X    while(ini >> w){
  166. X    if(w.m(r3)) break; // found the start of another section
  167. X        if(w.m(r1, l) != 3) continue; // ignore this line
  168. X//        cout << "Font match:" << l[1] << ", " << l[2] << endl;
  169. X        if(l[2].m(r2)){
  170. X            ttfonts.push(l[1]);
  171. X        } 
  172. X    }
  173. X
  174. X    cout << "ttfonts: " << endl << ttfonts << endl;
  175. X    ini.close();
  176. X
  177. X    cout << "Looking for non-truetype fonts" << endl;
  178. X
  179. X    SPString s, fnt, newfnt;
  180. X    SPStringList sl;
  181. X    while(fin >> s){
  182. X    ln++;
  183. X//        cout << "line " << ln << ": <" << s << ">" << endl;
  184. X        if(s.m("\\[fnt\\]")){
  185. X            fout << s << endl; // write out [fnt] line
  186. X                   // read next line which should have font in it
  187. X        if(!(fin >> s)){
  188. X        cerr << "Error reading font line " << ln << endl;
  189. X        exit(1);
  190. X        }
  191. X        ln++;
  192. X        fnt= s.split("' '").join(" "); // This trims whitespace
  193. X//        cout << "font name: <" << fnt << ">" << endl;
  194. X            if(!ttfonts.grep("^" + fnt + "$", "i")){ // not a truetype font
  195. X                int pos= s.index(fnt); // get position in string of font
  196. X                if(pos < 0){
  197. X                    cerr << "Couldn't find <" << fnt << "> in string <" << s << "> line " << ln << endl;
  198. X                    exit(1);
  199. X                }
  200. X
  201. X                // See if we already know what to exchange it with
  202. X        if(repfnts.isin(fnt)) // just replace it
  203. X            s.substr(pos, strlen(fnt)) = repfnts(fnt);
  204. X                else{ // need to ask what the new font name will be
  205. X            do{
  206. X            cout << "Replace font <" << fnt << "> with:"; cout.flush();
  207. X            cin >> newfnt;
  208. X            if(!(sl=ttfonts.grep("^" + newfnt + "$", "i"))){
  209. X                cerr << "<" << newfnt << "> is not a valid font" << endl;
  210. X                continue;
  211. X            }
  212. X            break;
  213. X            }while(1);
  214. X            s.substr(pos, strlen(fnt)) = sl[0]; // replace it
  215. X                    repfnts(fnt) = sl[0];  // remember for next time
  216. X                }
  217. X        fout << s << endl;
  218. X            }else{
  219. X//                cout << fnt << " is a truetype font" << endl;
  220. X                fout << s << endl; // write out original font line
  221. X            }
  222. X
  223. X       }else{
  224. X            fout << s << endl; // echo line out
  225. X        }
  226. X    }while(!fin.eof());
  227. X
  228. X    cout << "replacement fonts were:" << endl << repfnts << endl;
  229. X
  230. X    if(fout.fail())
  231. X        cerr << "Something bad happened to the output file" << endl;
  232. X    fout.close();
  233. X
  234. X}
  235. X
  236. X#endif
  237. END_OF_FILE
  238.   if test 3541 -ne `wc -c <'sample/chgfnt.c++'`; then
  239.     echo shar: \"'sample/chgfnt.c++'\" unpacked with wrong size!
  240.   fi
  241.   # end of 'sample/chgfnt.c++'
  242. fi
  243. if test -f 'sample/cislog.c++' -a "${1}" != "-c" ; then 
  244.   echo shar: Will not clobber existing file \"'sample/cislog.c++'\"
  245. else
  246.   echo shar: Extracting \"'sample/cislog.c++'\" \(2250 characters\)
  247.   sed "s/^X//" >'sample/cislog.c++' <<'END_OF_FILE'
  248. X//
  249. X// Display monthly connect time to CIS
  250. X//
  251. X
  252. X#include    <fstream.h>
  253. X#include    <stdlib.h>
  254. X#include    "splash.h"
  255. X#include    "assoc.h"
  256. X
  257. Xvoid main()
  258. X{
  259. Xchar buf[80];
  260. Xifstream fin("cis.log");
  261. Xint ln= 1, gotit= 0;
  262. XAssoc<int> tot("", 0);
  263. XRegexp reet("(..):(..):(..)"), remnth("^(..)/../..");
  264. XRegexp r1("^(../../..) (..:..).. (.*)");
  265. XSPString s;
  266. X
  267. X    fin >> s;    // eat first line
  268. X
  269. X    while(fin >> s){
  270. X    ln++;
  271. X//        cout << "line " << ln << ": <" << s << ">" << endl;
  272. X
  273. X        SPStringList l;
  274. X
  275. X//05/20/92 10:48PM CIS 2400 988-5366
  276. X//05/21/92 09:24PM OFFLINE                                   00:00:06
  277. X        if(s.m(r1, l)){
  278. X            if(l.scalar() < 4){
  279. X                cerr << "Didn't match all expressions" << endl;
  280. X                exit(1);
  281. X        }
  282. X//            cout << "Expressions matched: " << endl << l << endl;
  283. X        SPString a= l[3];
  284. X        if(a.m("^CIS")) gotit= 1;
  285. X        else if(a.m("^OFFLINE") && gotit){ // extract Elapsed time
  286. X                SPStringList et, mnth;
  287. X                int hr, mn, sc, tm;
  288. X
  289. X        if(a.m(reet, et) != 4){
  290. X            cerr << "Failed to extract Elapsed time" << endl;
  291. X                    exit(1);
  292. X        }
  293. X                hr= atoi(et[1]); mn= atoi(et[2]); sc= atoi(et[3]);
  294. X                tm= (hr*60) + mn + ((sc >= 30) ? 1 : 0);
  295. X
  296. X        gotit= 0;
  297. X        // extract month
  298. X                if(l[1].m(remnth, mnth) != 2){
  299. X                    cerr << "Failed to extract Month" << endl;
  300. X                    exit(1);
  301. X                }
  302. X
  303. X//                cout << "Month: " << mnth[1] << " Elapsed Time = " << tm << " mins" << endl;
  304. X        tot(mnth[1]) += tm;
  305. X                                 
  306. X            }else gotit= 0;
  307. X            
  308. X     }else{
  309. X            cerr << "Didn't match any expressions" << endl;
  310. X            exit(1);
  311. X        }
  312. X
  313. X    };
  314. X//    cout << "tot = " << endl << tot << endl;
  315. X    Assoc<SPString> months;
  316. X    months("01")= "January"; months("02")= "February"; months("03")= "March";
  317. X    months("04")= "April"; months("05")= "May"; months("06")= "June";
  318. X    months("07")= "July"; months("08")= "August"; months("09")= "September";
  319. X    months("10")= "October"; months("11")= "November"; months("12")= "December";
  320. X
  321. X    for(int i=0;i<tot.scalar();i++)
  322. X        cout << months(tot[i].key()) << ": " << tot[i].value() << " mins $"
  323. X             << tot[i].value() * (12.50/60.0) << endl;
  324. X}
  325. X
  326. END_OF_FILE
  327.   if test 2250 -ne `wc -c <'sample/cislog.c++'`; then
  328.     echo shar: \"'sample/cislog.c++'\" unpacked with wrong size!
  329.   fi
  330.   # end of 'sample/cislog.c++'
  331. fi
  332. if test -f 'sample/justify.c++' -a "${1}" != "-c" ; then 
  333.   echo shar: Will not clobber existing file \"'sample/justify.c++'\"
  334. else
  335.   echo shar: Extracting \"'sample/justify.c++'\" \(4024 characters\)
  336.   sed "s/^X//" >'sample/justify.c++' <<'END_OF_FILE'
  337. X/*
  338. X * Simple program to read STDIN and justify the text to the
  339. X * specified number of columns and output to STDOUT.
  340. X * The padding is alternated from line to line so as to look even.
  341. X * Blank lines in the input stream are preserved.
  342. X * This was designed to be used as a filter.
  343. X * As with fmt(1) indents are preserved, this can be disabled
  344. X * with an option.
  345. X * Also a change in indent level will be treated as the end of a 
  346. X * stream, so no words on the following line will be wrapped up to
  347. X * the current line.
  348. X */
  349. X
  350. X#include    <iostream.h>
  351. X#include    <stdlib.h>
  352. X#include    <ctype.h>
  353. X
  354. X#include    "splash.h"
  355. X#include    "tracer.h"
  356. X
  357. X// Some useful synonyms
  358. Xtypedef SPString Str;
  359. Xtypedef SPStringList StrList;
  360. X
  361. Xint tog= 0;
  362. X
  363. Xstatic int nextnonspace(const Str& s, int n)
  364. X{
  365. X    while(n < s.length() && s[n] == ' ') n++;    
  366. X    return n;
  367. X}
  368. X
  369. Xstatic int prevnonspace(const Str& s, int n)
  370. X{
  371. X    while(n >= 0 && s[n] == ' ') n--;    
  372. X    return n;
  373. X}
  374. X
  375. Xvoid justify(Str& ln, int width)
  376. X{
  377. XTRACER("justify(Str ln, int width)")
  378. X    LTRACE(2, ln)
  379. X    int p, o= tog?0:ln.length();
  380. X    while(ln.length() < width){
  381. X    if(tog){ // left to right pad
  382. X        p= ln.index(" ", o); // find a space
  383. X        if(p > 0){
  384. X        ln.substr(p, 0)= " "; // insert a space
  385. X        o= nextnonspace(ln, p); // start from next non-space
  386. X        }else if(o) o= 0; // reset
  387. X        else ln += " "; // put at end of line
  388. X    }else{ // right to left pad
  389. X        p= ln.rindex(" ", o); // find a space
  390. X        if(p > 0){
  391. X        ln.substr(p, 0)= " "; // insert a space
  392. X        o= prevnonspace(ln, p); // start from previous non-space
  393. X        }else if(o != ln.length()) o= ln.length(); // reset
  394. X        else ln += " "; // put at end of line
  395. X    }    
  396. X    }
  397. X    tog ^= 1;
  398. X}
  399. X
  400. Xvoid Usage()
  401. X{
  402. X    cout << "Usage: justify [-i] [width]" << endl;
  403. X    cout << "\t-i ignores leading whitespace" << endl;
  404. X    cout << "\twidth is the line width, default is 79" << endl;
  405. X    exit(1);
  406. X}
  407. X
  408. Xint main(int argc,  char **argv)
  409. X{
  410. XFTRACER("main()", 0, cout)
  411. XStr inl, curln, curword;
  412. XStrList words;
  413. Xint width= 79, wwidth, ignorews= 0, lastindent= 0;
  414. XStr lws;    // leading whitespace
  415. XStrList ARGS;
  416. X
  417. X    for(int i=1;i<argc;i++){ // load args
  418. X    ARGS.push(argv[i]);
  419. X    }
  420. X    
  421. X    while(ARGS){ // process them
  422. X    Str arg= ARGS.shift();
  423. X    if(arg == "-i") ignorews= 1;
  424. X    else if(arg == "-x") TRACE_ON
  425. X    else if(isdigit(arg[0])) width= atoi(arg);
  426. X    else Usage();
  427. X    }
  428. X    
  429. X    while(cin >> inl){
  430. X    LTRACE(2, inl)
  431. X
  432. X    if(inl.length() == 0){ // honour existing blank lines
  433. X        if(curln.length()){
  434. X        if(lws.length()) cout << lws; // leading space
  435. X        cout << curln << endl; // flush previous line
  436. X        }
  437. X        cout << endl; // output blank line
  438. X        curln= "";
  439. X        continue;
  440. X    }
  441. X
  442. X    if(!ignorews){ // don't ignore leading whitespace
  443. X        StrList t= m("^([ \t]+)", inl); // get leading whitespace
  444. X        LTRACE(4, "Length = " << t[0].length());
  445. X            if(t){
  446. X        int l= 0;
  447. X        for(int i=0;i<t[0].length();i++){ // expand tabs
  448. X            if(t[0][i] == '\t') l= l + (8 - l%8);
  449. X            else l++;
  450. X        }
  451. X        wwidth= width - l;
  452. X        }else wwidth= width;
  453. X        if(wwidth != lastindent && curln.length()){ // indent changed, flush line
  454. X        if(lws.length()) cout << lws; // leading space
  455. X        cout << curln << endl; // flush previous line
  456. X        curln= "";
  457. X        }
  458. X        lastindent= wwidth;
  459. X        lws= t[0];
  460. X    }else wwidth= width;
  461. X    
  462. X        words.push(inl.split("' '")); // put at end of word FIFO
  463. X    LTRACE(2, words)
  464. X    while(words){
  465. X        if(curln.length() == 0){
  466. X        curln= words.shift(); // get first word
  467. X        }
  468. X        while(curln.length() < wwidth){
  469. X        if(!words) break; // need to refill FIFO
  470. X        curword= words.shift(); // next word
  471. X        if(curln.length() + curword.length() + 1 > wwidth){
  472. X            words.unshift(curword); // put it back
  473. X            justify(curln, wwidth); // pads with spaces to width
  474. X        }else curln += (" " + curword); // add word to line
  475. X        }
  476. X        if(curln.length() >= wwidth){ // done with this line
  477. X        if(lws.length()) cout << lws; // leading space
  478. X        cout << curln << endl;
  479. X        curln= "";
  480. X        }
  481. X    }
  482. X    }
  483. X    if(curln.length()){
  484. X    if(lws.length()) cout << lws; // leading space
  485. X    cout << curln << endl;
  486. X    }
  487. X}
  488. END_OF_FILE
  489.   if test 4024 -ne `wc -c <'sample/justify.c++'`; then
  490.     echo shar: \"'sample/justify.c++'\" unpacked with wrong size!
  491.   fi
  492.   # end of 'sample/justify.c++'
  493. fi
  494. if test -f 'sample/tracer.c++' -a "${1}" != "-c" ; then 
  495.   echo shar: Will not clobber existing file \"'sample/tracer.c++'\"
  496. else
  497.   echo shar: Extracting \"'sample/tracer.c++'\" \(4542 characters\)
  498.   sed "s/^X//" >'sample/tracer.c++' <<'END_OF_FILE'
  499. X/*
  500. X** File - tracer.cxx
  501. X*/
  502. X
  503. X#ifndef TRACER_HXX
  504. X#include "tracer.h"
  505. X#endif
  506. X
  507. X#include <iostream.h>
  508. X#include <string.h>
  509. X
  510. Xchar*    Tracer::prog;           // program being worked on
  511. Xint      Tracer::mode;           // global mode of Tracer
  512. Xchar*    Tracer::watch;          // function to watch for and trace
  513. Xint     Tracer::level;
  514. Xostream* Tracer::str;
  515. X
  516. X// ****************************************************************:
  517. X//      Tracer
  518. X//
  519. X// Description:
  520. X//      Initialize local as well as static information.  Set up
  521. X//      for total cleanup at destruction.  Also outputs Tracer
  522. X//      to stream using operator<<.  Implicit assumption is that
  523. X//      this is only called once per run of a program.
  524. X// ****************************************************************:
  525. XTracer::Tracer(char* s, const int n, ostream &st)
  526. X{
  527. X        str= &st;
  528. X        prog = func = s;        // Set program name
  529. X        mode = n;               // Initialize the tracing mode (no default).
  530. X        lmode = 1;              // Recognize this as top-level.
  531. X    level = 0;
  532. X        if (mode)               // Should we output?
  533. X                *str << *this << ": entered" << endl;
  534. X}
  535. X
  536. X// ****************************************************************:
  537. X//      Tracer
  538. X//
  539. X// Description:
  540. X//      Initialize only local information.  No total cleanup
  541. X//      at destuction.  Also outputs Tracer to stream using
  542. X//      operator<<.  Also checks to see if input character
  543. X//      string contains information that Tracer is watching
  544. X//      for and turns tracing on if it does.  Implicit assumption
  545. X//      is that this is the way Tracer will be set up when needed.
  546. X// ****************************************************************:
  547. XTracer::Tracer(char* s, int l)
  548. X{
  549. X        func = s;               // Leave program alone, but set function
  550. X        emode= l;        // entry/exit mode
  551. X    level++;
  552. X        if (watch != 0)                 // Watching something?
  553. X        {
  554. X                if (strstr(func, watch) != 0)   // Watching for this?
  555. X                {                       // yes...
  556. X                        lmode = mode;   // remember global mode locally
  557. X                        mode = -1;      // turn tracing on
  558. X                }
  559. X        }
  560. X        else                            // no...
  561. X                lmode = 0;              // set local mode to not top level
  562. X
  563. X        if (mode & emode){                  // Should we output?
  564. X                *str << *this << ": entered" << endl;
  565. X        }
  566. X}
  567. X
  568. X
  569. X// ****************************************************************:
  570. X//      ~Tracer
  571. X//
  572. X// Description:
  573. X//      Check for totalcleanup flag and cleanup.
  574. X//      Also outputs Tracer to stream using operator<<.
  575. X// ****************************************************************:
  576. XTracer::~Tracer()
  577. X{
  578. X        if (mode & emode){                       // Should we output?
  579. X                *str << *this << ": exitted" << endl;
  580. X        }
  581. X        level--;
  582. X
  583. X        if (watch != 0)                 // Watching something?
  584. X        {
  585. X                if (strstr(func, watch) != 0)   // Watching for the function?
  586. X                {                       // yes...
  587. X                        mode = lmode;   // reset remembered global mode
  588. X                        lmode = 0;      // this is not the top level
  589. X                }
  590. X        }
  591. X
  592. X        if (lmode)                      // Is this top level?
  593. X                TotalCleanup();
  594. X}
  595. X
  596. X
  597. X// ****************************************************************:
  598. X//              TotalCleanup
  599. X//
  600. X// Description:
  601. X//      Do what's needed to finally cleanup Tracer.
  602. X//      For instance, might be a close of a log file.
  603. X// ****************************************************************:
  604. Xvoid
  605. XTracer::TotalCleanup()
  606. X{
  607. X        if (watch)
  608. X                delete watch;
  609. X}
  610. X
  611. X
  612. X// ****************************************************************:
  613. X//              SetWatch
  614. X//
  615. X// Description:
  616. X//      Set a function name to watch trace on.
  617. X// ****************************************************************:
  618. Xvoid
  619. XTracer::SetWatch(char* name)
  620. X{
  621. X        if (watch)
  622. X                delete watch;
  623. X
  624. X        watch = new char[strlen(name)+1];
  625. X        strcpy(watch, name);
  626. X}
  627. X
  628. X// ****************************************************************:
  629. X//              Operator<<
  630. X//
  631. X// Description:
  632. X//      Puts Tracer into an output stream.
  633. X// ****************************************************************:
  634. Xostream&
  635. Xoperator<<(ostream& str, Tracer& x)
  636. X{
  637. X    for(int i=0;i<x.level;i++) str << '.';
  638. X        str << x.func;   // output the Tracer object to stream
  639. X        return str;
  640. X}
  641. END_OF_FILE
  642.   if test 4542 -ne `wc -c <'sample/tracer.c++'`; then
  643.     echo shar: \"'sample/tracer.c++'\" unpacked with wrong size!
  644.   fi
  645.   # end of 'sample/tracer.c++'
  646. fi
  647. if test -f 'sample/tracer.h' -a "${1}" != "-c" ; then 
  648.   echo shar: Will not clobber existing file \"'sample/tracer.h'\"
  649. else
  650.   echo shar: Extracting \"'sample/tracer.h'\" \(4798 characters\)
  651.   sed "s/^X//" >'sample/tracer.h' <<'END_OF_FILE'
  652. X/*
  653. X** Tracer object
  654. X**
  655. X** Purpose:
  656. X**      Mostly for tracing function calls, but may be adapted for
  657. X**      logging a trace of a program to somewhere else.
  658. X*/
  659. X
  660. X#ifndef TRACER_HXX
  661. X#define TRACER_HXX
  662. X
  663. X// .NAME Tracer - class to manage providing a trace of functions.
  664. X// .LIBRARY util
  665. X// .HEADER Utility Classes
  666. X// .INCLUDE tracer.hxx
  667. X// .FILE tracer.hxx
  668. X// .FILE tracer.cxx
  669. X
  670. X// .SECTION Description
  671. X// This class makes use of some of the semantics of C++ to provide
  672. X// a convenient way of tracing function calls.  This code was initially
  673. X// suggested by Bjarne Stroustrup, but has now been modified to allow
  674. X// control of when tracing takes place.  Tracing messages are sprinkled
  675. X// about the user's code and, at the user's choosing, the type of
  676. X// tracing is enabled.  Users of this object class will rarely (if
  677. X// ever) directly see the class.  Instead, they will use the macro
  678. X// interface defined with this class.
  679. X
  680. X// .SECTION Tracing Types
  681. X// Tracer may be set to output its tracing information according to the
  682. X// type of mode it has been put into.  At the simplest level, Tracer may
  683. X// be set to output all tracing information by setting its type to -1
  684. X// (which is what TRACE_ON does).  At the next level, messages that
  685. X// Tracer is told about may be given a positive integer type < 32.
  686. X// Tracer may also be set to output only messages that are of certain
  687. X// types (via bitwise AND of current type with message type).  Users
  688. X// can, therefore, monitor all types of messages, some of the types,
  689. X// or just one of the types depending on the user's interest.  The final
  690. X// level is that a user may turn on monitoring of a function call by
  691. X// telling Tracer the name of the function to WATCH.  When Tracer hits
  692. X// the function in question, it turns TRACE_ON and turns TRACE_OFF when
  693. X// it leaves the function (so, all lower functions are also traced).
  694. X
  695. X#include <iostream.h>
  696. X
  697. X
  698. Xclass Tracer
  699. X{
  700. Xpublic:
  701. X        Tracer(char*, const int, ostream &st);   // Full tracer invocation
  702. X        Tracer(char*, int= -1);                  // Lower level invocation
  703. X
  704. X        ~Tracer();                      // Close tracer invocation
  705. X
  706. X        void    TotalCleanup();         // Clean up when fully done
  707. X
  708. X        void    SetMode(const int n){mode = n;} // Set current mode of tracing
  709. X        int     GetMode(){ return mode;}        // Determine current tracing mode
  710. X
  711. X        void    SetWatch(char*);            // Function name to begin tracing in
  712. X        char*   GetWatch(){return watch;};      // What we are watching for?
  713. X
  714. X        ostream& GetStream(void){ return *str; }
  715. X        friend ostream& operator<<(ostream&, Tracer&);
  716. X                                        // Output tracing information
  717. X
  718. Xprivate:
  719. X        char*           func;           // function being worked on
  720. X        int             lmode;          // local mode of Tracer
  721. X        int        emode;        // entry/exit mode, determines if printed
  722. X        static char*    prog;           // program being worked on
  723. X        static int      mode;           // global mode of Tracer
  724. X        static char*    watch;          // function to watch for and trace
  725. X    static int    level;        // function call nesting
  726. X    static ostream*    str;        // stream to output onto
  727. X};
  728. X
  729. X
  730. X// ****************************************************************
  731. X//              Macro Interface to Tracer Object
  732. X// ****************************************************************
  733. X#ifdef DOTRACER
  734. X
  735. X#define FTRACER(s,n,st)    /* Trace program s with type n */\
  736. X        Tracer  _trace(s, n, st);
  737. X
  738. X#define TRACER(s)       /* Trace function s */\
  739. X        Tracer  _trace(s);
  740. X
  741. X#define LTRACER(s, l)       /* Trace function s with type n */\
  742. X        Tracer  _trace(s, l);
  743. X
  744. X#define TRACE(s)        /* If TRACE_ON then output s */\
  745. X        if (_trace.GetMode()) _trace.GetStream() << _trace << ": " << s << endl;
  746. X
  747. X#define TRACEF(f)       /* If TRACE_ON then call function f */\
  748. X        if (_trace.GetMode()) f;
  749. X
  750. X#define TRACE_ON        /* Turn tracing on */\
  751. X        _trace.SetMode(-1);
  752. X
  753. X#define TRACE_OFF       /* Turn tracing off */\
  754. X        _trace.SetMode(0);
  755. X
  756. X#define LTRACE(l,s)     /* If (type & l) then output s */\
  757. X        if (_trace.GetMode() & l) \
  758. X                _trace.GetStream() << _trace << ": " << s << endl;
  759. X
  760. X#define LTRACEF(l,f)    /* If (type & l) then call function f */\
  761. X        if (_trace.GetMode() & l) f;
  762. X
  763. X#define STRACE(m)       /* Set tracing to type m */\
  764. X        _trace.SetMode(m);
  765. X
  766. X#define WATCH(s)        /* Set function to watch to s */\
  767. X        _trace.SetWatch(s);
  768. X
  769. X#else
  770. X
  771. X#define FTRACER(s,n,st) /**/
  772. X#define TRACER(s)       /**/
  773. X#define LTRACER(s,l)    /**/
  774. X#define TRACE(s)        /**/
  775. X#define TRACE_ON        /**/
  776. X#define TRACE_OFF       /**/
  777. X#define LTRACE(l,s)     /**/
  778. X#define LTRACEF(l,s)    /**/
  779. X#define STRACE(m)       /**/
  780. X#define WATCH(s)        /**/
  781. X
  782. X#endif
  783. X
  784. X#endif
  785. END_OF_FILE
  786.   if test 4798 -ne `wc -c <'sample/tracer.h'`; then
  787.     echo shar: \"'sample/tracer.h'\" unpacked with wrong size!
  788.   fi
  789.   # end of 'sample/tracer.h'
  790. fi
  791. if test -f 'sample/tstio.c++' -a "${1}" != "-c" ; then 
  792.   echo shar: Will not clobber existing file \"'sample/tstio.c++'\"
  793. else
  794.   echo shar: Extracting \"'sample/tstio.c++'\" \(806 characters\)
  795.   sed "s/^X//" >'sample/tstio.c++' <<'END_OF_FILE'
  796. X#include    <fstream.h>
  797. X#include    <strstream.h>
  798. X#include    <stdlib.h>
  799. X#include    "splash.h"
  800. X#include    "assoc.h"
  801. X
  802. Xvoid main()
  803. X{
  804. Xifstream fin("t.txt");
  805. Xofstream fout("t2.txt");
  806. X
  807. XSPString s;
  808. XSPStringList l;
  809. X
  810. X    while(fin >> s){
  811. X    cout << "read in string: " << s << endl;
  812. X    fout << s << endl;
  813. X    }
  814. X    
  815. X    fin.close();
  816. X    fout.close();
  817. X    
  818. X    fin.open("t.txt");
  819. X    
  820. X    fin >> l;
  821. X    
  822. X    cout << "List =" << endl << l << endl;
  823. X
  824. X#if 1
  825. X    strstream ss, iss;
  826. X    ss << "one\n" << "two\nthree\nfour\n";
  827. X    ss >> l;
  828. X    cout << l << endl;
  829. X    SPList<int> il;
  830. X    iss << 1 << " " << 2 << " " << 3 << " " << 4 << endl;
  831. X    iss << "5 6 7 8 9" << endl;
  832. X    iss >> il;
  833. X    cout << il << endl;
  834. X#endif
  835. X
  836. X
  837. X    cout << "Start Typing:" << endl;
  838. X    while(cin >> s){
  839. X    cout << "read in string: " << s << endl;
  840. X    }
  841. X
  842. X    
  843. X    
  844. X}
  845. END_OF_FILE
  846.   if test 806 -ne `wc -c <'sample/tstio.c++'`; then
  847.     echo shar: \"'sample/tstio.c++'\" unpacked with wrong size!
  848.   fi
  849.   # end of 'sample/tstio.c++'
  850. fi
  851. if test -f 'sample/xcl.c++' -a "${1}" != "-c" ; then 
  852.   echo shar: Will not clobber existing file \"'sample/xcl.c++'\"
  853. else
  854.   echo shar: Extracting \"'sample/xcl.c++'\" \(3936 characters\)
  855.   sed "s/^X//" >'sample/xcl.c++' <<'END_OF_FILE'
  856. X#include <iostream.h>
  857. X#include <fstream.h>
  858. X#include "splash.h"
  859. X#include "tracer.h"
  860. X
  861. X#ifdef    _Windows
  862. X#include "../win/debugwin/debugstr.h"
  863. X#define OUTSTREAM dout
  864. X#else
  865. X#define OUTSTREAM cout
  866. X#endif
  867. X
  868. Xifstream fin;
  869. X
  870. X// Globals
  871. XSPString curln, curclass;
  872. Xint bcnt;   // current brace count
  873. X
  874. X/*
  875. X * Reads in a line, and eliminates anything in between comments
  876. X * or quotes. Also keeps count of the brace level
  877. X */
  878. Xint getline()
  879. X{
  880. XLTRACER("getline", 4)
  881. X
  882. X    if(!(fin >> curln)) return 0;
  883. X    cout << curln << endl;
  884. X    LTRACE(2, curln)
  885. X    while(curln.m("\".*\"")){ // remove anything in quoted strings
  886. X    int o, c;
  887. X    SPString tl= curln.substr(0, o= curln.index("\""));
  888. X    do{ // make sure the quote is not backslashed
  889. X            c= curln.index("\"", o+1);
  890. X        o= c;
  891. X    }while(c > 1 && curln[c-1] == '\\');
  892. X    tl += curln.substr(c+1); // rest of line
  893. X    curln= tl;
  894. X//    cout << "quote stripped curln= " << curln <<endl;
  895. X    }
  896. X
  897. X    if(curln.m("//")){ // found a comment in line
  898. X    curln.substr(curln.index("//"))= ""; // chop it off
  899. X    }
  900. X
  901. X    if(curln.m("/\\*")){ // in c comment
  902. X    SPString tl= curln.substr(0, curln.index("/*"));
  903. X    if(curln.m("\\*/")){ // closing comment on same line
  904. X        tl += curln.substr(curln.index("*/")+2); // rest of line
  905. X        curln= tl;
  906. X//        cout << "comment stripped curln= " << curln <<endl;
  907. X    }else{ // find close of comment
  908. X        while(fin >> curln){
  909. X        cout << curln << endl;
  910. X        if(curln.m("\\*/")){
  911. X            tl += curln.substr(curln.index("*/")+2); // get rest of line
  912. X            break;        
  913. X        }
  914. X        }
  915. X        curln= tl;
  916. X    }
  917. X    }
  918. X    LTRACE(4, curln)
  919. X    int ob= curln.tr("{", "");
  920. X    int cb= curln.tr("}", "");
  921. X    int cnt= ob - cb;
  922. X    bcnt += cnt;
  923. X    LTRACE(4, "Brace count = " << bcnt);
  924. X    if(bcnt < 0){
  925. X    cout.flush();
  926. X    cerr << "Brace count dropped below zero,  oops" << endl;
  927. X    exit(1);
  928. X    }
  929. X    return 1;
  930. X}
  931. X
  932. Xvoid dofunction(const SPStringList &subm, int bc= 0)
  933. X{
  934. XTRACER("dofunction")
  935. XSPString fnname= subm[1], fnparams= subm[2];
  936. X
  937. XLTRACE(1, "In Function " << fnname << "(" << fnparams << ")")
  938. X
  939. X    if(curln.m("{.*}")){
  940. X//    cerr << "Can't insert TRACER here" << endl;
  941. X    return;
  942. X    }else if(curln.m("{")) bc--;
  943. X
  944. X    while(bcnt == bc && getline()); // find opening brace
  945. X    LTRACE(1, "Inside Function " << fnname)
  946. X
  947. X    if(fnname.m("^main$")){ // special treatment for main()
  948. X    cout << "FTRACER(\"main()\", 0)" << endl;
  949. X    }else{
  950. X    cout << "TRACER(\"";
  951. X    if(curclass.length()) cout << curclass << "::";
  952. X    cout << fnname << "(" << fnparams << ")\")" << endl;
  953. X    }
  954. X
  955. X    while(getline()){
  956. X    if(bcnt == bc){ // no longer in function
  957. X        LTRACE(1, "End of function " << fnname)
  958. X        break;
  959. X    }
  960. X    
  961. X    }
  962. X
  963. X}
  964. X
  965. Xvoid doclass(const SPStringList &subm)
  966. X{
  967. XTRACER("doclass")
  968. XSPStringList sl;
  969. X
  970. X    if(curln.m(";")) return; // if a ';' on line then probably a forward reference
  971. X    LTRACE(1, "Seen Class " << subm[1])
  972. X    curclass= subm[1];    // remember class name
  973. X    
  974. X    while(bcnt == 0 && getline()); // find opening brace
  975. X    LTRACE(1, "Inside Class " << curclass)
  976. X    
  977. X    while(getline()){
  978. X    if(bcnt == 0){ // no longer in class
  979. X        LTRACE(1, "End of class " << curclass)
  980. X        break;
  981. X    }
  982. X
  983. X    if(curln.m("[ \t]*([^ \t]+)[ \t]*\\(([^)]*)\\)", sl)){ // function def
  984. X        if(curln.m(";[ \t]*$")) continue; // declaration
  985. X        dofunction(sl, bcnt);
  986. X    }
  987. X    
  988. X    }
  989. X    curclass= "";
  990. X}
  991. X
  992. Xint main(int argc, char **argv)
  993. X{
  994. Xint debug= 0;
  995. X
  996. X    if(argc > 2 && *argv[1] == '-'){
  997. X    debug= atoi(&argv[1][1]);
  998. X    argc--; argv++;
  999. X    }
  1000. X
  1001. X
  1002. XFTRACER("xcl", debug, OUTSTREAM)
  1003. XSPStringList sl;
  1004. X
  1005. X    if(argc < 2){
  1006. X    cerr << "Usage: xcl [-n] fn" << endl;
  1007. X    exit(1);
  1008. X    }
  1009. X
  1010. X    fin.open(argv[1], ios::in);
  1011. X    if(!fin){
  1012. X    cerr << "Couldn't open file: " << argv[1] << endl;
  1013. X    exit(1);
  1014. X    }
  1015. X    
  1016. X    while(getline()){
  1017. X    if(curln.m("^[ \t]*class[ \t]+([a-zA-Z_]+[a-zA-Z_0-9]*)", sl)){
  1018. X        doclass(sl);
  1019. X        continue;
  1020. X    }
  1021. X
  1022. X        if(curln.m("[ \t]*([^ \t]+)[ \t]*\\(([^)]*)\\)", sl)){ // function def
  1023. X        if(curln.m(";[ \t]*$")) continue; // declaration
  1024. X        dofunction(sl, bcnt);
  1025. X    }
  1026. X    }
  1027. X}
  1028. X
  1029. END_OF_FILE
  1030.   if test 3936 -ne `wc -c <'sample/xcl.c++'`; then
  1031.     echo shar: \"'sample/xcl.c++'\" unpacked with wrong size!
  1032.   fi
  1033.   # end of 'sample/xcl.c++'
  1034. fi
  1035. echo shar: End of archive 1 \(of 1\).
  1036. cp /dev/null ark1isdone
  1037. MISSING=""
  1038. for I in 1 ; do
  1039.     if test ! -f ark${I}isdone ; then
  1040.     MISSING="${MISSING} ${I}"
  1041.     fi
  1042. done
  1043. if test "${MISSING}" = "" ; then
  1044.     echo You have the archive.
  1045.     rm -f ark[1-9]isdone
  1046. else
  1047.     echo You still must unpack the following archives:
  1048.     echo "        " ${MISSING}
  1049. fi
  1050. exit 0
  1051. exit 0 # Just in case...
  1052.