00001
00002
00003
00004
00005 #include "story.h"
00006
00007 story::~story()
00008 {
00009 story * si = first_daughter_node;
00010 story * sn;
00011 while (si != NULL)
00012 {
00013 sn = si->next_story_node;
00014 delete si;
00015 si = sn;
00016 }
00017 delete [] text;
00018 }
00019
00020 int is_chapter(story * s)
00021 {
00022 return s->get_chapter_flag();
00023 }
00024
00025 int is_chapter_begin_line(char * line)
00026 {
00027 return (*line == chapter_begin_char);
00028 }
00029
00030 int is_chapter_end_line(char * line)
00031 {
00032 return (*line == chapter_end_char);
00033 }
00034
00035 int get_story_line(istream & str, char * line)
00036 {
00037 str.get(line,MAX_STORY_LINE_LENGTH,'\n');
00038
00039 if(str.eof())
00040 return 0;
00041
00042 char c;
00043 if(str.get(c) && c!='\n')
00044 {
00045 cerr << "get_story_line : input line too long :'"<<line<<"'\n";
00046 exit(1);
00047 }
00048
00049 return 1;
00050 }
00051
00052 void add_daughter_story(story * s, story * d)
00053 {
00054 story *lc = s->get_last_daughter_node();
00055 if (lc)
00056 {
00057 lc->set_next_story_node(d);
00058 s->set_last_daughter_node(d);
00059 }
00060 else
00061 {
00062 s->set_first_daughter_node(d);
00063 s->set_last_daughter_node(d);
00064 }
00065 }
00066
00067 void add_chapter(story * s, story * chap)
00068 {
00069 if (chap == NULL)
00070 return;
00071
00072 add_daughter_story(s, chap);
00073 }
00074
00075 void rm_daughter_story(story * s, story * d)
00076 {
00077 story * fd = s->get_first_daughter_node();
00078 story * ad;
00079 story * nd;
00080
00081 if (fd == d)
00082 s->set_first_daughter_node(d->get_next_story_node());
00083 else
00084 {
00085 ad = fd;
00086 nd = ad->get_next_story_node();
00087 while (nd != d)
00088 {
00089 ad = nd;
00090 nd = ad->get_next_story_node();
00091 }
00092 nd = d->get_next_story_node();
00093 ad->set_next_story_node(nd);
00094 if (nd == NULL)
00095 s->set_last_daughter_node(ad);
00096 }
00097 delete d;
00098 }
00099
00100 story* mk_story_line() {story* s = new story(0); return s;}
00101
00102 story* mk_story_line(char * line)
00103 {
00104 story* s = new story(0);
00105 s->set_text(line);
00106 return s;
00107 }
00108
00109 story* mk_story_chapter() {story* s = new story(1); return s;}
00110
00111 story* mk_story_chapter(char * title)
00112 {
00113 story* s = new story(1);
00114 s->set_text(title);
00115 return s;
00116 }
00117
00118 void add_story_line(story * s, char * line)
00119 {
00120 if (line == NULL)
00121 return;
00122
00123 story * new_s = mk_story_line(line);
00124 add_daughter_story(s, new_s);
00125 }
00126
00127 story* get_chapter(istream& str, char* line)
00128 {
00129 if (!is_chapter_begin_line(line))
00130 {
00131 cerr << "get_chapter: first line not chapter_begin_line";
00132 exit(1);
00133 }
00134
00135 story * chap = mk_story_chapter(++line);
00136
00137 char new_line[MAX_STORY_LINE_LENGTH];
00138
00139 while (get_story_line(str, new_line) && !is_chapter_end_line(new_line))
00140 {
00141 if (is_chapter_begin_line(new_line))
00142 add_chapter(chap, get_chapter(str, new_line));
00143 else
00144 add_story_line(chap, new_line);
00145 }
00146
00147 if (new_line == NULL)
00148 {
00149 cerr << "get_chapter: new_line == NULL before end of chapter\n";
00150 exit(1);
00151 }
00152
00153 if (!streq(new_line+1, chap->get_text()))
00154 {
00155 cerr << "get_chapter: closing title ``" << new_line+1
00156 << "'' differs from opening title ``" << chap->get_text()
00157 << "''\n";
00158 exit(1);
00159 }
00160
00161 return chap;
00162 }
00163
00164 story* get_story(istream & str, char *line) {return get_chapter(str, line);}
00165
00166 story* get_story(istream& str)
00167 {
00168 char line[MAX_STORY_LINE_LENGTH];
00169
00170 if (!get_story_line(str, line))
00171 return(NULL);
00172
00173 if (!is_chapter_begin_line(line))
00174 {
00175 cerr << "get_story: first line not chapter_begin_line\n";
00176 exit(1);
00177 }
00178
00179 return get_chapter(str, line);
00180 }
00181
00182 void put_headline(ostream& str, story& s)
00183 {
00184 str << chapter_begin_char << s.get_text() << "\n";
00185 }
00186
00187 void put_tailline(ostream& str, story& s)
00188 {
00189 str << chapter_end_char << s.get_text() << "\n";
00190 }
00191
00192 void put_line_text(ostream& str, story& s)
00193 {
00194 str << s.get_text() << "\n";
00195 }
00196
00197 void put_chapter(ostream& str, story& s)
00198 {
00199 if (!is_chapter(&s))
00200 {
00201 cerr << "put_chapter: not a story\n";
00202 exit(1);
00203 }
00204 put_headline(str, s);
00205
00206 for (story * d = s.get_first_daughter_node(); d != NULL;
00207 d = d->get_next_story_node())
00208 {
00209 if (is_chapter(d))
00210 put_chapter(str, *d);
00211 else
00212 put_line_text(str, *d);
00213 }
00214
00215 put_tailline(str, s);
00216 }
00217
00218 void put_story_contents(ostream& str, story& s)
00219 {
00220 if (!is_chapter(&s))
00221 {
00222 cerr << "put_story_contents: not a story\n";
00223 exit(1);
00224 }
00225
00226 for (story * d = s.get_first_daughter_node(); d != NULL;
00227 d = d->get_next_story_node())
00228 {
00229 if (is_chapter(d))
00230 put_chapter(str, *d);
00231 else
00232 put_line_text(str, *d);
00233 }
00234 }
00235
00236 void put_story(ostream& str, story& s)
00237 {
00238 put_chapter(str, s);
00239 }
00240
00241 ostream & operator << (ostream & s, story * sptr)
00242 {put_story(s, *sptr); return s;}
00243
00244 istream & operator >> (istream & s, story * & sptr)
00245 {sptr = get_story(s); return s;}
00246
00247 #ifdef TOOLBOX
00248
00249 main()
00250 {
00251 story * s;
00252
00253 while (cin >> s)
00254 {
00255 #if 0
00256 putiq(s, "test message", 41);
00257 putiq(s, "test message", 42);
00258 putiq(s, "yet another test message", 137);
00259 putrq(s, "pi", 3.14);
00260 putsq(s, "star cluster", "47 Tuc");
00261 vector * tmp = new vector(1,2,3);
00262 putvq(s, "1-2-3-test vector", *tmp);
00263 #endif
00264
00265
00266
00267
00268
00269
00270
00271 cout << s;
00272 }
00273
00274
00275 }
00276
00277 #endif