Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

story.C

Go to the documentation of this file.
00001 //
00002 //  story.C
00003 //
00004 
00008 
00009 #include "story.h"
00010 
00011 #ifndef TOOLBOX
00012 
00013 // delete [] new_string lines added by Steve 8/5/97.
00014 
00015 // New code to check if story exists before using member
00016 // functions added by Steve 10/12/00.
00017 
00018 story::~story()
00019 {
00020     story * si = first_daughter_node;
00021     story * sn;
00022     while (si) {
00023         sn = si->next_story_node;
00024         delete si;
00025         si = sn;
00026     }
00027     if (text) {
00028 //      cerr << "text = " << text << endl;
00029         delete [] text;
00030     }
00031 }
00032 
00033 int  is_chapter(story * s)
00034 {
00035     if (s)
00036         return s->get_chapter_flag();
00037     else
00038         return 0;
00039 }
00040 
00041 int  is_chapter_begin_line(char * line)
00042 {
00043     return (*line == chapter_begin_char);
00044 }
00045 
00046 int  is_chapter_end_line(char * line)
00047 {
00048     return (*line == chapter_end_char);
00049 }
00050 
00051 int get_story_line(istream & str, char * line)
00052 {
00053     str.get(line,MAX_STORY_LINE_LENGTH,'\n');
00054 
00055     if(str.eof())
00056         return 0;
00057 
00058     char c;
00059     if(str.get(c) && c!='\n') {
00060         cerr << "get_story_line : input line too long :'"<<line<<"'\n";
00061         exit(1);
00062     }
00063 
00064     return 1;
00065 }
00066 
00067 void add_daughter_story(story * s, story * d)
00068 {
00069     if (!s || !d) return;
00070 
00071     story *fc = s->get_first_daughter_node();
00072     story *lc = s->get_last_daughter_node();
00073 
00074     // Redundant (?) check added by Steve 11/1/98.  Loses all
00075     // but the last daughter, but the best we can do...
00076 
00077     if (fc == NULL && lc != NULL) {
00078         warning("add_daughter_story: repairing inconsistent story list");
00079         s->set_first_daughter_node(lc);
00080     }
00081 
00082     if (lc) {
00083         lc->set_next_story_node(d);
00084         s->set_last_daughter_node(d);
00085     } else {
00086         s->set_first_daughter_node(d);
00087         s->set_last_daughter_node(d);
00088     }
00089 }
00090 
00091 void add_chapter(story * s, story * chap)
00092 {
00093     if (!s || !chap) return;
00094 
00095     add_daughter_story(s, chap);
00096 }
00097 
00098 void rm_daughter_story(story * s, story * d)
00099 {
00100     if (!s || !d) return;
00101 
00102     story * fd = s->get_first_daughter_node();
00103     story * ad;                                    // a daughter
00104     story * nd;                                    // next daughter
00105 
00106     if (fd == d) {
00107         s->set_first_daughter_node(d->get_next_story_node());
00108 
00109         // Added by Steve, 11/1/98, to deal with case of a single daughter:
00110 
00111         if (s->get_last_daughter_node() == d)
00112             s->set_last_daughter_node(NULL);
00113 
00114     } else
00115         {
00116         ad = fd;
00117         nd = ad->get_next_story_node();
00118         while (nd != d)
00119             {
00120             ad = nd;
00121             nd = ad->get_next_story_node();
00122             }
00123         nd = d->get_next_story_node();
00124         ad->set_next_story_node(nd);
00125         if (nd == NULL)
00126             s->set_last_daughter_node(ad);
00127         }
00128     delete d;    
00129 }
00130 
00131 story* mk_story_line()
00132 {
00133     story* s = new story(0);
00134     return s;
00135 }
00136 
00137 story* mk_story_line(char * line)
00138 {
00139     story* s = new story(0);
00140     s->set_text(line);
00141     return s;
00142 }
00143 
00144 story* mk_story_chapter()       {story* s = new story(1); return s;}
00145 
00146 story* mk_story_chapter(char * title)
00147 {
00148     story* s = new story(1);
00149     s->set_text(title);
00150     return s;
00151 }
00152 
00153 void add_story_line(story * s, char * line)
00154 {
00155     if (!s || !line) return;
00156 
00157     story * new_s = mk_story_line(line);
00158     add_daughter_story(s, new_s);
00159 }
00160 
00161 story* get_chapter(istream& str, char* line)
00162 {
00163     if (!is_chapter_begin_line(line)) {
00164         cerr << "get_chapter: first line not chapter_begin_line";
00165         exit(1);
00166     }
00167 
00168     story * chap = mk_story_chapter(++line);
00169 
00170     char new_line[MAX_STORY_LINE_LENGTH];
00171 
00172     while (get_story_line(str, new_line) && !is_chapter_end_line(new_line)) {
00173         if (is_chapter_begin_line(new_line))
00174             add_chapter(chap, get_chapter(str, new_line));
00175         else
00176             add_story_line(chap, new_line);
00177     }
00178 
00179     if (new_line == NULL) {
00180         cerr << "get_chapter: new_line == NULL before end of chapter\n";
00181         exit(1);
00182     }
00183 
00184     if (!streq(new_line+1, chap->get_text())) {
00185         cerr << "get_chapter: closing title ``" << new_line+1
00186              << "'' differs from opening title ``" << chap->get_text()
00187              << "''\n";
00188         exit(1);
00189     }
00190 
00191     return chap;
00192 }
00193 
00194 story* get_story(istream & str, char *line)  {return get_chapter(str, line);}
00195 
00196 story* get_story(istream& str)
00197 { 
00198     char line[MAX_STORY_LINE_LENGTH];
00199 
00200     if (!get_story_line(str, line))
00201         return(NULL);
00202 
00203     if (!is_chapter_begin_line(line))
00204         {
00205         cerr << "get_story: first line not chapter_begin_line\n";
00206         exit(1);
00207         }
00208 
00209     return get_chapter(str, line);
00210 }
00211 
00212 void put_headline(ostream& str, story& s)
00213 {
00214 #ifndef BAD_GNU_IO
00215     str << chapter_begin_char << s.get_text() << "\n";
00216 #else
00217     fprintf(stdout, "%c%s\n", chapter_begin_char, s.get_text());
00218 #endif
00219 }
00220 
00221 void put_tailline(ostream& str, story& s)
00222 {
00223 #ifndef BAD_GNU_IO
00224     str << chapter_end_char << s.get_text() << "\n";
00225 #else
00226     fprintf(stdout, "%c%s\n", chapter_end_char,s. get_text());
00227 #endif
00228 }
00229 
00230 void put_line_text(ostream& str, story& s)
00231 {
00232 #ifndef BAD_GNU_IO
00233     str << s.get_text() << "\n";
00234 #else
00235     fprintf(stdout, "%s\n", s.get_text());
00236 #endif
00237 }
00238 
00239 void put_chapter(ostream& str, story& s)
00240 {
00241     if (!is_chapter(&s))
00242         {
00243         cerr << "put_chapter: not a story\n";
00244         exit(1);
00245         }
00246     put_headline(str, s);
00247 
00248     for (story * d = s.get_first_daughter_node(); d != NULL;
00249                                                   d = d->get_next_story_node())
00250         {
00251         if (is_chapter(d))
00252             put_chapter(str, *d);
00253         else
00254             put_line_text(str, *d);
00255         }
00256     str << flush;
00257 
00258     put_tailline(str, s);
00259 }
00260 
00261 void put_story_contents(ostream& str, story& s)
00262 {
00263     if (!is_chapter(&s))
00264         {
00265         cerr << "put_story_contents: not a story\n";
00266         exit(1);
00267         }
00268 
00269     for (story * d = s.get_first_daughter_node(); d != NULL;
00270                                                   d = d->get_next_story_node())
00271         {
00272         if (is_chapter(d))
00273             put_chapter(str, *d);
00274         else
00275             put_line_text(str, *d);
00276         }
00277 }
00278 
00279 void put_story(ostream& str, story& s)
00280 {
00281     put_chapter(str, s);
00282 }
00283 
00284 // ostream & operator << (ostream & s, story * sptr)
00285 //    {put_story(s, *sptr); return s;}
00286 
00287 // istream & operator >> (istream & s, story * & sptr)
00288 //    {sptr = get_story(s); return s;}
00289 
00290 /*-----------------------------------------------------------------------------
00291  *     The following macros specify the buffer lengths for strings containing
00292  *  different types of quantities.
00293  *     The numbers given below are overestimates; if memory size is an 
00294  *  important issue, these numbers can be decreases somewhat, after careful
00295  *  analysis of how much space is actually needed in the worst case (beware of
00296  *  details such as minus signs, exponents, minus signs in exponents as well as
00297  *  in the mantissa, etc.).
00298  *-----------------------------------------------------------------------------
00299  */
00300 #define  BYTE_LENGTH          8
00301 #define  SAFE_INT_LENGTH     (5 + (BYTE_LENGTH*sizeof(int))/3)
00302 #define  SAFE_REAL_LENGTH    (10 + (BYTE_LENGTH*sizeof(real))/3)
00303 #define  SAFE_STRING_LENGTH   1    /* this should hold the string terminator */
00304 #define  SAFE_VECTOR_LENGTH  (3 * (SAFE_REAL_LENGTH + 2))
00305 #define  EXTRA_LENGTH  5           /* for initial "  " and " = " */
00306 
00307 /*-----------------------------------------------------------------------------
00308  *  write_iq  --  write an integer quantity to a line.
00309  *-----------------------------------------------------------------------------
00310  */
00311 local void  write_iq(story * a_story_line, char * name, int value)
00312 {
00313     if (!a_story_line || !name) return;
00314 
00315     char * new_string;
00316     int  new_string_length;
00317     
00318     new_string_length = EXTRA_LENGTH + strlen(name) + SAFE_INT_LENGTH;
00319     new_string  = new char[new_string_length];
00320 
00321     sprintf(new_string, "  %s = %d", name, value);
00322 
00323     a_story_line->set_text(new_string);
00324     delete [] new_string;
00325 }
00326 
00327 /*-----------------------------------------------------------------------------
00328  *  write_ulq  --  write an unsigned long integer quantity to a line.
00329  *-----------------------------------------------------------------------------
00330  */
00331 local void  write_ulq(story * a_story_line, char * name, unsigned long value)
00332 {
00333     if (!a_story_line || !name) return;
00334 
00335     char * new_string;
00336     int  new_string_length;
00337     
00338     new_string_length = EXTRA_LENGTH + strlen(name) + SAFE_INT_LENGTH;
00339     new_string  = new char[new_string_length];
00340 
00341     sprintf(new_string, "  %s = %lu", name, value);
00342 
00343     a_story_line->set_text(new_string);
00344     delete [] new_string;
00345 }
00346 
00347 /*-----------------------------------------------------------------------------
00348  *  write_rq  --  write a real quantity to a line.
00349  *-----------------------------------------------------------------------------
00350  */
00351 local void  write_rq(story * a_story_line, char * name, real value, int p = 6)
00352 {
00353     if (!a_story_line || !name) return;
00354 
00355     char * new_string;
00356     int  new_string_length;
00357     char format[128];
00358     
00359     new_string_length = EXTRA_LENGTH + strlen(name) + SAFE_REAL_LENGTH;
00360     new_string  = new char[new_string_length];
00361 
00362     // Allow variable precision (SLWM 6/99).
00363 
00364     sprintf(format, "  %%s = %%.%dg", p);
00365 
00366     // sprintf(new_string, "  %s = %lf", name, value);  // new format seems OK
00367     sprintf(new_string, format, name, value);           // here (SLWM 26/7/98)
00368 
00369     a_story_line->set_text(new_string);
00370     delete [] new_string;
00371 }
00372 
00373 /*-----------------------------------------------------------------------------
00374  *  write_sq  --  write a string quantity to a line.
00375  *-----------------------------------------------------------------------------
00376  */
00377 local void  write_sq(story * a_story_line, char * name, char * value)
00378 {
00379     if (!a_story_line || !name) return;
00380 
00381     char * new_string;
00382     int  new_string_length;
00383     
00384     new_string_length = EXTRA_LENGTH + strlen(name)
00385                                      + strlen(value) + SAFE_STRING_LENGTH;
00386     new_string  = new char[new_string_length];
00387 
00388     sprintf(new_string, "  %s = %s", name, value);
00389 
00390     a_story_line->set_text(new_string);
00391     delete [] new_string;
00392 }
00393 
00394 /*-----------------------------------------------------------------------------
00395  *  write_vq  --  write a vector quantity to a line.
00396  *-----------------------------------------------------------------------------
00397  */
00398 local void  write_vq(story * a_story_line, char * name, vector & value)
00399 {
00400     if (!a_story_line || !name) return;
00401 
00402     char * new_string;
00403     int  new_string_length;
00404     
00405     new_string_length = EXTRA_LENGTH + strlen(name) + SAFE_VECTOR_LENGTH;
00406     new_string  = new char[new_string_length];
00407 
00408     sprintf(new_string, "  %s = %.6g %.6g %.6g", name,  // %g here may cause
00409             value[0], value[1], value[2]);              // obscure problems
00410 
00411     a_story_line->set_text(new_string);
00412     delete [] new_string;
00413 }
00414 
00415 /*-----------------------------------------------------------------------------
00416  *  write_ra  --  write a real array to a line.
00417  *-----------------------------------------------------------------------------
00418  */
00419 local void  write_ra(story * a_story_line, char * name, real * value, int n)
00420 {
00421     if (!a_story_line || !name) return;
00422 
00423     char *new_string, *tmp;
00424     int  new_string_length;
00425 
00426     new_string_length = EXTRA_LENGTH + strlen(name)
00427                                 + n * (SAFE_REAL_LENGTH + 2);
00428     new_string  = new char[new_string_length];
00429     tmp = new char[SAFE_REAL_LENGTH + 2];
00430 
00431     sprintf(new_string, "  %s =", name);
00432 
00433     for (int i = 0; i < n; i++) {
00434 
00435 //      sprintf(tmp, " %.6g", value[i]);        // %g seems to cause problems
00436         sprintf(tmp, " %lf", value[i]);         // here, for unknown reasons
00437 
00438         strcat(new_string, tmp);
00439     }
00440 
00441     a_story_line->set_text(new_string);
00442     delete [] new_string;
00443     delete [] tmp;
00444 }
00445 
00446 /*-----------------------------------------------------------------------------
00447  *  write_ia  --  write an integer array to a line.
00448  *-----------------------------------------------------------------------------
00449  */
00450 local void  write_ia(story * a_story_line, char * name, int * value, int n)
00451 {
00452     if (!a_story_line || !name) return;
00453 
00454     char *new_string, *tmp;
00455     int  new_string_length;
00456 
00457     new_string_length = EXTRA_LENGTH + strlen(name)
00458                                 + n * (SAFE_INT_LENGTH + 2);
00459     new_string  = new char[new_string_length];
00460     tmp = new char[SAFE_INT_LENGTH + 2];
00461 
00462     sprintf(new_string, "  %s =", name);
00463 
00464     for (int i = 0; i < n; i++) {
00465 
00466         sprintf(tmp, " %d", value[i]);
00467 
00468         strcat(new_string, tmp);
00469     }
00470 
00471     a_story_line->set_text(new_string);
00472     delete [] new_string;
00473     delete [] tmp;
00474 }
00475 
00476 /*-----------------------------------------------------------------------------
00477  *  write_ia  --  write an unsigned long array to a line.
00478  *-----------------------------------------------------------------------------
00479  */
00480 local void  write_ia(story * a_story_line, char * name,
00481                      unsigned long * value, int n)
00482 {
00483     if (!a_story_line || !name) return;
00484 
00485     char *new_string, *tmp;
00486     int  new_string_length;
00487 
00488     new_string_length = EXTRA_LENGTH + strlen(name)
00489                                 + n * (SAFE_INT_LENGTH + 2);
00490     new_string  = new char[new_string_length];
00491     tmp = new char[SAFE_INT_LENGTH + 2];
00492 
00493     sprintf(new_string, "  %s =", name);
00494 
00495     for (int i = 0; i < n; i++) {
00496 
00497         sprintf(tmp, " %d", value[i]);
00498 
00499         strcat(new_string, tmp);
00500     }
00501 
00502     a_story_line->set_text(new_string);
00503     delete [] new_string;
00504     delete [] tmp;
00505 }
00506 
00507 /*-----------------------------------------------------------------------------
00508  *  qmatch  --  checks whether a line contains a physical quantity with a
00509  *              matching name; if so, returns TRUE, otherwise FALSE.
00510  *         note: 
00511  *              leading blanks are discarded, both in the name and in the text
00512  *              of a_line ; trailing blanks in the text up to the equal sign
00513  *              are also discarded; if the equal sign is missing (i.e. if the
00514  *              line is not a proper quantity line) FALSE is returned.
00515  *-----------------------------------------------------------------------------
00516  */
00517 local bool qmatch(story * a_story_line, char * name)
00518 {
00519     if (!a_story_line || !name) return false;
00520 
00521     int  i, j;
00522     char *s;
00523 
00524     if ((s = a_story_line->get_text()) == NULL)
00525         return(FALSE);
00526     i = 0;
00527     while (s[i] == ' ')
00528         i++;
00529 
00530     j = 0;
00531     while (name[j] != '\0')
00532         {
00533         if (name[j] == ' ')
00534             j++;
00535         else 
00536             break;
00537         }
00538 
00539     while (name[j] != '\0')
00540         {
00541         if (s[i] != name[j])
00542             return(FALSE);
00543         i++;
00544         j++;
00545         }
00546 
00547     while (s[i] == ' ')
00548         i++;
00549 
00550     if (s[i] != '=')
00551         return(FALSE);
00552     if (s[++i] != ' ')
00553         return(FALSE);
00554 
00555     return(TRUE);
00556 }
00557 
00558 /*-----------------------------------------------------------------------------
00559  *  find_qmatch  --  within a story, find a line which contains a physical
00560  *                   quantity with a matching name; or return NULL if such a
00561  *                   line is not found.
00562  *-----------------------------------------------------------------------------
00563  */
00564 story * find_qmatch(story * a_story, char * name)
00565 {
00566     if (!a_story || !name) return NULL;
00567 
00568     story * a_chapter;
00569 
00570     a_chapter = a_story->get_first_daughter_node();
00571 
00572     while (a_chapter != NULL)
00573         {
00574         if (qmatch(a_chapter, name))
00575             return(a_chapter);
00576         else
00577             a_chapter = a_chapter->get_next_story_node();
00578         }
00579 
00580     return(NULL);
00581 }
00582 
00583 /*-----------------------------------------------------------------------------
00584  *  get_qstring  --  
00585  *               note:
00586  *                    no check for presence of '=' ; BEWARE
00587  *-----------------------------------------------------------------------------
00588  */
00589 local char * get_qstring(story * a_story_line)
00590 {
00591     if (!a_story_line) return NULL;
00592 
00593     char *c;
00594     
00595     c = a_story_line->get_text();
00596     
00597     while (*(++c) != '=')
00598         ;
00599     while (*(++c) == ' ')
00600         ;
00601 
00602     return(c);
00603 }
00604 
00605 /*-----------------------------------------------------------------------------
00606  *  getiq  --  reads an integer quantity from a line in a story
00607  *-----------------------------------------------------------------------------
00608  */
00609 int getiq(story * a_story, char * name, bool verbose)
00610 {
00611     if (!a_story || !name) return 0;
00612 
00613     story * story_line;
00614 
00615     if ((story_line = find_qmatch(a_story, name)) == NULL)
00616         {
00617         if (verbose) cerr << "getiq: no quantity found with name \""
00618                           << name << "\"" << endl;
00619         return -VERY_LARGE_INTEGER;
00620         // exit(1);
00621         }
00622 
00623     return atoi(get_qstring(story_line));
00624 }
00625 
00626 /*-----------------------------------------------------------------------------
00627  *  getulq  --  reads an unsigned long integer quantity from a line in a story
00628  *-----------------------------------------------------------------------------
00629  */
00630 unsigned long getulq(story *  a_story, char * name, bool verbose)
00631 {
00632     if (!a_story || !name) return 0;
00633 
00634     story * story_line;
00635     unsigned long l;
00636 
00637     if ((story_line = find_qmatch(a_story, name)) == NULL)
00638         {
00639         if (verbose) cerr << "getulq: no quantity found with name \""
00640                           << name << "\"" << endl;
00641         return 0;
00642         // exit(1);
00643         }
00644 
00645     return strtoul(get_qstring(story_line), (char**)NULL, 10);
00646 }
00647 
00648 /*-----------------------------------------------------------------------------
00649  *  getrq  --  reads a real quantity from a line in a story
00650  *-----------------------------------------------------------------------------
00651  */
00652 real getrq(story * a_story, char * name, bool verbose)
00653 {
00654     if (!a_story || !name) return 0.0;
00655 
00656     story * story_line;
00657 
00658     if ((story_line = find_qmatch(a_story, name)) == NULL) {
00659 
00660         if (verbose) cerr << "getrq: no quantity found with name \""
00661                           << name << "\"" << endl;
00662         return -VERY_LARGE_NUMBER;
00663     }
00664 
00665     return atof(get_qstring(story_line));
00666 }
00667 
00668 /*-----------------------------------------------------------------------------
00669  *  getsq  --  reads a string quantity from a line in a story
00670  *             BEWARE: a pointer is returned to the original string.
00671  *                     this has two dangerous aspects:
00672  *                     1) the user may inadvertantly change the story line;
00673  *                     2) the story line may be changed before the user uses
00674  *                        the string.
00675  *             note: when needed, we can easily provide an alternative function
00676  *                   `getnsq' that returns a new string (as a copy).
00677  *-----------------------------------------------------------------------------
00678  */
00679 char *getsq(story * a_story, char * name, bool verbose)
00680 {
00681     if (!a_story || !name) return NULL;
00682 
00683     story * story_line;
00684 
00685     if ((story_line = find_qmatch(a_story, name)) == NULL)
00686         {
00687         if (verbose) cerr << "getiq: no quantity found with name \""
00688                           << name << "\"" << endl;
00689         return (char*)NULL;
00690         // exit(1);
00691         }
00692 
00693     return get_qstring(story_line);
00694 }
00695 
00696 /*-----------------------------------------------------------------------------
00697  *  getvq  --  reads a vector quantity from a line in a story
00698  *-----------------------------------------------------------------------------
00699  */
00700 vector getvq(story *  a_story, char * name, bool verbose)
00701 {
00702     if (!a_story || !name) return vector(-VERY_LARGE_NUMBER,
00703                                               -VERY_LARGE_NUMBER,
00704                                               -VERY_LARGE_NUMBER);
00705 
00706     story * story_line;
00707 
00708     if ((story_line = find_qmatch(a_story, name)) == NULL) {
00709         if (verbose) cerr << "getiq: no quantity found with name \""
00710                           << name << "\"" << endl;
00711         return vector(-VERY_LARGE_NUMBER,
00712                       -VERY_LARGE_NUMBER,
00713                       -VERY_LARGE_NUMBER);
00714         // exit(1);
00715     }
00716 
00717     vector v;
00718     sscanf(get_qstring(story_line), "%lf %lf %lf", &v[0], &v[1], &v[2]);
00719 
00720     return v;
00721 }
00722 
00723 #define GET_ARR_BUFSIZ 8192
00724 
00725 static char s[GET_ARR_BUFSIZ];
00726 
00727 local void get_array(char * sin, real * x, int n)
00728 {
00729     // Extract real array x from (a copy of) string sin.
00730 
00731     // Note: SPZ says this code as it stands causes problems on HP/g++...
00732     //       Certainly, it isn't very elegant!
00733 
00734     // Work with a copy of the input string.
00735 
00736     // Hmmm... problems with ccmalloc if we allocate space for s
00737     // and delete it later (no problem with just g++).  For now, use
00738     // static space and hope it is big enough.
00739 
00740     // char *s = new char[strlen(sin)];  // possible that this "new" is not
00741                                          // really static, so the string is
00742                                          // automatically deleted on exit?
00743 
00744     if (n > GET_ARR_BUFSIZ)
00745         warning("get_array: truncating input string");
00746 
00747     strncpy(s, sin, GET_ARR_BUFSIZ);
00748 
00749     char *s1 = s, *s2 = s;
00750     int i = 0;
00751 
00752     while (*(s2++) > '\0') {
00753         if (*(s2-1) > ' ' && *s2 <= ' ') {
00754             char save = *s2;
00755 
00756             *s2 = '\0';
00757             x[i++] = atof(s1);
00758             *s2 = save;
00759 
00760             if (i >= n) break;
00761             s1 = s2;
00762         }
00763     }
00764 
00765     // delete [] s;
00766 }
00767 
00768 local void get_array(char * sin, int * x, int n)        // overloaded!
00769 {
00770     // Copy of get_array, for int instead of real.  Previous comments apply.
00771 
00772     if (n > GET_ARR_BUFSIZ)
00773         warning("get_array: truncating input string");
00774 
00775     strncpy(s, sin, GET_ARR_BUFSIZ);
00776 
00777     char *s1 = s, *s2 = s;
00778     int i = 0;
00779 
00780     while (*(s2++) > '\0') {
00781         if (*(s2-1) > ' ' && *s2 <= ' ') {
00782             char save = *s2;
00783 
00784             *s2 = '\0';
00785             x[i++] = atoi(s1);                          // <-- only change!
00786             *s2 = save;
00787 
00788             if (i >= n) break;
00789             s1 = s2;
00790         }
00791     }
00792 }
00793 
00794 local void get_array(char * sin, unsigned long * x, int n)  // overloaded!
00795 {
00796     // Copy of get_array, for int instead of real.  Previous comments apply.
00797 
00798     if (n > GET_ARR_BUFSIZ)
00799         warning("get_array: truncating input string");
00800 
00801     strncpy(s, sin, GET_ARR_BUFSIZ);
00802 
00803     char *s1 = s, *s2 = s;
00804     int i = 0;
00805 
00806     while (*(s2++) > '\0') {
00807         if (*(s2-1) > ' ' && *s2 <= ' ') {
00808             char save = *s2;
00809 
00810             *s2 = '\0';
00811             x[i++] = atoi(s1);                          // <-- only change!
00812             *s2 = save;
00813 
00814             if (i >= n) break;
00815             s1 = s2;
00816         }
00817     }
00818 }
00819 
00820 /*-----------------------------------------------------------------------------
00821  *  getra  --  reads a real array of length n from a line in a story
00822  *-----------------------------------------------------------------------------
00823  */
00824 void getra(story *  a_story, char * name, real * x, int n, bool verbose)
00825 {
00826     if (!a_story || !name) {
00827         *x = -VERY_LARGE_NUMBER;
00828         return;
00829     }
00830 
00831     story * story_line;
00832 
00833     if ((story_line = find_qmatch(a_story, name)) == NULL) {
00834 
00835         if (verbose) cerr << "getra: no quantity found with name \""
00836                           << name << "\"" << endl;
00837 
00838         *x = -VERY_LARGE_NUMBER;
00839         return;
00840 
00841     }
00842 
00843     get_array(get_qstring(story_line), x, n);
00844 }
00845 
00846 /*-----------------------------------------------------------------------------
00847  *  getia  --  reads an integer array of length n from a line in a story
00848  *-----------------------------------------------------------------------------
00849  */
00850 void getia(story *  a_story, char * name, int * x, int n, bool verbose)
00851 {
00852     if (!a_story || !name) {
00853         *x = -VERY_LARGE_INTEGER;
00854         return;
00855     }
00856 
00857     story * story_line;
00858 
00859     if ((story_line = find_qmatch(a_story, name)) == NULL) {
00860 
00861         if (verbose) cerr << "getia: no quantity found with name \""
00862                           << name << "\"" << endl;
00863 
00864         *x = -VERY_LARGE_INTEGER;
00865         return;
00866 
00867     }
00868 
00869     get_array(get_qstring(story_line), x, n);
00870 }
00871 
00872 /*-----------------------------------------------------------------------------
00873  *  getia  --  reads an unsigned long array of length n from a line in a story
00874  *-----------------------------------------------------------------------------
00875  */
00876 void getia(story *  a_story, char * name, unsigned long * x,
00877            int n, bool verbose)
00878 {
00879     if (!a_story || !name) {
00880         *x = 0;
00881         return;
00882     }
00883 
00884     story * story_line;
00885 
00886     if ((story_line = find_qmatch(a_story, name)) == NULL) {
00887 
00888         if (verbose) cerr << "getia: no quantity found with name \""
00889                           << name << "\"" << endl;
00890 
00891         *x = 0;
00892         return;
00893 
00894     }
00895 
00896     get_array(get_qstring(story_line), x, n);
00897 }
00898 
00899 /*-----------------------------------------------------------------------------
00900  *  putiq  --  write an integer quantity at the end of a story;
00901  *             or, if a previous quantity of the same name is found,
00902  *             overwrite the line containing that quantity.
00903  *-----------------------------------------------------------------------------
00904  */
00905 void putiq(story * a_story, char * name, int value)
00906 {
00907     if (!a_story || !name) return;
00908 
00909     story * story_line;
00910     
00911     if ((story_line = find_qmatch(a_story, name)) == NULL)
00912         {
00913         story_line = new story; 
00914         add_daughter_story(a_story, story_line);
00915         }
00916 
00917     write_iq(story_line, name, value);
00918 }
00919 
00920 /*-----------------------------------------------------------------------------
00921  *  putulq  -- write an unsigned long integer quantity at the end of a
00922  *             story; or, if a previous quantity of the same name is found,
00923  *             overwrite the line containing that quantity.
00924  *-----------------------------------------------------------------------------
00925  */
00926 void putulq(story * a_story, char * name, unsigned long value)
00927 {
00928     if (!a_story || !name) return;
00929 
00930     story * story_line;
00931     
00932     if ((story_line = find_qmatch(a_story, name)) == NULL)
00933         {
00934         story_line = new story; 
00935         add_daughter_story(a_story, story_line);
00936         }
00937 
00938     write_ulq(story_line, name, value);
00939 }
00940 
00941 
00942 // Handy function for debugging (Steve, 10/98)...
00943 
00944 void dump_story(story* s, int indent)
00945 {
00946     if (!s) return;
00947 
00948     if (indent == 0) cerr << endl;
00949 
00950     PRI(indent); cerr << "story s = " << s << endl;
00951     PRI(indent); cerr << "flag = " << s->get_chapter_flag() << endl;
00952     PRI(indent); cerr << "text:  \"" << s->get_text() << "\"" << endl;
00953     PRI(indent); cerr << "next = " << s->get_next_story_node() << endl;
00954     PRI(indent); cerr << "first = " << s->get_first_daughter_node() << endl;
00955     PRI(indent); cerr << "last = " << s->get_last_daughter_node() << endl;
00956 
00957     if (indent >= 0) {
00958         if (s->get_first_daughter_node())
00959             for (story* ss = s->get_first_daughter_node(); ss != NULL;
00960                  ss = ss->get_next_story_node())
00961                 dump_story(ss, indent+4);
00962     }
00963 }
00964 
00965 /*-----------------------------------------------------------------------------
00966  *  putrq  --  write a real quantity at the end of a story;
00967  *             or, if a previous quantity of the same name is found,
00968  *             overwrite the line containing that quantity.
00969  *-----------------------------------------------------------------------------
00970  */
00971 void putrq(story * a_story, char * name, real value, int precision)
00972 {
00973     if (!a_story || !name) return;
00974 
00975     story * story_line;
00976 
00977     bool dbg = false;
00978     if (name[0] == '-') {
00979         name++;
00980         dbg = true;
00981     }
00982 
00983     if (dbg) {
00984         cerr << endl << "in putrq..." << endl;
00985         dump_story(a_story);
00986     }
00987 
00988     if ((story_line = find_qmatch(a_story, name)) == NULL)
00989         {
00990 
00991         if (dbg) cerr << "making new story" << endl;
00992 
00993         story_line = new story; 
00994         add_daughter_story(a_story, story_line);
00995         }
00996 
00997 
00998     if (dbg) {
00999         dump_story(a_story);
01000         PRL(story_line);
01001     }
01002 
01003     write_rq(story_line, name, value, precision);
01004 
01005     if (dbg) {
01006         cerr << "wrote " << name << " = " << value << " to story" << endl;
01007         put_story(cerr, *a_story);
01008         PRL(story_line->get_text());
01009         PRL(get_qstring(story_line));
01010         dump_story(a_story);
01011     }
01012 }
01013 
01014 /*-----------------------------------------------------------------------------
01015  *  putra  --  write a real array at the end of a story;
01016  *             or, if a previous quantity of the same name is found,
01017  *             overwrite the line containing that quantity.
01018  *-----------------------------------------------------------------------------
01019  */
01020 void putra(story * a_story, char * name, real * value, int n)
01021 {
01022     if (!a_story || !name) return;
01023 
01024     story * story_line;
01025     
01026     if ((story_line = find_qmatch(a_story, name)) == NULL)
01027         {
01028         story_line = new story; 
01029         add_daughter_story(a_story, story_line);
01030         }
01031 
01032     write_ra(story_line, name, value, n);
01033 }
01034 
01035 /*-----------------------------------------------------------------------------
01036  *  putia  --  write an integer array at the end of a story;
01037  *             or, if a previous quantity of the same name is found,
01038  *             overwrite the line containing that quantity.
01039  *-----------------------------------------------------------------------------
01040  */
01041 void putia(story * a_story, char * name, int * value, int n)
01042 {
01043     if (!a_story || !name) return;
01044 
01045     story * story_line;
01046     
01047     if ((story_line = find_qmatch(a_story, name)) == NULL)
01048         {
01049         story_line = new story; 
01050         add_daughter_story(a_story, story_line);
01051         }
01052 
01053     write_ia(story_line, name, value, n);
01054 }
01055 
01056 /*-----------------------------------------------------------------------------
01057  *  putia  --  write an unsigned long array at the end of a story;
01058  *             or, if a previous quantity of the same name is found,
01059  *             overwrite the line containing that quantity.
01060  *-----------------------------------------------------------------------------
01061  */
01062 void putia(story * a_story, char * name, unsigned long * value, int n)
01063 {
01064     if (!a_story || !name) return;
01065 
01066     story * story_line;
01067     
01068     if ((story_line = find_qmatch(a_story, name)) == NULL)
01069         {
01070         story_line = new story; 
01071         add_daughter_story(a_story, story_line);
01072         }
01073 
01074     write_ia(story_line, name, value, n);
01075 }
01076 
01077 /*-----------------------------------------------------------------------------
01078  *  putsq  --  write a string quantity at the end of a story;
01079  *             or, if a previous quantity of the same name is found,
01080  *             overwrite the line containing that quantity.
01081  *-----------------------------------------------------------------------------
01082  */
01083 void putsq(story * a_story, char * name, char * value)
01084 {
01085     if (!a_story || !name) return;
01086 
01087     story * story_line;
01088     
01089     if ((story_line = find_qmatch(a_story, name)) == NULL)
01090         {
01091         story_line = new story; 
01092         add_daughter_story(a_story, story_line);
01093         }
01094 
01095     write_sq(story_line, name, value);
01096 }
01097 
01098 /*-----------------------------------------------------------------------------
01099  *  putvq  --  write a vector quantity at the end of a story;
01100  *             or, if a previous quantity of the same name is found,
01101  *             overwrite the line containing that quantity.
01102  *-----------------------------------------------------------------------------
01103  */
01104 void putvq(story * a_story, char * name, vector & value)
01105 {
01106     if (!a_story || !name) return;
01107 
01108     story * story_line;
01109 
01110     if ((story_line = find_qmatch(a_story, name)) == NULL)
01111         {
01112         story_line = new story; 
01113         add_daughter_story(a_story, story_line);
01114         }
01115 
01116     write_vq(story_line, name, value);
01117 }
01118 
01119 /*-----------------------------------------------------------------------------
01120  *  rmq  --  removes a quantity line from a story.
01121  *           returns 1 when a line is actually removed,
01122  *           returns 0 when no line is found for quantity name `name'.
01123  *-----------------------------------------------------------------------------
01124  */
01125 int  rmq(story *  a_story, char * name)
01126 {
01127     if (!a_story || !name) return 0;
01128 
01129     story * story_line;
01130 
01131     if (story_line = find_qmatch(a_story, name))
01132         {
01133         rm_daughter_story(a_story, story_line);
01134         return 1;
01135         }
01136     else
01137         return 0;
01138 }
01139 
01140 /*-----------------------------------------------------------------------------
01141  *  is_quantity_name  --  checks whether there exists a quantity by the name
01142  *                        'name' in story 'a_story'.
01143  *                        returns 1 when that quantity is found,
01144  *                        returns 0 when that quantity is not found.
01145  *-----------------------------------------------------------------------------
01146  */
01147 int  is_quantity_name(story * a_story, char * name)
01148 {
01149     if (!a_story || !name) return 0;
01150 
01151     if (find_qmatch(a_story, name))
01152         return 1;
01153     else
01154         return 0;
01155 }
01156 
01157 
01158 #else
01159 
01160 main(int argc, char** argv)
01161     {
01162     story * s;
01163     check_help();
01164 
01165 //    while (cin >> s)
01166 //      {
01167 /*
01168         putiq(s, "test message", 41);
01169         putiq(s, "test message", 42);
01170         putiq(s, "yet another test message", 137);
01171         putrq(s, "pi", 3.14);
01172         putrq(s, "pi", 3.14, 2);
01173         putrq(s, "pi", 3.14, 10);
01174         putsq(s, "star cluster", "47 Tuc");
01175         vector * tmp = new vector(1,2,3);
01176         putvq(s, "1-2-3-test vector", *tmp);
01177         cout << "test message = " << getiq(s, "test message") << endl;
01178         cout << "yet another test message = "
01179              << getiq(s, "yet another test message") << endl;
01180         cout << "pi = " << getrq(s, "pi") << endl;
01181         cout << "star cluster = " << getsq(s, "star cluster") << endl;
01182         cout << "1-2-3-test vector = " << getvq(s, "1-2-3-test vector")
01183              << endl;
01184 */
01185 //        cout << s;
01186 //      }
01187 
01188 //    cerr << "story.C : TOOLBOX : Normal exit\n";
01189     }
01190 
01191 #endif

Generated at Sun Feb 24 09:57:17 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001