]> git.lyx.org Git - lyx.git/blob - src/mathed/array.C
compilation fixes for compaq cxx + small things
[lyx.git] / src / mathed / array.C
1
2 #include <config.h>
3
4 #ifdef __GNUG__
5 #pragma implementation
6 #endif
7
8 #include "debug.h"
9 #include "array.h"
10 #include "math_iter.h"
11 #include "math_inset.h"
12 #include "math_macro.h"
13
14 #include "support/LOstream.h"
15
16 using std::ostream;
17 using std::endl;
18
19 #ifndef CXX_GLOBAL_CSTD
20 using std::memmove;
21 #endif
22
23
24 namespace {
25
26 inline
27 void * my_memcpy(void * ps_in, void const * pt_in, size_t n)
28 {
29         char * ps = static_cast<char *>(ps_in);
30         char const * pt = static_cast<char const *>(pt_in);
31         while (n--) *ps++ = *pt++;
32         return ps_in;
33 }
34
35 } // namespace anon
36
37
38 MathedArray::MathedArray()
39         : bf_(1, '\0'), last_(0)
40 {}
41
42
43 MathedArray::~MathedArray()
44 {
45         // deep destruction
46         // let's leak for a while... 
47 /*
48         MathedIter it;
49         it.SetData(this);
50         while (it.OK()) {
51                 if (it.IsInset()) {
52                         MathedInset * inset = it.GetInset();
53                         delete inset;
54                 }
55                 it.Next();
56         }
57 */
58 }
59
60
61 MathedArray::MathedArray(MathedArray const & array)
62 {
63         // this "implementation" is obviously wrong: MathedIter should be
64         // implemented by MathedArray (not the other way round) but I think
65         // getting the _interface_ of MathedArray right is more important right
66         // now (Andre')
67
68         // shallow copy
69         bf_   = array.bf_;
70         last_ = array.last_;
71
72         // deep copy
73         deep_copy();
74 }
75
76
77 void MathedArray::deep_copy()
78 {
79         MathedIter it(this);
80         while (it.OK()) {
81                 if (it.IsInset()) {
82                         MathedInset * inset = it.GetInset();
83                         inset = inset->Clone();
84                         raw_pointer_insert(inset, it.getPos() + 1);
85                 }
86                 it.Next();
87         }
88 }
89
90
91 void MathedArray::substitute(MathMacro * m)
92 {
93         if (m->nargs() == 0)
94                 return;
95
96         MathedIter it(this);
97         while (it.OK()) {
98                 if (it.IsInset()) {
99                         MathedInset * inset = it.GetInset();
100                         if (inset->GetType() == LM_OT_MACRO_ARG) {
101                                 int n = static_cast<MathMacroArgument *>(inset)->number() - 1;
102                                 //lyxerr << "substituting an argument inset: " << n << "\n";
103                                 inset = m->arg(n)->Clone();
104                         } else {
105                                 inset->substitute(m);
106 /*                              
107                                 if (it.IsActive()) {
108                                         MathParInset * pinset = static_cast<MathParInset *>(inset);
109                                         int n = pinset->getMaxArgumentIdx();
110                                         int idx = pinset->getArgumentIdx();
111                                         for (int i = 0; i <= n; ++i) {
112                                                 pinset->setArgumentIdx(i);
113                                                 pinset->GetData().substitute(m);
114                                         }
115                                         pinset->setArgumentIdx(idx);
116                                 }
117 */
118
119                                 //lyxerr << "substituting in an ordinary inset\n";
120                         }
121                         raw_pointer_insert(inset, it.getPos() + 1);
122                 }
123                 it.Next();
124         }
125 }
126
127
128 MathedArray & MathedArray::operator=(MathedArray const & array)
129 {
130         MathedArray tmp(array);
131         swap(tmp);
132         return *this;
133 }
134
135
136 void MathedArray::push_back(MathedInset * inset, int t)
137 {
138         MathedIter it(this);
139         while (it.Next())
140                 ;
141         it.insertInset(inset, t);
142 }
143
144
145 void MathedArray::push_back(byte b, MathedTextCodes c)
146 {
147         MathedIter it(this);
148         while (it.Next())
149                 ;
150         it.insert(b, c);
151 }
152
153
154 void MathedArray::clear()
155 {
156         last_ = 0;
157         bf_.resize(1);
158         bf_[0] = 0;
159 }
160
161
162 void MathedArray::swap(MathedArray & array)
163 {
164         if (this != &array) {
165                 bf_.swap(array.bf_);
166                 std::swap(last_, array.last_);
167         }
168 }
169
170
171 MathedArray::iterator MathedArray::begin() 
172 {
173         return bf_.begin();
174 }
175
176
177 MathedArray::iterator MathedArray::end() 
178 {
179         return bf_.end();
180 }
181
182
183 MathedArray::const_iterator MathedArray::begin() const
184 {
185         return bf_.begin();
186 }
187
188
189 MathedArray::const_iterator MathedArray::end() const
190 {
191         return bf_.end();
192 }
193
194
195 int MathedArray::empty() const
196 {
197         return (last_ == 0);
198 }
199    
200
201 int MathedArray::last() const
202 {
203         return last_;
204 }
205
206
207 void MathedArray::last(int l)
208 {
209         last_ = l;
210 }
211
212
213 void MathedArray::need_size(int needed)
214 {
215         if (needed >= static_cast<int>(bf_.size()))
216                 resize(needed);
217 }
218
219
220 void MathedArray::resize(int newsize)
221 {
222         // still a bit smelly...
223         ++newsize;
224         bf_.resize(newsize + 1);
225         if (last_ >= newsize)
226                 last_ = newsize - 1;
227         bf_[last_] = 0;
228 }
229
230
231 void MathedArray::move(int p, int shift)
232 {
233         if (p <= last_) {
234                 need_size(last_ + shift);
235                 memmove(&bf_[p + shift], &bf_[p], last_ - p);
236                 last_ += shift;
237                 bf_[last_] = 0;
238         }
239 }
240
241
242
243 void MathedArray::shrink(int pos1, int pos2)
244 {
245         if (pos1 == 0 && pos2 >= last())        
246                 return;
247
248         short fc = 0;
249         if (pos1 > 0 && bf_[pos1] > ' ') {
250                 for (int p = pos1; p >= 0; --p) {
251                         if (MathIsFont(bf_[p])) {
252                                 if (p != pos1 - 1)
253                                         fc = bf_[p];
254                                 else
255                                         --pos1;
256                                 break;
257                         }
258                 }
259         }
260
261         if (pos2 > 0 && bf_[pos2] >= ' ' && MathIsFont(bf_[pos2 - 1]))
262                 --pos2;
263
264         int dx = pos2 - pos1;
265         MathedArray a;
266         a.resize(dx + 1);
267         strange_copy(&a, (fc) ? 1 : 0, pos1, dx);
268         if (fc) {
269                 a[0] = fc;
270                 ++dx;
271         }
272         a.last(dx);
273         a[dx] = '\0';
274
275         swap(a);
276         deep_copy();
277 }
278
279
280 #if 0
281 void MathedArray::insert(MathedArray::iterator pos,
282                          MathedArray::const_iterator beg,
283                          MathedArray::const_iterator end)
284 {
285         bf_.insert(pos, beg, end);
286         last_ = bf_.size() - 1;
287 }
288 #else
289 void MathedArray::merge(MathedArray const & a, int p)
290 {
291         my_memcpy(&bf_[p], &a.bf_[0], a.last());
292 }
293 #endif
294
295
296 void MathedArray::raw_pointer_copy(MathedInset ** p, int pos) const
297 {
298         my_memcpy(p, &bf_[pos], sizeof(MathedInset*));
299 }
300
301
302 #if 0
303 void MathedArray::insertInset(int pos, MathedInset * p, int type)
304 {
305         //bf_.insert(pos, type);
306         InsetTable tmp(pos, p);
307         insetList_.push_back(tmp);
308 }
309
310
311 MathedInset * MathedArray::getInset(int pos) 
312 {
313         InsetList::const_iterator cit = insetList_.begin();
314         InsetList::const_iterator end = insetList_.end();
315         for (; cit != end; ++cit) {
316                 if ((*cit).pos == pos)
317                         return (*cit).inset;
318         }
319         // not found
320         return 0;
321         // We would really like to throw an exception instead... (Lgb)
322         // throw inset_not_found();
323 }
324
325 #else
326 void MathedArray::raw_pointer_insert(void * p, int pos)
327 {
328         my_memcpy(&bf_[pos], &p, sizeof(p));
329 }
330 #endif
331
332
333 void MathedArray::strange_copy(MathedArray * dest, int dpos,
334                                 int spos, int len)
335 {
336         my_memcpy(&dest->bf_[dpos], &bf_[spos], len);
337 }
338
339
340 byte MathedArray::operator[](int i) const
341 {
342         return bf_[i];
343 }
344
345
346 byte & MathedArray::operator[](int i)
347 {
348         return bf_[i];
349 }
350
351
352 void MathedArray::dump2(ostream & os) const
353 {
354         buffer_type::const_iterator cit = bf_.begin();
355         buffer_type::const_iterator end = bf_.end();
356         for (; cit != end; ++cit) {
357                 os << (*cit);
358         }
359         os << endl;
360 }
361
362
363 void MathedArray::dump(ostream & os) const
364 {
365         MathedIter it( const_cast<MathedArray*>(this) );
366         while (it.OK()) {
367                 if (it.IsInset()) {
368                         MathedInset * inset = it.GetInset();
369                         os << "<inset: " << inset << ">";
370                 } 
371                 else if (it.IsTab())
372                         os << "<tab>";
373                 else if (it.IsCR())
374                         os << "<cr>";
375                 else if (it.IsScript())
376                         os << "<script>";
377                 else if (it.IsFont())
378                         os << "<font: " << int(it.at()) << ">";
379                 else if (it.at() >= 32 && it.at() < 127)
380                         os << it.at();
381                 else
382                         os << "<unknown: " << int(it.at()) << ">";
383                 it.Next();
384         }
385 }