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

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