5 #include "mixtesim_prototypes.h"
16 return (DAG)calloc(1,sizeof(struct _DAG));
26 for (i=0;i<dag->nb_nodes;i++) {
27 freeNode(dag->nodes[i]);
40 return (Node)calloc(1,sizeof(struct _Node));
59 void printDAG(DAG dag)
61 fprintf(stderr,"%d nodes: # (children) [parents]\n",dag->nb_nodes);
62 printNode(dag,dag->root);
68 void printNode(DAG dag, Node node)
71 fprintf(stderr,"%d (",node->global_index);
73 /* print children info */
74 for (i=0;i<node->nb_children-1;i++) {
75 fprintf(stderr,"%d,",node->children[i]->global_index);
77 if (node->nb_children> 0)
78 fprintf(stderr,"%d",node->children[node->nb_children-1]->global_index);
81 /* print parent info */
83 for (i=0;i<node->nb_parents-1;i++) {
84 fprintf(stderr,"%d,",node->parents[i]->global_index);
86 if (node->nb_parents > 0)
87 fprintf(stderr,"%d",node->parents[node->nb_parents-1]->global_index);
90 /* print special inf */
91 if (dag->root == node) {
92 fprintf(stderr,"ROOT\n");
93 } else if (dag->end == node) {
94 fprintf(stderr,"END\n");
99 for (i=0;i<node->nb_children;i++) {
100 printNode(dag, node->children[i]);
109 static int parseLine(DAG,char*);
110 static int parseNodeLine(DAG,char*);
111 static int parseNodeCountLine(DAG,char*);
112 static node_t string2NodeType(const char*);
113 static int string2NodeList(const char*,int**,int*);
114 static int finalizeDAG(DAG);
116 /* temporary array in which children lists are stored. Once all nodes
117 * have been parsed, one can go through these lists and assign actual
118 * Node pointers to real children lists
120 char **tmp_childrens;
125 DAG parseDAGFile(char *filename)
133 /* initialize the global children list array */
136 /* opening the DAG description file */
137 if (!(f=fopen(filename,"r"))) {
138 fprintf(stderr,"Impossible to open file '%s'\n",filename);
142 /* allocate memory for the DAG */
145 /* Go through the lines of the file */
146 while(fgets(line,4024,f)) {
148 if (line[0]=='#') /* comment lines */
150 if (line[0]=='\n') /* empty lines */
152 tmp=strdup(line); /* somehow, strduping makes it work ? */
153 if (parseLine(new,tmp) == -1) {
154 fprintf(stderr,"Error in DAG description file at line %d\n",count);
162 /* fill in child lists, parent lists, and perform a few
165 if (finalizeDAG(new) == -1) {
170 /* free the temporary global child list array */
171 for (i=0;i<new->nb_nodes;i++) {
172 if (tmp_childrens[i])
173 free(tmp_childrens[i]);
181 * finalizeDAG(): fills in the child lists with actual pointers,
182 * creates the parent lists, checks some things about the Root
185 static int finalizeDAG(DAG dag)
188 int *childrenlist,nb_children;
190 /* Set the children pointers */
191 for (i=0;i<dag->nb_nodes;i++) {
192 Node node=dag->nodes[i];
194 /* convert the textual list to an integer list */
195 if (string2NodeList(tmp_childrens[i],&childrenlist,&nb_children) == -1) {
196 fprintf(stderr,"Error: invalid child list '%s'\n",
200 /* set the number of children */
201 node->nb_children=nb_children;
203 /* create the child list with pointers to nodes */
205 node->children=(Node*)calloc(nb_children,sizeof(Node));
206 for (j=0;j<nb_children;j++) {
207 node->children[j]=dag->nodes[childrenlist[j]];
213 /* Set the parent pointers */
214 for (i=0;i<dag->nb_nodes;i++) {
215 for (j=0;j<dag->nodes[i]->nb_children;j++) {
216 Node node=dag->nodes[i]->children[j];
217 node->parents=(Node*)realloc(node->parents,
218 (node->nb_parents+1)*sizeof(Node));
219 node->parents[node->nb_parents]=dag->nodes[i];
220 (node->nb_parents)++;
224 /* A few sanity checks */
225 if (!(dag->root) || !(dag->end)) {
226 fprintf(stderr,"Error: Graph has missing end points\n");
230 if (dag->root->nb_parents != 0) {
231 fprintf(stderr,"Error: The Root should have no parents\n");
234 if (dag->end->nb_children != 0) {
235 fprintf(stderr,"Error: The End should have no children\n");
244 static int parseLine(DAG dag, char *line)
248 /* If the line does not start with a keyword, then bail */
249 ptr=strchr(line,' ');
251 fprintf(stderr,"Syntax error\n");
257 /* deal with the two possible keywords */
258 if (!strncmp(line,"NODE_COUNT",strlen("NODE_COUNT")))
259 return parseNodeCountLine(dag,ptr+1);
260 if (!strncmp(line,"NODE",strlen("NODE")))
261 return parseNodeLine(dag,ptr+1);
263 fprintf(stderr,"Unknown keyword %s\n",line);
268 * parseNodeCountLine()
270 * NODE_COUNT <number>
272 int parseNodeCountLine(DAG dag, char *line)
276 /* more than one NODE_COUNT statements ? */
277 if (dag->nb_nodes != 0) {
278 fprintf(stderr,"Error: Only one Node Count specification allowed\n");
282 /* get the count and checks that it's >0 */
285 fprintf(stderr,"Error: invalid Node count\n");
289 /* allocate the node array within the dag */
291 dag->nodes=(Node *)calloc(dag->nb_nodes,sizeof(Node));
292 /* allocate space in the temporary gobal childlist array */
293 tmp_childrens=(char **)calloc(dag->nb_nodes,sizeof(char*));
300 * NODE <index> <childlist> <type> <cost>
302 int parseNodeLine(DAG dag, char *line)
307 char *s_index,*s_childlist,*s_type,*s_cost;
312 /* NODE_COUNT should be called before NODE */
313 if (dag->nb_nodes == 0) {
314 fprintf(stderr,"Error: Node Count must be specified before Nodes\n");
319 ptr=strchr(line,' ');
321 fprintf(stderr,"Syntax error\n");
330 ptr=strchr(line,' ');
332 fprintf(stderr,"Syntax error\n");
340 ptr=strchr(line,' ');
342 fprintf(stderr,"Syntax error\n");
350 ptr=strchr(line,'\n');
352 fprintf(stderr,"Syntax error\n");
358 /* Process strings, but store childlist for later */
360 if ((type=string2NodeType(s_type)) ==-1)
363 tmp_childrens[index]=strdup(s_childlist);
365 /* Creating the node */
367 node->global_index = index;
371 /* Is this the root ? */
372 if (node->type == NODE_ROOT) {
374 fprintf(stderr,"Error: only one Root node allowed\n");
381 /* Is this the end ? */
382 if (node->type == NODE_END) {
384 fprintf(stderr,"Error: only one End node allowed\n");
391 /* Is the node beyond the total number of nodes ? */
392 if (node->global_index >= dag->nb_nodes) {
393 fprintf(stderr,"Error: More nodes than the node count\n");
397 /* Have we seen that node before ? */
398 if (dag->nodes[node->global_index] != NULL) {
399 fprintf(stderr,"Error: Two nodes share index %d\n",
403 /* add the node to the global array */
404 dag->nodes[node->global_index]=node;
410 * parser x,y,z and returns {x,y,z} and 3
411 * Does not really do good error checking
413 static int string2NodeList(const char *string, int **list, int *nb_nodes)
420 /* no children "-" */
421 if (!strcmp(string,"-")) {
427 /* Get all indexes in the list */
428 start = (char*)string;
429 while((ptr = strchr(start,','))) {
431 *list=(int*)realloc(*list,(count+1)*sizeof(int));
432 (*list)[count]=atoi(start);
436 *list=(int*)realloc(*list,(count+1)*sizeof(int));
437 (*list)[count]=atoi(start);
447 static node_t string2NodeType(const char *string) {
448 if (!strcmp(string,"ROOT")) {
450 } else if (!strcmp(string,"END")) {
452 } else if (!strcmp(string,"COMPUTATION")) {
453 return NODE_COMPUTATION;
454 } else if (!strcmp(string,"TRANSFER")) {
455 return NODE_TRANSFER;
457 fprintf(stderr,"Error: Unknown Node Type '%s'\n",string);