source: palm/trunk/UTIL/chemistry/gasphase_preproc/kpp/src/code.c @ 3538

Last change on this file since 3538 was 2696, checked in by kanani, 7 years ago

Merge of branch palm4u into trunk

File size: 17.6 KB
Line 
1/******************************************************************************
2
3  KPP - The Kinetic PreProcessor
4        Builds simulation code for chemical kinetic systems
5
6  Copyright (C) 1995-1996 Valeriu Damian and Adrian Sandu
7  Copyright (C) 1997-2005 Adrian Sandu
8
9  KPP is free software; you can redistribute it and/or modify it under the
10  terms of the GNU General Public License as published by the Free Software
11  Foundation (http://www.gnu.org/copyleft/gpl.html); either version 2 of the
12  License, or (at your option) any later version.
13
14  KPP is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  details.
18
19  You should have received a copy of the GNU General Public License along
20  with this program; if not, consult http://www.gnu.org/copyleft/gpl.html or
21  write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  Boston, MA  02111-1307,  USA.
23
24  Adrian Sandu
25  Computer Science Department
26  Virginia Polytechnic Institute and State University
27  Blacksburg, VA 24060
28  E-mail: sandu@cs.vt.edu
29
30******************************************************************************/
31
32
33#include "gdata.h"
34#include "code.h"
35#include <unistd.h>
36#include <string.h>
37
38/*            NONE, ADD, SUB, MUL, DIV, POW, CONST, ELM, VELM, MELM, EELM  */
39int PRI[] = {   10,   1,   1,   2,   2,   3,    10,  10,   10,   10,   10 };
40
41void (*WriteElm)( NODE *n );
42void (*WriteSymbol)( int op );
43void (*WriteAssign)( char* lval, char* rval );
44void (*WriteComment)( char *fmt, ...  );
45void (*Declare)( int v );
46void (*ExternDeclare)( int v );
47void (*GlobalDeclare)( int v );
48void (*InitDeclare)( int var, int nv, void * values );
49void (*DeclareConstant)( int v, char *val );
50void (*FunctionStart)( int f, int *vars );
51void (*FunctionPrototipe)( int f, ... );
52void (*FunctionBegin)( int f, ... );
53void (*FunctionEnd)( int f );
54
55NODE * substList;
56int substENABLED = 1;
57int crtop = NONE;
58char *outBuf;
59char *outBuffer;
60
61VARIABLE cnst = { "", CONST, REAL, 0, 0 };
62VARIABLE expr = { "", EELM, 0, 0, 0 };
63VARIABLE *varTable[ MAX_VAR ] = { &cnst, &expr };
64
65int IsConst( NODE *n, float val );
66NODE * BinaryOp( int op, NODE *n1, NODE *n2 );
67int NodeCmp( NODE *n1, NODE *n2 );
68NODE * NodeCopy( NODE *n1 );
69void WriteNode( NODE *n );
70void WriteOp( int op );
71void ExpandElm( NODE * n );
72int ExpandNode( NODE *n, int lastop );
73NODE * LookUpSubst( NODE *n );
74
75FILE * param_headerFile   = 0;
76FILE * initFile = 0; /*  mz_rs_20050117 */
77FILE * driverFile = 0;
78FILE * integratorFile = 0;
79FILE * linalgFile = 0;
80FILE * functionFile = 0;
81FILE * jacobianFile = 0;
82FILE * rateFile = 0;
83FILE * stoichiomFile = 0;
84FILE * utilFile = 0;
85FILE * sparse_dataFile = 0;
86FILE * sparse_jacFile = 0;
87FILE * sparse_hessFile = 0;
88FILE * sparse_stoicmFile = 0;
89FILE * stochasticFile = 0;
90FILE * global_dataFile = 0;
91FILE * hessianFile = 0;
92FILE * mapFile = 0;
93FILE * makeFile = 0;
94FILE * monitorFile = 0;
95FILE * mex_funFile = 0;
96FILE * mex_jacFile = 0;
97FILE * mex_hessFile = 0;
98
99FILE * currentFile;
100
101int ident = 0;
102
103FILE * UseFile( FILE * file )
104{
105FILE *oldf;
106    if (file == NULL) {
107      printf("\n\nKPP Warning (internal): trying to UseFile NULL file pointer!\n");
108    }
109    oldf = currentFile;
110    currentFile = file; 
111    return oldf;
112}
113 
114void OpenFile( FILE **fpp, char *name, char * ext, char * identity )
115{
116char bufname[200];
117char buf[200];
118time_t t;
119int blength;
120
121  time( &t );
122  sprintf( bufname, "%s%s", name, ext ); 
123  if( *fpp ) fclose( *fpp );
124  *fpp = fopen( bufname, "w" );
125  if ( *fpp == 0 ) 
126    FatalError(3,"%s: Can't create file", bufname );
127 
128  UseFile( *fpp );
129 
130  WriteDelim();
131  WriteComment("");
132  WriteComment("%s",identity);
133  WriteComment("");
134  WriteComment("Generated by KPP-%s symbolic chemistry Kinetics PreProcessor",
135                KPP_VERSION );
136  WriteComment("      (http://www.cs.vt.edu/~asandu/Software/KPP)");
137  WriteComment("KPP is distributed under GPL, the general public licence");
138  WriteComment("      (http://www.gnu.org/copyleft/gpl.html)");
139  WriteComment("(C) 1995-1997, V. Damian & A. Sandu, CGRER, Univ. Iowa" );
140  WriteComment("(C) 1997-2005, A. Sandu, Michigan Tech, Virginia Tech" );
141  WriteComment("    With important contributions from:" );
142  WriteComment("       M. Damian, Villanova University, USA");
143  WriteComment("       R. Sander, Max-Planck Institute for Chemistry, Mainz, Germany");
144  WriteComment("");
145  WriteComment("%-20s : %s", "File", bufname );
146  strcpy( buf, (char*)ctime( &t ) ); 
147  buf[ (int)strlen(buf) - 1 ] = 0;
148  WriteComment("%-20s : %s", "Time", buf );
149  WriteComment("%-20s : %s", "Working directory", getcwd(buf, 200) );
150  WriteComment("%-20s : %s", "Equation file", eqFileName );
151  WriteComment("%-20s : %s", "Output root filename", rootFileName );
152  WriteComment("");
153  WriteDelim();
154  NewLines(1); 
155/* Include Headers in .c  Files, except Makefile */
156  blength = strlen(bufname);
157  if ( (bufname[blength-2]=='.')&&(bufname[blength-1]=='c') ) {
158    C_Inline("#include <stdio.h>");
159    C_Inline("#include <stdlib.h>");
160    C_Inline("#include <math.h>");
161    C_Inline("#include <string.h>");
162    C_Inline("#include \"%s_Parameters.h\"", rootFileName);
163    C_Inline("#include \"%s_Global.h\"", rootFileName);
164    if( useJacSparse )
165       C_Inline("#include \"%s_Sparse.h\"", rootFileName);
166    }   
167  NewLines(2);
168}
169
170void AllowBreak()
171{
172  *(outBuffer-1) |= 0x80;
173}
174
175void bprintf( char *fmt, ... )
176{
177Va_list args;
178
179  if ( !fmt ) return;
180  Va_start( args, fmt );
181  vsprintf( outBuffer, fmt, args );
182  va_end( args );
183  outBuffer += strlen( outBuffer ); 
184}
185
186void FlushBuf()
187{
188char *p;
189
190  p = outBuf;
191  while( *p )
192    *p++ &= ~0x80;
193  fprintf( currentFile, outBuf );
194  outBuffer = outBuf;
195  *outBuffer = 0;
196}
197
198void FlushThisBuf( char * buf )
199{
200char *p;
201
202  p = buf;
203  while( *p )
204    *p++ &= ~0x80;
205  fprintf( currentFile, buf );
206}
207
208void WriteDelim()
209{
210/*
211  WriteComment("****************************************************************");
212*/ 
213  WriteComment("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
214}
215
216void NewLines( int n )
217{
218  for( ; n > 0; n-- ) 
219    bprintf("\n");
220
221  FlushBuf(); 
222}
223
224void IncludeFile( char * fname ) 
225{
226FILE *fp;
227#define MAX_LINE 200
228char line[ MAX_LINE ];
229
230
231  fp = fopen( fname, "r" );
232  if ( fp == 0 )
233    FatalError(3,"%s: Can't read file", fname );
234
235  FlushBuf();
236 
237  while( !feof(fp) ) {
238    *line = '\0';
239    fgets( line, MAX_LINE, fp );
240    fputs( line, currentFile );
241  }
242 
243  fclose( fp );
244}
245
246void IncludeCode( char* fmt, ... )
247{
248Va_list args;
249char buf[200];
250char cmd[500];
251static char tmpfile[] = "kppfile.tmp";
252FILE * fp;
253
254  Va_start( args, fmt );
255  vsprintf( buf, fmt, args );
256  va_end( args );
257
258  switch( useLang ) { 
259    case F77_LANG: sprintf( buf, "%s.f", buf );
260                 break;
261    case F90_LANG: sprintf( buf, "%s.f90", buf );
262                 break;
263    case C_LANG: sprintf( buf, "%s.c", buf );
264                 break;
265    case MATLAB_LANG: sprintf( buf, "%s.m", buf );
266                 break;
267    default: printf("\n Language '%d' not implemented!\n",useLang); 
268                 exit(1);
269  }
270  fp = fopen( buf, "r" );
271  if ( fp == 0 )
272    FatalError(3,"%s: Can't read file", buf );
273  fclose(fp);
274   
275  strcpy( cmd, "sed " );
276 
277  sprintf( cmd, "%s -e 's/KPP_ROOT/%s/g'", cmd, rootFileName ); 
278  sprintf( cmd, "%s -e 's/KPP_NVAR/%d/g'", cmd, VarNr ); 
279  sprintf( cmd, "%s -e 's/KPP_NFIX/%d/g'", cmd, FixNr ); 
280  sprintf( cmd, "%s -e 's/KPP_NSPEC/%d/g'", cmd,SpcNr ); 
281  sprintf( cmd, "%s -e 's/KPP_NREACT/%d/g'", cmd, EqnNr ); 
282  sprintf( cmd, "%s -e 's/KPP_NONZERO/%d/g'", cmd, Jac_NZ ); 
283  sprintf( cmd, "%s -e 's/KPP_LU_NONZERO/%d/g'", cmd, LU_Jac_NZ ); 
284  sprintf( cmd, "%s -e 's/KPP_NHESS/%d/g'", cmd, Hess_NZ ); 
285 
286  switch( useLang ) { 
287    case F77_LANG:
288                 sprintf( cmd, "%s -e 's/KPP_REAL/%s/g'", cmd, F77_types[real] ); 
289                 break;
290    case F90_LANG:
291                 sprintf( cmd, "%s -e 's/KPP_REAL/%s/g'", cmd, F90_types[real] ); 
292                 break;
293    case C_LANG:
294                 sprintf( cmd, "%s -e 's/KPP_REAL/%s/g'", cmd, C_types[real] ); 
295                 break;                             
296    case MATLAB_LANG:
297                 break;                             
298    default: printf("\n Language '%d' not implemented!\n",useLang); 
299                 exit(1);
300  }           
301     
302  sprintf( cmd, "%s %s > %s", cmd, buf, tmpfile ); 
303
304  system( cmd );
305  IncludeFile( tmpfile );
306  sprintf( cmd, "rm %s", tmpfile );
307  system( cmd );
308}
309
310void MapFunctionComment( int f, int *vars )
311{
312FILE *oldf;
313 
314  oldf = UseFile( mapFile );
315  FunctionStart( f, vars );
316  /*NewLines(1);
317  CommentFncBegin( f, vars );*/
318  FlushBuf();
319  UseFile( oldf );
320}
321
322int DefineVariable( char * name, int t, int bt, int maxi, int maxj, char * comment )
323{
324int i;
325VARIABLE * var;
326
327  for( i = 0; i < MAX_VAR; i++ ) 
328    if( varTable[ i ] == 0 ) break;
329 
330  if( varTable[ i ] != 0 ) { 
331    printf("\nVariable Table overflow");
332    return -1;
333  }
334
335  var = (VARIABLE*) malloc( sizeof( VARIABLE ) );
336  var->name = name;
337  var->type = t;
338  var->baseType = bt;
339  var->maxi = maxi;
340  var->maxj = maxj;
341  var->value = -1;
342  var->comment = comment;
343 
344  varTable[ i ] = var;
345  return i;   
346}
347
348void FreeVariable( int n )
349{
350  if( varTable[ n ] ) { 
351    free( varTable[ n ] );
352    varTable[ n ] = 0;
353  } 
354}
355 
356NODE * Elm( int v, ... )
357{
358Va_list args;
359NODE *n;
360ELEMENT *elm;
361VARIABLE *var;
362int i, j;
363float val;
364char *expr;
365 
366  var = varTable[ v ];
367  n   = (NODE*)    malloc( sizeof(NODE) );
368  elm = (ELEMENT*) malloc( sizeof(ELEMENT) );
369  n->left = 0;
370  n->right = 0;
371  n->sign = 1;
372  n->type = var->type;
373  n->elm = elm;
374  elm->var = v;
375   
376  Va_start( args, v );
377  switch( var->type ) {
378    case CONST: switch( var->baseType ) {
379                  case REAL: elm->val.cnst = (float)va_arg( args, double );
380                             break;
381                  case INT:  elm->val.cnst = (float)va_arg( args, int );           
382                }
383                if( elm->val.cnst < 0 ) {
384                  elm->val.cnst = -elm->val.cnst;
385                  n->sign = -1;
386                }
387                break;
388    case ELM:   
389                break;
390    case VELM:  elm->val.idx.i = va_arg( args, int );
391                break;
392    case MELM:  elm->val.idx.i = va_arg( args, int );
393                elm->val.idx.j = va_arg( args, int );
394                break;
395    case EELM:  elm->val.expr = va_arg( args, char* );
396                break;
397  } 
398  va_end( args );
399 
400  return n;
401}
402
403int IsConst( NODE *n, float val )
404{
405  return ( ( n ) &&
406           ( n->type == CONST ) &&
407           ( n->elm->val.cnst == val ) 
408         );
409}
410
411NODE * BinaryOp( int op, NODE *n1, NODE *n2 )
412{
413NODE *n;
414 
415  n   = (NODE*)    malloc( sizeof(NODE) );
416  n->left = n1;
417  n->right = n2;
418  n->type = op;
419  n->sign = 1;
420  n->elm = 0;
421  return n;
422}
423
424NODE * Add( NODE *n1, NODE *n2 )
425{
426  if( n1 == 0 ) return n2;
427  if( n2 == 0 ) return n1;
428 
429  if( IsConst( n1, 0 ) ) {
430    FreeNode( n1 );
431    return n2;   
432  }
433  if( IsConst( n2, 0 ) ) {
434    FreeNode( n2 );
435    return n1;
436  }
437  return BinaryOp( ADD, n1, n2 );                                 
438}
439
440NODE * Sub( NODE *n1, NODE *n2 )
441{
442  if( n1 == 0 ) return BinaryOp( SUB, 0, n2 );
443  if( n2 == 0 ) return n1;
444 
445  if( IsConst( n1, 0 ) ) {
446    FreeNode( n1 );
447    return  BinaryOp( SUB, 0, n2 );   
448  }
449  if( IsConst( n2, 0 ) ) {
450    FreeNode( n2 );
451    return n1;
452  }
453  return BinaryOp( SUB, n1, n2 );                                 
454}
455
456NODE * Mul( NODE *n1, NODE *n2 )
457{
458  if( n1 == 0 ) return n2;
459  if( n2 == 0 ) return n1;
460 
461  if( IsConst( n1, 1 ) ) { 
462    n2->sign *= n1->sign;
463    FreeNode( n1 );
464    return n2;   
465  }
466  if( IsConst( n2, 1 ) ) {
467    n2->sign *= n1->sign;
468    FreeNode( n2 );
469    return n1;
470  }
471  if( IsConst( n1, 0 ) ) { 
472    FreeNode( n2 );
473    return n1;   
474  }
475  if( IsConst( n2, 0 ) ) {
476    FreeNode( n1 );
477    return n2;
478  }
479 
480  return BinaryOp( MUL, n1, n2 );                                 
481}
482
483NODE * Div( NODE *n1, NODE *n2 )
484{
485  if( n1 == 0 ) return BinaryOp( DIV, Const(1), n2 );
486  if( n2 == 0 ) return n1;
487
488  if( IsConst( n2, 1 ) ) {
489    n2->sign *= n1->sign;
490    FreeNode( n2 );
491    return n1;
492  }
493                 
494  return BinaryOp( DIV, n1, n2 );   
495}
496
497NODE * Pow( NODE *n1, NODE *n2 )
498{
499  if( n1 == 0 ) return n2;
500  if( n2 == 0 ) return n1;
501  return BinaryOp( POW, n1, n2 );   
502}
503
504void FreeNode( NODE * n )
505{
506  if( n == 0 ) return;
507  FreeNode( n->left );
508  FreeNode( n->right );
509  if( n->elm ) free( n->elm );
510  free( n );
511}
512
513int NodeCmp( NODE *n1, NODE *n2 )
514{
515ELEMENT *elm1;
516ELEMENT *elm2;
517
518  if( n1 == n2 ) return 1;
519  if( n1 == 0 ) return 0;
520  if( n2 == 0 ) return 0;
521
522  if( (n1->type % SUBST) != (n2->type % SUBST) ) return 0;
523
524  elm1 = n1->elm;
525  elm2 = n2->elm;
526
527  if( elm1 == elm2 ) return 1;
528  if( elm1 == 0 ) return 0;
529  if( elm2 == 0 ) return 0;
530
531  if( elm1->var != elm2->var )return 0;
532  switch( n1->type ) {
533    case CONST: if( elm1->val.cnst != elm2->val.cnst ) return 0;
534                break;
535    case ELM:   break;
536    case VELM:  if( elm1->val.idx.i != elm2->val.idx.i ) return 0;
537                break;
538    case MELM:  if( elm1->val.idx.i != elm2->val.idx.i ) return 0;
539                if( elm1->val.idx.j != elm2->val.idx.j ) return 0;
540                break;
541    case EELM:  if( strcmp( elm1->val.expr, elm2->val.expr ) != 0 ) return 0;
542                break;
543  }
544
545  return 1;
546}
547
548NODE * NodeCopy( NODE *n1 )
549{
550NODE *n;
551ELEMENT *elm;
552 
553  n   = (NODE*)    malloc( sizeof(NODE) );
554  elm = (ELEMENT*) malloc( sizeof(ELEMENT) );
555  *n = *n1;
556  n->elm = elm;
557  *n->elm = *n1->elm;
558  return n;
559}
560
561void WriteNode( NODE *n )
562{
563  crtop = NONE;
564  ExpandNode( n, NONE );
565}
566
567void WriteOp( int op )
568{
569  WriteSymbol( op );
570  crtop = NONE;
571}
572
573void ExpandElm( NODE * n )
574{
575NODE *cn;
576
577  if( substENABLED == 0 ) {
578    WriteElm( n );
579    return;
580  }   
581  cn = LookUpSubst( n );
582  if( cn == 0 ) {
583    WriteElm( n );
584  } else {
585    if( cn->type > SUBST ) {
586      WriteElm( n );
587    } else {
588      cn->type += SUBST;
589      WriteSymbol( O_PAREN );
590      WriteNode( cn->right );       
591      WriteSymbol( C_PAREN );
592      cn->type -= SUBST;
593    }
594  }
595}
596
597int ExpandNode( NODE *n, int lastop )
598{
599int needParen = 0;
600
601  if( n == 0 ) return lastop;
602
603  if( ( n->left ) &&
604      ( PRI[ n->left->type ] < PRI[ n->type ] ) )
605      needParen = 1;
606
607  if( needParen ) {
608    WriteOp( crtop );
609    WriteSymbol( O_PAREN );
610  }
611  lastop = ExpandNode( n->left, lastop );
612  if( needParen ) WriteSymbol( C_PAREN );
613
614  switch( n->type ) {
615    case ADD: 
616    case SUB:   
617    case MUL:   
618    case DIV:   
619    case POW:   crtop = n->type;
620                break;
621    case NONE:  printf("ERROR - null element"); 
622                break;
623    case CONST:
624    case ELM:
625    case VELM:
626    case MELM:
627    case EELM:
628                switch( crtop ) {
629                  case MUL: case DIV: case POW:
630                    WriteOp( crtop );
631                    if ( n->sign == -1 ) {
632                      WriteSymbol( O_PAREN );
633                      WriteOp( SUB );
634                      ExpandElm( n );
635                      WriteSymbol( C_PAREN );
636                    } else {
637                      ExpandElm( n );
638                    }
639                    break;
640                  case ADD:  if( n->sign == -1 )
641                               crtop = SUB;
642                             WriteOp( crtop );
643                             ExpandElm( n );
644                             break;
645                  case SUB:  if( n->sign == -1 )
646                               crtop = ADD;
647                             WriteOp( crtop );
648                             ExpandElm( n );
649                             break;
650                  case NONE: if( n->sign == -1 )
651                               WriteOp( SUB );
652                             ExpandElm( n );
653                             break;
654                }
655                break;
656  }
657
658  if( ( n->right ) &&
659      ( PRI[ n->right->type ] <= PRI[ n->type ] ) )
660      needParen = 1; 
661
662  if( needParen ) {
663    WriteOp( crtop );
664    WriteSymbol( O_PAREN );
665  } 
666  lastop = ExpandNode( n->right, n->type );
667  if( needParen ) WriteSymbol( C_PAREN );
668  return lastop;
669}
670
671void Assign( NODE *lval, NODE *rval )
672{
673char *ls;
674char *rs;
675char *olds;
676
677  ls = (char*)malloc( MAX_OUTBUF );
678  rs = (char*)malloc( MAX_OUTBUF );
679
680  olds = outBuffer;
681  outBuffer = ls;
682  WriteNode( lval );
683  outBuffer = rs;
684  WriteNode( rval );
685  outBuffer = olds;
686
687  WriteAssign( ls, rs );
688
689  free( rs ); 
690  free( ls ); 
691  FreeNode( lval );
692  FreeNode( rval );
693}
694
695NODE * LookUpSubst( NODE *n )
696{
697NODE *cn;
698 
699  cn = substList;
700  while( cn != 0 ) {
701    if( NodeCmp( n, cn ) ) 
702      return cn;
703    cn = cn->left; 
704  }
705  return 0;
706}
707
708void MkSubst( NODE *n1, NODE *n2 )
709{
710NODE *n;
711
712  n = LookUpSubst( n1 );
713  if( n == 0 ) {
714    n = n1;
715    n->left = substList;
716    substList = n;
717  } else {
718    FreeNode( n->right );
719    FreeNode( n1 );
720  }
721  n->right = n2;
722}
723
724void RmSubst( NODE *n )
725{
726NODE *pn;
727NODE *cn;
728
729  pn = 0;
730  cn = substList;
731  while( cn != 0 ) {
732    if( NodeCmp( n, cn ) ) 
733      break;
734    pn = cn;
735    cn = cn->left;
736  }
737  if( cn == 0 ) return;
738
739  FreeNode( cn->right );
740  if( pn )
741    pn->left = cn->left;
742  else 
743    substList = cn->left; 
744 
745  cn->right = 0;
746  cn->left = 0;
747  FreeNode( cn );
748}
749
750void DisplaySubst()
751{
752NODE *n;
753
754  n = substList;
755  substENABLED = 0;
756  while( n != 0 ) {
757    printf("Subst: ");
758    WriteElm( n );
759    printf( " --> " );   
760    WriteNode( n->right );
761    printf("\n");
762    n = n->left;
763  }
764  substENABLED = 1;
765}
766
767void CommentFncBegin( int f, int *vars )
768{
769VARIABLE *var;
770char * name;
771int narg;
772int i;
773
774  name = varTable[ f ]->name;
775  narg = varTable[ f ]->maxi;
776  var = varTable[ f ];
777
778  WriteDelim();
779  WriteComment("");
780  WriteComment("%s - %s", var->name, var->comment );   
781  WriteComment("  Arguments :");
782  for( i = 0; i < narg; i++ ) {
783    var = varTable[vars[i]];
784    WriteComment("     %-10s- %s", var->name, var->comment ); 
785  } 
786  WriteComment("");
787  WriteDelim();
788  NewLines(1);
789}
790
791void CommentFunctionBegin( int f, ... )
792{
793Va_list args;
794int i;
795int vars[20];
796char * name;
797int narg;
798
799  name = varTable[ f ]->name;
800  narg = varTable[ f ]->maxi;
801
802  Va_start( args, f ); 
803  for( i = 0; i < narg; i++ ) 
804    vars[i] = va_arg( args, int );
805  va_end( args );
806
807  CommentFncBegin( f, vars );
808  /* MapFunctionComment( f, vars ); */
809}
810
811void CommentFunctionEnd( int f )
812{
813  WriteComment("End of %s function", varTable[ f ]->name );   
814  WriteDelim();
815  NewLines(2);
816}
817
Note: See TracBrowser for help on using the repository browser.