1 /*
2  * Author:      Daniel Ratton Figueiredo <ratton@land.ufrj.br>
3  * Author:      William Chia-Wei Cheng (bill.cheng@acm.org)
4  *
5  * Copyright (C) 2001-2009, William Chia-Wei Cheng.
6  *
7  * This file may be distributed under the terms of the Q Public License
8  * as defined by Trolltech AS of Norway and appearing in the file
9  * LICENSE.QPL included in the packaging of this file.
10  *
11  * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
12  * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
13  * PURPOSE.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
14  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
15  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
16  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
17  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  *
19  * @(#)$Header: /mm2/home/cvs/bc-src/tgif/tangram2.c,v 1.19 2011/05/25 16:45:49 cvsps Exp $
20  */
21 
22 #define _INCLUDE_FROM_TANGRAM2_C_
23 
24 #include <ctype.h>
25 
26 #include "tgifdefs.h"
27 
28 #include "attr.e"
29 #include "auxtext.e"
30 #include "box.e"
31 #include "cmd.e"
32 #include "color.e"
33 #include "dialog.e"
34 #include "drawing.e"
35 #include "exec.e"
36 #include "menu.e"
37 #include "msg.e"
38 #include "miniline.e"
39 #include "move.e"
40 #include "obj.e"
41 #include "pattern.e"
42 #include "rcbox.e"
43 #include "select.e"
44 #include "setup.e"
45 #include "strtbl.e"
46 #include "tangram2.e"
47 #include "text.e"
48 #include "util.e"
49 
50 char	cmdLineGenParser[MAXSTRING];
51 
52 #define DO_CMD(cmd) ExecACommandFromBuffer(cmd,NULL)
53 
54 static TgMenuItemInfo tangram2MenuItemInfo[] = {
55    { "About Tangram-II", NULL, "Information about Tangram-II", NULL,
56      CMDID_ABOUT_TANGRAM2 },
57    { NULL, NULL, NULL, NULL, INVALID }
58 };
59 TgMenuInfo tangram2MenuInfo={ TGMUTYPE_TEXT, tangram2MenuItemInfo,
60                               CreateTangram2Menu };
61 
62 /* ======================= Init & CleanUp ======================= */
63 
CleanUpTangram2()64 void CleanUpTangram2()
65 {
66    CleanUpTangram2ShortCut();
67 }
68 
InitTangram2()69 int InitTangram2()
70 {
71    InitTangram2ShortCut();
72 
73    return TRUE;
74 }
75 
76 /* ======================= Tangram2 Shortcuts ======================= */
77 
78 static struct ShortCutRec tangram2ShortCutXlateTbl[] = {
79    { '\0', 0, "AboutTangram2()", 0, CMDID_ABOUT_TANGRAM2 },
80    { '\0', 0, "Tangram2GenerateChain()", 1, CMDID_TANGRAM2_GENERATE_CHAIN },
81    { '\0', 0, "Tangram2StartSimulator()", 1, CMDID_TANGRAM2_START_SIMULATOR },
82    { '\0', 0, "Tangram2SimulationStep()", 0, CMDID_TANGRAM2_SIMULATION_STEP },
83    { '\0', 0, "Tangram2EndSimulator()", 0, CMDID_TANGRAM2_END_SIMULATOR },
84    { '\0', 0, "", 0, 0 }
85 };
86 
87 static int tangram2ShortCutCmdIdIndex[MAXTANGRAM2CMDIDS-CMDID_TANGRAM2_BASE];
88 
CleanUpTangram2ShortCut()89 void CleanUpTangram2ShortCut()
90 {
91 }
92 
InitTangram2ShortCut()93 int InitTangram2ShortCut()
94 {
95    int i=0, num_cmdids=MAXTANGRAM2CMDIDS-CMDID_TANGRAM2_BASE;
96 
97    for (i=0; i < num_cmdids; i++) {
98       tangram2ShortCutCmdIdIndex[i] = INVALID;
99    }
100    for (i=0; *(tangram2ShortCutXlateTbl[i].name) != '\0'; i++) {
101       int cmdid=tangram2ShortCutXlateTbl[i].cmdid;
102 
103       if (cmdid != INVALID) {
104          int index=cmdid-CMDID_TANGRAM2_BASE;
105 
106          if (tangram2ShortCutCmdIdIndex[index] == INVALID) {
107             tangram2ShortCutCmdIdIndex[index] = i;
108          } else {
109             fprintf(stderr, "Warning:  duplicate cmdid %1d.\n", cmdid);
110          }
111       }
112    }
113    return TRUE;
114 }
115 
ValidTangram2CmdName(buf,len,pn_num_args)116 int ValidTangram2CmdName(buf, len, pn_num_args)
117    char *buf;
118    int len, *pn_num_args;
119    /*
120     * returns 0 if no match
121     * otherwise, returns (CMDID_TANGRAM2_BASE|index) where index is the
122     *       index into tangram2ShortCutXlateTbl
123     */
124 {
125    int i;
126 
127    for (i=0; *(tangram2ShortCutXlateTbl[i].name) != '\0'; i++) {
128       if (strncmp(tangram2ShortCutXlateTbl[i].name, buf, len) == 0) {
129          *pn_num_args = tangram2ShortCutXlateTbl[i].num_args;
130 
131          return (i+CMDID_TANGRAM2_BASE);
132       }
133    }
134    return 0;
135 }
136 
ValidTangram2CmdId(nCmdId)137 int ValidTangram2CmdId(nCmdId)
138    int nCmdId;
139 {
140    int cmd_index=nCmdId-CMDID_TANGRAM2_BASE, xlate_index=INVALID;
141 
142    if (nCmdId >= MAXTANGRAM2CMDIDS || nCmdId < CMDID_TANGRAM2_BASE) {
143       return FALSE;
144    }
145    xlate_index = tangram2ShortCutCmdIdIndex[cmd_index];
146    if (xlate_index == INVALID ||
147          tangram2ShortCutXlateTbl[xlate_index].num_args != 0) {
148       return FALSE;
149    }
150    return TRUE;
151 }
152 
DoTangram2Cmd(nCmdId,args)153 int DoTangram2Cmd(nCmdId, args)
154    int nCmdId;
155    char *args;
156    /* returns INVALID if the event can be caught by other windows */
157 {
158    switch (nCmdId) {
159    case CMDID_ABOUT_TANGRAM2: AboutTangram2(); break;
160    case CMDID_TANGRAM2_GENERATE_CHAIN:  Tangram2GenerateChain(args);  break;
161    case CMDID_TANGRAM2_START_SIMULATOR: Tangram2StartSimulator(args); break;
162    case CMDID_TANGRAM2_SIMULATION_STEP: Tangram2SimulationStep();     break;
163    case CMDID_TANGRAM2_END_SIMULATOR:   Tangram2EndSimulator();       break;
164    default: break;
165    }
166    return BAD;
167 }
168 
FetchTangram2ShortCutNumArgs(index,pn_num_args)169 int FetchTangram2ShortCutNumArgs(index, pn_num_args)
170    int index, *pn_num_args;
171 {
172    *pn_num_args = tangram2ShortCutXlateTbl[index].num_args;
173 
174    return TRUE;
175 }
176 
DoTangram2ShortCut(index,args)177 int DoTangram2ShortCut(index, args)
178    int index;
179    char *args;
180    /* return FALSE if cannot execute shortcut */
181 {
182    if (index < 0 || index >= MAXTANGRAM2CMDIDS-CMDID_TANGRAM2_BASE) {
183       return FALSE;
184    }
185    if (tangram2ShortCutXlateTbl[index].num_args == 0) {
186       DoTangram2Cmd(tangram2ShortCutXlateTbl[index].cmdid, NULL);
187    } else {
188       DoTangram2Cmd(tangram2ShortCutXlateTbl[index].cmdid, args);
189    }
190    return TRUE;
191 }
192 
193 /* ======================= Tangram2 Internal Commands ======================= */
194 
195 void ExecStartSimulator ARGS_DECL((struct ObjRec *, char*));
196 void ExecSimulateStep ARGS_DECL((struct ObjRec *, char*));
197 void ExecEndSimulator ARGS_DECL((struct ObjRec *, char*));
198 
199 static
200 ExecInfo gTangram2ExecInfo[] = {
201    { (NLFN*)ExecStartSimulator,      "start_simulator",                   0, 0},
202    { (NLFN*)ExecSimulateStep,        "simulate_step",                     0, 0},
203    { (NLFN*)ExecEndSimulator,        "end_simulator",                     0, 0},
204    { NULL, NULL, 0, 0 }
205 };
206 
Tangram2GetExecInfo(func_name)207 ExecInfo *Tangram2GetExecInfo(func_name)
208    char *func_name;
209 {
210    ExecInfo *pei=NULL;
211 
212    for (pei=gTangram2ExecInfo; pei->pfunc != NULL; pei++) {
213       if (strcmp(pei->func_name, func_name) == 0) {
214          return pei;
215       }
216    }
217    return NULL;
218 }
219 
220 /* --------------- Tangram2 Internal Commands Implementation --------------- */
221 
222 #define MAXCONNECTTRIES           3
223 #define PORT                   6743
224 
225 static int simulator_socket=INVALID;
226 static struct ObjRec *objGC=NULL; /* Generate Chain   button */
227 static struct ObjRec *objSS=NULL; /* Start Simulation button */
228 static struct ObjRec *objSp=NULL; /* Simulation Step  button */
229 
230 #define SP_OPT_HAS_VALUE      (1<<0)
231 #define SP_OPT_HAS_FORMAT     (1<<1)
232 #define SP_OPT_IN_ARRAY       (1<<2)
233 #define SP_OPT_FIRST_IN_ARRAY (1<<3)
234 #define SP_OPT_LAST_IN_ARRAY  (1<<4)
235 
236 #define CT_CODE_INIT_SIMULATION   0
237 #define CT_CODE_END_OF_SIMULATION 1
238 #define CT_CODE_STEP_SIMULATION   2
239 
240 #define MAXOBJECTNAME           120
241 #define MAXSYMBOLNAME           120
242 #define MAXVALUESIZE            240
243 #define MAXFORMATSIZE           24
244 #define MAXEVENTNAME            512
245 
246 #define SKIP_WHITESPACE(x) { while( isspace((int)(*(x))) ) (x)++; }
247 
248 /* Control Packet */
249 typedef struct tagT_ControlPacket {
250   int code;
251 
252   /* info to update TGIF's screen */
253   int step;
254   double elapsed_time;
255 
256   /* number of Symbol packets following */
257   int symcount;
258 
259   /* name of latest event executed by the simulator */
260   char last_event[MAXEVENTNAME];
261 } T_ControlPacket;
262 
263 /* Symbol Packet */
264 typedef struct tagT_SymbolPacket {
265   char object_name[MAXOBJECTNAME];
266   char symbol_name[MAXSYMBOLNAME];
267   int  options;                    /* available options: SP_OPT_HAS_VALUE
268                                                          SP_OPT_HAS_FORMAT
269                                                          SP_OPT_IN_ARRAY
270                                                          SP_OPT_FIRST_IN_ARRAY
271                                                          SP_OPT_LAST_IN_ARRAY */
272   int  array_index;                /* if SP_OPT_IN_ARRAY this is the index */
273   char value_string[MAXVALUESIZE]; /* if SP_OPT_HAS_VALUE this is the value */
274   char value_format[MAXFORMATSIZE];
275 } T_SymbolPacket;
276 
277 /* Function prototypes */
278 static int sendSymbolPacket( int, T_SymbolPacket * );
279 static int recvSymbolPacket( int, T_SymbolPacket * );
280 
281 static int sendControlPacket( int, T_ControlPacket * );
282 static int recvControlPacket( int, T_ControlPacket * );
283 
284 static void addSymToBuffer   ( T_SymbolPacket * );
285 static void sendAllSymPackets( int );
286 
287 static T_SymbolPacket * packet_queue = NULL;
288 static int              packet_queue_size = 0,
289                         packet_queue_max_size = 0;
290 
291 static
sendSymbolPacket(int soc,T_SymbolPacket * pack_out)292 int sendSymbolPacket( int soc, T_SymbolPacket * pack_out )
293 {
294     int  bywrite;
295 
296     if( (bywrite = write( soc, pack_out, sizeof(T_SymbolPacket) )) < 0 )
297     {
298         perror( "write" );
299         return(-1);
300     }
301     return(1);
302 }
303 
304 static
recvSymbolPacket(int soc,T_SymbolPacket * pack_in)305 int recvSymbolPacket( int soc, T_SymbolPacket * pack_in )
306 {
307     int  byread;
308 
309     if( (byread = read( soc, pack_in, sizeof(T_SymbolPacket)) ) < 0 )
310     {
311         perror( "read" );
312         return(-1);
313     }
314     return(1);
315 }
316 
317 static
sendControlPacket(int soc,T_ControlPacket * pack_out)318 int sendControlPacket( int soc, T_ControlPacket * pack_out )
319 {
320     int  bywrite;
321 
322     if( (bywrite = write( soc, pack_out, sizeof(T_ControlPacket) )) < 0 )
323     {
324         perror( "write" );
325         return(-1);
326     }
327     return(1);
328 }
329 
330 static
recvControlPacket(int soc,T_ControlPacket * pack_in)331 int recvControlPacket( int soc, T_ControlPacket * pack_in )
332 {
333     int  byread;
334 
335     if( (byread = read( soc, pack_in, sizeof(T_ControlPacket)) ) < 0 )
336     {
337         perror( "read" );
338         return(-1);
339     }
340     return(1);
341 }
342 
343 static
addSymToBuffer(T_SymbolPacket * packet)344 void addSymToBuffer( T_SymbolPacket * packet )
345 {
346     if( !packet_queue )
347     {
348         packet_queue_max_size = 8;
349         packet_queue = malloc( packet_queue_max_size *
350                                sizeof(T_SymbolPacket) );
351     }
352     else if( packet_queue_size+1 > packet_queue_max_size ) /* queue overflow */
353     {
354         packet_queue_max_size <<= 1;
355         packet_queue = realloc( packet_queue,
356                                 packet_queue_max_size *
357                                 sizeof(T_SymbolPacket) );
358     }
359 
360     memcpy( packet_queue+packet_queue_size, packet, sizeof(T_SymbolPacket) );
361     packet_queue_size++;
362 }
363 
364 static
sendAllSymPackets(int soc)365 void sendAllSymPackets( int soc )
366 {
367     int i;
368 
369     for( i = 0; i < packet_queue_size; i++ )
370         sendSymbolPacket( soc, packet_queue+i );
371 
372     if( packet_queue )
373     {
374         free( packet_queue );
375         packet_queue = NULL;
376         packet_queue_max_size = 0;
377     }
378 
379     packet_queue_size = 0;
380 }
381 
382 static
BadAttr_Simulator(attr_name,cmd_name)383 int BadAttr_Simulator(attr_name, cmd_name)
384    char *attr_name, *cmd_name;
385 {
386    char msg[MAXSTRING+1];
387 
388    sprintf(msg, "Can not find the '%s' %s '%s' command.",
389          attr_name, "attribute while executing the", cmd_name);
390    MsgBox(msg, TOOL_NAME, INFO_MB);
391    return FALSE;
392 }
393 
ExecStartSimulator(obj_ptr,orig_cmd)394 void ExecStartSimulator(obj_ptr, orig_cmd)
395    char *orig_cmd;
396    struct ObjRec *obj_ptr;
397    /* start_simulator(); */
398 {
399     char host[ 10 ];
400     char *protocol = "udp";
401     struct hostent     *phe;
402     struct servent     *pse;
403     struct protoent    *ppe;
404     struct sockaddr_in  sin;
405     int sin_size;
406     int s, type, max_desc;
407     char buffer;
408     fd_set soc_pool;
409     struct timeval timeout;
410     int one = 1;
411     char *service = "6743";
412 
413     strcpy( host, "localhost" );
414     memset( (char *)&sin, 0, sizeof( sin ) );
415     sin.sin_family = AF_INET;
416     if( (pse = getservbyname( service, protocol )) != NULL )
417         sin.sin_port = pse->s_port;
418     else
419         if( (sin.sin_port = htons( (u_short)atoi( service ) )) == 0 )
420         {
421             fprintf( stderr,"TGIF: Can't get \"%s\" service entry\n", service );
422             return;
423         }
424 
425     if( (phe = gethostbyname( host )) != NULL )
426         memcpy( (char *)&sin.sin_addr, phe->h_addr, phe->h_length );
427     else
428     {
429         sin.sin_addr.s_addr = inet_addr( host );
430 #ifdef linux
431         if( sin.sin_addr.s_addr == INADDR_NONE )
432         {
433             fprintf( stderr, "TGIF: Can't get \"%s\" host entry\n", host );
434             return;
435         }
436 #endif /* linux */
437     }
438 
439     if( (ppe = getprotobyname( protocol )) == NULL )
440     {
441         fprintf( stderr, "TGIF: Can't get \"%s\" protocol entry\n", protocol );
442         return;
443     }
444     if( strcmp( protocol, "udp" ) == 0 )
445         type = SOCK_DGRAM;
446     else
447         type = SOCK_STREAM;
448 
449     if( (s = socket( PF_INET, type, ppe->p_proto )) < 0 )
450     {
451         fprintf( stderr, "TGIF: Can't create socket\n" );
452         return;
453     }
454 
455     if( setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (char *)&one,
456         sizeof( one ) ) < 0 )
457     {
458         perror( "TGIF: REUSEADDR" );
459         return;
460     }
461 
462     if( bind( s, (struct sockaddr *)&sin, sizeof( sin ) ) < 0 )
463     {
464         perror( "TGIF: bin" );
465         return;
466     }
467 
468     if( type == SOCK_STREAM && listen( s, 0 ) < 0 )
469     {
470         fprintf( stderr, "TGIF: Can't listen on %s port\n", service );
471         return;
472     }
473     fprintf(stdout,"TGIF: ready to receive data from the simulator.\n");
474     fflush(stdout);
475 
476     FD_ZERO( &soc_pool );
477     FD_SET( s, &soc_pool );
478     max_desc = s + 1;
479     timeout.tv_sec  = 10;
480     timeout.tv_usec = 0;
481     if( select( max_desc, &soc_pool, NULL, NULL, &timeout ) < 0 )
482     {
483         perror( "TGIF: select" );
484         return;
485     }
486     if( FD_ISSET( s, &soc_pool ) )
487     {
488         sin_size = sizeof( sin );
489         if( recvfrom( s, &buffer, sizeof(buffer), 0, (struct sockaddr *)&sin,
490                       (void*)(&sin_size) ) < 0 )
491         {
492             perror( "TGIF: recv" );
493             return;
494         }
495 
496         if( connect( s, (struct sockaddr *)&sin, sin_size ) < 0 )
497         {
498             fprintf( stderr, "TGIF: Can't connect to %s.%s\n", host, service );
499             return;
500         }
501 
502         sleep( 1 );
503         if( send( s, &buffer, sizeof(buffer), 0 ) < 0 )
504         {
505             perror( "TGIF: send" );
506             return;
507         }
508 
509     }
510     else
511     {
512         fprintf( stderr, "TGIF: Timeout expired\n" );
513         return;
514     }
515 
516     simulator_socket = s;
517 
518     printf("TGIF: Client Connected.\n");
519 }
520 
ExecEndSimulator(obj_ptr,orig_cmd)521 void ExecEndSimulator(obj_ptr, orig_cmd)
522    char *orig_cmd;
523    struct ObjRec *obj_ptr;
524    /* end_simulator(); */
525 {
526     T_ControlPacket pack_out;
527 
528     if (simulator_socket == INVALID) {
529         perror("invalid simulator_socket");
530         return;
531     }
532     /* monta o pacote */
533     memset((char *)&pack_out, 0, sizeof(T_ControlPacket));
534     pack_out.code = CT_CODE_END_OF_SIMULATION;
535 
536     /* envia o pacote ao simulador */
537     sendControlPacket( simulator_socket, &pack_out );
538 
539     close(simulator_socket);
540     printf("TGIF: Simulation finished.\n");
541 }
542 
543 static
AppendLinesToAttr(attr_ptr,ppsz_lines)544 void AppendLinesToAttr(attr_ptr, ppsz_lines)
545    struct AttrRec *attr_ptr;
546    char **ppsz_lines;
547 {
548    char **ppsz=NULL;
549    struct TextRec *text_ptr=attr_ptr->obj->detail.t;
550 
551    for (ppsz=ppsz_lines; *ppsz != NULL; ppsz++) {
552       MiniLineInfo *pFirstMiniLine=NULL, *pLastMiniLine=NULL;
553 
554       CreateMiniLineFromString(*ppsz, &pFirstMiniLine, &pLastMiniLine);
555       text_ptr->minilines.last->next = pFirstMiniLine;
556       pFirstMiniLine->prev = text_ptr->minilines.last;
557       text_ptr->minilines.last = pLastMiniLine;
558       text_ptr->lines++;
559    }
560    RecalcTextMetrics(text_ptr, attr_ptr->obj->x, text_ptr->baseline_y);
561    UpdTextBBox(attr_ptr->obj);
562 }
563 
564 
UpdateStateVars(soc,obj_ptr,ct_pack_in)565 static void UpdateStateVars( soc, obj_ptr, ct_pack_in )
566 int soc;
567 struct ObjRec *obj_ptr;
568 T_ControlPacket * ct_pack_in;
569 {
570     int i;
571     int begin, end;
572     int alignment_size, name_length;
573     char line[ MAXSYMBOLNAME+MAXFORMATSIZE+MAXVALUESIZE ];
574     char line_format[ MAXFORMATSIZE ];
575     char var_value[ MAXSTRING + 1 ];
576     char last_object_name[ MAXOBJECTNAME ];
577     char name_string[ MAXSYMBOLNAME+MAXFORMATSIZE ];
578     char value_string[ MAXVALUESIZE ];
579     char att_name[ 15 ];
580     struct ObjRec *owner_obj=NULL, *named_obj;
581     struct ObjRec *att_owner_obj=NULL;
582     struct AttrRec *attr_ptr;
583     T_SymbolPacket pack_in;
584 
585     begin = 0;
586 
587     last_object_name[0] = 0;
588     CleanTmpStr();
589     alignment_size = 12;
590     sprintf( line_format, "%%-%ds%%s", alignment_size );
591 
592     for( i = 0; i < ct_pack_in->symcount; i++ )
593     {
594         recvSymbolPacket( soc, &pack_in );
595 
596         /* if we are changing between objects, must update 'Watches='
597            in the last object */
598         if( last_object_name[0] != 0 &&
599             strcmp( last_object_name, pack_in.object_name ) != 0 )
600         {
601             named_obj = FindObjWithName( botObj, obj_ptr, last_object_name,
602                                          FALSE, FALSE, &owner_obj, NULL );
603 
604             strcpy( att_name, "Watches=" );
605             attr_ptr  = FindAttrWithName( named_obj, att_name, &att_owner_obj );
606 
607             if( attr_ptr != NULL )
608             {
609                 char *count_buf = (char*)malloc( (strlen(att_name)+40) *
610                                                  sizeof(char) );
611 
612                 if( count_buf == NULL )
613                     FailAllocMessage();
614 
615                 sprintf( count_buf, "%s", att_name );
616 
617                 if( PrependToTmpStr( count_buf ) )
618                     ReplaceAttrAllValues( named_obj, attr_ptr, &topTmpStr,
619                                           &botTmpStr );
620 
621                 free(count_buf);
622             }
623 
624             CleanTmpStr();
625             alignment_size = 12;
626             sprintf( line_format, "%%-%ds%%s", alignment_size );
627         }
628         strcpy( last_object_name, pack_in.object_name );
629 
630         /* handle new packet */
631 
632         /* packets without values report invalid variables */
633         if( !(pack_in.options & SP_OPT_HAS_VALUE) )
634         {
635             continue;
636         }
637 
638         if( !(pack_in.options & SP_OPT_IN_ARRAY) )
639         {
640             if( pack_in.options & SP_OPT_HAS_FORMAT )
641                 sprintf( name_string, "%s<%s>", pack_in.symbol_name,
642                                                 pack_in.value_format );
643             else
644                 sprintf( name_string, "%s", pack_in.symbol_name );
645 
646             sprintf( value_string, "%s", pack_in.value_string );
647 
648             name_length = strlen( name_string );
649             while( name_length >= alignment_size )
650                 alignment_size += 4;
651             sprintf( line_format, "%%-%ds%%s", alignment_size );
652 
653             sprintf( line, line_format, name_string, value_string );
654             AppendToTmpStr( line );
655         }
656         else
657         {
658             if( pack_in.options & SP_OPT_FIRST_IN_ARRAY )
659             {
660                 begin = pack_in.array_index;
661                 end   = -1;
662                 strcpy( var_value, pack_in.value_string );
663             }
664             else
665             {
666                 strcat( var_value, ", " );
667                 strcat( var_value, pack_in.value_string );
668             }
669 
670             if( pack_in.options & SP_OPT_LAST_IN_ARRAY )
671             {
672                 end = pack_in.array_index;
673 
674                 if( pack_in.options & SP_OPT_HAS_FORMAT )
675                 {
676                     if( end == begin )
677                         sprintf( name_string, "%s[%d]<%s>", pack_in.symbol_name,
678                                  begin, pack_in.value_format );
679                     else
680                         sprintf( name_string, "%s[%d:%d]<%s>",
681                                  pack_in.symbol_name,
682                                  begin, end, pack_in.value_format );
683                 }
684                 else
685                 {
686                     if( end == begin )
687                         sprintf( name_string, "%s[%d]", pack_in.symbol_name,
688                                  begin );
689                     else
690                         sprintf( name_string, "%s[%d:%d]", pack_in.symbol_name,
691                                  begin, end );
692                 }
693 
694                 if( end == begin )
695                     sprintf( value_string, "%s", var_value );
696                 else
697                     sprintf( value_string, "[%s]", var_value );
698 
699 
700                 name_length = strlen( name_string );
701                 while( name_length >= alignment_size )
702                     alignment_size += 4;
703                 sprintf( line_format, "%%-%ds%%s", alignment_size );
704 
705                 sprintf( line, line_format, name_string, value_string );
706                 AppendToTmpStr( line );
707             }
708         }
709     }
710 
711     /* if there was an object in the last packet, must update 'Watches=' */
712     if( last_object_name[0] != 0 )
713     {
714         named_obj = FindObjWithName( botObj, obj_ptr, last_object_name,
715                                      FALSE, FALSE, &owner_obj, NULL );
716 
717         strcpy( att_name, "Watches=" );
718         attr_ptr  = FindAttrWithName( named_obj, att_name, &att_owner_obj );
719 
720         if( attr_ptr != NULL )
721         {
722             char *count_buf = (char*)malloc( (strlen(att_name)+40) *
723                                              sizeof(char) );
724 
725             if( count_buf == NULL )
726                 FailAllocMessage();
727 
728             sprintf( count_buf, "%s", att_name );
729 
730             if( PrependToTmpStr( count_buf ) )
731                 ReplaceAttrAllValues( named_obj, attr_ptr, &topTmpStr,
732                                       &botTmpStr );
733 
734             free(count_buf);
735         }
736 
737         CleanTmpStr();
738     }
739 }
740 
ParseFormat(format)741 int ParseFormat( format )
742 char * format;
743 {
744     char * pt;
745     int n_params, open;
746 
747     /* Syntax for formats: [.]*%[.]*[dioxX eEfFgGaA][.]* */
748     n_params = 0;
749     open     = 0;
750     pt       = format;
751 
752     do
753     {
754         /* look for a parameter beginning with '%' */
755         while( *pt != '%' && *pt != '\0' ) pt++;
756         if( *pt == '\0' )
757             break;
758 
759         pt++;
760         if( *pt == '%' )
761         {
762             pt++;
763             continue;
764         }
765 
766         open = 1;
767 
768         /* look for any of the acceptable characters for int's and doubles */
769         pt = strpbrk( pt, "dioxXeEfFgGaA" );
770         if( !pt )
771             break;
772 
773         open = 0;
774         n_params++;
775         pt++;
776     } while( 1 );
777 
778     if( n_params != 1 || open )
779         return -1;
780 
781     return 0;
782 }
783 
ParseStateVariable(buffer,symname,symvalue,symformat,options,initial_index,final_index)784 int ParseStateVariable( buffer, symname, symvalue, symformat,
785                         options, initial_index, final_index )
786 char * buffer; char * symname; char * symvalue; char * symformat;
787 int * options; int * initial_index; int * final_index;
788 {
789     int i;
790     char * pt;
791 
792     /* Syntax for requests: symname([i(:f)])(<symformat>)=(symvalue) */
793 
794     SKIP_WHITESPACE(buffer);
795     if( !isalpha((int)(*buffer)) ) return -1;
796 
797     *options = 0;
798 
799     /* getting the variable name */
800     for( i = 0; isalpha((int)(*buffer)) ||
801                 isdigit((int)(*buffer)) ||
802                 *buffer == '_';
803          buffer++, i++ )
804     {
805         symname[i] = *buffer;
806     }
807     symname[i] = 0;
808 
809     if( strlen( symname ) <= 0 ||
810         strncmp( symname, "Watches", 10 ) == 0 )
811         return(-1);
812 
813     SKIP_WHITESPACE(buffer);
814 
815     /* OPTIONAL: getting array indices */
816     if( *buffer == '[' )
817     {
818         buffer++;
819 
820         *initial_index = strtol( buffer, &pt, 0 );
821         if( pt == buffer )
822             return(-1);
823         buffer = pt;
824         if( *initial_index < 0 )
825             return(-1);
826 
827         *final_index = *initial_index;
828 
829         SKIP_WHITESPACE(buffer);
830 
831         if( *buffer == ':' )
832         {
833             buffer++;
834             *final_index = strtol( buffer, &pt, 0 );
835 
836             if( pt == buffer )
837                 return(-1);
838 
839             buffer = pt;
840             if( *final_index < *initial_index )
841                 return(-1);
842         }
843 
844         SKIP_WHITESPACE(buffer);
845 
846         if( *buffer != ']' )
847             return(-1);
848 
849         buffer++;
850 
851         *options |= SP_OPT_IN_ARRAY;
852     }
853 
854     SKIP_WHITESPACE(buffer);
855 
856     /* OPTIONAL: getting format string */
857     if( *buffer == '<' )
858     {
859         buffer++;
860 
861         pt = buffer;
862 
863         while( *pt != '>' && *pt != '\0' && *pt != '\n' )
864             pt++;
865 
866         if( pt != buffer )
867         {
868             strncpy( symformat, buffer, pt-buffer );
869             symformat[ pt - buffer ] = 0;
870             if( ParseFormat( symformat ) < 0 )
871                 return(-1);
872         }
873 
874         buffer = pt;
875 
876         if( *buffer == '>' )
877         {
878             buffer++;
879             *options |= SP_OPT_HAS_FORMAT;
880         }
881     }
882 
883     SKIP_WHITESPACE(buffer);
884 
885     /* OPTIONAL: getting the '=' sign */
886     if( *buffer == '=' )
887     {
888         buffer++;
889 
890         SKIP_WHITESPACE(buffer);
891 
892         /* OPTIONAL: getting the value */
893         if( *buffer == '[' )
894         {
895             buffer++;
896             pt = buffer;
897 
898             while( *pt != ']' && *pt != '\0' && *pt != '\n' )
899                 pt++;
900 
901             if( pt == buffer )
902                 return(-1);
903 
904             strncpy( symvalue, buffer, pt-buffer );
905             symvalue[ pt - buffer ] = 0;
906             buffer = pt;
907             *options |= SP_OPT_HAS_VALUE;
908 
909             if( *buffer != ']' )
910                 return(-1);
911         }
912         else
913         {
914             strtod( buffer, &pt );
915 
916             if( pt != buffer )
917             {
918                 strncpy( symvalue, buffer, pt-buffer );
919                 symvalue[ pt - buffer ] = 0;
920                 buffer = pt;
921                 *options |= SP_OPT_HAS_VALUE;
922             }
923         }
924     }
925 
926     return(0);
927 }
928 
929 static
getNextValue(char * values,char ** endpt)930 char * getNextValue( char * values, char ** endpt )
931 {
932     static char value[MAXVALUESIZE];
933     char * buffer;
934 
935     buffer = values;
936 
937     SKIP_WHITESPACE(buffer);
938 
939     strtod( buffer, endpt );
940     if( *endpt == buffer )
941         return(NULL);
942 
943     strncpy( value, buffer, *endpt-buffer );
944     value[ *endpt - buffer ] = 0;
945 
946     SKIP_WHITESPACE(*endpt);
947 
948     if( **endpt == ',' )
949         (*endpt)++;
950     else
951         *endpt = NULL;
952 
953     return(value);
954 }
955 
SendStepInfo(soc,ct_pack_out)956 void SendStepInfo( soc, ct_pack_out )
957 int soc;
958 T_ControlPacket * ct_pack_out;
959 {
960     int j;
961     int need_to_free_tmp_buf;
962     int initial_index, final_index;
963     int options;
964     char symvalue  [ MAXVALUESIZE ];
965     char symbol_name[ MAXSYMBOLNAME ];
966     char symformat [ MAXFORMATSIZE ];
967     char * value_string, * pt;
968     char *tmp_buf;
969     struct ObjRec *first_obj_ptr, *optr;
970     struct AttrRec *name_attr;
971     struct AttrRec *stat_attr;
972     MiniLineInfo *pMiniLine;
973 
974     T_SymbolPacket   sympack;
975 
976     CleanTmpStr();
977 
978     first_obj_ptr = topObj;
979     for( optr = first_obj_ptr; optr != NULL; optr = optr->next )
980     {
981         stat_attr = FindAttrWithName(optr,"Watches=",NULL);
982         if( stat_attr != NULL )
983         {
984             /* Found an object that has the Watches attribute */
985 
986             /* Query the object's name */
987             name_attr = FindAttrWithName(optr,"name=",NULL);
988 
989             /* For each line in the Watches attribute */
990             for( pMiniLine=stat_attr->obj->detail.t->minilines.first;
991                  pMiniLine != NULL;
992                  pMiniLine=pMiniLine->next)
993             {
994                 /* Convert attribute line text to a string */
995                 tmp_buf = ConvertMiniLineToString( pMiniLine,
996                                                    &need_to_free_tmp_buf );
997 
998                 /* if we can parse a valid state variable request */
999                 if( ParseStateVariable( tmp_buf, symbol_name, symvalue,
1000                                         symformat, &options,
1001                                         &initial_index, &final_index ) == 0 )
1002                 {
1003                     /* initialize packet's fields */
1004                     sympack.object_name[0]  = 0;
1005                     sympack.symbol_name[0]  = 0;
1006                     sympack.options         = 0;
1007                     sympack.array_index     = -1;
1008                     sympack.value_string[0] = 0;
1009                     sympack.value_format[0] = 0;
1010 
1011                     /* state variable name */
1012                     strcpy( sympack.object_name, name_attr->attr_value.s );
1013                     strcpy( sympack.symbol_name, symbol_name );
1014 
1015                     if( options & SP_OPT_HAS_FORMAT )
1016                         strcpy( sympack.value_format, symformat );
1017 
1018                     /* if state variable is part of an array */
1019                     if( options & SP_OPT_IN_ARRAY )
1020                     {
1021                         pt = symvalue;
1022 
1023                         for( j = initial_index; j <= final_index; j++ )
1024                         {
1025                             /* initialize options to those parsed */
1026                             /* SP_OPT_IN_ARRAY   is always present
1027                                SP_OPT_HAS_FORMAT may or may not appear
1028                                SP_OPT_HAS_VALUE  may appear but is ignored */
1029                             sympack.options = options;
1030 
1031                             /* add SP_OPT_FIRST_IN_ARRAY */
1032                             if( j == initial_index )
1033                                 sympack.options |= SP_OPT_FIRST_IN_ARRAY;
1034 
1035                             /* add SP_OPT_LAST_IN_ARRAY */
1036                             if( j == final_index )
1037                                 sympack.options |= SP_OPT_LAST_IN_ARRAY;
1038 
1039                             /* add current index */
1040                             sympack.array_index = j;
1041 
1042                             /* check for value */
1043                             value_string = getNextValue( pt, &pt );
1044                             if( value_string )
1045                             {
1046                                 sympack.options |= SP_OPT_HAS_VALUE;
1047                                 strcpy( sympack.value_string, value_string );
1048                             }
1049                             else
1050                                 sympack.options &= ~SP_OPT_HAS_VALUE;
1051 
1052                             /* add variable to packet queue */
1053                             addSymToBuffer( &sympack );
1054 
1055                             /* if next call to getNextValue will fail break */
1056                             if( !pt )
1057                             {
1058                                 j++;
1059                                 break;
1060                             }
1061                         }
1062 
1063                         /* add rest of variables without value */
1064                         for( ; j <= final_index; j++ )
1065                         {
1066                             /* initialize options to those parsed */
1067                             /* SP_OPT_IN_ARRAY   is always present
1068                                SP_OPT_HAS_FORMAT may or may not appear
1069                                SP_OPT_HAS_VALUE  is ignored */
1070                             sympack.options = options & ~SP_OPT_HAS_VALUE;
1071 
1072                             /* add SP_OPT_FIRST_IN_ARRAY */
1073                             if( j == initial_index )
1074                                 sympack.options |= SP_OPT_FIRST_IN_ARRAY;
1075 
1076                             /* add SP_OPT_LAST_IN_ARRAY */
1077                             if( j == final_index )
1078                                 sympack.options |= SP_OPT_LAST_IN_ARRAY;
1079 
1080                             /* add current index */
1081                             sympack.array_index = j;
1082 
1083                             /* add variable to packet queue */
1084                             addSymToBuffer( &sympack );
1085                         }
1086                     }
1087                     else /* !( options & SP_OPT_IN_ARRAY ) */
1088                     {
1089                         sympack.options = options;
1090 
1091                         /* check for value */
1092                         if( sympack.options & SP_OPT_HAS_VALUE )
1093                         {
1094                             pt = symvalue;
1095                             value_string = getNextValue( pt, &pt );
1096                             if( value_string )
1097                                 strcpy( sympack.value_string, value_string );
1098                         }
1099 
1100                         /* add variable to packet queue */
1101                         addSymToBuffer( &sympack );
1102                     }
1103                 }
1104 
1105                 if( need_to_free_tmp_buf )
1106                     UtilFree(tmp_buf);
1107             }
1108 
1109             /* Clear the Watches= attribute after sending all symbols */
1110             tmp_buf = (char*)malloc( 20 * sizeof(char) );
1111             if( tmp_buf == NULL )
1112                 FailAllocMessage();
1113 
1114             strcpy( tmp_buf, "Watches=" );
1115 
1116             AppendToTmpStr( tmp_buf );
1117 
1118             ReplaceAttrAllValues( optr, stat_attr, &topTmpStr, &botTmpStr );
1119             CleanTmpStr();
1120 
1121             free(tmp_buf);
1122         }
1123     }
1124 
1125     ct_pack_out->symcount = packet_queue_size;
1126     sendControlPacket( soc, ct_pack_out );
1127     sendAllSymPackets( soc );
1128 }
1129 
ExecSimulateStep(obj_ptr,orig_cmd)1130 void ExecSimulateStep(obj_ptr, orig_cmd)
1131    char *orig_cmd;
1132    struct ObjRec *obj_ptr;
1133 {
1134    struct AttrRec *attr_ptr;
1135    struct ObjRec *attr_owner_obj=NULL;
1136    static char execDummyStr[MAXSTRING+1];
1137 
1138    struct ObjRec *owner_obj=NULL, *named_obj;
1139    static char obj_name[MAXSTRING+1];
1140 
1141    T_ControlPacket pack_out, pack_in;
1142 
1143    static int transitions = 0;
1144    static double tempo = 0;
1145    int step = 1;
1146 
1147    if (simulator_socket == INVALID) {
1148       perror("invalid simulator_socket");
1149       return;
1150    }
1151 
1152    /* pega o valor do atributo step */
1153    strcpy(execDummyStr, "Step=");
1154    attr_ptr = FindAttrWithName(obj_ptr, execDummyStr, &attr_owner_obj);
1155    if (attr_ptr == NULL) { BadAttr_Simulator(execDummyStr, orig_cmd); return; }
1156    step = atoi(attr_ptr->attr_value.s);
1157 
1158    /*
1159     * step nao pode ser menor do que zero (se for zero entao esta com play_mode)
1160     */
1161    if (step <= 0) {
1162       step = 1;
1163    }
1164 
1165    /* monta o pacote */
1166    memset((char *)&pack_out, 0, sizeof(T_ControlPacket));
1167    pack_out.code = CT_CODE_STEP_SIMULATION;
1168    pack_out.step = step;
1169 
1170    /* send information to mark_find */
1171    SendStepInfo( simulator_socket, &pack_out );
1172 
1173    /* receive control information */
1174    if( recvControlPacket( simulator_socket, &pack_in ) < 0 )
1175       return;
1176 
1177    /* desmonta o pacote */
1178    tempo = pack_in.elapsed_time;
1179    transitions = step;
1180 
1181    /* set current text justification to center justified */
1182    DO_CMD("set_selected_text_just(\"left\")");
1183    /* set current text font to Helvetica Bold */
1184    DO_CMD("set_selected_text_font(\"Courier\")");
1185    /* set current text size to 14 */
1186    DO_CMD("set_selected_text_size(14)");
1187    /* set current text color to 'black' */
1188    DO_CMD("set_selected_obj_color(\"black\")");
1189 
1190    /* set o valor do step_time (tempo de duracao deste step) */
1191    strcpy(execDummyStr, "step_time=");
1192    attr_ptr = FindAttrWithName(obj_ptr, execDummyStr, &attr_owner_obj);
1193    if (attr_ptr == NULL) { BadAttr_Simulator(execDummyStr, orig_cmd); return; }
1194    sprintf(execDummyStr, "%.3f", tempo);
1195    ReplaceAttrFirstValue(attr_owner_obj, attr_ptr, execDummyStr);
1196 
1197    /* atualiza o valor do atributo Time do objeto "__START_SIMULATOR__" */
1198    strcpy(obj_name, "__START_SIMULATOR__");
1199    named_obj = FindObjWithName(botObj, obj_ptr, obj_name, FALSE, FALSE,
1200          &owner_obj, NULL);
1201 
1202    strcpy(execDummyStr, "Time=");
1203    attr_ptr = FindAttrWithName(named_obj, execDummyStr, &attr_owner_obj);
1204    if (attr_ptr == NULL) { BadAttr_Simulator(execDummyStr, orig_cmd); return; }
1205    tempo += atof(attr_ptr->attr_value.s);
1206    sprintf(execDummyStr, "%.3f", tempo);
1207    ReplaceAttrFirstValue(attr_owner_obj, attr_ptr, execDummyStr);
1208 
1209    /* atualiza o valor do atributo Transitions do mesmo objeto */
1210    strcpy(execDummyStr, "Transitions=");
1211    attr_ptr = FindAttrWithName(named_obj, execDummyStr, &attr_owner_obj);
1212    if (attr_ptr == NULL) { BadAttr_Simulator(execDummyStr, orig_cmd); return; }
1213    transitions += atof(attr_ptr->attr_value.s);
1214    sprintf(execDummyStr, "%d", transitions);
1215    ReplaceAttrFirstValue(attr_owner_obj, attr_ptr, execDummyStr);
1216 
1217    /* atualiza o valor do atributo Last_Event do mesmo objeto */
1218    strcpy(execDummyStr, "Last_Event=");
1219    attr_ptr = FindAttrWithName(named_obj, execDummyStr, &attr_owner_obj);
1220    if (attr_ptr == NULL) { BadAttr_Simulator(execDummyStr, orig_cmd); return; }
1221    strcpy(execDummyStr, pack_in.last_event);
1222    ReplaceAttrFirstValue(attr_owner_obj, attr_ptr, execDummyStr);
1223 
1224    /* Update state vars shown in screen */
1225    UpdateStateVars( simulator_socket, obj_ptr, &pack_in );
1226 }
1227 
1228 /* ======================= Tangram2 Menu ======================= */
1229 
RefreshTangram2Menu(menu)1230 int RefreshTangram2Menu(menu)
1231    TgMenu *menu;
1232 {
1233    int ok=TRUE;
1234 
1235    return ok;
1236 }
1237 
CreateTangram2Menu(parent_menu,x,y,menu_info,status_str_xlated)1238 TgMenu *CreateTangram2Menu(parent_menu, x, y, menu_info, status_str_xlated)
1239    TgMenu *parent_menu;
1240    int x, y;
1241    TgMenuInfo *menu_info;
1242    int status_str_xlated; /* ignored, always 0 */
1243 {
1244    TgMenu *menu=TgCreateMenuFromMenuInfo(parent_menu, x, y, menu_info, FALSE);
1245 
1246    if (menu != NULL) {
1247       if (!RefreshTangram2Menu(menu)) {
1248          return TgDestroyMenu(menu, TRUE);
1249       }
1250    }
1251    return menu;
1252 }
1253 
Tangram2Menu(X,Y,TrackMenubar)1254 int Tangram2Menu(X, Y, TrackMenubar)
1255    int X, Y, TrackMenubar;
1256 {
1257    int rc=INVALID;
1258    TgMenu *menu=(tangram2MenuInfo.create_proc)(NULL, X, Y, &tangram2MenuInfo,
1259          INVALID);
1260 
1261    activeMenu = MENU_TANGRAM2;
1262    if (menu != NULL) {
1263       rc = TgMenuLoop(menu);
1264       TgDestroyMenu(menu, TRUE);
1265    }
1266    return rc;
1267 }
1268 
1269 /* ========================= Tangram2 Menu Data ========================= */
1270 
1271 
1272 static char *GenerateChainInit[] = {
1273   "get_current_file(\"str\");",
1274   "read_file_into_attr(\"| basename $(str) .obj\", \"basename\");",
1275   "strcpy(file_name, \"$(basename).parser\");",
1276   "strcpy(str, \" \");",
1277   "write_attr_into_file(str, $(file_name));",
1278   NULL
1279 };
1280 
1281 static char *GenerateChainExec[] = {
1282   "disable_undo();",
1283   "exec(init);",
1284   "exec(write_model);",
1285   "exec(write_global_rewards);",
1286   "exec(write_indep_chains);",
1287   "enable_undo();",
1288    NULL
1289 };
1290 
1291 static char *GenerateChainWriteModel[] = {
1292   "find_obj_names_on_all_pages(obj_list,\"Declaration=*\");",
1293   "get_line_in_attr(total_objs,obj_list,0);",
1294   "for_i(i,1,$(total_objs),1,write_obj);",
1295   NULL
1296 };
1297 
1298 static char *GenerateChainErrorParts[] = {
1299   "message_box(NULL,\"Objects must have these four parts: Variables_and_parameters, Events, Messages and Rewards. $(str)\",\"Mode Error\", \"stop\");",
1300   "exec(stop);",
1301   NULL
1302 };
1303 
1304 
1305 static char *GenerateChainStop[] = {
1306   "enable_undo();",
1307   "stop();",
1308   NULL
1309 };
1310 
1311 
1312 static char *GenerateChainAppendGlobalRewards[] = {
1313   "append_attr_into_file(__GLOBAL_REWARDS__.global_rewards, $(file_name));",
1314  NULL
1315 };
1316 
1317 
1318 static char *GenerateChainWriteIndependentChains[] = {
1319   "strcpy(str, \"Independent_Chains {\");",
1320   "append_attr_into_file(str,$(file_name));",
1321   "is_attr(result, __INDEP_CHAINS__.independent_chains);",
1322   "if($(result) != 0, append_indep_chains, NULL);",
1323   "strcpy(str, \"}\");",
1324   "append_attr_into_file(str,$(file_name));",
1325   NULL
1326 };
1327 
1328 static char *GenerateChainAppendIndepChains[] = {
1329   "append_attr_into_file(__INDEP_CHAINS__.independent_chains, $(file_name));",
1330   NULL
1331 };
1332 
1333 
1334 static char *GenerateChainWriteGlobalRewards[] = {
1335   "strcpy(str, \"Global_Rewards {\");",
1336   "append_attr_into_file(str,$(file_name));",
1337   "is_attr(result, __GLOBAL_REWARDS__.global_rewards);",
1338   "if($(result) != 0, append_global_rewards, NULL);",
1339   "strcpy(str, \"}\");",
1340   "append_attr_into_file(str,$(file_name));",
1341   NULL
1342 };
1343 
1344 static char *GenerateChainWriteMaxValues[] = {
1345   "strcpy(max_file_name, \"$(basename).maxvalues\");",
1346   "strcpy(str, \"$(__SETUP__.max_values)\");",
1347   "write_attr_into_file(__SETUP__.max_values, $(max_file_name));",
1348  NULL
1349 };
1350 
1351 
1352 static char *GenerateChainWriteObj[] = {
1353   "get_line_in_attr(obj_name,obj_list,$(i));",
1354   "strcpy(str, \"Object_Desc $(obj_name) (\");",
1355   "append_attr_into_file(str,$(file_name));",
1356   "is_attr(result,$(obj_name).Declaration);",
1357   "strcpy(str,\"Missing Declaration part in object: $(obj_name).\");",
1358   "if($(result) == 0,error_parts,NULL);",
1359   "strcpy(str, \"Declaration {\");",
1360   "append_attr_into_file(str,$(file_name));",
1361   "append_attr_into_file($(obj_name).Declaration,$(file_name));",
1362   "strcpy(str, \"}\");",
1363   "append_attr_into_file(str,$(file_name));",
1364   "is_attr(result,$(obj_name).Initialization);",
1365   "strcpy(str,\"Missing Initialization part in object: $(obj_name).\");",
1366   "if($(result) == 0,error_parts,NULL);",
1367   "strcpy(str, \"Initialization {\");",
1368   "append_attr_into_file(str,$(file_name));",
1369   "append_attr_into_file($(obj_name).Initialization,$(file_name));",
1370   "strcpy(str, \"}\");",
1371   "append_attr_into_file(str,$(file_name));",
1372   "is_attr(result,$(obj_name).Events);",
1373   "strcpy(str,\"Missing Events part in object: $(obj_name).\");",
1374   "if($(result) == 0,error_parts,NULL);",
1375   "strcpy(str, \"Events {\");",
1376   "append_attr_into_file(str,$(file_name));",
1377   "append_attr_into_file($(obj_name).Events,$(file_name));",
1378   "strcpy(str, \"}\");",
1379   "append_attr_into_file(str,$(file_name));",
1380   "is_attr(result,$(obj_name).Messages);",
1381   "strcpy(str,\"Missing Messages part in object: $(obj_name).\");",
1382   "if($(result) == 0,error_parts,NULL);",
1383   "strcpy(str, \"Messages {\");",
1384   "append_attr_into_file(str,$(file_name));",
1385   "append_attr_into_file($(obj_name).Messages,$(file_name));",
1386   "strcpy(str, \"}\");",
1387   "append_attr_into_file(str,$(file_name));",
1388   "is_attr(result,$(obj_name).Rewards);",
1389   "strcpy(str,\"Missing Rewards part in object: $(obj_name).\");",
1390   "if($(result) == 0,error_parts,NULL);",
1391   "strcpy(str, \"Rewards {\");",
1392   "append_attr_into_file(str,$(file_name));",
1393   "append_attr_into_file($(obj_name).Rewards,$(file_name));",
1394   "strcpy(str, \"}\");",
1395   "append_attr_into_file(str,$(file_name));",
1396   "strcpy(str, \")\");",
1397   "append_attr_into_file(str,$(file_name));",
1398   NULL
1399 };
1400 /*-----------------------------------------------------------------------*/
1401 static char *StartSimulatorSetModeB[] = {
1402   NULL
1403 };
1404 
1405 static char *StartSimulatorSetModeI[] = {
1406  "strcpy(Transitions, \"0\");",
1407  "strcpy(Time, \"0.0\");",
1408  "start_simulator();",
1409   NULL
1410 };
1411 
1412 static char *StartSimulatorErrorMode[] = {
1413  "message_box(NULL,\"Please, Mode has to be I(Interactive) or B(Batch)!\",\"Mode Error\", \"stop\");",
1414   NULL
1415 };
1416 
1417 static char *StartSimulatorExec[] = {
1418  "disable_undo();",
1419  "show_attr(Transitions);",
1420  "show_attr(Time);",
1421  "exec(__GENERATE_CHAIN__.init);",
1422  "if(\"$(Mode)\"!=\"I\"&&\"$(Mode)\"!=\"B\",error_mode,NULL);"
1423  "strcpy(file_name, \"$(__GENERATE_CHAIN__.file_name)\");",
1424  "strcpy(str, \" \");",
1425  "write_attr_into_file(str, $(file_name));",
1426  "exec(__GENERATE_CHAIN__.write_model);"
1427  "exec(__GENERATE_CHAIN__.write_global_rewards);"
1428  "exec(__GENERATE_CHAIN__.write_indep_chains);",
1429  "if(\"$(Mode)\"==\"I\",set_mode_I,NULL);",
1430  "if(\"$(Mode)\"==\"B\",set_mode_B,NULL);",
1431  "enable_undo();",
1432  NULL
1433 };
1434 /*-----------------------------------------------------------------------*/
1435 static char *SimulationStepLoopAnimation[] = {
1436  "for_i(Ani_C_Step,1,$(Ani_T_Steps),1,Do_Animation);",
1437  "round(sleep_time,$(Time_Scale)*$(step_time)*1000);",
1438  "sleep(NULL,$(sleep_time));",
1439   NULL
1440 };
1441 
1442 static char *SimulationStepDoAnimation[] = {
1443  "find_obj_names(obj_list,\"\",\"Animation=*\");",
1444  "get_line_in_attr(no_objs,obj_list,0);",
1445  "for_i(obj_index,1,$(no_objs),1,Animate_Obj);",
1446   NULL
1447 };
1448 
1449 static char *SimulationStepAnimateObj[] = {
1450  "get_line_in_attr(cur_obj,obj_list,$(obj_index));",
1451  "exec(\"$(cur_obj).Animation\");",
1452   NULL
1453 };
1454 
1455 
1456 static char *SimulationStepCallSimulator[] = {
1457   "simulate_step();",
1458   NULL
1459 };
1460 
1461 static char *SimulationStepPlayOneStep[] = {
1462  "set_allow_interrupt(FALSE);",
1463  "exec(step_simulation);",
1464  "set_allow_interrupt(TRUE);",
1465  "sleep(NULL,$(Delay));",
1466   NULL
1467 };
1468 
1469 static char *SimulationStepStop[] = {
1470   "stop();",
1471   NULL
1472 };
1473 
1474 static char *SimulationStepExec[] = {
1475  "disable_undo();",
1476  "if(\"$(Step)\"==\"0\",play_simulation,step_simulation);",
1477  "enable_undo();",
1478  "redraw_drawing_area();",
1479   NULL
1480 };
1481 
1482 static char *SimulationStepPlaySimulation[] = {
1483   "while(1,play_one_step);",
1484   NULL
1485 };
1486 
1487 static char *SimulationStepStepSimulation[] = {
1488  "exec(call_simulator);",
1489  "if(\"$(Animation)\"==\"ON\",Loop_Animation,NULL);",
1490   NULL
1491 };
1492 
1493 /**
1494 static char *SimulationStepParseObj[] = {
1495   NULL
1496 };
1497 
1498 static char *SimulationStepWriteVars[] = {
1499   NULL
1500 };
1501 
1502 static char *SimulationStepWriteVarLine[] = {
1503   NULL
1504 };
1505 
1506 static char *SimulationStepUpdateObjects[] = {
1507   NULL
1508 };
1509 
1510 static char *SimulationStepUpdateVars[] = {
1511   NULL
1512 };
1513 **/
1514 /* ====================== Tangram2 Auxiliar Functions ======================= */
1515 
createGenerateChainButton(dbglevel,maxstates,output)1516 struct ObjRec *createGenerateChainButton( dbglevel, maxstates, output )
1517 char *dbglevel;
1518 char *maxstates;
1519 char *output;
1520 {
1521    struct ObjRec *tmp_box_obj=NULL;
1522 
1523    CreateBoxObj(0,0,10,10,TRUE);
1524    tmp_box_obj = topObj;
1525 
1526    /* Note: AddAttrByNameAndValue() adds the new object at tmp_box_obj->fattr */
1527    AddAttrByNameAndValue(tmp_box_obj, "i=", "");
1528    AddAttrByNameAndValue(tmp_box_obj, "dbglevel=", dbglevel);
1529    AddAttrByNameAndValue(tmp_box_obj, "maxstates=", maxstates);
1530    AddAttrByNameAndValue(tmp_box_obj, "output=", output);
1531    AddAttrByNameAndValue(tmp_box_obj, "processID=", "");
1532    AddAttrByNameAndValue(tmp_box_obj, "name=", "__GENERATE_CHAIN__");
1533    AddAttrByNameAndValue(tmp_box_obj, "basename=", "");
1534    AddAttrByNameAndValue(tmp_box_obj, "total_objs=", "");
1535    AddAttrByNameAndValue(tmp_box_obj, "file_name=", "");
1536    AddAttrByNameAndValue(tmp_box_obj, "command=", "");
1537    AddAttrByNameAndValue(tmp_box_obj, "str=", "");
1538    AddAttrByNameAndValue(tmp_box_obj, "result=", "");
1539    AddAttrByNameAndValue(tmp_box_obj, "obj_name=", "");
1540    AddAttrByNameAndValue(tmp_box_obj, "max_file_name=", "");
1541    AddAttrByNameAndValue(tmp_box_obj, "obj_list=", "");
1542 
1543    AddAttrByNameAndValue(tmp_box_obj, "init=", "");
1544    AppendLinesToAttr(tmp_box_obj->fattr, GenerateChainInit);
1545 
1546    AddAttrByNameAndValue(tmp_box_obj, "exec=", "");
1547    AppendLinesToAttr(tmp_box_obj->fattr, GenerateChainExec);
1548 
1549    AddAttrByNameAndValue(tmp_box_obj, "write_model=", "");
1550    AppendLinesToAttr(tmp_box_obj->fattr, GenerateChainWriteModel);
1551 
1552    AddAttrByNameAndValue(tmp_box_obj, "write_obj=", "");
1553    AppendLinesToAttr(tmp_box_obj->fattr, GenerateChainWriteObj);
1554 
1555    AddAttrByNameAndValue(tmp_box_obj, "stop=", "");
1556    AppendLinesToAttr(tmp_box_obj->fattr, GenerateChainStop);
1557 
1558    AddAttrByNameAndValue(tmp_box_obj, "error_parts=", "");
1559    AppendLinesToAttr(tmp_box_obj->fattr, GenerateChainErrorParts);
1560 
1561    AddAttrByNameAndValue(tmp_box_obj, "write_max_values=", "");
1562    AppendLinesToAttr(tmp_box_obj->fattr, GenerateChainWriteMaxValues);
1563 
1564    AddAttrByNameAndValue(tmp_box_obj, "write_global_rewards=", "");
1565    AppendLinesToAttr(tmp_box_obj->fattr, GenerateChainWriteGlobalRewards);
1566 
1567    AddAttrByNameAndValue(tmp_box_obj, "append_global_rewards=", "");
1568    AppendLinesToAttr(tmp_box_obj->fattr, GenerateChainAppendGlobalRewards);
1569 
1570    AddAttrByNameAndValue(tmp_box_obj, "write_indep_chains=", "");
1571    AppendLinesToAttr(tmp_box_obj->fattr, GenerateChainWriteIndependentChains);
1572 
1573    AddAttrByNameAndValue(tmp_box_obj, "append_indep_chains=", "");
1574    AppendLinesToAttr(tmp_box_obj->fattr, GenerateChainAppendIndepChains);
1575 
1576    AddNewSelObj(tmp_box_obj);
1577 
1578    return( tmp_box_obj );
1579 }
1580 
1581 
createStartSimulatorButton(runs,event,trans,time,mode)1582 struct ObjRec *createStartSimulatorButton( runs, event, trans, time, mode )
1583 char *runs;
1584 char *event;
1585 char *trans;
1586 char *time;
1587 char *mode;
1588 {
1589    struct ObjRec *tmp_box_obj = NULL;
1590    int y = 5;
1591 
1592    CreateRCBoxObj(4,y,500,y+55,TRUE);
1593    tmp_box_obj = topObj;
1594 
1595    tmp_box_obj->color = 9;
1596    if (mainDisplay != NULL) {
1597       UtilStrCpyN(tmp_box_obj->color_str, sizeof(tmp_box_obj->color_str),
1598             colorMenuItems[tmp_box_obj->color]);
1599    }
1600    tmp_box_obj->detail.rcb->width = 2;
1601    y += 5;
1602 
1603    AddAttrByNameAndValue(tmp_box_obj, "Runs=", runs);
1604 
1605    AddAttrByNameAndValue(tmp_box_obj, "Time=", time);
1606    tmp_box_obj->fattr->shown = TRUE;
1607    MoveObj(tmp_box_obj->fattr->obj, 20, y - tmp_box_obj->fattr->obj->obbox.lty);
1608    y += 14;
1609 
1610    AddAttrByNameAndValue(tmp_box_obj, "Transitions=", trans);
1611    tmp_box_obj->fattr->shown = TRUE;
1612    MoveObj(tmp_box_obj->fattr->obj, 20, y - tmp_box_obj->fattr->obj->obbox.lty);
1613    y += 14;
1614 
1615    AddAttrByNameAndValue(tmp_box_obj, "Last_Event=", event);
1616    tmp_box_obj->fattr->shown = TRUE;
1617    MoveObj(tmp_box_obj->fattr->obj, 20, y - tmp_box_obj->fattr->obj->obbox.lty);
1618    y += 14;
1619 
1620    AddAttrByNameAndValue(tmp_box_obj, "Mode=", mode);
1621    AddAttrByNameAndValue(tmp_box_obj, "file_name=", "");
1622    AddAttrByNameAndValue(tmp_box_obj, "command=", "");
1623    AddAttrByNameAndValue(tmp_box_obj, "simulating=", "");
1624    AddAttrByNameAndValue(tmp_box_obj, "str=", "");
1625    AddAttrByNameAndValue(tmp_box_obj, "name=", "__START_SIMULATOR__");
1626 
1627    AddAttrByNameAndValue(tmp_box_obj, "set_mode_B=", "");
1628    AppendLinesToAttr(tmp_box_obj->fattr, StartSimulatorSetModeB);
1629 
1630    AddAttrByNameAndValue(tmp_box_obj, "set_mode_I=", "");
1631    AppendLinesToAttr(tmp_box_obj->fattr, StartSimulatorSetModeI);
1632 
1633    AddAttrByNameAndValue(tmp_box_obj, "error_mode=", "");
1634    AppendLinesToAttr(tmp_box_obj->fattr, StartSimulatorErrorMode);
1635 
1636    AddAttrByNameAndValue(tmp_box_obj, "exec=", "");
1637    AppendLinesToAttr(tmp_box_obj->fattr, StartSimulatorExec);
1638 
1639    AdjObjBBox(tmp_box_obj);
1640 
1641    AddNewSelObj(tmp_box_obj);
1642    RedrawDrawWindow(botObj);
1643 
1644    return( tmp_box_obj );
1645 }
1646 
createSimulationStepButton(time,anim,delay,step)1647 struct ObjRec *createSimulationStepButton( time, anim, delay, step )
1648 char *time;
1649 char *anim;
1650 char *delay;
1651 char *step;
1652 {
1653    struct ObjRec *tmp_box_obj = NULL;
1654 
1655    CreateBoxObj(0,0,10,10,TRUE);
1656    tmp_box_obj = topObj;
1657 
1658    /* Note: AddAttrByNameAndValue() adds the new object at tmp_box_obj->fattr */
1659    AddAttrByNameAndValue(tmp_box_obj, "Time_Scale=", time);
1660    AddAttrByNameAndValue(tmp_box_obj, "Animation=", anim);
1661    AddAttrByNameAndValue(tmp_box_obj, "Delay=", delay);
1662    AddAttrByNameAndValue(tmp_box_obj, "Step=", step);
1663    AddAttrByNameAndValue(tmp_box_obj, "state_var_str=", "1");
1664    AddAttrByNameAndValue(tmp_box_obj, "line_size=", "7");
1665    AddAttrByNameAndValue(tmp_box_obj, "obj_list=", "");
1666    AddAttrByNameAndValue(tmp_box_obj, "sleep_time=", "2049");
1667    AddAttrByNameAndValue(tmp_box_obj, "step_time=", "2049");
1668    AddAttrByNameAndValue(tmp_box_obj, "name=", "__SIMULATION_STEP__");
1669    AddAttrByNameAndValue(tmp_box_obj, "cur_obj=", "");
1670    AddAttrByNameAndValue(tmp_box_obj, "obj_index=", "");
1671    AddAttrByNameAndValue(tmp_box_obj, "no_objs=", "");
1672    AddAttrByNameAndValue(tmp_box_obj, "Ani_T_Steps=", "10");
1673    AddAttrByNameAndValue(tmp_box_obj, "Ani_C_Step=", "11");
1674    AddAttrByNameAndValue(tmp_box_obj, "step_index=", "");
1675    AddAttrByNameAndValue(tmp_box_obj, "no_state_vars=", "3");
1676    AddAttrByNameAndValue(tmp_box_obj, "state_var_value=", "8");
1677    AddAttrByNameAndValue(tmp_box_obj, "state_var_name=", "8");
1678    AddAttrByNameAndValue(tmp_box_obj, "obj_name=", "");
1679    AddAttrByNameAndValue(tmp_box_obj, "new_line=", "");
1680    AddAttrByNameAndValue(tmp_box_obj, "buffer=", "");
1681    AddAttrByNameAndValue(tmp_box_obj, "state_var_line=", "");
1682    AddAttrByNameAndValue(tmp_box_obj, "state_var_list=", "");
1683    AddAttrByNameAndValue(tmp_box_obj, "state_var_tok=", "");
1684    AddAttrByNameAndValue(tmp_box_obj, "var_index=", "");
1685 
1686    AddAttrByNameAndValue(tmp_box_obj, "Loop_Animation=", "");
1687    AppendLinesToAttr(tmp_box_obj->fattr, SimulationStepLoopAnimation);
1688 
1689    AddAttrByNameAndValue(tmp_box_obj, "Animate_Obj=", "");
1690    AppendLinesToAttr(tmp_box_obj->fattr, SimulationStepAnimateObj);
1691 
1692    AddAttrByNameAndValue(tmp_box_obj, "Do_Animation=", "");
1693    AppendLinesToAttr(tmp_box_obj->fattr, SimulationStepDoAnimation);
1694 
1695    AddAttrByNameAndValue(tmp_box_obj, "call_simulator=", "");
1696    AppendLinesToAttr(tmp_box_obj->fattr, SimulationStepCallSimulator);
1697 
1698    AddAttrByNameAndValue(tmp_box_obj, "play_one_step=", "");
1699    AppendLinesToAttr(tmp_box_obj->fattr, SimulationStepPlayOneStep);
1700 
1701    AddAttrByNameAndValue(tmp_box_obj, "stop=", "");
1702    AppendLinesToAttr(tmp_box_obj->fattr, SimulationStepStop);
1703 
1704    AddAttrByNameAndValue(tmp_box_obj, "step_simulation=", "");
1705    AppendLinesToAttr(tmp_box_obj->fattr, SimulationStepStepSimulation);
1706 
1707    AddAttrByNameAndValue(tmp_box_obj, "play_simulation=", "");
1708    AppendLinesToAttr(tmp_box_obj->fattr, SimulationStepPlaySimulation);
1709 /**
1710    AddAttrByNameAndValue(tmp_box_obj, "update_objects=", "");
1711    AppendLinesToAttr(tmp_box_obj->fattr, SimulationStepUpdateObjects);
1712 
1713    AddAttrByNameAndValue(tmp_box_obj, "update_vars=", "");
1714    AppendLinesToAttr(tmp_box_obj->fattr, SimulationStepUpdateVars);
1715 
1716    AddAttrByNameAndValue(tmp_box_obj, "parse_obj=", "");
1717    AppendLinesToAttr(tmp_box_obj->fattr, SimulationStepParseObj);
1718 
1719    AddAttrByNameAndValue(tmp_box_obj, "write_vars=", "");
1720    AppendLinesToAttr(tmp_box_obj->fattr, SimulationStepWriteVars);
1721 
1722    AddAttrByNameAndValue(tmp_box_obj, "write_var_line=", "");
1723    AppendLinesToAttr(tmp_box_obj->fattr, SimulationStepWriteVarLine);
1724 **/
1725    AddAttrByNameAndValue(tmp_box_obj, "exec=", "");
1726    AppendLinesToAttr(tmp_box_obj->fattr, SimulationStepExec);
1727 
1728    AddNewSelObj(tmp_box_obj);
1729 
1730    return( tmp_box_obj );
1731 }
1732 
1733 /******************************************************************************/
1734 /* This function extracts the args that are comma separated in 'args' and     */
1735 /* stores them in 'dst'.                                                      */
1736 /* return 0 if failed, no_args if success.                                    */
1737 /* arguments:                                                                 */
1738 /*    args: comma separated list of tokens                                    */
1739 /*    dst : char vector pointer where the tokens will be stored               */
1740 /*    no_args: number of tokens in 'args'                                     */
1741 /*    max_arg_length: max token's size                                        */
1742 /******************************************************************************/
parseArgs(args,dst,no_args,max_arg_length)1743 int parseArgs( args, dst, no_args, max_arg_length )
1744 char *args;
1745 char *dst;
1746 int no_args;
1747 int max_arg_length;
1748 {
1749     int i, j;
1750     char *ptr;
1751 
1752     memset( dst, 0, no_args * max_arg_length );
1753     ptr = args;
1754     /* Remove leading " and spaces */
1755     while( *ptr == '\"' || *ptr == ' ' )
1756         ptr++;
1757 
1758     for( i = 0; i < no_args; i++ )
1759     {
1760         j = 0;
1761         while( *ptr != '\0' && *ptr != ';' && *ptr != '\"' &&
1762                j < max_arg_length )
1763             *(dst + max_arg_length * i + j++) = *ptr++;
1764 
1765         if( *ptr == ';' || *ptr == '\"' )
1766             ptr++;
1767         else
1768             if( *ptr != '\0' )
1769                 break;
1770     }
1771 
1772     return( i == no_args );
1773 }
1774 /* ======================= Tangram2 Menu Functions ======================= */
1775 
AboutTangram2()1776 void AboutTangram2()
1777 {
1778    sprintf(gszMsgBox, "%s\n\n%s %s.",
1779          "Welcome to Tangram-II!",
1780          "Brought to you by the Tangram-II team at the",
1781          "Universidade Federal do Rio de Janeiro");
1782    MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1783 }
1784 
1785 /******************************************************************************/
1786 /* This function creates a invisible button, executes this button and removes */
1787 /* it. This function also needs to extract three arguments that are colapsed  */
1788 /* in arg. This is done because tgif supports only one argument functions.    */
1789 /******************************************************************************/
Tangram2GenerateChain(args)1790 void Tangram2GenerateChain( args )
1791 char *args; /* semi-colon separated list (arg1;arg2;arg3) */
1792 {
1793    int saved_fill=objFill, saved_pen=penPat;
1794    struct ObjRec *tmp_box_obj=NULL;
1795    struct AttrRec *exec_attr=NULL;
1796    char arg[3][1024];
1797 
1798    /* Extracts parameters from args */
1799    if( !parseArgs( args, arg, 3, 1024 ) )
1800    {
1801         fprintf( stderr, "TGIF: Usage Tangram2GenerateChain( \"arg1;arg2;arg3\" )\n" );
1802         return;
1803    }
1804 
1805    MakeQuiescent(); /* select nothing, edit nothing */
1806 
1807    objFill = penPat = NONEPAT;
1808 
1809    tmp_box_obj = createGenerateChainButton( arg[0], arg[1], arg[2] );
1810 
1811    objFill = saved_fill;
1812    penPat = saved_pen;
1813 
1814    exec_attr = FindAttrWithName(topSel->obj, "exec=", NULL);
1815    if (exec_attr != NULL) {
1816       DoExecLoop(topSel->obj, exec_attr);
1817    }
1818    MakeQuiescent();
1819    AddNewSelObj(tmp_box_obj);
1820    PrepareToRecord(CMD_DELETE, topSel, botSel, numObjSelected);
1821    UnlinkObj(topSel->obj);
1822    FreeObj(topSel->obj);
1823    RemoveAllSel();
1824    RecordCmd(CMD_DELETE, NULL, NULL, NULL, 0);
1825 
1826 }
1827 
Tangram2StartSimulator(args)1828 void Tangram2StartSimulator( args )
1829 char *args;
1830 {
1831    int saved_fill=objFill, saved_pen=penPat;
1832    struct AttrRec *exec_attr=NULL;
1833    char arg[12][1024]; /* first 3 for generate_chain */
1834 
1835    struct AttrRec *attr_ptr;
1836    struct ObjRec *attr_owner_obj=NULL;
1837    static char execDummyStr[MAXSTRING+1];
1838 
1839    struct ObjRec *owner_obj=NULL, *named_obj;
1840    static char obj_name[MAXSTRING+1];
1841 
1842    T_ControlPacket pack_out, pack_in;
1843 
1844 
1845 
1846    /* Extracts parameters from args */
1847    if( !parseArgs( args, arg, 12, 1024 ) )
1848    {
1849         return;
1850    }
1851 
1852    MakeQuiescent(); /* select nothing, edit nothing */
1853    objFill = penPat = NONEPAT;
1854 
1855    /* set current text justification to center justified */
1856    DO_CMD("set_selected_text_just(\"left\")");
1857    /* set current text font to Helvetica Bold */
1858    DO_CMD("set_selected_text_font(\"Courier\")");
1859    /* set current text size to 14 */
1860    DO_CMD("set_selected_text_size(14)");
1861    /* set current text color to 'black' */
1862    DO_CMD("set_selected_obj_color(\"black\")");
1863 
1864    objGC = createGenerateChainButton( arg[0], arg[1], arg[2] );
1865    objSp = createSimulationStepButton( arg[8], arg[9], arg[10], arg[11] );
1866 
1867    objFill = saved_fill;
1868    penPat = saved_pen;
1869    objSS = createStartSimulatorButton( arg[3], arg[4], arg[5], arg[6], arg[7] );
1870 
1871    exec_attr = FindAttrWithName(objSS, "exec=", NULL);
1872    if (exec_attr != NULL) {
1873       DoExecLoop(objSS, exec_attr);
1874    }
1875 
1876    /* send initial simulation request packet */
1877    memset((char *)&pack_out, 0, sizeof(T_ControlPacket));
1878    pack_out.code = CT_CODE_INIT_SIMULATION;
1879 
1880    /* send information to mark_find */
1881    SendStepInfo( simulator_socket, &pack_out );
1882 
1883    /* receive control information */
1884    if( recvControlPacket( simulator_socket, &pack_in ) < 0 )
1885       return;
1886 
1887    /* atualiza o valor do atributo Time do objeto "__START_SIMULATOR__" */
1888    strcpy(obj_name, "__START_SIMULATOR__");
1889    named_obj = FindObjWithName(botObj, topObj, obj_name, FALSE, FALSE,
1890          &owner_obj, NULL);
1891 
1892    strcpy(execDummyStr, "Time=");
1893    attr_ptr = FindAttrWithName(named_obj, execDummyStr, &attr_owner_obj);
1894    if (attr_ptr == NULL) { return; }
1895    strcpy( execDummyStr, "0" );
1896    ReplaceAttrFirstValue(attr_owner_obj, attr_ptr, execDummyStr);
1897 
1898    /* atualiza o valor do atributo Transitions do mesmo objeto */
1899    strcpy(execDummyStr, "Transitions=");
1900    attr_ptr = FindAttrWithName(named_obj, execDummyStr, &attr_owner_obj);
1901    if (attr_ptr == NULL) { return; }
1902    strcpy( execDummyStr, "0" );
1903    ReplaceAttrFirstValue(attr_owner_obj, attr_ptr, execDummyStr);
1904 
1905    /* atualiza o valor do atributo Last_Event do mesmo objeto */
1906    strcpy(execDummyStr, "Last_Event=");
1907    attr_ptr = FindAttrWithName(named_obj, execDummyStr, &attr_owner_obj);
1908    if (attr_ptr == NULL) { return; }
1909    strcpy(execDummyStr, pack_in.last_event);
1910    ReplaceAttrFirstValue(attr_owner_obj, attr_ptr, execDummyStr);
1911 
1912    /* Update state vars shown in screen */
1913    UpdateStateVars( simulator_socket, topObj, &pack_in );
1914 }
1915 
Tangram2SimulationStep()1916 void Tangram2SimulationStep()
1917 {
1918    struct AttrRec *exec_attr=NULL;
1919 
1920    exec_attr = FindAttrWithName(objSp, "exec=", NULL);
1921    if (exec_attr != NULL) {
1922       DoExecLoop(objSp, exec_attr);
1923    }
1924 }
1925 
Tangram2EndSimulator()1926 void Tangram2EndSimulator()
1927 {
1928    ExecEndSimulator( NULL, NULL );
1929 
1930    /* Delete all created buttons */
1931    MakeQuiescent();
1932    AddNewSelObj(objGC);
1933    AddNewSelObj(objSS);
1934    AddNewSelObj(objSp);
1935    DelAllSelObj();
1936 
1937    RedrawDrawWindow(botObj);
1938 }
1939 
1940 /* ======================= Tangram2 Misc Functions ======================= */
1941 
Tangram2UpdateInitAttr(port_obj,signal_name)1942 void Tangram2UpdateInitAttr(port_obj, signal_name)
1943    struct ObjRec *port_obj;
1944    char *signal_name;
1945 {
1946    struct AttrRec *attr_ptr=FindAttrWithName(port_obj, "name=", NULL);
1947    MiniLinesInfo *minilines=NULL;
1948    MiniLineInfo *pMiniLine=NULL;
1949    struct TextRec *text_ptr=NULL;
1950    char *port_name=NULL, *new_line=NULL, *parent_obj_name=NULL;
1951    int port_name_len=0;
1952 
1953    if (attr_ptr == NULL) return;
1954    port_name = attr_ptr->attr_value.s;
1955    port_name_len = strlen(port_name);
1956    if (port_name_len == 0) {
1957       MsgBox(TgLoadString(STID_PORT_OBJ_HAS_EMPTY_NAME), TOOL_NAME, INFO_MB);
1958       return;
1959    }
1960    attr_ptr = FindAttrWithName(port_obj->tmp_parent, "type=", NULL);
1961    if (attr_ptr != NULL &&
1962          strcmp(attr_ptr->attr_value.s, "tgBroadcastWire") == 0) {
1963       /* a tgBroadcastWire object is really not a Tangram-II object */
1964       return;
1965    }
1966    attr_ptr = FindAttrWithName(port_obj->tmp_parent, "name=", NULL);
1967    if (attr_ptr != NULL) {
1968       parent_obj_name = attr_ptr->attr_value.s;
1969    }
1970    attr_ptr = FindAttrWithName(port_obj->tmp_parent, "Initialization=", NULL);
1971    if (attr_ptr == NULL) {
1972       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_FIND_INIT_ATTR_PORT_PA),
1973             (parent_obj_name==NULL ? TgLoadCachedString(CSTID_PARANED_UNKNOWN) :
1974             parent_obj_name));
1975       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1976       return;
1977    }
1978    text_ptr = attr_ptr->obj->detail.t;
1979    minilines = (&text_ptr->minilines);
1980    for (pMiniLine=minilines->first->next; pMiniLine != NULL;
1981          pMiniLine=pMiniLine->next) {
1982       int need_to_free_tmp_buf=FALSE, blank_count=0;
1983       char *tmp_buf=ConvertMiniLineToString(pMiniLine, &need_to_free_tmp_buf);
1984       char *attr_value=UtilStrDup(tmp_buf), *psz=NULL, *start=NULL;
1985 
1986       if (attr_value == NULL) FailAllocMessage();
1987       for (start=attr_value; *start == ' ' || *start == '\t'; start++) {
1988          blank_count++;
1989       }
1990       if (*start != '\0') {
1991          char *prefix=NULL;
1992 
1993          if (blank_count > 0) {
1994             char saved_ch=(*start);
1995 
1996             *start = '\0';
1997             prefix = UtilStrDup(attr_value);
1998             if (prefix == NULL) FailAllocMessage();
1999             *start = saved_ch;
2000          }
2001          psz = strchr(start, '=');
2002          if (psz != NULL) {
2003             *psz = '\0';
2004             if (strncmp(port_name, start, port_name_len) == 0 &&
2005                   (start[port_name_len] == ' ' ||
2006                   start[port_name_len] == '\t' ||
2007                   start[port_name_len] == '\0')) {
2008                /* found it */
2009                int misc_len=strlen(&start[port_name_len]);
2010                int len=blank_count+port_name_len+(misc_len<<1)+1+
2011                      strlen(signal_name);
2012 
2013                new_line = (char*)malloc(len);
2014                if (new_line == NULL) FailAllocMessage();
2015                sprintf(new_line, "%s%s%s=%s%s",
2016                      (prefix==NULL ? "" : prefix), port_name,
2017                      &start[port_name_len], &start[port_name_len],
2018                      signal_name);
2019                break;
2020             }
2021             *psz = '=';
2022          }
2023          UtilFree(prefix);
2024       }
2025       UtilFree(attr_value);
2026       if (need_to_free_tmp_buf) UtilFree(tmp_buf);
2027    }
2028    if (pMiniLine == NULL) {
2029       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_FIND_VAR_IN_INIT_ATTR),
2030             port_name, (parent_obj_name==NULL ?
2031             TgLoadCachedString(CSTID_PARANED_UNKNOWN) : parent_obj_name));
2032       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2033       return;
2034    }
2035    FreeStrBlockList(pMiniLine->first_block->next);
2036    pMiniLine->first_block->next = NULL;
2037    pMiniLine->last_block = pMiniLine->first_block;
2038    DynStrSet(&pMiniLine->first_block->seg->dyn_str, new_line);
2039    RecalcTextMetrics(text_ptr, attr_ptr->obj->x, text_ptr->baseline_y);
2040    UpdTextBBox(attr_ptr->obj);
2041 }
2042 
2043