source: tol/toltcl/generic/tolaccess.cpp @ cdb9682

1941-docker-image-to-testdevel
Last change on this file since cdb9682 was 6f16730, checked in by Jorge Pérez <josp.jorge@…>, 17 years ago
  • fixing misspell in Address (related to #705)
  • tol::info address (related to #705)
  • changing version number to 2.0.1

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@1134 be4846ae-f051-483a-831f-b64e7d08527f

  • Property mode set to 100644
File size: 61.8 KB
RevLine 
[6d7779d]1/* tolaccess.cpp: This file implements an interface between object in tol
2                  and "objects" in tclThis file define a set of utils
3                  functions.
4                  GNU/tolTcl Library
5
6   Copyright (C) 2001, 2002, 2003 - Bayes Decisión, SL
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21   USA.
22 */
23
24#include <ctype.h>
25
26#if defined(_MSC_VER)
27#  include <win_tolinc.h>
28#endif
29
30#include <tol/tol_init.h>
31#include <tol/tol_version_def.h>
32#include <tol/tol_bcommon.h>
[e9bbf15]33#include <tol/tol_bstruct.h>
[6d7779d]34#include <tol/tol_blanguag.h>
35#include <tol/tol_bmatgra.h>
[c14b554]36#include <tol/tol_bvmatgra.h>
37#include <tol/tol_bnameblock.h>
[6d7779d]38#include <tol/tol_bspfun.h>
[a64730a]39#include <tol/tol_bcodgra.h>
[6d7779d]40#include <tol/tol_bsetgra.h>
41#include <tol/tol_btsrgra.h>
42#include <tol/tol_btxtgra.h>
43#include <tol/tol_bmethodhook.h>
44
45#include <toltclInt.h>
46#include <tt_pool.h>
47
48
49/*
50 * if SyntaxObject has IsFile implemented, uncomment the following
51 * define:
52 */
53
[aca1089]54#define ISFILE_IMPLEMENTED
[6d7779d]55
56typedef void (* getmethod)( const BSyntaxObject *, BText & );
57typedef int  (* checkmethod)( const BSyntaxObject * );
58
59static
60int QuickSort( Tcl_Interp * interp, Tcl_Obj * list );
61
62inline
63char * skipWhite(char * pch)
64{
65  while (*pch && isspace(*pch))
66    ++pch;
67  return pch;
68}
69
70static
[d143dd9]71BText GetObjectName(const BSyntaxObject * so)
[6d7779d]72{
[d143dd9]73  return so->HasName() ? so->FullName() : so->LocalName();
[6d7779d]74}
75
76static
77void GetName( const BSyntaxObject * so, BText & res )
78{
[d143dd9]79  res = so->FullName();
[6d7779d]80}
81
82static
83void GetIdentify( const BSyntaxObject * so, BText & res )
84{
85  res = so->Identify();
86}
87
88static
89void GetPath( const BSyntaxObject * so, BText & res )
90{
91  res = so->TolPath();
92}
93
94static
95int
96ExcludeAnything( const BSyntaxObject * so )
97{
98  return so != GraAnything();
99}
100
101static
102int HasNoSource( const BSyntaxObject * so )
103{
104  return !so->Source();
105}
106
107static
108int BList2TclList( Tcl_Interp * interp,
109                   BList * blist, Tcl_Obj * tcl_list,
110                   getmethod m, checkmethod accept = NULL)
111{
112  char * str;
113  Tcl_Obj * name;
114  Tcl_DString dstr;
115  BText tmp;
116
117  while(blist)
118  {
119    BSyntaxObject* so = (BSyntaxObject*)Car(blist);
120    if(!accept || (*accept)(so))
121    {
122      (*m)(so,tmp);
123      str = Tcl_ExternalToUtfDString(NULL,tmp,-1,&dstr);
124      name = Tcl_NewStringObj(str,-1);
125      Tcl_DStringFree(&dstr);
126      if ( Tcl_ListObjAppendElement(interp, tcl_list, name) != TCL_OK ) {
127        Tcl_DecrRefCount(name);
128        return TCL_ERROR;
129      }
130    }
131    blist = Cdr(blist);
132  }
133  return TCL_OK;
134}
135
136/*
137 * Fill in obj_result the result of avaluating in TOL the given
138 * string.
139 *
140 */
141
142/* cdr of console_stack point to first item */
143static BList console_stack;
144// Read only stack
145static BList console_stack_hidden;
146
147static
148void my_concat(BList* head, BList* tail)
149{
150  if (head->Cdr()) {
151    my_concat(head->Cdr(), tail);
152  } else {
153    head->PutCdr(tail);
154  }
155}
156
157int Tol_EvalExpr (Tcl_Obj * obj_expr, int hidden, Tcl_Obj * obj_result)
158{
159  BList * tol_result;
160  Tcl_DString dstr;
161  char * expr;
162 
163  Tcl_DStringInit(&dstr);
164  expr = Tcl_UtfToExternalDString(NULL,Tcl_GetString(obj_expr),-1,&dstr);
165  tol_result = MultyEvaluate(expr);
166  Tcl_DStringFree(&dstr);
167  if(tol_result) {
168    my_concat(hidden?&console_stack_hidden:&console_stack, tol_result);
169  }
170  /*  Tcl_AppendStringsToObj(obj_result,
171      "couldn't evaluate tol expresion \"",
172      Tcl_GetString(obj_expr), "\"", NULL);
173      return TCL_ERROR;*/
174  return TCL_OK;
175}
176
177int Tol_GetStructure( Tcl_Interp * interp, Tcl_Obj * name, Tcl_Obj * obj_result )
178{
179  Tcl_DString dstr;
180  BStruct * structure;
181  BStruct * substruct;
182
183  Tcl_DStringInit( &dstr );
184  Tcl_UtfToExternalDString( NULL, Tcl_GetString(name), -1, &dstr );
[c14b554]185  if ( Tcl_DStringLength( &dstr ) &&
186       (structure = FindStruct(Tcl_DStringValue(&dstr)))) {
187   
[6d7779d]188    Tcl_Obj * tmp[2];
189    Tcl_Obj * info[2];
190    Tcl_Obj ** fields;
191    BText btxt;
192    int nfields;
193   
194    nfields = structure->Size();
195    fields = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*) * nfields );
196    for ( int i = 0; i < nfields; i++ ) {
197      BField & field = (*structure)[i];
198      btxt = field.Name();
199      Tcl_DStringFree(&dstr);
200      Tcl_ExternalToUtfDString( NULL, btxt, -1, &dstr );
201      info[0] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
202      Tcl_DStringFree( &dstr );
203      if ( (substruct = field.Struct()) ) {
204        btxt = substruct->Name();
205        Tcl_ExternalToUtfDString( NULL, btxt, -1, &dstr );
206        tmp[0] = Tcl_NewStringObj( "STRUCT", 6 );
207        tmp[1] = Tcl_NewStringObj( Tcl_DStringValue(&dstr), -1);
208        info[1] = Tcl_NewListObj( 2, tmp );
209      } else if ( field.Grammar() ) {
210        btxt = field.Grammar()->Name();
211        Tcl_ExternalToUtfDString( NULL, btxt, -1, &dstr );
212        info[1] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
213      }
214      fields[i] = Tcl_NewListObj(2,info);
215    }
216    Tcl_SetListObj( obj_result, nfields, fields );
217    Tcl_Free( (char*)fields );
218  }
219  return TCL_OK;
220}
221
[c14b554]222BSet* ContainerGetSet(const BSyntaxObject *container)
223{
224  if (container) {
225    if (container->Grammar()==GraSet())
226      return &(((BUserSet*)container)->Contens());
227    else if (container->Grammar()==GraNameBlock())
228      return &(((BUserNameBlock*)container)->Contens().Set());
229  }
230  return NULL;
231}
232 
[6d7779d]233/*
234 * Return the path of a set if it is a file, trigger an error in other case
235 *
236 */
237
238int Tol_GetSetPath( Tcl_Interp * interp, Tcl_Obj * name, Tcl_Obj * obj_result )
239{
240  Tcl_DString uniBuffer;
241  const BSyntaxObject * syn;
242
243 /* if name contains spaces the we should try it first as a string */
244  Tcl_DStringInit(&uniBuffer);
245  Tcl_UtfToExternalDString(NULL,Tcl_GetString(name),-1,&uniBuffer);
246  BText fname(Tcl_DStringValue(&uniBuffer));
247  syn = (BSyntaxObject*)BSetFromFile::FindCompiled(fname);
248  Tcl_DStringFree(&uniBuffer);
249  if (!syn) {
[c14b554]250    syn = Tol_ResolveObject(interp, name, obj_result);
[6d7779d]251  }
252  if ( !syn )
253    return TCL_ERROR;
[c14b554]254  BSet *ptrSet = ContainerGetSet(syn);
255  if ( ptrSet->SubType() >= BSet::MODFile && ptrSet->SubType() <= BSet::BMIFile ) {
[6d7779d]256    Tcl_DString dstr;
257    BText path( syn->TolPath() );
258
259    Tcl_DStringInit( &dstr );
260    Tcl_ExternalToUtfDString(NULL,path,-1,&dstr);
261    Tcl_SetStringObj( obj_result, Tcl_DStringValue(&dstr), -1 );
262    return TCL_OK;
263  } else {
264    Tcl_AppendStringsToObj( obj_result, Tcl_GetString(name),
265                            " is not a valid file object", NULL );
266    return TCL_ERROR;
267  }
268}
269
270/*
271 * Fill in obj_result the content of the given tol object's names. The
272 * object are searched in the console's stack.
273 *
274 * Return:
275 *
276 *   {GRAMMAR NAME CONTENT PATH DESCRIPTION ISFILE [Has SubSet? SUBTYPE STRUCTURE]}
277 */
278
279int Tol_ListStack(Tcl_Interp * interp,int objc,Tcl_Obj *CONST objv[],
280                  Tcl_Obj * obj_result)
281{
282  BSyntaxObject * so;
283  BText btxt;
284  Tcl_DString dstr;
285  BList * tol_item;
286  Tcl_Obj * robjv[9];
287  int robjc;
288  Tcl_Obj * tcl_item;
289  int tcl_result;
290  BSet * ptrSet = 0;
291  int tmpCard;
292  int j;
293 
294  Tcl_DStringInit(&dstr);
295 
296  tol_item = console_stack.Cdr();
297  while (tol_item) {
298    so = (BSyntaxObject*)Car(tol_item);
299   
300    /* GRAMMAR NAME */
301    btxt = so->Grammar()->Name();
302    Tcl_ExternalToUtfDString(NULL,btxt,-1,&dstr);
303    robjv[0] = Tcl_NewStringObj(Tcl_DStringValue(&dstr),-1);
304    Tcl_DStringFree(&dstr);
305   
306    /* OBJECT NAME */
307//  btxt = so->Identify();
[d143dd9]308    GetName( so, btxt );
[6d7779d]309    Tcl_ExternalToUtfDString(NULL,btxt,-1,&dstr);
310    robjv[1] = Tcl_NewStringObj(Tcl_DStringValue(&dstr),-1);
311    Tcl_DStringFree(&dstr);
312   
313    /* OBJECT CONTENT */
314    btxt = so->Info();
315    Tcl_ExternalToUtfDString(NULL,btxt,-1,&dstr);
316    robjv[2] = Tcl_NewStringObj(Tcl_DStringValue(&dstr),-1);
317    Tcl_DStringFree(&dstr);
318   
319    /* OBJECT PATH */
320    btxt = so->SourcePath();
321    Tcl_ExternalToUtfDString(NULL,btxt,-1,&dstr);
322    robjv[3] = Tcl_NewStringObj(Tcl_DStringValue(&dstr),-1);
323    Tcl_DStringFree(&dstr);
324   
325    /* OBJECT DESCRIPTION */
326    btxt = so->Description();
327    Tcl_ExternalToUtfDString(NULL,btxt,-1,&dstr);
328    robjv[4] = Tcl_NewStringObj(Tcl_DStringValue(&dstr),-1);
329    Tcl_DStringFree(&dstr);
330   
331    /* IS THE OBJECT A FILE? */
332    robjv[5] = Tcl_NewIntObj(so->IsFile());
[c14b554]333////    if ( so->Grammar()==GraSet() ) {
334    if ( so->Grammar()==GraSet() || so->Grammar()==GraNameBlock()) {
[6d7779d]335      /* HAS SUBSET */
[c14b554]336////      ptrSet = &(((BUserSet*)so)->Contens());
337      ptrSet = ContainerGetSet(so);
[6d7779d]338      tmpCard = ptrSet->Card();
339      for (j=1; j<=tmpCard; ++j )
340        if ( (*ptrSet)[j]->Grammar()==GraSet() )
341          break;
342      robjv[6] = Tcl_NewIntObj(j<=tmpCard);
343       
344      /* SUBTYPE INFO */
345      robjv[7] = Tcl_NewIntObj( ptrSet->SubType() );
346       
347      /* STRUCT INFO */
348      if ( ptrSet->Struct() ) {
349        btxt = ptrSet->Struct()->Name();
350        Tcl_ExternalToUtfDString(NULL,btxt,-1,&dstr);
351        robjv[8] = Tcl_NewStringObj( Tcl_DStringValue(&dstr), -1 );
352        Tcl_DStringFree( &dstr );
353      } else
354        robjv[8] = Tcl_NewStringObj( NULL, 0 );
355      robjc = 9;
356    } else
357      robjc = 6;
358   
359    /* build the tcl item as a list */
360    tcl_item = Tcl_NewListObj(robjc,robjv);
361   
362    /* append to the end of the result */
363    tcl_result = Tcl_ListObjAppendElement(interp,obj_result,tcl_item);
364    if (tcl_result != TCL_OK) {
365      Tcl_SetStringObj(obj_result,"",-1);
366      Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
367      return TCL_ERROR;
368    }
369    tol_item = Cdr(tol_item);
370  }
371  return TCL_OK;
372}
373
374struct tcl_info_t
375{
376  Tcl_Interp *interp;
377  int objc;
378  Tcl_Obj* CONST* objv;
379  Tcl_DString &dstr;
380};
381
382/*
383 * Tol_ReleaseStack --
384 *
385 * Recursive version in order to release stack in reverse order
386 *
387 * Preconditions:
388 *
389 *   P != NULL
390 */
391static
392int Tol_ReleaseStack(tcl_info_t &info, BList *P)
393{
394  int result;
395 
396  assert(P != NULL);
397
398  if (P->Cdr()) {
399    /* keep on looking for rest of items */
400    result = Tol_ReleaseStack(info, P->Cdr());
401    /* process this item */
402    BList *current = P->Cdr();
403    BSyntaxObject * so;
404    int i;
405    so = (BSyntaxObject*)(current->Car());
406    if (info.objc) {
407      const char* name = so->Name().String();
408      for (i = 0; i<info.objc; ++i) {
409        Tcl_UtfToExternalDString(NULL,Tcl_GetString(info.objv[i]),-1,
410                                 &info.dstr);
411        if (!strcmp(Tcl_DStringValue(&info.dstr), name)) {
412          Tcl_DStringFree(&info.dstr);
413          break;
414        }
415        Tcl_DStringFree(&info.dstr);
416      }
417    } else {
418      /* mark current as being found */
419      i = -1;
420    }
421    if (i<info.objc) {
422      BList *next = current->Cdr();
423      /* delete will DecNRefs to the Car */
424      delete current;
425      /* now try to release the BSyntaxObject */
426      DESTROY(so);
427      /* chain the list */
428      P->PutCdr(next);
429    }
430  } else {
431    /* EOR */
432    result = TCL_OK;
433  }
434  return result;
435}
436
437int Tol_ReleaseStack(Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[],
438                     Tcl_Obj * obj_result)
439{
440  Tcl_DString dstr;
441  tcl_info_t tcl_info = {interp, objc, objv, dstr};
442  Tcl_DStringInit(&dstr);
443
444  return Tol_ReleaseStack(tcl_info, &console_stack);
445}
446
447/*!
448 * Tol_GetConsoleObject --
449 *
450 *     Returns the object with given index in the console object list.
451 */
452BSyntaxObject * Tol_GetConsoleObject(int index )
453{
454  BList * current = console_stack.Cdr();
455  int i = 1;
456  while (current) {
457    if (i==index) break;
458    current = Cdr(current);
459    ++i;
460  }
461  return current ? (BSyntaxObject*)(current->Car()) : NULL;
462}
463
464
465/*
[c14b554]466 * return the container (File, Set or NameBlock) with name obj_name,
467 * in case of error return NULL and leave a description in
468 * obj_result.
[6d7779d]469 *
470 */
[c14b554]471const BSyntaxObject * Tol_FindGlobalContainer(const char* Type,
472                                              const char* obj_name,
473                                              Tcl_Obj*    obj_result)
[6d7779d]474{
[c14b554]475  BGrammar *gra;
476  BSyntaxObject* var;
477  Tcl_DString uniBuffer;
[6d7779d]478
[c14b554]479  if (!strcmp(Type, "Set"))
480    gra = GraSet();
481  else if (!strcmp(Type, "NameBlock"))
482    gra = GraNameBlock();
483  else if (!strcmp(Type, "File"))
484    gra = NULL;
485  else {
486    Tcl_AppendStringsToObj(obj_result,"type '",
487                           Type,
488                           "' is not a container grammar", NULL );
[6d7779d]489    return NULL;
490  }
491  Tcl_DStringInit(&uniBuffer);
[c14b554]492  Tcl_UtfToExternalDString(NULL,obj_name,-1,&uniBuffer);
493  if (!gra) {
494    /* should look in Files */
[6d7779d]495    BText fname(Tcl_DStringValue(&uniBuffer));
[c14b554]496    if (!(var=(BSyntaxObject*)BSetFromFile::FindCompiled(fname))) {
497      Tcl_AppendStringsToObj(obj_result,"file \"",
498                             obj_name,
499                             "\" is not included", NULL );
[6d7779d]500    }
[c14b554]501  } else if (!(var=gra->FINDVARIABLE(Tcl_DStringValue(&uniBuffer)))) {
502      Tcl_AppendStringsToObj(obj_result,"\"",
503                             obj_name,
504                             "\" isn't a ", Type, " variable", NULL );
[6d7779d]505  }
506  Tcl_DStringFree(&uniBuffer);
507  return var;
508}
509
510/*
[c14b554]511 * given a tol set, returns its child corresponding to the set of
512 * indexes indexes of size n.  In case of error return NULL and leave
513 * a description in obj_result.
[6d7779d]514 *
515 */
516
[c14b554]517const BSyntaxObject * Tol_FindChild(Tcl_Interp    *interp,
518                                    const BSyntaxObject *syn_obj,
519                                    Tcl_Obj       **indexes, int n,
520                                    Tcl_Obj       *obj_result)
[6d7779d]521{
522  int tcl_code;
523  Tcl_DString dstr;
[c14b554]524  BSet *container;
[6d7779d]525  int idx, card;
526  int i;
527
528  for (i=0; i<n; ++i) {
[c14b554]529    if (!(container = ContainerGetSet(syn_obj))) {
530      BText info(syn_obj->Info());
531      Tcl_DStringInit(&dstr);
532      Tcl_ExternalToUtfDString(NULL,info,-1,&dstr);
533      Tcl_AppendStringsToObj(obj_result,"object \"",
534                             Tcl_DStringValue(&dstr),
535                             "\" is not a container",
536                             NULL);
537      Tcl_DStringFree(&dstr);
538      break;
539    }
540    /* get the current object index */
[6d7779d]541    tcl_code = Tcl_GetIntFromObj(interp,indexes[i],&idx);
542    if (tcl_code != TCL_OK) {
543      Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
544      break;
545    }
[c14b554]546    card = container->Card();
547    if (idx<1 || idx>card) {
548      Tcl_AppendStringsToObj(obj_result,
549                             "index '",
550                             Tcl_GetString(indexes[i]),
551                             "' out of range",
552                             NULL);
[6d7779d]553      break;
554    }
[c14b554]555    /* take the next object in the list */
556    syn_obj = (*container)[idx];
[6d7779d]557  }
558  return i == n ? syn_obj : NULL;
559}
560
561/*!
562 *  Tol_ResolveObject --
563 *
[c14b554]564 *     Resolve a SyntaxObject given a toltcl object reference. A
565 *     reference is {TYPE ?container? i1 i2 ... in} or a global
566 *     container's name of type File|Set|NameBlock|Console. When TYPE
567 *     is Console then container is not given. The grammar of the
568 *     object found is matched to the given argument grammar. If the
569 *     return value is NULL an error message is left in interp.
[6d7779d]570 */
571
[c14b554]572const BSyntaxObject * Tol_ResolveObject(Tcl_Interp *interp,
573                                        Tcl_Obj    *obj_ref,
574                                        Tcl_Obj    *obj_result)
[6d7779d]575{
576  Tcl_Obj ** items;
577  int n;
578  int tcl_code;
[c14b554]579  char * type;
[6d7779d]580
581  /* look for subitem given in obj_ref */
582  tcl_code = Tcl_ListObjGetElements(interp, obj_ref, &n, &items);
[c14b554]583  if (tcl_code != TCL_OK) {
584    Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
[6d7779d]585    return NULL;
[c14b554]586  }
[6d7779d]587
[c14b554]588  // this Tcl_Obj is to leave error messages
[6d7779d]589  const BSyntaxObject * syn = NULL;
[c14b554]590
591  if (n >= 2) {
592    type = Tcl_GetString(items[0]);
593    if (!strcmp(type,"Console") || !strcmp(type,"File") ||
594        !strcmp(type,"Set") || !strcmp(type,"NameBlock") ) {
595      if (!strcmp(type,"Console")) {
596        // is a reference in the console, items[1] is the first index in
597        // the path, following indexes are indexes withing containers.
598        int i1;
599        if ((tcl_code = Tcl_GetIntFromObj(interp,items[1],&i1)!=TCL_OK)) {
600          Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
601          return NULL;
602        }
603        if (!(syn=Tol_GetConsoleObject(i1))) {
604          Tcl_AppendStringsToObj(obj_result, "index ",
605                                 Tcl_GetString(items[1]),
606                                 " not found in console", NULL);
607          return NULL;
608        }
609      } else {
610      /* should be File, Set or NameBlock, it is a hierarchical container */
611        if (!(syn=Tol_FindGlobalContainer(Tcl_GetString(items[0]),
612                                          Tcl_GetString(items[1]),
613                                          obj_result))) {
614          return NULL;
615        }
[6d7779d]616      }
[c14b554]617      assert(syn);
618      if (n>2) {
619        // there are more indexes & syn should be a Container
620        if (!(syn=Tol_FindChild(interp,
621                                syn, items+2, n-2, obj_result))) {
622          return NULL;
[6d7779d]623        }
[c14b554]624      }
625    } else {
626      if (n==2) {
627        // look global var in grammar
628        BGrammar * gra;
629        gra = BGrammar::FindByName(type);
630        if (!gra) {
631          Tcl_AppendStringsToObj(obj_result, "\"",
632                                                   type,
633                                                   "\" isn't a grammar", NULL);
634          return NULL;
[6d7779d]635        }
[c14b554]636        Tcl_DString dstr;
637        Tcl_DStringInit(&dstr);
638        Tcl_UtfToExternalDString(NULL,Tcl_GetString(items[1]),-1,&dstr);
639        if (!(syn = gra->FINDVARIABLE(Tcl_DStringValue(&dstr))))
640          Tcl_AppendStringsToObj(obj_result, "variable '",
641                                 obj_ref, "' not found in grammar '",
642                                 gra->Name().String(), "'", NULL);
643        Tcl_DStringFree(&dstr);
644        /* found and matched */
645        return syn;
[6d7779d]646      }
647    }
648  } else {
[c14b554]649      Tcl_AppendStringsToObj(obj_result,
650                             "incorrect object reference in ResolveObject",
651                             NULL);
[6d7779d]652  }
[c14b554]653/*  if (grammar && syn && syn->Grammar()!=grammar) {
654    Tcl_AppendStringsToObj(obj_result, "grammar for object '",
655                           Tcl_GetString(obj_ref),
656                           "' does not match grammar '",
657                           grammar->Name().String(), "'", NULL);
658    syn = NULL;
659  }
660*/
[6d7779d]661  return syn;
662}
663
664int Tol_FindSOInSet(BSet * ptrSet, const BSyntaxObject * syn,
665                    ToltclPool & indexes)
666{
667  int j;
668  const BSyntaxObject * so;
669 
670  for (j = 1; j <= ptrSet->Card(); j++) {
671    so = (*ptrSet)[j];
[c14b554]672    BSet *ptrSet;
673    if (so == syn || ((ptrSet=ContainerGetSet(so)) &&
674                      Tol_FindSOInSet(ptrSet,
[6d7779d]675                                      syn, indexes))) {
676      /* found!!! */
677      indexes.AppendObject((void*)j);     
678      return 1;
679    }
680  }
681
682  return 0;
683}
684 
685/*
686 *  Puts in obj_result the global reference of the given
687 *  syntaxobject. The syntaxobject could be given as set member or as
688 *  global variable. In case of error leave in obj_result the message.
689 *  Returns TCL_OK if succesfull or TCL_ERROR in case of error.
690 */
691
692int Tol_GetReference(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[],
693                     Tcl_Obj * obj_result)
694{
695  Tcl_Obj ** items;
696  int n;
697  int tcl_code;
698  const BSyntaxObject * source, * syn;
699  BSet * ptrSet;
700  ToltclPool indexes;
701  Tcl_DString dstr;
[c14b554]702  int j;
703  char * graname, * objname;
[6d7779d]704
705  assert(!Tcl_IsShared(obj_result));
[c14b554]706  tcl_code = Tcl_ListObjGetElements(interp,objv[0],&n,&items);
707  assert(tcl_code == TCL_OK);
708  if (n<2) {
709    Tcl_AppendStringsToObj(obj_result,
710                           "wrong # args: should be 'tol::info",
711                           " reference {grammar|container objname ?indexes?}'",
712                           NULL);
713    return TCL_ERROR;   
714  }
715  if (n==2 && strcmp(Tcl_GetString(items[0]),"Console")) {
[6d7779d]716  // global access
717    BGrammar * gra;
[c14b554]718    graname = Tcl_GetString(items[0]);
[6d7779d]719    gra = BGrammar::FindByName(graname);
720    if (!gra) {
721      Tcl_AppendStringsToObj( obj_result, "\"",
722                              graname,
723                              "\" isn't a grammar", NULL);
724      return TCL_ERROR;
725    }
[c14b554]726    objname = Tcl_GetString(items[1]);
727    Tcl_UtfToExternalDString(NULL,objname,-1,&dstr);
[6d7779d]728    syn = gra->FINDVARIABLE(Tcl_DStringValue(&dstr));
729    Tcl_DStringFree(&dstr);
730    if (!syn) {
731      Tcl_AppendStringsToObj(obj_result, "\"",
[c14b554]732                             Tcl_GetString(items[1]),
[6d7779d]733                             "\" isn't a variable in grammar ",
734                             graname, NULL);
735      return TCL_ERROR;
736    }
[c14b554]737    source = syn->Source();
738    if (!source) {
739      /* is a global variable not defined inside a file */
740      items = (Tcl_Obj**)Tcl_Alloc(sizeof(Tcl_Obj*) * 2);
741      Tcl_ExternalToUtfDString(NULL, graname, -1, &dstr);
742      items[0] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
743      Tcl_DStringFree(&dstr);
744      Tcl_ExternalToUtfDString(NULL, objname, -1, &dstr);
745      items[1] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
746      Tcl_DStringFree(&dstr);
747      Tcl_SetListObj(obj_result, 2, items);
748      Tcl_Free((char*)items);
749      return TCL_OK;
750    }
[6d7779d]751  } else {
752    // member access
[c14b554]753    if (!(syn=Tol_ResolveObject(interp,objv[0],obj_result))) {
[6d7779d]754      return TCL_ERROR;
755    }
[c14b554]756    /* here we have a valid reference */
757    tcl_code = Tcl_ListObjGetElements(interp,objv[0],&n,&items);
758    assert(tcl_code == TCL_OK);
759    if (!strcmp(Tcl_GetString(items[0]),"File") ||
760        !strcmp(Tcl_GetString(items[0]),"Console")) {
761      /* here we have in objv[0] the answer */
762      Tcl_SetListObj(obj_result, n, items);
763      return TCL_OK;     
764    }
765    source = syn->Source();
766    if (!source) {
767      /* here we have in objv[0] the answer too */
768      Tcl_SetListObj(obj_result, n, items);
769      return TCL_OK;
[6d7779d]770    }
771  }
[c14b554]772  /* at this point variable has to be defined inside a file */
773  assert(source);
774  ptrSet = &(((BUserSet*)source)->Contens());
775  if (Tol_FindSOInSet(ptrSet, syn, indexes)) {
776    items = (Tcl_Obj**)Tcl_Alloc(sizeof(Tcl_Obj*) * (indexes.GetSize()+2));
777    Tcl_ExternalToUtfDString(NULL, "File", -1, &dstr);
778    items[0] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
779    Tcl_DStringFree(&dstr);
780    Tcl_ExternalToUtfDString(NULL, source->Name(), -1, &dstr);
781    items[1] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
[6d7779d]782    Tcl_DStringFree(&dstr);
[c14b554]783    int last = indexes.GetLast();
784    for(j = last; j >= 0; j--)
785      items[last+2-j] = Tcl_NewIntObj(long(*indexes._GetObject(j)));
786    Tcl_SetListObj(obj_result, indexes.GetSize()+2, items);
787    Tcl_Free((char*)items);
[6d7779d]788    return TCL_OK;
789  } else {
[c14b554]790    /* this should not happend because syn should be inside syn->source */
791    Tcl_AppendStringsToObj(obj_result,
[6d7779d]792                             "internal error: syn not found in syn->Source()",
793                             NULL);
[c14b554]794    return TCL_ERROR;
[6d7779d]795  }
796}
797
798
799/*
800 * Iterate over a first level's children of a given set.  The set
[c14b554]801 * could be a container Set, File or NameBlock if the index list is
802 * empty or container[i1][i2]...[ik] for the given indexes
803 * {i1,i2,...,ik}
[6d7779d]804 *
[aca1089]805 * Used by tol::forallchil
806 *
[6d7779d]807 */
808
809int Tol_IterChildren(Tcl_Interp * interp,
810                     int objc,
811                     Tcl_Obj *CONST objv[],
812                     Tcl_Obj * obj_result)
813{
[c14b554]814  const BSyntaxObject* container;
[6d7779d]815  Tcl_DString dstr;
816  Tcl_Obj * ArgIndexes;
817  int tcl_code, cont_loop;
818  int i, card ;
819  int n, index_length;
820  Tcl_Obj ** items;
[aca1089]821  Tcl_Obj ** script_header;
[c14b554]822
823  int length = 0;
[6d7779d]824 
[c14b554]825  if (Tcl_ListObjLength(interp,objv[0],&length)!=TCL_OK) {
826    Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
827    return TCL_ERROR;
828  }
[aca1089]829  if ( length < 2 ) {
830    Tcl_AppendStringsToObj( obj_result,
831                            "invalid object reference '",
832                            Tcl_GetString(objv[0]),
833                            "must be {TYPE ?name? i1 i2 ... ik}",
834                            NULL );
[6d7779d]835    return TCL_ERROR;
836  }
[c14b554]837
[aca1089]838  /* expand header of script */
839  tcl_code = Tcl_ListObjGetElements( interp, objv[ 1 ],
840                                     &length, &script_header );
841  if ( tcl_code != TCL_OK ) {
842    Tcl_AppendObjToObj( obj_result, Tcl_GetObjResult( interp ) );
[c14b554]843    return TCL_ERROR;
844  }
[aca1089]845
846  if ( !length ) {
847    Tcl_AppendStringsToObj( obj_result,
848                            "invalid script argument of length 0",
849                            NULL );
850    return TCL_ERROR;
851  }
852  int ARG_SCRIPT    = length - 1;
853  int ARG_GRAMMAR   = ARG_SCRIPT + 1;
854  int ARG_NAME      = ARG_GRAMMAR + 1;
855  int ARG_CONTENT   = ARG_NAME + 1;
856  int ARG_PATH      = ARG_CONTENT + 1;
857  int ARG_DESC      = ARG_PATH + 1;
858  int ARG_INDEXES   =  ARG_DESC + 1;
859  int ARG_ISFILE    = ARG_INDEXES + 1;
860  int ARG_HASSUBSET = ARG_ISFILE + 1;
861  int ARG_SUBTYPE   = ARG_HASSUBSET + 1;
862  int ARG_STRUCT    = ARG_SUBTYPE + 1;
863  int NUM_ARGS      = ARG_STRUCT + 1;
864 
865  if ( !( container=Tol_ResolveObject( interp, objv[0], obj_result ) ) ) {
866    return TCL_ERROR;
867  }
868  BSet *set = ContainerGetSet( container );
[c14b554]869  if (!set) {
870    Tcl_AppendStringsToObj(obj_result,
871                           "object '",
872                           Tcl_GetString(objv[0]),
873                           "' is not a valid container ",
874                           NULL);
875      return TCL_ERROR;
876  }
877 
878  card = set->Card();
879 
[6d7779d]880  int datac;
[aca1089]881  Tcl_Obj ** datav = new ( Tcl_Obj* [ NUM_ARGS ] );
882
[6d7779d]883  // is ok to ask for a list
[aca1089]884  Tcl_ListObjGetElements( interp, objv[ 0 ], &n, &items );
[c14b554]885 
886  if (strcmp(Tcl_GetString(items[0]),"Console")) {
887    if (n>2)
888      ArgIndexes = Tcl_NewListObj(n-2,items+2);
889    else
890      ArgIndexes = Tcl_NewListObj(0,NULL);
891  } else {
892    if (n>1)
893      ArgIndexes = Tcl_NewListObj(n-1,items+1);
894    else
895      ArgIndexes = Tcl_NewListObj(0,NULL);
896  }
897
[aca1089]898  for( i = 0; i < ARG_GRAMMAR; ++i ) {
899    datav[ i ] = script_header[ i ];
900  }
[6d7779d]901 
902  datav[ARG_GRAMMAR] = Tcl_NewObj();
903  datav[ARG_NAME]    = Tcl_NewObj();
904  datav[ARG_CONTENT] = Tcl_NewObj();
905  datav[ARG_PATH]    = Tcl_NewObj();
906  datav[ARG_DESC]    = Tcl_NewObj();
907  Tcl_Obj * last_index = Tcl_NewIntObj(0);
908  Tcl_ListObjAppendElement(NULL,ArgIndexes,last_index);
909  datav[ARG_INDEXES] = ArgIndexes;
910  Tcl_ListObjLength(NULL,datav[ARG_INDEXES],&index_length);
911  datav[ARG_ISFILE] = Tcl_NewObj();
912  datav[ARG_HASSUBSET] = Tcl_NewObj();
913  datav[ARG_SUBTYPE] = Tcl_NewObj();
914  datav[ARG_STRUCT] = Tcl_NewObj();
[aca1089]915  for ( i = 0; i < NUM_ARGS; ++i ) {
916    Tcl_IncrRefCount( datav[i] );
917  }
[6d7779d]918 
[c14b554]919  BSyntaxObject *syn_i;
920  BSet          *set_i; /* just in case syn_i be a container */
[6d7779d]921  /* now iter over its children */
922 
923  Tcl_DStringInit(&dstr);
924  BText btxt;
[c14b554]925 
[aca1089]926  for ( i = 1; i <= card; ++i ) {
[c14b554]927    syn_i = (*set)[i];
[6d7779d]928   
929    /* read the grammar */
930    btxt = syn_i->Grammar()->Name();
931    Tcl_ExternalToUtfDString(NULL,btxt,-1,&dstr);
932    if (Tcl_IsShared(datav[ARG_GRAMMAR])) {
933      Tcl_DecrRefCount(datav[ARG_GRAMMAR]);
934      datav[ARG_GRAMMAR] = Tcl_NewStringObj(Tcl_DStringValue(&dstr),-1);
935      Tcl_IncrRefCount(datav[ARG_GRAMMAR]);
936    } else
937      Tcl_SetStringObj(datav[ARG_GRAMMAR], Tcl_DStringValue(&dstr),-1);
938    Tcl_DStringFree(&dstr);
939   
940    /* read the name */
941    //btxt = syn_i->Identify();
[d143dd9]942    GetName( syn_i, btxt );
[6d7779d]943    Tcl_ExternalToUtfDString(NULL,btxt,-1,&dstr);
944    if (Tcl_IsShared(datav[ARG_NAME])) {
945      Tcl_DecrRefCount(datav[ARG_NAME]);
946      datav[ARG_NAME] = Tcl_NewStringObj(Tcl_DStringValue(&dstr),-1);
947      Tcl_IncrRefCount(datav[ARG_NAME]);
948    } else
949      Tcl_SetStringObj(datav[ARG_NAME], Tcl_DStringValue(&dstr),-1);
950    Tcl_DStringFree(&dstr);
951   
952    /* read the content */
953    btxt = syn_i->Info();
954    Tcl_ExternalToUtfDString(NULL,btxt,-1,&dstr);
955    if (Tcl_IsShared(datav[ARG_CONTENT])) {
956      Tcl_DecrRefCount(datav[ARG_CONTENT]);
957      datav[ARG_CONTENT] = Tcl_NewStringObj(Tcl_DStringValue(&dstr),-1);
958      Tcl_IncrRefCount(datav[ARG_CONTENT]);
959    } else
960      Tcl_SetStringObj(datav[ARG_CONTENT],Tcl_DStringValue(&dstr),-1);
961    Tcl_DStringFree(&dstr);
962   
963    /* read the path */
964    btxt = syn_i->SourcePath();
965    Tcl_ExternalToUtfDString(NULL,btxt,-1,&dstr);
966    if (Tcl_IsShared(datav[ARG_PATH])) {
967      Tcl_DecrRefCount(datav[ARG_PATH]);
968      datav[ARG_PATH] = Tcl_NewStringObj(Tcl_DStringValue(&dstr),-1);
969      Tcl_IncrRefCount(datav[ARG_PATH]);
970    } else
971      Tcl_SetStringObj(datav[ARG_PATH],Tcl_DStringValue(&dstr),-1);
972    Tcl_DStringFree(&dstr);
973   
[aca1089]974    /* read the description */   
[6d7779d]975    btxt = syn_i->Description();
976    Tcl_ExternalToUtfDString(NULL,btxt,-1,&dstr);
977    if (Tcl_IsShared(datav[ARG_DESC])) {
978      Tcl_DecrRefCount(datav[ARG_DESC]);
979      datav[ARG_DESC] = Tcl_NewStringObj(Tcl_DStringValue(&dstr),-1);
980      Tcl_IncrRefCount(datav[ARG_DESC]);
981    } else
982      Tcl_SetStringObj(datav[ARG_DESC],Tcl_DStringValue(&dstr),-1);
983    Tcl_DStringFree(&dstr);
984   
[c14b554]985    if ((set_i=ContainerGetSet(syn_i))) {
[6d7779d]986      /* update last index */
987      if (Tcl_IsShared(last_index)) {
988        last_index = Tcl_NewIntObj(i);
989        Tcl_ListObjReplace(NULL, datav[ARG_INDEXES], index_length-1,
990                           1, 1, &last_index);
991      }
992      /* set the last value index */
[aca1089]993      Tcl_SetIntObj( last_index, i );
[6d7779d]994      /* to refresh the string */
[aca1089]995      Tcl_InvalidateStringRep( datav[ ARG_INDEXES ] );
996      if ( Tcl_IsShared( datav[ ARG_ISFILE ] ) ) {
997        Tcl_DecrRefCount( datav[ ARG_ISFILE ] );
[6d7779d]998#ifdef ISFILE_IMPLEMENTED
[aca1089]999        datav[ ARG_ISFILE ] = Tcl_NewIntObj( syn_i->IsFile( ) );
[6d7779d]1000#else
[aca1089]1001        datav[ARG_ISFILE] = Tcl_NewIntObj( 0 );
[6d7779d]1002#endif
[aca1089]1003        Tcl_IncrRefCount( datav[ ARG_ISFILE ] );
[6d7779d]1004      } else
1005#ifdef ISFILE_IMPLEMENTED
[aca1089]1006        Tcl_SetIntObj( datav[ ARG_ISFILE ], syn_i->IsFile( ) );
[6d7779d]1007#else
[aca1089]1008      Tcl_SetIntObj( datav[ ARG_ISFILE ], 0 );
[6d7779d]1009#endif
1010      /* verify if has subset */
[aca1089]1011      int tmpCard = set_i->Card( );
[c14b554]1012      int j;
[6d7779d]1013      for (j=1; j<=tmpCard; ++j )
[aca1089]1014        if ( ContainerGetSet( ( *set_i )[ j ] ) )
[6d7779d]1015          break;
[aca1089]1016      if ( Tcl_IsShared( datav[ ARG_HASSUBSET ] ) ) {
1017        Tcl_DecrRefCount( datav[ ARG_HASSUBSET ] );
1018        datav[ ARG_HASSUBSET ] = Tcl_NewIntObj( j <= tmpCard );
1019        Tcl_IncrRefCount( datav[ ARG_HASSUBSET ] );
[6d7779d]1020      } else
[aca1089]1021        Tcl_SetIntObj( datav[ ARG_HASSUBSET ], j <= tmpCard );
[6d7779d]1022       
1023      /* subtype info */
[aca1089]1024      if ( Tcl_IsShared( datav[ ARG_SUBTYPE ] ) ) {
1025        Tcl_DecrRefCount( datav[ ARG_SUBTYPE ] );
1026        datav[ ARG_SUBTYPE ] = Tcl_NewIntObj( set_i->SubType( ) );
1027        Tcl_IncrRefCount( datav[ ARG_SUBTYPE ] );
[6d7779d]1028      } else
[aca1089]1029        Tcl_SetIntObj( datav[ ARG_SUBTYPE ],set_i->SubType( ) );
[6d7779d]1030       
1031      /* STRUCT INFO */
[aca1089]1032      if ( set_i->Struct( ) ) {
1033        btxt = set_i->Struct( )->Name( );
1034        Tcl_ExternalToUtfDString( NULL, btxt, -1, &dstr );
[6d7779d]1035      }
[aca1089]1036      if ( Tcl_IsShared( datav[ ARG_STRUCT ] ) ) {
1037        Tcl_DecrRefCount( datav[ ARG_STRUCT ] );
1038        datav[ ARG_STRUCT ] = Tcl_NewStringObj( Tcl_DStringValue( &dstr ),-1 );
1039        Tcl_IncrRefCount( datav[ ARG_STRUCT ] );
[6d7779d]1040      } else
[aca1089]1041        Tcl_SetStringObj( datav[ ARG_STRUCT ], Tcl_DStringValue( &dstr ),-1 );
1042      Tcl_DStringFree( &dstr );
[6d7779d]1043      datac = NUM_ARGS;
1044    } else
1045      datac = ARG_INDEXES;
[aca1089]1046    tcl_code = Tcl_EvalObjv( interp, datac, datav, TCL_EVAL_GLOBAL );
1047    if ( tcl_code == TCL_BREAK ) {
1048      tcl_code = TCL_OK;
1049      break;
[6d7779d]1050    }
[aca1089]1051    if ( tcl_code == TCL_ERROR ) {
1052      Tcl_AppendObjToObj( obj_result, Tcl_GetObjResult( interp ) );
[6d7779d]1053      break;
[aca1089]1054    }
[6d7779d]1055  }
1056 
1057  /* liberar los objetos tcl */
[aca1089]1058  /* OJO aqui tenia ARG_GRAMMAR en lugar de 0 */
1059  for ( i = 0; i < NUM_ARGS; ++i ) {
1060    Tcl_DecrRefCount( datav[ i ] );
1061  }
1062  delete []datav;
1063  return tcl_code;
[6d7779d]1064}
1065
1066/*
1067 * Fill in obj_result the content of the matrix variable.
1068 *
1069 */
1070
1071int Tol_GetMatrixContent(Tcl_Interp * interp,
1072                         Tcl_Obj * obj_name,
1073                         Tcl_Obj * obj_result)
1074{
1075  //BGrammar * gra = NULL;
[c14b554]1076  const BSyntaxObject *tol_obj = NULL;
[6d7779d]1077   
[c14b554]1078  if (!(tol_obj=Tol_ResolveObject(interp, obj_name, obj_result))) {
[6d7779d]1079    return TCL_ERROR;
1080  }
[c14b554]1081
1082  BMatrix<double> vmat;
1083  BMatrix<double> &theMat = vmat;
1084
1085  if (tol_obj->Grammar()==GraVMatrix()) {
1086    BVMat &V = VMat((BSyntaxObject *)tol_obj);
1087    V.GetDMat(vmat);
1088  } else if (tol_obj->Grammar()==GraMatrix()) {
1089    theMat = ((DMat&)Mat((BSyntaxObject *)tol_obj));
1090  } else { 
1091    Tcl_AppendStringsToObj( obj_result, Tcl_GetString(obj_name),
1092                            " is not a valid Matrix|VMatrix object", NULL );   
1093    return TCL_ERROR;
1094  }
1095   
[6d7779d]1096#define IT_NAME 0
1097#define IT_ROWS 1
1098#define IT_COLS 2
1099#define IT_DATA 3
1100#define IT_SIZE 4
1101     
1102  Tcl_Obj * items[4];
1103  Tcl_Obj ** subitems;
1104  int r, Rows, c, Cols;
1105  BDat & dat = BDat::Unknown();
1106 
[c14b554]1107  //BMatrix<BDat> & mat = (BMatrix<BDat>&)(((BUserMat*)tol_obj)->Contens());
[6d7779d]1108 
1109  //items[IT_NAME] = Tcl_NewStringObj(tol_obj->Identify(),-1);
[d143dd9]1110  BText tmp;
1111  GetName( tol_obj, tmp );
1112  items[IT_NAME] = Tcl_NewStringObj(tmp.Buffer(),-1);
[c14b554]1113  Rows = theMat.Rows();
1114  Cols = theMat.Columns();
[6d7779d]1115  items[IT_ROWS] = Tcl_NewIntObj(Rows);
1116  items[IT_COLS] = Tcl_NewIntObj(Cols);
1117  subitems = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*Rows*Cols );
1118  for ( r = 0; r < Rows; ++r )
1119    for ( c = 0; c < Cols; ++c ) {
[c14b554]1120      dat = theMat(r,c);
[6d7779d]1121      if (dat.IsKnown())
1122        subitems[r*Cols+c] = Tcl_NewDoubleObj(dat.Value());
1123      else
1124        subitems[r*Cols+c] = Tcl_NewStringObj("?",-1);
1125    }
1126  items[IT_DATA] = Tcl_NewListObj( Rows*Cols, subitems );
1127  Tcl_SetListObj( obj_result,IT_SIZE, items );
1128  Tcl_Free( (char*)subitems );
1129  return TCL_OK;
1130}
1131
1132/*
1133 * Fill in obj_result the content of the serie variable.
1134 *
1135 */
1136
1137int Tol_GetSerieContent(Tcl_Interp * interp,
1138                        int objc,
1139                        Tcl_Obj *CONST objv[],
1140                        Tcl_Obj * obj_result)
1141{
[c14b554]1142  const BSyntaxObject* var = Tol_ResolveObject(interp,
1143                                               objv[0],
1144                                               obj_result/*,
1145                                               GraSerie()*/);
[6d7779d]1146  if (!var) {
1147    return TCL_ERROR;
1148  }
1149
1150  // parse dates arguments
1151 
1152  BDate I0, I1;
1153  int tcl_code;
1154
1155  BUserTimeSerie * serie = (BUserTimeSerie*)var;
1156  serie->ReadData();
1157
1158  if (objc == 1) {
1159    I0 = serie->FirstDate();
1160    I1 = serie->LastDate();
1161  } else {
1162    tcl_code = Tol_ParseDate(interp,Tcl_GetString(objv[1]),I0);
1163    if (tcl_code != TCL_OK) {
1164      Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
1165      return TCL_ERROR;
1166    }
1167    if (objc == 3) {
1168      tcl_code = Tol_ParseDate(interp,Tcl_GetString(objv[2]),I1);
1169      if (tcl_code != TCL_OK) {
1170        Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
1171        return TCL_ERROR;
1172      }
1173    }
1174  }
1175 
1176  if ( !I0.HasValue() )
1177    I0 = BDate::DefaultFirst();
1178  if ( !I1.HasValue() )
1179    I1 = BDate::DefaultLast();
1180
1181  BUserTimeSet * tms;
1182  Tcl_Obj ** obj_array;
1183  int length;
1184
1185  char buffer[1024];
1186
1187  tms = serie->Dating();
1188
1189  if ( !tms ) {
1190    Tcl_AppendStringsToObj(obj_result,"Serie \"",
[c14b554]1191                           Tcl_GetString(objv[0]),
[6d7779d]1192                           "\" does not have dating", NULL);
1193    return TCL_ERROR;
1194  }
1195
1196  // ajustamos el intervalo de fechas al fechado
1197
1198  I0 = tms->FirstNoLess(I0);
1199  I1 = tms->FirstNoGreat(I1);
1200  length = tms->Difference(I0,I1)+1;
1201  if ( length <= 0 ) {
1202    Tcl_SetStringObj(obj_result,
1203                     "last date must be greater or equal than first",-1);
1204    return TCL_ERROR;
1205  }
1206
1207  BDat  value;
1208  BText tmp;
1209  Tcl_Obj * subitems[2];
1210
1211  // ++ because we identify the TimeSet as the first element
1212
1213  ++length;
1214  obj_array = (Tcl_Obj**)ckalloc(length*sizeof(Tcl_Obj*));
1215
1216  //tmp = tms->Identify();
[d143dd9]1217  GetName(tms, tmp);
[6d7779d]1218  obj_array[0] = Tcl_NewStringObj(tmp,-1);
1219  for ( int i = 1; i < length; i++ ) {
1220    tmp = I0.GetText();
1221    subitems[0] = Tcl_NewStringObj(tmp,-1);
1222#if defined(_TOL_FROZEN_)
1223    value = (*serie)[I0];
1224#else
1225    value = (*serie)(I0);
1226#endif
1227    if ( value.IsKnown() )
1228      subitems[1] = Tcl_NewDoubleObj(value.Value());
1229    else
1230      subitems[1] = Tcl_NewStringObj("?",-1);
1231    obj_array[i] = Tcl_NewListObj(2,subitems);
1232    I0 += tms;
1233
1234    sprintf(buffer,"%d",i);
1235    Tcl_VarEval(interp, "puts ", buffer, NULL);
1236  }
1237  Tcl_SetListObj(obj_result,length,obj_array);
1238  Tcl_Free( (char*)obj_array );
1239  return TCL_OK;
1240}
1241
1242int Tol_ParseDate(Tcl_Interp * interp, char * what, BDate & date)
1243{
1244  int    year, month, day, hour, min;
1245  double sec;
1246 
1247  int tcl_code;
1248  Tcl_Obj * tcl_result;
1249  int objc;
1250  Tcl_Obj ** objv;
1251
1252  month = day = 1;
1253  hour  = min = 0;
1254  sec   = 0.0;
1255  char re_pat[] = "{^(?:y([0-9]+)(?:m([0-9]+))?(?:d([0-9]+))?)$}";
1256
1257  tcl_code = Tcl_VarEval(interp, "regexp -inline ", re_pat, " ",what, NULL);
1258  if ( tcl_code != TCL_OK )
1259    return TCL_ERROR;
1260  tcl_result = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
1261  /* this should be a valid list, unless Tcl be corrupt */
1262  Tcl_ListObjGetElements(interp,tcl_result,&objc,&objv);
1263  if ( objc == 0 ) {
1264    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1265                           "invalid date: \"",what,"\"",NULL);
1266    Tcl_DecrRefCount(tcl_result);
1267    return TCL_ERROR;
1268  }
1269
1270  /* and objc must be 4 */
1271
1272  Tcl_GetIntFromObj(interp,objv[1],&year);
1273  Tcl_GetIntFromObj(interp,objv[2],&month);
1274  Tcl_GetIntFromObj(interp,objv[3],&day);
1275
1276  /* now is save to release tcl_result */
1277
1278  Tcl_DecrRefCount(tcl_result);
1279
1280  date.PutDate(year,month,day);
1281  if ( !date.HasValue() ) {
1282    Tcl_ResetResult(interp);
1283    char buffer[1024];
1284    sprintf(buffer,"y%dm%dd%d",year,month,day);
1285    tcl_result = Tcl_GetObjResult(interp);
1286    Tcl_AppendStringsToObj(tcl_result,
1287                           what," = ",buffer," is valid but unknown",NULL);
1288    return TCL_ERROR;
1289  }
1290  return TCL_OK;
1291}
1292
1293/*
1294 * Set the language to be used  by TOL. Fill in obj_result the previous
1295 * language.
1296 *
1297 */
1298
1299int Tol_SetLanguage(Tcl_Interp * interp, Tcl_Obj * lang, Tcl_Obj * obj_result)
1300{
1301  BBool curLang = BText::Language();
1302  BIdiomEnum nextLang;
1303 
1304  char * strLang = Tcl_GetString( lang );
1305  if ( !strcasecmp( strLang, "es" ) )
1306    nextLang = BSPANISH;
1307  else {
1308    /* anything else will be assumed as english */
1309    nextLang = BENGLISH;
1310  }
1311  /* set the previous language as result */
1312  if ( curLang == BSPANISH )
1313    Tcl_SetStringObj( obj_result, "es", -1 );
1314  else
1315    Tcl_SetStringObj( obj_result, "en", -1 );
1316  /* tell TOL what language to use from now on */
1317  BText::PutLanguage( nextLang );
1318  return TCL_OK;
1319}
1320
1321/*
1322 * Return the language used  by TOL. Fill in obj_result the current
1323 * language.
1324 *
1325 */
1326
1327int Tol_GetLanguage(Tcl_Interp * interp, Tcl_Obj * obj_result)
1328{
1329  BBool curLang = BText::Language();
1330 
1331  if ( curLang == BSPANISH )
1332    Tcl_SetStringObj( obj_result, "es", -1 );
1333  else
1334    Tcl_SetStringObj( obj_result, "en", -1 );
1335  return TCL_OK;
1336}
1337
1338/*
1339 * Fill in obj_result the version info corresponding to tol
1340 *
1341 *   {major MajorNum minor MinorNum release ReleaseNum coment Comment}
1342 *
1343 */
1344
1345int Tol_InfoVersion( Tcl_Interp * interp,  Tcl_Obj * obj_result )
1346{
1347#define VERSION_INFO_SIZE 4*2
1348 
1349  Tcl_Obj * items[VERSION_INFO_SIZE];
1350  char buffer[64];
1351
1352  /* Major Info */
1353  items[0] = Tcl_NewStringObj( "major", -1 );
1354  items[1] = Tcl_NewIntObj( VERSION_MAJOR );
1355  /* Minor Info */
1356  items[2] = Tcl_NewStringObj( "minor", -1 );
1357  items[3] = Tcl_NewIntObj( VERSION_MINOR );
1358  /* Release Info */
1359  items[4] = Tcl_NewStringObj( "release", -1 );
1360  sprintf(buffer,"%d", VERSION_RELEASE);
1361  items[5] = Tcl_NewStringObj(buffer, -1);
1362  /* Comment Info */
1363  items[6] = Tcl_NewStringObj( "comment", -1 );
1364  items[7] = Tcl_NewStringObj(TOLVersionBuild(), -1 );
1365  /* asign the items to the result list */
1366  Tcl_SetListObj( obj_result, VERSION_INFO_SIZE, items );
1367  return TCL_OK;
1368}
1369
1370/*
1371 * Fill in obj_result the list of files included in TOL
1372 *
1373 */
1374
1375
1376int Tol_InfoIncluded (Tcl_Interp * interp,Tcl_Obj * obj_result)
1377{
1378  BList* lst = BSetFromFile::Compiled();
1379
1380  BText txt(LstText(lst,"","",","));
1381  return BList2TclList(interp,lst,obj_result,&GetPath,&HasNoSource);
1382}
1383
1384/* OJO con la declaracion de tmpSet */
1385
1386int Tol_InfoFile(Tcl_Interp * interp, Tcl_Obj * file,
1387                 Tcl_Obj * obj_result)
1388{
1389  Tcl_DString dstr;
1390  const BSyntaxObject * so;
1391
1392  Tcl_DStringInit(&dstr);
1393  Tcl_UtfToExternalDString(NULL,Tcl_GetString(file),-1,&dstr);
1394 
1395  BText fname(Tcl_DStringValue(&dstr));
1396  so = (const BSyntaxObject*)BSetFromFile::FindCompiled(fname);
1397  Tcl_DStringFree(&dstr);
1398  if (!so) {
1399    Tcl_AppendStringsToObj(obj_result,"file \"",
1400                           Tcl_GetString(file),
1401                           "\" isn't included", NULL );
1402    return TCL_ERROR;
1403  }
1404  Tcl_Obj * info[6];
1405  /* adicionar la informacion del subtype y si tiene algun set
1406   * como descendiente
1407   */
1408  BText soInfo(so->Info());
1409  BText soPath(so->SourcePath());
1410  BText soDesc(so->Description());
1411
1412  char * pch = soInfo;
1413  if (pch) pch = skipWhite(pch);
[aca1089]1414  else pch = (char*)"";
[6d7779d]1415
1416  Tcl_ExternalToUtfDString(NULL,pch,-1,&dstr);
1417  info[0] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
1418  Tcl_DStringFree(&dstr);
1419
1420  Tcl_ExternalToUtfDString(NULL,soPath,-1,&dstr);
1421  info[1] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
1422  Tcl_DStringFree(&dstr);
1423
1424  Tcl_ExternalToUtfDString(NULL,soDesc,-1,&dstr);
1425  info[2] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
1426  Tcl_DStringFree(&dstr);
1427
1428  /* HAS SUBSET */
1429  BSet * ptrSet = &(((BUserSet*)so)->Contens());
1430  int tmpCard = ptrSet->Card();
1431  int j;
1432  for (j=1; j<=tmpCard; ++j )
[c14b554]1433    if (ContainerGetSet((*ptrSet)[j]))
[6d7779d]1434      break;
1435  info[3] = Tcl_NewIntObj(j<=tmpCard);
1436   
1437  /* SUBTYPE INFO */
1438  info[4] = Tcl_NewIntObj( ptrSet->SubType() );
1439  /* STRUCTURE */
1440  info[5] = Tcl_NewStringObj( NULL, 0 );
1441  Tcl_SetListObj(obj_result, 6, info);
1442  return TCL_OK;
1443}
1444
1445/*
1446 * Fill in obj_result the result of evaluating including the file
1447 * given as argument: the absolute path.
1448 *
1449 */
1450
1451int Tol_IncludeFile(Tcl_Interp * interp,Tcl_Obj * obj_file,Tcl_Obj * obj_result)
1452{
1453  Tcl_DString dstr;
1454  BText fName;
1455
1456  Tcl_DStringInit(&dstr);
1457  fName = Tcl_UtfToExternalDString(NULL,Tcl_GetString(obj_file),-1,&dstr);
1458  BSetFromFile* uSet = (BSetFromFile*)BSetFromFile::FindCompiled(fName);
1459  Tcl_DStringFree(&dstr);
1460
1461  if(uSet) {
1462    DESTROY(uSet);
1463  }
1464  IncludeFile(fName);
1465  return TCL_OK;
1466}
1467
1468int Tol_DecompileFile( Tcl_Interp * interp,
1469                       Tcl_Obj * obj_file,
1470                       Tcl_Obj * obj_result )
1471{
1472  Tcl_DString dstr;
1473  BText fName;
1474
1475  Tcl_DStringInit(&dstr);
1476  fName = Tcl_UtfToExternalDString(NULL,Tcl_GetString(obj_file),-1,&dstr);
1477  BSetFromFile* uSet = (BSetFromFile*)BSetFromFile::FindCompiled(fName);
1478  Tcl_DStringFree(&dstr);
1479
1480  if(uSet) {
1481    DESTROY(uSet);
1482  } else {
1483    Tcl_AppendStringsToObj( obj_result, "file '",
1484                            Tcl_GetString(obj_file),
1485                            "' is not compiled", NULL );
1486    return TCL_ERROR;
1487  }
1488  if ( uSet ) {
1489    Tcl_AppendStringsToObj( obj_result, "could not decompile file '",
1490                            Tcl_GetString(obj_file), "'", NULL );
1491    return TCL_ERROR;
1492  }
1493  return TCL_OK;
1494}
1495/*
1496 *
1497 * Fill in obj_result the list of grammars defined in TOL
1498 *
1499 */
1500
1501int Tol_SetGrammarsObj(Tcl_Interp * interp, Tcl_Obj * obj_result )
1502{
1503
1504  BList* lstGra = BGrammar::Instances();
1505
1506  if (BList2TclList(interp,lstGra,obj_result,&GetName,&ExcludeAnything)==TCL_OK) {
1507    Tcl_Obj * name = Tcl_NewStringObj("Anything", -1);
1508    if (Tcl_ListObjAppendElement(interp,obj_result,name) != TCL_OK) {
1509      Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
1510      return TCL_ERROR;
1511    }
1512    if (QuickSort(interp,obj_result) != TCL_OK) {
1513      Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
1514      return TCL_ERROR;
1515    }
1516    return TCL_OK;
1517  }
1518  Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
1519  return TCL_ERROR;
1520}
1521
1522/*
1523 *
1524 * Fill in obj_result the description of gra_name.
1525 *
1526 */
1527
1528int Tol_SetGrammarDescObj(Tcl_Interp * interp, Tcl_Obj * gra_name,
1529                          Tcl_Obj * obj_result )
1530{
1531  BGrammar * gra = BGrammar::FindByName(Tcl_GetString(gra_name));
1532
1533  if (gra) {
1534    BText desc(gra->Description());
1535    Tcl_SetStringObj(obj_result, desc, -1);
1536    return TCL_OK;
1537  }
1538  Tcl_AppendStringsToObj( obj_result, "\"",
1539                          Tcl_GetString(gra_name),
1540                          "\" isn't a grammar", NULL );
1541  return TCL_ERROR;
1542}
1543
1544/*
1545 *  Tol_FillFunctionInfo --
1546 *
1547 *    Used in Tol_SetFunctionsObj & Tol_SetFunctionInfoObj to return the info
1548 *    for the function requested.
1549 */
1550
1551static
1552int Tol_FillFunctionInfo(BOperator * opr, Tcl_Obj * obj_result)
1553{
1554  Tcl_Obj * info[3];
1555  Tcl_DString dstr_info;
1556  Tcl_DString dstr;
1557
1558  Tcl_DStringInit(&dstr_info);
1559  BText args(opr->Arguments());
1560 
1561  if(args.Last()!='}') // name doesn't comes within the arguments expression
1562  {   
1563      // grammar name
1564      Tcl_DStringAppend(&dstr_info, opr->Grammar()->Name(), -1);
1565      Tcl_DStringAppend(&dstr_info, " ", -1);
1566      // function name
1567      Tcl_DStringInit(&dstr);
[d143dd9]1568      Tcl_ExternalToUtfDString(NULL, opr->FullName(), -1, &dstr);
[6d7779d]1569      Tcl_DStringAppend(&dstr_info, Tcl_DStringValue(&dstr), -1);
1570      Tcl_DStringFree(&dstr);
1571  }
1572
1573  Tcl_ExternalToUtfDString(NULL,args.String(),-1,&dstr);
1574  Tcl_DStringAppend(&dstr_info, Tcl_DStringValue(&dstr), -1);
1575  Tcl_DStringFree(&dstr);
1576  info[0] = Tcl_NewStringObj(Tcl_DStringValue(&dstr_info), -1);
1577  Tcl_DStringFree(&dstr_info);
1578  Tcl_ExternalToUtfDString(NULL,opr->SourcePath(),-1,&dstr);
1579  info[1] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
1580  Tcl_DStringFree(&dstr);
1581  Tcl_ExternalToUtfDString(NULL,opr->Description(),-1,&dstr);
1582  info[2] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
1583  Tcl_DStringFree(&dstr);
1584  Tcl_SetListObj(obj_result, 3, info);
1585  return TCL_OK;
1586}
1587
1588/*
1589 *
1590 * Fill in obj_result the functions defined for grammar gra_name.  If gra_name
[c14b554]1591 * is a list it is considered as an object reference {type ?name? i1 ... ik}
[6d7779d]1592 *
1593 */
1594
1595int Tol_SetFunctionsObj (Tcl_Interp * interp, Tcl_Obj * gra_name,
1596                         Tcl_Obj * obj_result)
1597{
[c14b554]1598  int length = 0;
[6d7779d]1599 
[c14b554]1600  if (Tcl_ListObjLength(interp,gra_name,&length)!=TCL_OK) {
[6d7779d]1601    Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
1602    return TCL_ERROR;
1603  }
[c14b554]1604  if (length>1) {
1605    const BSyntaxObject *syn;
1606    if (!(syn=Tol_ResolveObject(interp, gra_name, obj_result))) {
[6d7779d]1607      return TCL_ERROR;
[c14b554]1608    }
1609   
[6d7779d]1610    if (syn->Grammar() != GraCode()) {
1611      Tcl_AppendStringsToObj(obj_result, "'", Tcl_GetString(gra_name),
1612                             "' is not a function object", NULL);
1613      return TCL_ERROR;
1614    }
1615    BOperator * opr =  ((BGraContens<BCode>*)syn)->Contens().Operator();
1616    return Tol_FillFunctionInfo(opr, obj_result);
1617  }
1618  /* gra_name should be a grammar name */
1619  if (!strcmp(Tcl_GetString(gra_name), "Anything")) {
1620    const BSpFunHash& spf = BSpecialFunction::Instances();
1621    BSpFunHash::const_iterator iter;
1622    for(iter=spf.begin(); iter!=spf.end(); iter++)
1623    {
[c14b554]1624      Tcl_ListObjAppendElement(interp, obj_result,
1625                               Tcl_NewStringObj(iter->second->Name(), -1));
[6d7779d]1626    }
1627    if (QuickSort(interp,obj_result) != TCL_OK) {
1628      Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
1629      return TCL_ERROR;
1630    }
1631    return TCL_OK;
1632  }
1633
1634  BGrammar * gra = BGrammar::FindByName(Tcl_GetString(gra_name));
1635 
1636  if (gra) {
1637    BList * lstOper = gra->GetOperators();
1638    if (BList2TclList(interp,lstOper,obj_result,&GetName) != TCL_OK) {
1639      Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
1640      DESTROY(lstOper);
1641      return TCL_ERROR;
1642    }
1643    DESTROY(lstOper);
1644    if (QuickSort(interp,obj_result) != TCL_OK) {
1645      Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
1646      return TCL_ERROR;
1647    }
1648    return TCL_OK;
1649  }
[c14b554]1650
1651  Tcl_AppendStringsToObj(obj_result, "'",
1652                         Tcl_GetString(gra_name),
1653                         "' isn't a grammar", NULL);
[6d7779d]1654  return TCL_ERROR;
1655}
1656
[a64730a]1657static
1658BOperator* TT_FindOperator( const BGrammar *G, const char *expr )
1659{
1660  BOperator* opr = G->FindOperator( expr );
1661  if ( opr ) {
1662    return opr;
1663  }
1664  bool oldEnabled = BOut::Disable();
[9c1a7ca]1665  bool stopFlag = BGrammar::StopFlag();
1666  BGrammar::Turn_StopFlag_Off();
[a64730a]1667  BSyntaxObject* obj = GraCode( )->BGrammar::LeftEvaluateExpr( expr );
[9c1a7ca]1668  if ( stopFlag ) {
1669    BGrammar::Turn_StopFlag_On();
1670  } else {
1671    BGrammar::Turn_StopFlag_Off();
1672  }
[a64730a]1673  if( oldEnabled ) { BOut::Enable( ); }
[20663cb]1674  if(obj)
1675  {
[88df01a]1676    if( obj->Mode( ) == BUSERFUNMODE )
[20663cb]1677    {
[88df01a]1678      opr = dynamic_cast<BOperator*>( obj );
[20663cb]1679    }   
[88df01a]1680    if( obj->Mode( ) == BOBJECTMODE )
[20663cb]1681    {
1682      BUserCode *uc = dynamic_cast<BUserCode*>( obj );
[88df01a]1683      opr = uc ? uc->Contens().Operator( ) : NULL;
1684      if( opr && ( opr->Grammar( ) != G ) ) { opr = NULL; }
[20663cb]1685    }
1686  }
[88df01a]1687  return( opr );
[a64730a]1688}
1689
[6d7779d]1690/*
1691 * Fill in obj_result the function's prototype and description
1692 * for a given function in a given grammar.
1693 *
1694 */
1695
1696int Tol_SetFunctionInfoObj (Tcl_Obj * gra_name,
1697                            Tcl_Obj * fun_name,
1698                            Tcl_Obj * obj_result)
1699{
1700  Tcl_DString dstr;
1701  Tcl_Obj * info[3];
1702
1703  if (!strcmp(Tcl_GetString(gra_name), "Anything")) {
1704    Tcl_DStringInit(&dstr);
1705    Tcl_UtfToExternalDString(NULL,Tcl_GetString(fun_name),-1,&dstr);
1706    const BSpecialFunction * spf = BSpecialFunction::Get(Tcl_DStringValue(&dstr));
1707    Tcl_DStringFree(&dstr);
1708    if (spf) {
1709      char * name, * args;
1710      size_t len;
1711     
1712      name = ((BText&)spf->Name()).Buffer();
1713      args = ((BText&)spf->Arguments()).Buffer();
1714      len = strlen(args);
1715      if(!len || args[len-1]!='}') {
1716        info[0] = Tcl_NewStringObj("Anything ", -1);
1717        Tcl_AppendStringsToObj(info[0],name,args,NULL);
1718      } else {
1719        info[0] = Tcl_NewStringObj("", -1);;
1720        Tcl_AppendStringsToObj(info[0],args,NULL);
1721      }
1722      info[1] = Tcl_NewStringObj("",-1);
1723      Tcl_ExternalToUtfDString(NULL,spf->Description(),-1,&dstr);
1724      info[2] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
1725      Tcl_DStringFree(&dstr);
1726      Tcl_SetListObj(obj_result, 3, info);
1727      return TCL_OK;
1728    }
1729    Tcl_AppendStringsToObj( obj_result, "\"",
1730                            Tcl_GetString(fun_name),
1731                            "\" isn't a function in grammar Anything", NULL );
1732  } else {
1733    BGrammar * gra = BGrammar::FindByName(Tcl_GetString(gra_name));
1734 
1735    if (gra) {
1736      Tcl_DStringInit(&dstr);
[a64730a]1737      Tcl_UtfToExternalDString( NULL, Tcl_GetString( fun_name ), -1, &dstr );
1738      BOperator* opr = TT_FindOperator( gra, Tcl_DStringValue( &dstr ) );
[6d7779d]1739      Tcl_DStringFree(&dstr);
1740      if (opr) {
1741        return Tol_FillFunctionInfo(opr, obj_result);
1742      }
1743      // release the previous use of dstr
1744      //Tcl_DStringFree(&dstr);
1745      Tcl_AppendStringsToObj( obj_result, "\"",
1746                              Tcl_GetString(fun_name),
1747                              "\" isn't a function in grammar ",
1748                              Tcl_GetString(gra_name), NULL );
1749    } else
1750      Tcl_AppendStringsToObj( obj_result, "\"",
1751                              Tcl_GetString(gra_name),
1752                              "\" isn't a grammar", NULL );
1753  }
1754  return TCL_ERROR;
1755}
1756
1757/* ojo info debe tener espacio para 7 Tcl_Obj como maximo */
1758/* retorna cuantos Tcl_Obj creo */
1759
1760int SynObj2TclObj( const BSyntaxObject * var, Tcl_Obj * info[] )
1761{
1762  Tcl_DString dstr;
1763  int infoc;
[c14b554]1764
[6d7779d]1765  Tcl_DStringInit(&dstr);
[c14b554]1766
1767  /* GRAMMAR */
[aca1089]1768#ifdef ISFILE_IMPLEMENTED
1769  info[ 0 ] = Tcl_NewStringObj(var->IsFile( ) ? "File" :
1770                               var->Grammar( )->Name( ).String( ), -1 );
1771#else
1772  info[ 0 ] = Tcl_NewStringObj( var->Grammar( )->Name( ).String( ), -1 );
1773#endif
[c14b554]1774   
1775  /* NAME */
[d143dd9]1776  BText synname;
1777 
1778  GetName(var, synname);
[c14b554]1779  Tcl_ExternalToUtfDString(NULL,synname,-1,&dstr);
1780  info[1] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
1781  Tcl_DStringFree(&dstr);
1782   
1783  /* REST OF FIELDS */
1784 
[6d7779d]1785  BText varInfo(var->Info());
1786  BText varPath(var->SourcePath());
1787  BText varDesc(var->Description());
1788 
1789  /* OBJECT CONTENT */
1790  char * pch = varInfo;
[aca1089]1791 
[6d7779d]1792  if (pch) pch = skipWhite(pch);
[aca1089]1793  else pch = (char*)"";
[6d7779d]1794 
1795  Tcl_ExternalToUtfDString(NULL,pch,-1,&dstr);
[c14b554]1796  info[2] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
[6d7779d]1797  Tcl_DStringFree(&dstr);
1798 
1799  /* OBJECT PATH */
1800  Tcl_ExternalToUtfDString(NULL,varPath,-1,&dstr);
[c14b554]1801  info[3] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
[6d7779d]1802  Tcl_DStringFree(&dstr);
1803 
1804  /* OBJECT DESCRIPTION */
1805  Tcl_ExternalToUtfDString(NULL,varDesc,-1,&dstr);
[c14b554]1806  info[4] = Tcl_NewStringObj(Tcl_DStringValue(&dstr), -1);
[6d7779d]1807  Tcl_DStringFree(&dstr);
1808 
1809#ifdef ISFILE_IMPLEMENTED
[c14b554]1810  info[5] = Tcl_NewIntObj(var->IsFile());
[6d7779d]1811#else
[c14b554]1812  info[5] = Tcl_NewIntObj(0);
[6d7779d]1813#endif
[c14b554]1814  //info[6] = Tcl_NewIntObj(var->System());
1815  BSet *ptrSet;
1816  if ((ptrSet=ContainerGetSet(var))) {
[6d7779d]1817    /* HAS SUBSET */
1818    int tmpCard = ptrSet->Card();
1819    int j;
1820    for (j=1; j<=tmpCard; ++j )
1821      if ( (*ptrSet)[j]->Grammar()==GraSet() )
1822        break;
[c14b554]1823    info[6] = Tcl_NewIntObj(j<=tmpCard);
[6d7779d]1824     
1825    /* SUBTYPE */
[c14b554]1826    info[7] = Tcl_NewIntObj( ptrSet->SubType() );
[6d7779d]1827     
1828    /* STRUCTURE */
1829    if ( ptrSet->Struct() ) {
1830      BText btxt( ptrSet->Struct()->Name() );
1831      Tcl_ExternalToUtfDString(NULL,btxt,-1,&dstr);
[c14b554]1832      info[8] = Tcl_NewStringObj( Tcl_DStringValue(&dstr), -1 );
[6d7779d]1833      Tcl_DStringFree( &dstr );
1834    } else
[c14b554]1835      info[8] = Tcl_NewStringObj( NULL, 0 );
1836    infoc = 9;
[6d7779d]1837  } else
[c14b554]1838    infoc = 6;
[6d7779d]1839 
1840  return infoc;
1841}
1842
[c14b554]1843int Tol_SetVariableInfoObj (Tcl_Obj * gra_name,
1844                            Tcl_Obj * var_name,
1845                            Tcl_Obj * obj_result);
1846
[6d7779d]1847/*!
1848 * Fill in obj_result the variables defined for grammar gra_name.
[c14b554]1849 * Or the element info if gra_name is a reference of an element
1850 * of a global container.
[6d7779d]1851 */
[c14b554]1852int Tol_SetVariablesObj (Tcl_Interp *interp, Tcl_Obj *gra_name,
1853                         Tcl_Obj *obj_result)
[6d7779d]1854{
[c14b554]1855  const BSyntaxObject *syn ;
1856 
1857  int length = 0;
[6d7779d]1858  Tcl_Obj ** items;
1859  int tcl_code;
[c14b554]1860 
1861  if (Tcl_ListObjLength(interp,gra_name,&length)!=TCL_OK) {
[6d7779d]1862    Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
1863    return TCL_ERROR;
1864  }
[c14b554]1865  if (length!=1) {
1866    if (length == 2) {
1867      tcl_code = Tcl_ListObjGetElements(interp,gra_name,&length,&items);
1868      assert(tcl_code == TCL_OK);
1869      if (strcmp(Tcl_GetString(items[0]),"Console"))
1870        return Tol_SetVariableInfoObj(items[0], items[1], obj_result);
1871    }
1872    if (!(syn=Tol_ResolveObject(interp, gra_name, obj_result))) {
[6d7779d]1873      return TCL_ERROR;
1874    }
[c14b554]1875//    Tcl_DString dstr;
[6d7779d]1876    Tcl_Obj * info[9];
1877    int infoc;
1878   
[c14b554]1879    infoc = SynObj2TclObj(syn, info);
[6d7779d]1880    Tcl_SetListObj(obj_result,infoc,info);
1881    return TCL_OK;
1882  }
[c14b554]1883  BGrammar *gra = BGrammar::FindByName(Tcl_GetString(gra_name));
1884  if (!gra) {
1885    Tcl_AppendStringsToObj( obj_result, "'",
1886                            Tcl_GetString(gra_name),
1887                            "' isn't a grammar", NULL );
1888    return TCL_ERROR;
[6d7779d]1889  }
[c14b554]1890  BList * lstVar = gra->GetVariables();
1891  if (BList2TclList(interp,lstVar,obj_result,&GetIdentify) != TCL_OK) {
[6d7779d]1892    Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
[c14b554]1893    DESTROY(lstVar);
[6d7779d]1894    return TCL_ERROR;
1895  }
[c14b554]1896  DESTROY(lstVar);
1897  if (QuickSort(interp,obj_result) != TCL_OK) {
1898    Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
1899    return TCL_ERROR;
[6d7779d]1900  }
[c14b554]1901  return TCL_OK;
[6d7779d]1902}
1903
1904/*
1905 * Fill in obj_result the variables's description for a given variable
1906 * in a given grammar.
1907 *
1908 */
1909
1910int Tol_SetVariableInfoObj (Tcl_Obj * gra_name,
1911                            Tcl_Obj * var_name,
1912                            Tcl_Obj * obj_result)
1913{
1914  BGrammar * gra = BGrammar::FindByName(Tcl_GetString(gra_name));
1915  Tcl_DString dstr;
1916 
1917  Tcl_DStringInit(&dstr);
1918  if (gra) {
1919    Tcl_UtfToExternalDString(NULL,Tcl_GetString(var_name),-1,&dstr);
1920    const BSyntaxObject* var = gra->FINDVARIABLE(Tcl_DStringValue(&dstr));
1921    Tcl_DStringFree(&dstr);
1922
1923    if (var) {
[c14b554]1924      Tcl_Obj * info[9];
[6d7779d]1925      int infoc;
1926      infoc = SynObj2TclObj( var, info );
1927      Tcl_SetListObj(obj_result,infoc,info);
1928//#define __INFO_PRINT_NREFS__
1929#ifdef __INFO_PRINT_NREFS__
1930      printf("NREF = %d\n", var->NRefs());
1931#endif
1932      return TCL_OK;
1933    }
1934    Tcl_AppendStringsToObj( obj_result, "\"",
1935                            Tcl_GetString(var_name),
1936                            "\" isn't a variable in grammar ",
1937                            Tcl_GetString(gra_name), NULL );
1938  } else
1939    Tcl_AppendStringsToObj( obj_result, "\"",
1940                            Tcl_GetString(gra_name),
1941                            "\" isn't a grammar", NULL );
1942  return TCL_ERROR;
1943}
1944
1945/*
[aca1089]1946 * Fill in obj_result the string representation of the
1947 * address of the object referenced in obj_ref.
1948 */
[6f16730]1949int Tol_GetAddressFromObject( Tcl_Interp * interp,
[aca1089]1950                             Tcl_Obj * obj_ref,
1951                             Tcl_Obj * obj_result)
1952{
1953  const BSyntaxObject *syn ;
1954
1955#ifndef _NDEBUG
1956#define _PRINT_ADDR_OBJREF_
1957#endif
1958
1959#ifdef _PRINT_ADDR_OBJREF_
1960  printf( "obj_ref = %s\n", Tcl_GetString( obj_ref ) );
1961#endif
1962
1963  if ( !( syn = Tol_ResolveObject( interp, obj_ref, obj_result ) ) ) {
1964    return TCL_ERROR;
1965  }
1966  BText addr = syn->GetAddressFromObject( );
1967  Tcl_AppendStringsToObj( obj_result, addr.Buffer( ), NULL );
1968  return TCL_OK;
1969}
1970                           
1971/*
[6d7779d]1972 * We must be sure that the strings use 7 bit ASCII chararters.
1973 * Otherwise we must take care of the Utf representation.
1974 *
1975 */
1976
1977static
1978int StrObjCompare(const void * O1, const void * O2)
1979{
1980  char * str1 = (*(Tcl_Obj**)O1)->bytes;
1981  char * str2 = (*(Tcl_Obj**)O2)->bytes;
1982  int check1, check2;
1983
1984  check1 = isalpha(str1[0]);
1985  check2 = isalpha(str2[0]);
1986
1987  if ( check1 && !check2 )
1988    return 1;
1989  if ( check2 && !check1 )
1990    return -1;
1991  return strcmp(str1,str2);
1992}
1993
1994static
1995int QuickSort( Tcl_Interp * interp, Tcl_Obj * list )
1996{
1997  Tcl_Obj ** obj_array;
1998  int length;
1999
2000  if (Tcl_ListObjGetElements(interp, list, &length, &obj_array) != TCL_OK) {
2001    return TCL_ERROR;
2002  }
2003  qsort((void*)obj_array, length, sizeof(Tcl_Obj*), &StrObjCompare);
2004  return TCL_OK;
2005}
2006
2007static
2008void Tol_HciWriter( const BText & str )
2009{
2010  Tcl_CmdInfo cmd_info;
2011
2012  if (TT_interp && Tcl_GetCommandInfo(TT_interp,"Tol_HciWriter",&cmd_info) ) {
2013    Tcl_DString dstr;
2014    Tcl_Obj * objv[2];
2015   
2016    Tcl_DStringInit(&dstr);
2017    Tcl_IncrRefCount(objv[0]=Tcl_NewStringObj("Tol_HciWriter",-1));
2018    Tcl_ExternalToUtfDString(NULL, ((BText&)str).Buffer(), -1, &dstr);
2019    Tcl_IncrRefCount(objv[1]=Tcl_NewStringObj(Tcl_DStringValue(&dstr), Tcl_DStringLength(&dstr)));
2020    Tcl_DStringFree(&dstr);
2021 
2022    int status = Tcl_EvalObjv(TT_interp, 2, objv, TCL_EVAL_GLOBAL);
2023    if (status != TCL_OK) {
2024      printf("message: %s\n", ((BText&)str).Buffer());
2025      printf("objv[1] : %s\n", Tcl_GetString(objv[1]));
2026      printf("%s\n", TT_interp->result);
2027    }
2028    /* release the objects */
2029    Tcl_DecrRefCount(objv[0]);
2030    Tcl_DecrRefCount(objv[1]);
2031  }
2032}
2033
2034void Tol_InstallHciWriter()
2035{
2036  BOut::PutHciWriter(Tol_HciWriter);
2037  BOut::PutLogHciWriter(Tol_HciWriter);
2038}
2039
2040static
2041void Tol_SerieChart(BList * series, const BText& FileName )
2042{
2043#define CMD_SERIECHART "Tol_SerieChartMethod"
2044#define GRP_NAME "__grptmp_chart__%d"
2045
2046  Tcl_CmdInfo cmd_info;
2047  static int id = 0;
2048
2049  if (TT_interp && Tcl_GetCommandInfo(TT_interp,CMD_SERIECHART,&cmd_info) ) {
2050    Tcl_DString dstr;
2051    Tcl_Obj * objv[3];
2052    Tcl_Obj * obj_result=Tcl_NewObj();
2053    int tcl_result;
2054    char grpname[1024];
2055   
2056    Tcl_IncrRefCount(obj_result);
2057
2058    // first create the group of series
2059    sprintf(grpname, GRP_NAME, ++id);
2060    tcl_result = Tol_CreateSerieGrp(TT_interp, grpname, series, obj_result);
2061    if (tcl_result==TCL_ERROR) {
2062      printf("%s -- error in Tol_CreateSerieGrp: %s\n", CMD_SERIECHART,
2063             Tcl_GetString(obj_result));
2064      Tcl_DecrRefCount(obj_result);
2065      return;
2066    }
2067    // release the obj_result
2068    Tcl_DecrRefCount(obj_result);   
2069    // chart command
2070    Tcl_IncrRefCount(objv[0]=Tcl_NewStringObj(CMD_SERIECHART,-1));
2071    // serie group argument
2072    Tcl_IncrRefCount(objv[1]=Tcl_NewStringObj(grpname,-1));   
2073    // file name argument
2074    Tcl_DStringInit(&dstr);
2075    Tcl_ExternalToUtfDString(NULL, ((BText&)FileName).Buffer(), -1, &dstr);
2076    Tcl_IncrRefCount(objv[2]=Tcl_NewStringObj(Tcl_DStringValue(&dstr), Tcl_DStringLength(&dstr)));
2077    Tcl_DStringFree(&dstr);
2078    int status = Tcl_EvalObjv(TT_interp, 3, objv, TCL_EVAL_GLOBAL);
2079    if (status != TCL_OK) {
2080      printf("%s -- error in Tcl_EvalObjv:\n", CMD_SERIECHART);
2081      printf("%s\n", TT_interp->result);
2082      printf("objv[1] : %s\n", Tcl_GetString(objv[1]));
2083      printf("objv[2] : %s\n", Tcl_GetString(objv[2]));
2084    }
2085    /* release the objects */
2086    for (int i=0; i<3; i++)
2087      Tcl_DecrRefCount(objv[i]);
2088    /* the group of series should be destroyied in the Hook */
2089    /*Tcl_VarEval(TT_interp, "tol::seriegrp destroy ", grpname, NULL);*/
2090  }
2091}
2092
2093int Tol_Tcl_Eval(char * script, const char ** result)
2094{
2095  int status;
2096 
2097  status = Tcl_Eval(TT_interp, script);
2098  *result = Tcl_GetStringResult(TT_interp);
2099  return status==TCL_OK;
2100}
2101
[aca1089]2102Tcl_Obj *TolObj2TclObj( BSyntaxObject *tolObj )
[6d7779d]2103{
[aca1089]2104  const char *grammar = tolObj->Grammar( )->Name( ).String( );
2105
2106  if ( !strcmp( grammar, "Text" ) ) {
2107    const BText &value = Text( tolObj );
2108    return Tcl_NewStringObj( value.String( ),-1 );
2109  } else if ( !strcmp( grammar, "Real" ) ) {
2110    const BDat &value = Dat( tolObj );
2111    return Tcl_NewDoubleObj( value.Value( ) );
2112  } else if ( !strcmp( grammar, "Set" ) ) {
2113    // a Tol Set maps to a Tcl list
2114    const BSet &setObj = ( ( BUserSet* )tolObj )->Contens( );
2115    int card = setObj.Card( );
2116    Tcl_Obj **objv = ( Tcl_Obj** )Tcl_Alloc( sizeof( Tcl_Obj* ) * card );
2117    for( int i = 1; i <= card; i++ ) {
2118      objv[ i - 1 ] = TolObj2TclObj( setObj[ i ] );
2119    }
2120    Tcl_Obj *listObj = Tcl_NewListObj( card, objv );
2121    Tcl_Free( ( char* )objv );
2122    return listObj;
[6d7779d]2123  } else {
[aca1089]2124    // other types are not treated
2125    return Tcl_NewStringObj( tolObj->Dump( ).String( ),-1 );   
[6d7779d]2126  }
2127}
2128
[aca1089]2129int Tol_Tcl_EvalEx( const BSet &Args, const char ** result )
[6d7779d]2130{
2131  int status;
2132  Tcl_Obj **objv;
[aca1089]2133  int card = Args.Card( );
[6d7779d]2134 
[aca1089]2135  if ( !Args.Card( ) ) {
[6d7779d]2136    *result = "";
2137    status = TCL_OK;
2138  } else {
[aca1089]2139    objv = ( Tcl_Obj** )Tcl_Alloc( sizeof( Tcl_Obj* ) * card );
2140    for( int i=1; i<=card; i++ ) {
2141      objv[ i-1 ] = TolObj2TclObj( Args[i] );
2142      Tcl_IncrRefCount( objv[ i - 1 ] );
[6d7779d]2143    }
[aca1089]2144    status = Tcl_EvalObjv( TT_interp, card, objv, TCL_EVAL_GLOBAL );
2145    *result = Tcl_GetStringResult( TT_interp );
2146    for( int i = 0; i < card; i++ ) {
[6d7779d]2147      Tcl_DecrRefCount(objv[i]);
2148    }
2149  }
2150  return status==TCL_OK;
2151}
2152
2153int Tol_StopEvaluation()
2154{
2155  StopFlagOn();
2156  return TCL_OK;
2157}
2158
2159/*
2160 * Fill in obj_result the format .
2161 *
2162 */
2163
2164int Tol_LCFormat(Tcl_Interp*    interp,
2165                 Tcl_Obj *CONST obj_value,
2166                 Tcl_Obj *      obj_result)
2167{
2168  double value;
2169  char buffer[256];
2170 
2171  /* read the double value from tcl obj */
2172  if (Tcl_GetDoubleFromObj(TT_interp, obj_value, &value)==TCL_ERROR)
2173    {
2174      Tcl_AppendObjToObj(obj_result,Tcl_GetObjResult(interp));
2175      return TCL_ERROR;
2176    }
2177  lc_format(value, buffer);
2178  Tcl_AppendStringsToObj(obj_result, buffer, NULL);
2179  return TCL_OK;
2180}
2181
2182void Tol_InstallMethodsHook()
2183{
2184  InstallSerieChartHook(&Tol_SerieChart);
2185  InstallTclEval(&Tol_Tcl_Eval);
2186  InstallTclEvalEx(&Tol_Tcl_EvalEx);
2187}
Note: See TracBrowser for help on using the repository browser.