source: git/Singular/p_Procs.cc @ b0bcea

spielwiese
Last change on this file since b0bcea was b0bcea, checked in by Olaf Bachmann <obachman@…>, 23 years ago
* defaults for p_Procs git-svn-id: file:///usr/local/Singular/svn/trunk@4561 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 25.7 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    p_Procs.cc
6 *  Purpose: implementation of primitive procs for polys
7 *  Author:  obachman (Olaf Bachmann)
8 *  Created: 8/00
9 *  Version: $Id: p_Procs.cc,v 1.2 2000-08-24 15:31:22 obachman Exp $
10 *******************************************************************/
11#include "mod2.h"
12
13
14/***************************************************************
15 * 
16 * Configurations
17 *
18 *******************************************************************/
19
20/***************************************************************
21 Here is how it works:
22 At run-time, SetProcs is used to choose the appropriate PolyProcs
23              based on the ring properies.
24 At generate-time, SetProcs is used to generate all
25              possible PolyProcs.
26 Which PolyProcs are generated/used can be controled by values of
27 HAVE_FAST_P_PROCS, HAVE_FAST_LENGTH, HAVE_FAST_ORD, and FAST_FIELD
28 
29 At generate-time, the file p_Procs.inc is generated,
30 which provides implementations of the p_Procs, based on
31 the p_*_Templates.cc and header files which provide the respective
32 macros.
33
34 At run-time, a fast proc is set/choosen if found/generated, else
35 a general proc is set/choosen.
36 *******************************************************************/
37
38// Set HAVE_FAST_P_PROCS to:
39//   0 -- only FieldGeneral_LengthGeneral_OrdGeneral
40//   1 -- plus FieldZp_Length*_OrdGeneral procs
41//   2 -- plus FieldZp_Length*_Ord* procs
42//   3 -- plus Field*_Length*_OrdGeneral procs
43//   4 -- all Field*_Length*_Ord* procs
44const int HAVE_FAST_P_PROCS = 2;
45
46// Set HAVE_FAST_FIELD to:
47//   0 -- only FieldGeneral
48//   1 -- special cases for FieldZp
49//   nothing else is implemented, yet
50const int HAVE_FAST_FIELD = 1;
51
52// Set HAVE_FAST_LENGTH to:
53//   0 -- only LengthGeneral
54//   1 -- special cases for length <= 1
55//   2 -- special cases for length <= 2
56//   3 -- special cases for length <= 4
57//   4 -- special cases for length <= 8
58const int HAVE_FAST_LENGTH = 3;
59
60// Set HAVE_FAST_ORD to:
61//  0  -- only OrdGeneral
62//  1  -- special for ords with n_min <= 1
63//  2  -- special for ords with n_min <= 2
64//  3  -- special ords for with n_min <= 3
65//  4  -- special for all ords
66const int HAVE_FAST_ORD = 4;
67
68// undefine this, if ExpLSize always equals CompLSize
69#define HAVE_LENGTH_DIFF
70// Set HAVE_FAST_ZERO_ORD to:
71//  0 -- no zero ords are considered
72//  1 -- only ZeroOrds for OrdPosNomogPosZero, OrdNomogPosZero, OrdPomogNegZero
73//  2 -- ZeroOrds for all
74const int HAVE_FAST_ZERO_ORD = 1;
75
76// Predicate which returns true if alloc/copy/free of numbers is
77// like that of Zp
78#define ZP_COPY_FIELD(field) \
79  (field == FieldZp || field == FieldGF || field == FieldR)
80
81/***************************************************************
82 * 
83 * Definitions of our fields, lengths, ords, procs we work with
84 *
85 *******************************************************************/
86
87// Here are the different parameters for setting the PolyProcs:
88
89// If you add/remove things from here, also remeber to adjust the
90// respective *_2_String
91typedef enum p_Field
92{
93  FieldGeneral = 0,
94  FieldZp,         
95  FieldR,
96  FieldGF,
97#if HAVE_MORE_FIELDS_IMPLEMENTED
98  FieldQ,
99  FieldLong_R,
100  FieldLong_C,
101  FieldZp_a,
102  FieldQ_a,
103#endif
104  FieldUnknown
105};
106typedef enum p_Length // Length of exponent vector in words
107{
108  LengthGeneral = 0, // n >= 1
109  LengthEight,       // n == 8   
110  LengthSeven,
111  LengthSix,
112  LengthFive,
113  LengthFour,
114  LengthThree,
115  LengthTwo,
116  LengthOne,
117  LengthUnknown
118};
119typedef enum p_Ord 
120{                   
121  OrdGeneral = 0,   
122                    //     ordsgn   
123                    //  0   1   i   n-1 n   n_min   Example
124  OrdPomog,         //  +   +   +   +   +   1       (lp,C)
125  OrdNomog,         //  -   -   -   -   -   1       (ls, c), (ds, c)
126#define ORD_MAX_N_1 OrdNomog
127
128#ifdef HAVE_LENGTH_DIFF
129  OrdPomogZero,     //  +   +   +   +   0   2       (Dp, C), Even vars
130  OrdNomogZero,     //  -   -   -   -   0   2       (ds, c), Even vars
131#endif
132
133  OrdNegPomog,      //  -   +   +   +   +   2       (c, lp), (Ds, c)
134  OrdPomogNeg,      //  +   +   +   +   -   2       (lp, c)
135#define ORD_MAX_N_2 OrdPomogNeg
136
137  OrdPosNomog,      //  +   -   -   -   +   3       (dp, c) (for n == 2, use PomogNeg)
138  OrdNomogPos,      //  -   -   -   -   +   3       (ls, C) (for n == 2, use NegPomog)
139
140#ifdef HAVE_LENGTH_DIFF
141  OrdNegPomogZero,  //  -   +   +   +   0   3       (c, lp), (Ds, c)
142  OrdPomogNegZero,  //  +   +   +   -   0   3       (lp, c)
143#endif
144
145  OrdPosPosNomog,   //  +   +   -   -   -   3       (C, dp)
146  OrdPosNomogPos,   //  +   -   -   -   +   3       (dp, C)
147  OrdNegPosNomog,   //  -   +   -   -   -   3       (c, dp)
148#define ORD_MAX_N_3 OrdNegPosNomog
149
150#ifdef HAVE_LENGTH_DIFF
151  OrdNomogPosZero,  //  -   -   -   +   0   4       (ls, C) (for n == 3, use NegPomogZero)
152  OrdPosNomogZero,  //  +   -   -   -   0   4       (dp, c) (for n == 3, use PomogNegZero)
153
154  OrdPosPosNomogZero,// +   +   -   -   0   4       (C, dp)
155  OrdPosNomogPosZero,// +   -   -   +   0   4       (dp, C)
156  OrdNegPosNomogZero,// -   +   -   -   0   4       (c, dp)
157#endif
158
159  OrdUnknown
160};
161
162typedef enum p_Proc
163{
164  p_Copy_Proc = 0,
165  p_Delete_Proc,
166  p_ShallowCopyDelete_Proc,
167  p_Mult_n_Proc,
168  p_Mult_m_Proc,
169  p_Add_q_Proc,
170  p_Minus_m_Mult_q_Proc,
171  p_Unknown_Proc
172};
173
174// *_2_String conversions of these enums
175// they are only needed at for GENERATE_P_PROCS or RDEBUG
176#if defined(GENERATE_P_PROCS) || defined(RDEBUG)
177char* p_FieldEnum_2_String(p_Field field)
178{
179  switch(field)
180  {
181      case FieldGeneral: return "FieldGeneral";
182      case FieldZp: return "FieldZp";         
183      case FieldR: return "FieldR";
184      case FieldGF: return "FieldGF";
185#if HAVE_MORE_FIELDS_IMPLEMENTED
186      case FieldQ: return "FieldQ";
187      case FieldLong_R: return "FieldLong_R";
188      case FieldLong_C: return "FieldLong_C";
189      case FieldZp_a: return "FieldZp_a";
190      case FieldQ_a: return "FieldQ_a";
191#endif
192      case FieldUnknown: return "FieldUnknown";
193  }
194  return "NoField_2_String";
195}
196
197char* p_LengthEnum_2_String(p_Length length)
198{
199  switch(length)
200  {
201      case LengthGeneral: return "LengthGeneral"; 
202      case LengthEight: return "LengthEight";       
203      case LengthSeven: return "LengthSeven";
204      case LengthSix: return "LengthSix";
205      case LengthFive: return "LengthFive";
206      case LengthFour: return "LengthFour";
207      case LengthThree: return "LengthThree";
208      case LengthTwo: return "LengthTwo";
209      case LengthOne: return "LengthOne";
210      case LengthUnknown: return "LengthUnknown";
211  }
212  return "NoLength_2_String";
213}
214
215char* p_OrdEnum_2_String(p_Ord ord)
216{
217  switch(ord)
218  {
219      case OrdGeneral: return "OrdGeneral";   
220      case OrdPomog: return "OrdPomog";         
221      case OrdNomog: return "OrdNomog";         
222      case OrdNegPomog: return "OrdNegPomog";     
223      case OrdPomogNeg: return "OrdPomogNeg";     
224      case OrdPosNomog: return "OrdPosNomog";     
225      case OrdNomogPos: return "OrdNomogPos";     
226      case OrdPosPosNomog: return "OrdPosPosNomog";   
227      case OrdPosNomogPos: return "OrdPosNomogPos";   
228      case OrdNegPosNomog: return "OrdNegPosNomog";   
229#ifdef HAVE_LENGTH_DIFF
230      case OrdNegPomogZero: return "OrdNegPomogZero"; 
231      case OrdPomogNegZero: return "OrdPomogNegZero"; 
232      case OrdPomogZero: return "OrdPomogZero";     
233      case OrdNomogZero: return "OrdNomogZero";     
234      case OrdNomogPosZero: return "OrdNomogPosZero"; 
235      case OrdPosNomogZero: return "OrdPosNomogZero"; 
236      case OrdPosPosNomogZero: return "OrdPosPosNomogZero";
237      case OrdPosNomogPosZero: return "OrdPosNomogPosZero";
238      case OrdNegPosNomogZero: return "OrdNegPosNomogZero";
239#endif
240      case OrdUnknown: return "OrdUnknown";
241  }
242  return "NoOrd_2_String";
243}
244
245char* p_ProcEnum_2_String(p_Proc proc)
246{
247  switch(proc)
248  {
249      case p_Copy_Proc: return "p_Copy_Proc";
250      case p_Delete_Proc: return "p_Delete_Proc";
251      case p_ShallowCopyDelete_Proc: return "p_ShallowCopyDelete_Proc";
252      case p_Mult_n_Proc: return "p_Mult_n_Proc";
253      case p_Mult_m_Proc: return "p_Mult_m_Proc";
254      case p_Add_q_Proc: return "p_Add_q_Proc";
255      case p_Minus_m_Mult_q_Proc: return "p_Minus_m_Mult_q_Proc";
256      case p_Unknown_Proc: return "p_Unknown_Proc";
257  }
258  return "NoProc_2_String";
259}
260#endif // defined(GENERATE_P_PROCS) || defined(RDEBUG)
261
262
263#ifdef GENERATE_P_PROCS
264#include <stdio.h>
265#define assume_violation(f, l)  do{fprintf(stderr, "assume violation: %s:%d\n", f, l);exit(1);}while(0)
266#endif
267
268/***************************************************************
269 * 
270 *
271 * Deal with OrdZero
272 *
273 *******************************************************************/
274#ifdef HAVE_LENGTH_DIFF
275static inline int IsZeroOrd(p_Ord ord)
276{
277  return (ord == OrdPomogZero || ord == OrdNomogZero ||
278          ord == OrdNegPomogZero || ord == OrdPosNomogZero ||
279          ord == OrdPomogNegZero || ord == OrdNomogPosZero ||
280          ord == OrdPosNomogPosZero || ord == OrdPosPosNomogZero ||
281          ord == OrdNegPosNomogZero);
282}
283
284static inline p_Ord ZeroOrd_2_NonZeroOrd(p_Ord ord, int strict)
285{
286  if (IsZeroOrd(ord))
287  {
288    switch (ord)
289    {
290        case OrdPomogZero:      return OrdPomog;
291        case OrdNomogZero:      return OrdNomog;
292        case OrdNegPomogZero:   return OrdNegPomog;
293        case OrdPosNomogZero:   return OrdPosNomog;
294        case OrdPosPosNomogZero:    return OrdPosPosNomog;
295        case OrdNegPosNomogZero:    return OrdNegPosNomog;
296        default:   
297          if (strict) return OrdGeneral;
298          else if (ord == OrdPomogNegZero) return OrdPomogNeg;
299          else if (ord == OrdNomogPosZero) return OrdNomogPos;
300          else if (ord == OrdPosNomogPosZero) return OrdPosNomogPos;
301          else return OrdGeneral;
302    }
303  }
304  else
305  {
306    return ord;
307  }
308}
309#else
310#define IsZeroOrd(ord) 0
311#define ZeroOrd_2_NonZeroOrd(ord) (ord)
312#endif
313
314/***************************************************************
315 * 
316 * Filters which are applied to field/length/ord, before a proc is
317 * choosen
318 *
319 *******************************************************************/
320static inline void FastP_ProcsFilter(p_Field &field, p_Length &length, p_Ord &ord)
321{
322  if (HAVE_FAST_P_PROCS >= 4) return;
323 
324  if ((HAVE_FAST_P_PROCS == 0) ||
325      (HAVE_FAST_P_PROCS <= 3 && field != FieldZp))
326  {
327    field = FieldGeneral;
328    length = LengthGeneral;
329    ord = OrdGeneral;
330    return;
331  }
332  if (HAVE_FAST_P_PROCS == 1 || (HAVE_FAST_P_PROCS == 3 && field != FieldZp))
333    ord = OrdGeneral;
334}
335
336static inline void FastFieldFilter(p_Field &field)
337{
338  if (HAVE_FAST_FIELD == 0 || field != FieldZp)
339    field = FieldGeneral;
340}
341     
342static inline void FastLengthFilter(p_Length &length)
343{
344  if ((HAVE_FAST_LENGTH == 3 && length <= LengthFive) ||
345      (HAVE_FAST_LENGTH == 2 && length <= LengthFour) ||
346      (HAVE_FAST_LENGTH == 1 && length <= LengthTwo) ||
347      (HAVE_FAST_LENGTH <= 0))
348  {
349    length = LengthGeneral;
350  }
351}
352
353static inline void FastOrdFilter(p_Ord &ord)
354{
355  if ((HAVE_FAST_ORD == 3 && ord >= OrdNomogPosZero) ||
356      (HAVE_FAST_ORD == 2 && ord >= OrdPosNomog) ||
357      (HAVE_FAST_ORD == 1 && ord >= OrdPomogZero) ||
358      (HAVE_FAST_ORD <= 0))
359    ord = OrdGeneral;
360}
361
362static inline void FastOrdZeroFilter(p_Ord &ord)
363{
364  if (IsZeroOrd(ord))
365  {
366    if ((HAVE_FAST_ZERO_ORD == 1 && (ord != OrdPosNomogPosZero && 
367                                     ord != OrdNomogPosZero && 
368                                     ord != OrdPomogNegZero)) ||
369        (HAVE_FAST_ZERO_ORD <= 0))
370      ord = ZeroOrd_2_NonZeroOrd(ord, 1);
371  }
372}
373
374static inline void NCopy__Filter(p_Field &field)
375{
376  if (ZP_COPY_FIELD(field)) field = FieldZp;
377}
378
379// in p_Add_q, p_MemCmp works with CompLSize,
380// hence, we do not need to consider ZeroOrds
381static inline void p_Add_q__Filter(p_Length &length, p_Ord &ord)
382{
383  if (IsZeroOrd(ord))
384  {
385    ord = ZeroOrd_2_NonZeroOrd(ord, 0);
386    if (length > LengthGeneral)
387    {
388      length = (p_Length) ((int)length + 1);
389    }
390  }
391}
392
393static inline void FastProcFilter(p_Proc proc, p_Field &field, p_Length &length, 
394                                   p_Ord &ord)
395{
396  switch(proc)
397  {
398      case p_Add_q_Proc:
399        p_Add_q__Filter(length, ord);
400        break;
401       
402      case p_Copy_Proc:
403      case p_Delete_Proc:
404        NCopy__Filter(field);
405        break;
406       
407      default: break;
408  }
409
410  FastOrdFilter(ord);
411  FastLengthFilter(length);
412  FastFieldFilter(field);
413  FastP_ProcsFilter(field, length, ord);
414}
415
416// returns 1 if combination of field/length/ord is invalid
417static inline int IsValidSpec(p_Field field, p_Length length, p_Ord ord)
418{
419  if (field == FieldUnknown || length == LengthUnknown || ord == OrdUnknown)
420    return 0;
421
422  if (length >= LengthThree && // i.e. 1, 2, or 3
423      ord > ORD_MAX_N_3)       //  i.e. OrdNomogPosZero and below
424    return 0;
425 
426  if (length >= LengthTwo &&    // i.e. 1 or 2
427      ord > ORD_MAX_N_2)        // i.e. PosNomog and below
428    return 0;
429
430  if (length == LengthOne && 
431      ord > ORD_MAX_N_1)           // i.e. PosPomogZero and below
432    return 0;
433
434  // we cover everything for length <= two
435  if (ord == OrdGeneral && length >= LengthTwo)
436    return 0;
437  return 1;
438}
439
440 
441static inline int index(p_Field field, p_Length length)
442{
443  return field*LengthUnknown + length;
444}
445
446static inline int index(p_Field field, p_Length length, p_Ord ord)
447{
448  return field*LengthUnknown*OrdUnknown + length*OrdUnknown + ord;
449}
450
451static inline int index(p_Proc proc, p_Field field, p_Length length, p_Ord ord)
452{
453  switch(proc)
454  {
455      case p_Delete_Proc:
456      case p_Mult_n_Proc:
457        return field;
458       
459      case p_ShallowCopyDelete_Proc:
460        return length;
461       
462      case p_Copy_Proc:
463      case p_Mult_m_Proc:
464        return index(field, length);
465
466      case p_Add_q_Proc:
467      case p_Minus_m_Mult_q_Proc:
468        return index(field, length, ord);
469       
470      default:
471        assume(0);
472        return -1;
473  }
474}
475
476// The procedure which does the work of choosing/generating a
477// set of poly procs
478static void SetProcs(p_Field field, p_Length length, p_Ord ord);
479
480
481#ifndef GENERATE_P_PROCS
482
483/***************************************************************
484 *
485 * Runtime stuff
486 *
487 ***************************************************************/
488#include "structs.h"
489#include "ring.h"
490#include "polys.h"
491#include "polys-impl.h"
492#include "p_Procs.h"
493#include "p_Numbers.h"
494#include "p_MemCmp.h"
495#include "p_MemAdd.h"
496#include "p_MemCopy.h"
497#define FreeAndAdvance(p)                       \
498do                                              \
499{                                               \
500  poly _pn = pNext(p);                          \
501  omFreeBinAddr(p);                             \
502  p = _pn;                                      \
503}                                               \
504while (0)
505
506// now include the generated pprocs
507extern int rComp0_Func(poly p1,poly p2);
508#undef rComp0
509#define rComp0 rComp0_Func
510#include "p_Procs.inc"
511
512// the rest is related to getting the procs
513static inline p_Field p_FieldIs(ring r)
514{
515  if (rField_is_Zp(r)) return FieldZp;         
516  if (rField_is_R(r)) return FieldR;
517  if (rField_is_GF(r)) return FieldGF;
518#ifdef HAVE_MORE_FIELDS_IMPLEMENTED
519  if (rField_is_Q(r)) return FieldQ;
520  if (rField_is_long_R(r)) return FieldLong_R;
521  if (rField_is_long_C(r)) return FieldLong_C;
522  if (rField_is_Zp_a(r)) return FieldZp_a;
523  if (rField_is_Q_a(r)) return FieldQ_a;
524#endif
525  return FieldGeneral;
526}
527
528static inline p_Length p_LengthIs(ring r)
529{
530  assume(r->ExpLSize > 0);
531  if (r->ExpLSize == 1) return LengthOne;
532  if (r->ExpLSize == 2) return LengthTwo;
533  if (r->ExpLSize == 3) return LengthThree;
534  if (r->ExpLSize == 4) return LengthFour;
535  if (r->ExpLSize == 5) return LengthFive;
536  if (r->ExpLSize == 6) return LengthSix;
537  if (r->ExpLSize == 7) return LengthSeven;
538  if (r->ExpLSize == 8) return LengthEight;
539  return LengthGeneral;
540}
541
542static inline int p_IsNomog(long* sgn, int l)
543{
544  int i;
545  for (i=0;i<l;i++)
546    if (sgn[i] > 0) return 0;
547 
548  return 1;
549}
550
551static inline int p_IsPomog(long* sgn, int l)
552{
553  int i;
554  for (i=0;i<l;i++)
555    if (sgn[i] < 0) return 0;
556  return 1;
557}
558
559static inline p_Ord p_OrdIs(ring r)
560{
561  long* sgn = r->ordsgn;
562  long l = r->ExpLSize;
563  int zero = 0;
564 
565  if (sgn[l-1] == 0) 
566  {
567    l--;
568    zero = 1;
569  }
570 
571  // we always favour the pomog cases
572  if (p_IsPomog(sgn,l)) return (zero ? OrdPomogZero : OrdPomog);
573  if (p_IsNomog(sgn,l)) return (zero ? OrdNomogZero : OrdNomog);
574 
575  assume(l > 1);
576 
577  if (sgn[0] == -1 && p_IsPomog(&sgn[1], l-1))
578    return (zero ? OrdNegPomogZero : OrdNegPomog);
579  if (sgn[l-1] == -1 && p_IsPomog(sgn, l-1))
580    return (zero ? OrdPomogNegZero : OrdPomogNeg);
581
582  if (sgn[0] == 1 && p_IsNomog(&sgn[1], l-1)) 
583    return (zero ? OrdPosNomogZero : OrdPosNomog);
584  if (sgn[l-1] == 1 && p_IsNomog(sgn, l-1))
585    return (zero ? OrdNomogPosZero : OrdNomogPos);
586
587  assume(l > 2);
588 
589  if (sgn[0] == 1 && sgn[1] == 1 && p_IsNomog(&sgn[2], l-2))
590    return (zero ? OrdPosPosNomogZero : OrdPosPosNomog);
591
592  if (sgn[0] == 1 && sgn[l-1] == 1 && p_IsNomog(&sgn[1], l-2))
593    return (zero ? OrdPosNomogPosZero : OrdPosNomogPos);
594
595  if (sgn[0] == -1 && sgn[1] == 0 && p_IsNomog(&sgn[2], l-2))
596    return (zero ? OrdNegPosNomogZero : OrdNegPosNomog);
597
598  return OrdGeneral;
599}
600 
601static p_Procs_s *_p_procs;
602// Choose a set of p_Procs
603void p_SetProcs(ring r, p_Procs_s* p_Procs)
604{
605  p_Field     field = p_FieldIs(r);
606  p_Length    length = p_LengthIs(r);
607  p_Ord       ord = p_OrdIs(r);
608 
609  assume(p_Procs != NULL);
610#ifdef RDEBUG
611  memset(p_Procs, 0, sizeof(p_Procs_s));
612#endif
613  _p_procs = p_Procs;
614  assume(IsValidSpec(field, length, ord));
615
616  SetProcs(field, length, ord);
617  assume(
618    (p_Procs->p_Delete != NULL) &&
619    (p_Procs->p_ShallowCopyDelete != NULL) &&
620    (p_Procs->p_Mult_n != NULL) &&
621    (p_Procs->p_Copy != NULL) &&
622    (p_Procs->p_Mult_m != NULL) &&
623    (p_Procs->p_Add_q != NULL) &&
624    (p_Procs->p_Minus_m_Mult_q != NULL));
625}
626
627#ifdef RDEBUG
628void p_Debug_GetSpecNames(const ring r, char* &field, char* &length, char* &ord)
629{
630  p_Field     e_field = p_FieldIs(r);
631  p_Length    e_length = p_LengthIs(r);
632  p_Ord       e_ord = p_OrdIs(r);
633 
634  field  = p_FieldEnum_2_String(p_FieldIs(r));
635  length = p_LengthEnum_2_String(p_LengthIs(r));
636  ord    = p_OrdEnum_2_String(p_OrdIs(r));
637}
638// like SetProcs, only that names are set
639static int set_names = 0;
640void p_Debug_GetProcNames(const ring r, p_Procs_s* p_Procs)
641{
642  set_names = 1;
643  p_SetProcs(r, p_Procs);
644  set_names = 0;
645}
646#endif // RDEBUG
647
648#define __SetProc(what, type, field, length, ord) \
649  _p_procs->what = (what##_Proc_Ptr) what##_Proc_##type [index(what##_Proc, field, length, ord)]
650
651#define ___SetProc(what, field, length, ord) __SetProc(what, funcs, field, length, ord)
652
653#ifdef RDEBUG
654#define _SetProc(what, field, length, ord)      \
655do                                              \
656{                                               \
657  if (set_names)                                \
658    __SetProc(what, names, field, length, ord); \
659  else                                          \
660    ___SetProc(what, field, length, ord);       \
661}                                               \
662while(0)
663#else
664#define _SetProc ___SetProc
665#endif
666
667#else /* GENERATE_P_PROCS */
668/***************************************************************
669 *
670 * generate time stuff
671 *
672 ***************************************************************/
673#include <stdio.h>
674#include <stdlib.h>
675#include <string.h>
676
677char*** generated_p_procs;
678
679inline int AlreadyHaveProc(p_Proc proc, p_Field field, p_Length length, p_Ord ord)
680{
681  return (generated_p_procs[proc])[index(proc, field, length, ord)] != 0;
682}
683
684const char* macros_field[] = {"p_nCopy","p_nDelete", "p_nMult", "p_nAdd", "p_nSub", "p_nIsZero", "p_nEqual" , "p_nNeg", NULL};
685
686const char* macros_length[] =
687{"p_MemCopy", "p_MemAdd", NULL};
688
689const char* macros_length_ord[] = {"p_MemCmp", NULL};
690int DummyProcs = 0;
691
692void AddProc(const char* s_what, p_Proc proc, p_Field field, p_Length length, p_Ord ord)
693{
694  int i;
695  const char* s_length = p_LengthEnum_2_String(length);
696  const char* s_ord = p_OrdEnum_2_String(ord);
697  const char* s_field = p_FieldEnum_2_String(field);
698  char* s_full_proc_name = (char*) malloc(200);
699 
700  sprintf(s_full_proc_name, "%s__%s_%s_%s", s_what, s_field, s_length, s_ord);
701             
702  (generated_p_procs[proc])[index(proc, field, length, ord)] = s_full_proc_name;
703 
704  // define all macros
705  printf("\n// definition of %s\n", s_full_proc_name);
706  i = 0;
707  while (macros_field[i] != NULL)
708  {
709    printf("#undef %s\n#define %s\t%s_%s\n", 
710           macros_field[i], macros_field[i],  macros_field[i], s_field);
711    i++;
712  }
713  i = 0;
714  while (macros_length[i] != NULL)
715  {
716    printf("#undef %s\n#define %s\t%s_%s\n", 
717           macros_length[i], macros_length[i], macros_length[i], s_length);
718    i++;
719  }
720  i = 0;
721  while (macros_length_ord[i] != NULL)
722  {
723    printf("#undef %s\n#define %s\t%s_%s_%s\n", 
724           macros_length_ord[i], macros_length_ord[i], macros_length_ord[i], s_length, s_ord);
725    i++;
726  }
727
728  // define DECLARE_LENGTH
729  printf("#undef DECLARE_LENGTH\n");
730  if (length != LengthGeneral)
731    printf("#define DECLARE_LENGTH(what) ((void)0)\n");
732  else
733    printf("#define DECLARE_LENGTH(what) what\n");
734 
735  // define DECLARE_ORDSGN
736  printf("#undef DECLARE_ORDSGN\n");
737  if (ord != OrdGeneral)
738    printf("#define DECLARE_ORDSGN(what) ((void)0)\n");
739  else
740    printf("#define DECLARE_ORDSGN(what) what\n");
741
742  // define p_Mult_m, for p_Minus_m_Mult_q
743  if (strcmp(s_what, "p_Minus_m_Mult_q") == 0)
744  {
745    printf("#undef p_Mult_m\n");
746    printf("#define p_Mult_m p_Mult_m__%s_%s_OrdGeneral\n", s_field, s_length);
747  }
748  printf("#undef %s\n#define %s %s\n", s_what, s_what, s_full_proc_name);
749  printf("#include \"%s__Template.cc\"\n", s_what);
750  printf("#undef %s\n#undef p_Mult_m\n", s_what);
751}
752
753void GenerateProc(const char* s_what, p_Proc proc, p_Field field, p_Length length, p_Ord ord)
754{
755  if (! AlreadyHaveProc(proc, field, length, ord))
756    AddProc(s_what, proc, field, length, ord);
757}
758
759int main()
760{
761  int field;
762  int length; 
763  int ord;
764  int i, j;
765  int NumberOfHaveProcs = 0;
766 
767 
768  printf("/* -*-c++-*- */\n");
769  printf("/***************************************************************\n");
770  printf(" This file was generated automatically by p_Procs.cc: DO NOT EDIT\n\n");
771  printf(" This file provides the needed implementation of p_Procs\n");
772  printf(" See the end for a summary. \n");
773  printf("*******************************************************************/\n");
774
775  generated_p_procs = (char***) malloc(p_Unknown_Proc*sizeof(char**));
776  for (i=0; i<p_Unknown_Proc; i++)
777  {
778    generated_p_procs[i] = 
779      (char**) calloc(index((p_Proc)i, FieldUnknown, LengthUnknown, OrdUnknown), sizeof(char*));
780  }
781 
782  // set default procs
783  for (field = 0; field < (int) FieldUnknown; field++)
784  {
785    for (length=0; length < (int) LengthUnknown; length++)
786    {
787      for (ord=0; ord < (int)OrdUnknown; ord++)
788      {
789        if (IsValidSpec((p_Field) field, (p_Length) length, (p_Ord) ord))
790            SetProcs((p_Field) field, (p_Length) length, (p_Ord) ord);
791      }
792    }
793  }
794
795  printf("
796/***************************************************************
797  Names of procs for RDEBUG */
798#ifdef RDEBUG\n");
799
800  for (i=0; i<p_Unknown_Proc; i++)
801  {
802    printf("static const char* %s_names[] = {", p_ProcEnum_2_String((p_Proc)i));
803    for (j=0;j<index((p_Proc)i, FieldUnknown, LengthUnknown, OrdUnknown); j++)
804    {
805      char* s = (generated_p_procs[i])[j];
806      if (s != 0)
807      {
808        printf("\n\"%s\",", s);
809      }
810      else
811        printf("0,");
812         
813    }
814    printf("\n};\n");
815  }
816  printf("
817#endif // RDEBUG
818
819
820/***************************************************************/
821/* Tables for lookup of procedures: */\n");
822
823  for (i=0; i<p_Unknown_Proc; i++)
824  {
825    printf("static const %s_Ptr %s_funcs[] = {", p_ProcEnum_2_String((p_Proc)i), p_ProcEnum_2_String((p_Proc)i));
826    for (j=0;j<index((p_Proc)i, FieldUnknown, LengthUnknown, OrdUnknown); j++)
827    {
828      char* s = (generated_p_procs[i])[j];
829      if (s != 0)
830      {
831        NumberOfHaveProcs++;
832        printf("\n%s,", s);
833      }
834      else
835        printf("0,");
836         
837    }
838    printf("\n};\n");
839  }
840  printf("
841/***************************************************************
842 * Summary:
843 *   HAVE_FAST_P_PROCS  = %d,
844 *   HAVE_FAST_FIELD    = %d,
845 *   HAVE_FAST_LENGTH   = %d,
846 *   HAVE_FAST_ORD      = %d,
847 *   HAVE_FAST_ZERO_ORD = %d
848 *   
849 *   Generated PolyProcs= %d
850 *
851 *******************************************************************/\n",
852         HAVE_FAST_P_PROCS, HAVE_FAST_FIELD, HAVE_FAST_LENGTH, HAVE_FAST_ORD, HAVE_FAST_ZERO_ORD,
853         NumberOfHaveProcs);
854}
855
856#define _SetProc(what, field, length, ord) \
857      GenerateProc(#what, what##_Proc, field, length, ord)
858#endif // GENERATE_P_PROCS
859
860/***************************************************************
861 *
862 * Setting the procedures
863 *
864 ***************************************************************/
865
866#define SetProc(what, field, length, ord)                   \
867do                                                          \
868{                                                           \
869  p_Field t_field = field;                                  \
870  p_Ord t_ord = ord;                                        \
871  p_Length t_length = length;                               \
872  FastProcFilter(what##_Proc, t_field, t_length, t_ord);   \
873  _SetProc(what, t_field, t_length, t_ord);                 \
874}                                                           \
875while (0)                                                   \
876 
877static void SetProcs(p_Field field, p_Length length, p_Ord ord)
878{
879  SetProc(p_Delete, field, LengthGeneral, OrdGeneral);
880  SetProc(p_Mult_n, field, LengthGeneral, OrdGeneral);
881  SetProc(p_ShallowCopyDelete, FieldGeneral, length, OrdGeneral);
882  SetProc(p_Copy, field, length, OrdGeneral);
883  SetProc(p_Mult_m, field, length, OrdGeneral);
884  SetProc(p_Add_q, field, length, ord);
885  SetProc(p_Minus_m_Mult_q, field, length, ord);
886}
887
888
889
Note: See TracBrowser for help on using the repository browser.