source: git/Singular/dyn_modules/systhreads/lintree.cc @ c1ce47

fieker-DuValspielwiese
Last change on this file since c1ce47 was c1ce47, checked in by Reimer Behrends <behrends@…>, 5 years ago
Fixed systhreads build with ppcc.
  • Property mode set to 100644
File size: 21.4 KB
Line 
1#include "threadconf.h"
2#include "lintree.h"
3#include <iostream>
4
5#define TRANSEXT_PRIVATES 1 /* allow access to transext internals */
6
7#include <kernel/mod2.h>
8
9#include <omalloc/omalloc.h>
10
11#include <misc/intvec.h>
12#include <misc/options.h>
13
14#include <reporter/si_signals.h>
15#include <reporter/s_buff.h>
16
17#include <coeffs/bigintmat.h>
18#include <coeffs/longrat.h>
19#include <coeffs/shortfl.h>
20
21#include <polys/monomials/ring.h>
22#include <polys/monomials/p_polys.h>
23#include <polys/ext_fields/transext.h>
24#include <polys/simpleideals.h>
25#include <polys/matpol.h>
26
27#include <kernel/oswrapper/timer.h>
28#include <kernel/oswrapper/feread.h>
29#include <kernel/oswrapper/rlimit.h>
30
31#include <Singular/tok.h>
32#include <Singular/ipid.h>
33#include <Singular/ipshell.h>
34#include <Singular/subexpr.h>
35#include <Singular/links/silink.h>
36#include <Singular/cntrlc.h>
37#include <Singular/lists.h>
38#include <Singular/blackbox.h>
39
40number nlRInit(long);
41
42namespace LinTree {
43
44using namespace std;
45
46vector<LinTreeEncodeFunc> encoders;
47vector<LinTreeDecodeFunc> decoders;
48vector<LinTreeRefFunc> refupdaters;
49vector<char> needs_ring;
50
51void install(int typ,
52  LinTreeEncodeFunc enc,
53  LinTreeDecodeFunc dec,
54  LinTreeRefFunc ref)
55{
56  size_t n;
57  for (;;) {
58    n = encoders.size();
59    if (n > typ) break;
60    if (n == 0)
61      n = 256;
62    else
63      n = n * 2;
64    encoders.resize(n);
65    decoders.resize(n);
66    refupdaters.resize(n);
67    needs_ring.resize(n);
68  }
69  encoders[typ] = enc;
70  decoders[typ] = dec;
71  refupdaters[typ] = ref;
72}
73
74void set_needs_ring(int typ) {
75  needs_ring[typ] = 1;
76}
77
78void encode(LinTree &lintree, leftv val) {
79  void encode_ring(LinTree &lintree, const ring r);
80  int typ = val->Typ();
81  char enc_ring = 0;
82  LinTreeEncodeFunc fn;
83  if (typ < encoders.size()) {
84    fn = encoders[typ];
85    enc_ring = needs_ring[typ];
86  }
87  else
88    fn = NULL;
89  if (fn) {
90    if (enc_ring && !lintree.has_last_ring()) {
91      lintree.put_int(-1);
92      encode_ring(lintree, currRing);
93      lintree.set_last_ring(currRing);
94    }
95    lintree.put_int(typ);
96    fn(lintree, val);
97  } else
98    lintree.mark_error("trying to share unsupported data type");
99}
100
101leftv decode(LinTree &lintree) {
102  ring decode_ring_raw(LinTree &lintree);
103  int typ = lintree.get_int();
104  if (typ < 0) {
105    lintree.set_last_ring(decode_ring_raw(lintree));
106    typ = lintree.get_int();
107  }
108  LinTreeDecodeFunc fn = decoders[typ];
109  return fn(lintree);
110}
111
112void updateref(LinTree &lintree, int by) {
113  int typ = lintree.get_int();
114  LinTreeRefFunc fn = refupdaters[typ];
115  fn(lintree, by);
116}
117
118leftv new_leftv(int code, void *data) {
119  leftv result = (leftv) omAlloc0Bin(sleftv_bin);
120  result->rtyp = code;
121  result->data = (char *)data;
122  return result;
123}
124
125leftv new_leftv(int code, long data) {
126  leftv result = (leftv) omAlloc0Bin(sleftv_bin);
127  result->rtyp = code;
128  result->data = (char *)data;
129  return result;
130}
131
132void encode_mpz(LinTree &lintree, const mpz_t num) {
133  size_t nbytes = (mpz_sizeinbase(num, 2) + 7UL) / 8UL;
134  char *p = (char *) alloca(nbytes);
135  mpz_export(p, &nbytes, 1, 1, 0, 0, num);
136  lintree.put(nbytes);
137  lintree.put_bytes(p, nbytes);
138}
139
140void decode_mpz(LinTree &lintree, mpz_t &num) {
141  size_t nbytes = lintree.get<size_t>();
142  const char *p = lintree.get_bytes(nbytes);
143  mpz_import(num, nbytes, 1, 1, 0, 0, p);
144}
145
146// NONE
147
148void encode_none(LinTree &lintree, leftv val) {
149}
150
151leftv decode_none(LinTree &lintree) {
152  return new_leftv(NONE, 0L);
153}
154
155void ref_none(LinTree &lintree, int by) {
156}
157
158
159// INT_CMD
160
161void encode_int(LinTree &lintree, leftv val) {
162  long data = (long)(val->Data());
163  lintree.put(data);
164}
165
166leftv decode_int(LinTree &lintree) {
167  long data = lintree.get<long>();
168  return new_leftv(INT_CMD, data);
169}
170
171void ref_int(LinTree &lintree, int by) {
172  lintree.skip<long>();
173}
174
175// STRING_CMD
176
177void encode_string(LinTree &lintree, leftv val) {
178  char *p = (char *)val->Data();
179  size_t len = strlen(p);
180  lintree.put(len);
181  lintree.put_bytes(p, len);
182}
183
184leftv decode_string(LinTree &lintree) {
185  size_t len = lintree.get<size_t>();
186  const char *p = lintree.get_bytes(len);
187  leftv result = new_leftv(STRING_CMD, (void *)NULL);
188  result->data = omAlloc0(len+1);
189  memcpy(result->data, p, len);
190  return result;
191}
192
193void ref_string(LinTree &lintree, int by) {
194  size_t len = lintree.get<size_t>();
195  lintree.skip_bytes(len);
196}
197
198// DEF_CMD
199
200void encode_def(LinTree &lintree, leftv val) {
201  char *p = (char *)val->Name();
202  size_t len = strlen(p);
203  lintree.put(len);
204  lintree.put_bytes(p, len);
205}
206
207leftv decode_def(LinTree &lintree) {
208  size_t len = lintree.get<size_t>();
209  const char *p = lintree.get_bytes(len);
210  leftv result = new_leftv(DEF_CMD, (void *)NULL);
211  char *name = (char *) omAlloc0(len+1);
212  result->name = name;
213  result->rtyp = 0;
214  memcpy(name, p, len);
215  int error = result->Eval();
216  if (error) {
217    lintree.mark_error("error in name lookup");
218  }
219  return result;
220}
221
222void ref_def(LinTree &lintree, int by) {
223  size_t len = lintree.get<size_t>();
224  lintree.skip_bytes(len);
225}
226
227// NUMBER_CMD
228
229
230void encode_longrat_cf(LinTree &lintree, const number n) {
231  if (SR_HDL(n) & SR_INT) {
232    long nn = SR_TO_INT(n);
233    lintree.put<int>(-1);
234    lintree.put<long>(nn);
235  } else {
236    lintree.put<int>(n->s);
237    if (n->s < 2) {
238      encode_mpz(lintree, n->z);
239      encode_mpz(lintree, n->n);
240    } else {
241      encode_mpz(lintree, n->z);
242    }
243  }
244}
245
246number decode_longrat_cf(LinTree &lintree) {
247  number result;
248  int subtype = lintree.get_int();
249  if (subtype < 0)
250    result = INT_TO_SR(lintree.get<long>());
251  else if (subtype < 2) {
252    result = nlRInit(0);
253    mpz_init(result->n);
254    decode_mpz(lintree, result->z);
255    decode_mpz(lintree, result->n);
256    result->s = subtype;
257  } else {
258    result = nlRInit(0);
259    decode_mpz(lintree, result->z);
260    result->s = subtype;
261  }
262  return result;
263}
264
265void encode_number_cf(LinTree &lintree, const number n, const coeffs cf) {
266  void encode_poly(LinTree &lintree, int typ, poly p, const ring r);
267  n_coeffType ct = getCoeffType(cf);
268  // lintree.put_int((int)ct);
269  switch (ct) {
270    case n_transExt:
271      {
272      fraction f= (fraction) n;
273      encode_poly(lintree, POLY_CMD, NUM(f), cf->extRing);
274      encode_poly(lintree, POLY_CMD, DEN(f), cf->extRing);
275      }
276      break;
277    case n_algExt:
278      encode_poly(lintree, POLY_CMD, (poly) n, cf->extRing);
279      break;
280    case n_Zp:
281      lintree.put<long>((long) n);
282      break;
283    case n_Q:
284      encode_longrat_cf(lintree, n);
285      break;
286    default:
287      lintree.mark_error("coefficient type not supported");
288      break;
289  }
290}
291
292number decode_number_cf(LinTree &lintree, const coeffs cf) {
293  poly decode_poly(LinTree &lintree, const ring r);
294  n_coeffType ct = getCoeffType(cf);
295  switch (ct) {
296    case n_transExt:
297      {
298      fraction f= (fraction) n_Init(1, cf);
299      NUM(f) = decode_poly(lintree, cf->extRing);
300      DEN(f) = decode_poly(lintree, cf->extRing);
301      return (number) f;
302      }
303    case n_algExt:
304      return (number) decode_poly(lintree, cf->extRing);
305    case n_Zp:
306      return (number) (lintree.get<long>());
307    case n_Q:
308      return decode_longrat_cf(lintree);
309    default:
310      lintree.mark_error("coefficient type not supported");
311      return NULL;
312  }
313}
314
315leftv decode_number(LinTree &lintree) {
316  return new_leftv(NUMBER_CMD,
317    decode_number_cf(lintree, ((ring)lintree.get_last_ring())->cf));
318}
319
320void encode_number(LinTree &lintree, leftv val) {
321  encode_number_cf(lintree, (number)val->Data(),
322    ((ring) lintree.get_last_ring())->cf);
323}
324
325void ref_number_cf(LinTree &lintree, coeffs cf, int by) {
326  void ref_poly(LinTree &lintree, int by);
327  switch (getCoeffType(cf)) {
328    case n_transExt:
329      ref_poly(lintree, by);
330      ref_poly(lintree, by);
331      break;
332    case n_algExt:
333      ref_poly(lintree, by);
334      break;
335    case n_Zp:
336      lintree.skip<long>();
337      break;
338    default:
339      abort(); // should never happen
340      break;
341  }
342}
343
344void ref_number(LinTree &lintree, int by) {
345  coeffs cf = ((ring) lintree.get_last_ring())->cf;
346  ref_number_cf(lintree, cf, by);
347}
348
349// BIGINT_CMD
350
351void encode_bigint(LinTree &lintree, leftv val) {
352  encode_number_cf(lintree, (number) val->Data(), coeffs_BIGINT);
353}
354
355leftv decode_bigint(LinTree &lintree) {
356  return new_leftv(BIGINT_CMD,
357    decode_number_cf(lintree, coeffs_BIGINT));
358}
359
360void ref_bigint(LinTree &lintree, int by) {
361  ref_number_cf(lintree, coeffs_BIGINT, by);
362}
363
364// INTMAT_CMD
365
366leftv decode_intmat(LinTree &lintree) {
367  int rows = lintree.get_int();
368  int cols = lintree.get_int();
369  int len = rows * cols;
370  intvec *v = new intvec(rows, cols, 0);
371  for (int i = 0; i < len; i++) {
372    (*v)[i] = lintree.get_int();
373  }
374  return new_leftv(INTMAT_CMD, v);
375}
376
377void encode_intmat(LinTree &lintree, leftv val) {
378  intvec *v = (intvec *)(val->Data());
379  int rows = v->rows();
380  int cols = v->cols();
381  int len = v->length();
382  lintree.put_int(rows);
383  lintree.put_int(cols);
384  for (int i = 0; i < len; i++) {
385    lintree.put_int((*v)[i]);
386  }
387}
388
389void ref_intmat(LinTree &lintree, int by) {
390  int rows = lintree.get_int();
391  int cols = lintree.get_int();
392  int len = rows * cols;
393  for (int i = 0; i < len; i++) {
394    (void) lintree.get_int();
395  }
396}
397
398// POLY_CMD
399
400void encode_poly(LinTree &lintree, int typ, poly p, const ring r) {
401  lintree.put_int(pLength(p));
402  while (p != NULL) {
403    encode_number_cf(lintree, pGetCoeff(p), r->cf);
404    lintree.put_int(p_GetComp(p, r));
405    for (int j=1; j<=rVar(r); j++) {
406      lintree.put_int(p_GetExp(p, j, r));
407    }
408    pIter(p);
409  }
410}
411
412void encode_poly(LinTree &lintree, int typ, poly p) {
413  encode_poly(lintree, typ, p, (ring) lintree.get_last_ring());
414}
415
416void encode_poly(LinTree &lintree, leftv val) {
417  encode_poly(lintree, val->Typ(), (poly) val->Data());
418}
419
420poly decode_poly(LinTree &lintree, const ring r) {
421  int len = lintree.get_int();
422  poly p;
423  poly ret = NULL;
424  poly prev = NULL;
425  for (int l = 0; l < len; l++) {
426    p = p_Init(r);
427    pSetCoeff0(p, decode_number_cf(lintree, r->cf));
428    int d;
429    d = lintree.get_int();
430    p_SetComp(p, d, r);
431    for(int i=1;i<=rVar(r);i++)
432    {
433      d=lintree.get_int();
434      p_SetExp(p,i,d,r);
435    }
436    p_Setm(p,r);
437    p_Test(p,r);
438    if (ret==NULL) ret=p;
439    else           pNext(prev)=p;
440    prev=p;
441  }
442  return ret;
443}
444
445leftv decode_poly(LinTree &lintree) {
446  ring r = (ring) lintree.get_last_ring();
447  return new_leftv(POLY_CMD, decode_poly(lintree, r));
448}
449
450void ref_poly(LinTree &lintree, int by) {
451  ring r = (ring) lintree.get_last_ring();
452  int len = lintree.get_int();
453  for (int l = 0; l <len; l++) {
454    ref_number(lintree, by);
455    lintree.skip_int();
456    for (int i=1; i<=rVar(r); i++)
457      lintree.skip_int();
458  }
459}
460
461// IDEAL_CMD
462ideal decode_ideal(LinTree &lintree, int typ, const ring r) {
463  int n = lintree.get_int();
464  ideal I = idInit(n, 1);
465  for (int i=0; i<IDELEMS(I); i++)
466    I->m[i] = decode_poly(lintree, r);
467  return I;
468}
469
470void encode_ideal(LinTree &lintree, int typ, const ideal I, const ring R) {
471  matrix M = (matrix) I;
472  int mn;
473  if (typ == MATRIX_CMD)
474  {
475    mn = MATROWS(M) * MATCOLS(M);
476    lintree.put_int(MATROWS(M));
477    lintree.put_int(MATCOLS(M));
478  } else {
479    mn = IDELEMS(I);
480    lintree.put_int(IDELEMS(I));
481  }
482  int tt;
483  if (typ == MODUL_CMD)
484    tt = VECTOR_CMD;
485  else
486    tt = POLY_CMD;
487  for (int i=0; i<mn; i++)
488    encode_poly(lintree, tt, I->m[i], R);
489}
490
491void encode_ideal(LinTree &lintree, int typ, const ideal I) {
492  encode_ideal(lintree, typ, I, (ring) lintree.get_last_ring());
493}
494
495void encode_ideal(LinTree &lintree, leftv val) {
496  void encode_ring(LinTree &lintree, const ring r);
497  int typ = val->Typ();
498  void *data = val->Data();
499  switch (typ) {
500    case IDEAL_CMD:
501    case MATRIX_CMD:
502      break;
503    case MODUL_CMD:
504      {
505        ideal M = (ideal) data;
506        lintree.put_int((int) M->rank);
507      }
508      break;
509  }
510  encode_ideal(lintree, typ, (ideal) data);
511}
512
513leftv decode_ideal(LinTree &lintree) {
514  ideal I = decode_ideal(lintree, IDEAL_CMD, (ring) lintree.get_last_ring());
515  return new_leftv(IDEAL_CMD, I);
516}
517
518void ref_ideal(LinTree &lintree, int by) {
519  int n = lintree.get_int();
520  for (int i=0; i<n; i++)
521    ref_poly(lintree, by);
522}
523
524
525// RING_CMD
526
527void encode_ring(LinTree &lintree, const ring r) {
528  if (r == NULL) {
529    lintree.put_int(-4);
530    return;
531  }
532  if (r == lintree.get_last_ring()) {
533    lintree.put_int(-5);
534    return;
535  }
536  if (rField_is_Q(r) || rField_is_Zp(r)) {
537    lintree.put_int(n_GetChar(r->cf));
538    lintree.put_int(r->N);
539  } else if (rFieldType(r) == n_transExt) {
540    lintree.put_int(-1);
541    lintree.put_int(r->N);
542  } else if (rFieldType(r) == n_algExt) {
543    lintree.put_int(-2);
544    lintree.put_int(r->N);
545  } else {
546    lintree.put_int(-3);
547    lintree.put_int(r->N);
548    lintree.put_cstring(nCoeffName(r->cf));
549  }
550  for (int i=0; i<r->N; i++) {
551    lintree.put_cstring(r->names[i]);
552  }
553  int i = 0;
554  if (r->order) while (r->order[i] != 0) i++;
555  lintree.put_int(i);
556  i = 0;
557  if (r->order) while (r->order[i] != 0) {
558    lintree.put_int(r->order[i]);
559    lintree.put_int(r->block0[i]);
560    lintree.put_int(r->block1[i]);
561    switch (r->order[i]) {
562      case ringorder_a:
563      case ringorder_wp:
564      case ringorder_Wp:
565      case ringorder_ws:
566      case ringorder_Ws:
567      case ringorder_aa:
568        for (int j = r->block0[i]; j <= r->block1[i]; j++)
569          lintree.put_int(r->wvhdl[i][j-r->block0[i]]);
570        break;
571      case ringorder_a64:
572      case ringorder_M:
573      case ringorder_L:
574      case ringorder_IS:
575        lintree.mark_error("ring order not implemented");
576        break;
577      default:
578        break;
579    }
580    i++;
581  }
582  if (rFieldType(r) == n_transExt || rFieldType(r) == n_algExt) {
583    encode_ring(lintree, r->cf->extRing);
584  }
585  if (r->qideal) {
586    lintree.put_int(IDEAL_CMD);
587    encode_ideal(lintree, IDEAL_CMD, r->qideal, r);
588  } else {
589    lintree.put_int(0);
590  }
591}
592
593void encode_ring(LinTree &lintree, leftv val) {
594  encode_ring(lintree, (ring) val->Data());
595}
596
597ring decode_ring_raw(LinTree &lintree) {
598  int ch = lintree.get_int();
599  int N = lintree.get_int();
600  coeffs cf = NULL;
601  char **names = NULL;
602  switch (ch) {
603    case -1:
604    case -2:
605    case -3:
606      {
607        const char *cf_name = lintree.get_cstring();
608        cf = nFindCoeffByName((char *)cf_name);
609        if (cf == NULL) {
610          lintree.mark_error("cannot find coeffient name");
611          return NULL;
612        }
613      }
614      break;
615    case -4:
616      return NULL;
617      break;
618    case -5:
619      return (ring) lintree.get_last_ring();
620      break;
621  }
622  if (N != 0) {
623    names = (char **)omAlloc(N*sizeof(char *));
624    for (int i=0; i<N; i++)
625      names[i] = omStrDup(lintree.get_cstring());
626  }
627  int num_ord;
628  num_ord = lintree.get_int();
629  rRingOrder_t *ord =
630    (rRingOrder_t *)omAlloc0((num_ord + 1)*sizeof(rRingOrder_t));
631  int *block0 = (int *)omAlloc0((num_ord + 1)*sizeof(int));
632  int *block1 = (int *)omAlloc0((num_ord + 1)*sizeof(int));
633  int **wvhdl = (int **)omAlloc0((num_ord + 1)*sizeof(int*));
634  for (int i=0; i<num_ord; i++)
635  {
636    ord[i] = (rRingOrder_t) lintree.get_int();
637    block0[i] = lintree.get_int();
638    block1[i] = lintree.get_int();
639    switch (ord[i]) {
640      case ringorder_a:
641      case ringorder_wp:
642      case ringorder_Wp:
643      case ringorder_ws:
644      case ringorder_Ws:
645      case ringorder_aa:
646        wvhdl[i] = (int *)omAlloc((block1[i]-block0[i]+1)*sizeof(int));
647        for (int j=block0[i]; j<=block1[i]; j++)
648          wvhdl[i][j-block0[i]] = lintree.get_int();
649        break;
650      case ringorder_a64:
651      case ringorder_M:
652      case ringorder_L:
653      case ringorder_IS:
654        lintree.mark_error("ring oder not implemented for lintrees");
655        break;
656      default:
657        break;
658    }
659  }
660  if (N == 0) {
661    omFree(ord);
662    omFree(block0);
663    omFree(block1);
664    omFree(wvhdl);
665    return NULL;
666  } else {
667    ring r = NULL;
668    if (ch >= 0)
669      r = rDefault(ch, N, names, num_ord, ord, block0, block1, wvhdl);
670    else if (ch == -1) {
671      TransExtInfo T;
672      T.r = decode_ring_raw(lintree);
673      if (T.r == NULL) return NULL;
674      cf = nInitChar(n_transExt, &T);
675      r = rDefault(cf, N, names, num_ord, ord, block0, block1, wvhdl);
676    } else if (ch == -2) {
677      TransExtInfo T;
678      T.r = decode_ring_raw(lintree);
679      if (T.r == NULL) return NULL;
680      cf = nInitChar(n_algExt, &T);
681      r = rDefault(cf, N, names, num_ord, ord, block0, block1, wvhdl);
682    } else if (ch == -3) {
683      r = rDefault(cf, N, names, num_ord, ord, block0, block1, wvhdl);
684    }
685    lintree.set_last_ring(r);
686    if (lintree.get_int()) {
687      r->qideal = decode_ideal(lintree, IDEAL_CMD, r);
688    }
689    return r;
690  }
691}
692
693leftv decode_ring(LinTree &lintree) {
694  return new_leftv(RING_CMD, decode_ring_raw(lintree));
695}
696
697void ref_ring(LinTree &lintree, int by) {
698  int ch = lintree.get_int();
699  int N = lintree.get_int();
700  switch (ch) {
701    case -3:
702      lintree.skip_cstring();
703    case -4:
704    case -5:
705      return;
706  }
707  for (int i=0; i<N; i++)
708    lintree.skip_cstring();
709  int num_ord = lintree.get_int();
710  for (int i=0; i<N; i++) {
711    int ord = lintree.get_int();
712    int block0 = lintree.get_int();
713    int block1 = lintree.get_int();
714    switch (ord) {
715      case ringorder_a:
716      case ringorder_wp:
717      case ringorder_Wp:
718      case ringorder_ws:
719      case ringorder_Ws:
720      case ringorder_aa:
721        for (int j=block0; j<=block1; j++)
722          lintree.skip_int();
723        break;
724    }
725  }
726  if (N != 0) {
727    if (ch == -1 || ch == -2) {
728      ref_ring(lintree, by);
729    }
730  }
731}
732
733// LIST_CMD
734
735void encode_list(LinTree &lintree, leftv val) {
736  lists l = (lists) val->Data();
737  int n = lSize(l);
738  lintree.put_int(n);
739  for (int i=0; i<=n; i++) {
740    encode(lintree, &l->m[i]);
741  }
742}
743
744leftv decode_list(LinTree &lintree) {
745  int n = lintree.get_int();
746  lists l = (lists)omAlloc(sizeof(*l));
747  l->Init(n+1);
748  for (int i=0; i<=n; i++) {
749    leftv val = decode(lintree);
750    memcpy(&l->m[i], val, sizeof(*val));
751    omFreeBin(val, sleftv_bin);
752  }
753  return new_leftv(LIST_CMD, l);
754}
755
756void ref_list(LinTree &lintree, int by) {
757  int n = lintree.get_int();
758  for (int i = 0; i < n; i++) {
759    updateref(lintree, by);
760  }
761}
762
763// COMMAND
764
765void encode_command(LinTree &lintree, leftv val) {
766  command cmd = (command) val->Data();
767  lintree.put_int(cmd->op);
768  lintree.put_int(cmd->argc);
769  if (cmd->argc >= 1)
770    encode(lintree, &cmd->arg1);
771  if (cmd->argc < 4) {
772    if (cmd->argc >= 2)
773      encode(lintree, &cmd->arg2);
774    if (cmd->argc >= 3)
775      encode(lintree, &cmd->arg3);
776  }
777}
778
779leftv decode_command(LinTree &lintree) {
780  command cmd = (command)omAlloc0(sizeof(*cmd));
781  int op = lintree.get_int();
782  int argc = lintree.get_int();
783  cmd->op = op;
784  cmd->argc = argc;
785  if (argc >= 1) {
786    leftv val = decode(lintree);
787    memcpy(&cmd->arg1, val, sizeof(*val));
788    omFreeBin(val, sleftv_bin);
789  }
790  if (argc < 4) {
791    if (argc >= 2) {
792      leftv val = decode(lintree);
793      memcpy(&cmd->arg2, val, sizeof(*val));
794      omFreeBin(val, sleftv_bin);
795    }
796    if (argc >= 3) {
797      leftv val = decode(lintree);
798      memcpy(&cmd->arg3, val, sizeof(*val));
799      omFreeBin(val, sleftv_bin);
800    }
801  }
802  leftv result = new_leftv(COMMAND, cmd);
803  int error = result->Eval();
804  if (error) {
805    lintree.mark_error("error in eval");
806  }
807  return result;
808}
809
810void ref_command(LinTree &lintree, int by) {
811  int op = lintree.get_int();
812  int argc = lintree.get_int();
813  if (argc >= 1)
814    updateref(lintree, by);
815  if (argc < 4) {
816    if (argc >= 2) updateref(lintree, by);
817    if (argc >= 3) updateref(lintree, by);
818  }
819}
820
821void dump_string(string str) {
822  printf("%d: ", (int)str.size());
823  for (int i=0; i<str.size(); i++) {
824    char ch = str[i];
825    if (ch < ' ' || ch >= 0x7f)
826      printf("#%02x", (int) ch & 0xff);
827    else
828      printf("%c", ch);
829  }
830  printf("\n");
831  fflush(stdout);
832}
833
834void encoding_error(const char* s) {
835  Werror("libthread encoding error: %s", s);
836}
837
838void decoding_error(const char* s) {
839  Werror("libthread decoding error: %s", s);
840}
841
842
843std::string to_string(leftv val) {
844  LinTree lintree;
845  encode(lintree, val);
846  if (lintree.has_error()) {
847    encoding_error(lintree.error_msg());
848    lintree.clear();
849    lintree.put_int(NONE);
850  }
851  return lintree.to_string();
852}
853
854leftv from_string(std::string &str) {
855  LinTree lintree(str);
856  leftv result = decode(lintree);
857  if (lintree.has_error()) {
858    decoding_error(lintree.error_msg());
859    result = new_leftv(NONE, 0L);
860  }
861  return result;
862}
863
864void init() {
865  install(NONE, encode_none, decode_none, ref_none);
866  install(INT_CMD, encode_int, decode_int, ref_int);
867  install(LIST_CMD, encode_list, decode_list, ref_list);
868  install(STRING_CMD, encode_string, decode_string, ref_string);
869  install(COMMAND, encode_command, decode_command, ref_command);
870  install(DEF_CMD, encode_def, decode_def, ref_def);
871  install(NUMBER_CMD, encode_number, decode_number, ref_number);
872  install(BIGINT_CMD, encode_bigint, decode_bigint, ref_bigint);
873  install(INTMAT_CMD, encode_intmat, decode_intmat, ref_intmat);
874  set_needs_ring(NUMBER_CMD);
875  install(RING_CMD, encode_ring, decode_ring, ref_ring);
876  install(POLY_CMD, encode_poly, decode_poly, ref_poly);
877  set_needs_ring(POLY_CMD);
878  install(IDEAL_CMD, encode_ideal, decode_ideal, ref_ideal);
879  set_needs_ring(IDEAL_CMD);
880}
881
882LinTree::LinTree() : cursor(0), memory(*new string()), error(NULL), last_ring(NULL) {
883}
884
885LinTree::LinTree(const LinTree &other) : cursor(0), memory(*new string(other.memory)), error(NULL), last_ring(NULL) {
886}
887
888LinTree& LinTree::operator =(const LinTree &other) {
889  cursor = other.cursor;
890  memory = *new string(other.memory);
891  error = NULL;
892  last_ring = NULL;
893  return *this;
894}
895
896LinTree::LinTree(std::string &source) :
897  cursor(0), memory(*new string(source)), error(NULL), last_ring(NULL) {
898}
899
900void LinTree::set_last_ring(void *r) {
901  if (last_ring)
902    rKill((ring) last_ring);
903  last_ring = r;
904  if (r) ((ring) r)->ref++;
905}
906
907LinTree::~LinTree() {
908  if (last_ring)
909    rKill((ring) last_ring);
910}
911
912}
Note: See TracBrowser for help on using the repository browser.