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