Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
1578b97278b102991be50ea5f8d15d4fa9c6b386
[simgrid.git] / src / surf / surfxml_parse.c
1 /* Copyright (c) 2006, 2007, 2008, 2009, 2010. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "xbt/misc.h"
8 #include "xbt/log.h"
9 #include "xbt/str.h"
10 #include "xbt/dict.h"
11 #include "surf/surfxml_parse_private.h"
12 #include "surf/surf_private.h"
13
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_parse, surf,
15                                 "Logging specific to the SURF parsing module");
16 #undef CLEANUP
17 #include "simgrid_dtd.c"
18
19 /* Initialize the parsing globals */
20 int route_action = 0;
21 xbt_dict_t traces_set_list = NULL;
22 //xbt_dynar_t traces_connect_list = NULL;
23 xbt_dict_t trace_connect_list_host_avail = NULL;
24 xbt_dict_t trace_connect_list_power = NULL;
25 xbt_dict_t trace_connect_list_link_avail = NULL;
26 xbt_dict_t trace_connect_list_bandwidth = NULL;
27 xbt_dict_t trace_connect_list_latency = NULL;
28
29 /* This buffer is used to store the original buffer before substituing it by out own buffer. Use full for the foreach tag */
30 static xbt_dynar_t surfxml_bufferstack_stack = NULL;
31 int surfxml_bufferstack_size = 2048;
32 static char *old_buff = NULL;
33 static void surf_parse_error(char *msg);
34
35 void surfxml_bufferstack_push(int new)
36 {
37   if (!new)
38     old_buff = surfxml_bufferstack;
39   else {
40     xbt_dynar_push(surfxml_bufferstack_stack, &surfxml_bufferstack);
41     surfxml_bufferstack = xbt_new0(char, surfxml_bufferstack_size);
42   }
43 }
44
45 void surfxml_bufferstack_pop(int new)
46 {
47   if (!new)
48     surfxml_bufferstack = old_buff;
49   else {
50     free(surfxml_bufferstack);
51     xbt_dynar_pop(surfxml_bufferstack_stack, &surfxml_bufferstack);
52   }
53 }
54
55 /* Stores the set name reffered to by the foreach tag */
56 static char *foreach_set_name;
57 static xbt_dynar_t main_STag_surfxml_host_cb_list = NULL;
58 static xbt_dynar_t main_STag_surfxml_link_cb_list = NULL;
59
60 /* make sure these symbols are defined as strong ones in this file so that the linked can resolve them */
61 xbt_dynar_t STag_surfxml_platform_cb_list = NULL;
62 xbt_dynar_t ETag_surfxml_platform_cb_list = NULL;
63 xbt_dynar_t STag_surfxml_host_cb_list = NULL;
64 xbt_dynar_t ETag_surfxml_host_cb_list = NULL;
65 xbt_dynar_t STag_surfxml_router_cb_list = NULL;
66 xbt_dynar_t ETag_surfxml_router_cb_list = NULL;
67 xbt_dynar_t STag_surfxml_link_cb_list = NULL;
68 xbt_dynar_t ETag_surfxml_link_cb_list = NULL;
69 xbt_dynar_t STag_surfxml_route_cb_list = NULL;
70 xbt_dynar_t ETag_surfxml_route_cb_list = NULL;
71 xbt_dynar_t STag_surfxml_link_c_ctn_cb_list = NULL;
72 xbt_dynar_t ETag_surfxml_link_c_ctn_cb_list = NULL;
73 xbt_dynar_t STag_surfxml_process_cb_list = NULL;
74 xbt_dynar_t ETag_surfxml_process_cb_list = NULL;
75 xbt_dynar_t STag_surfxml_argument_cb_list = NULL;
76 xbt_dynar_t ETag_surfxml_argument_cb_list = NULL;
77 xbt_dynar_t STag_surfxml_prop_cb_list = NULL;
78 xbt_dynar_t ETag_surfxml_prop_cb_list = NULL;
79 xbt_dynar_t STag_surfxml_set_cb_list = NULL;
80 xbt_dynar_t ETag_surfxml_set_cb_list = NULL;
81 xbt_dynar_t STag_surfxml_foreach_cb_list = NULL;
82 xbt_dynar_t ETag_surfxml_foreach_cb_list = NULL;
83 xbt_dynar_t STag_surfxml_route_c_multi_cb_list = NULL;
84 xbt_dynar_t ETag_surfxml_route_c_multi_cb_list = NULL;
85 xbt_dynar_t STag_surfxml_cluster_cb_list = NULL;
86 xbt_dynar_t ETag_surfxml_cluster_cb_list = NULL;
87 xbt_dynar_t STag_surfxml_trace_cb_list = NULL;
88 xbt_dynar_t ETag_surfxml_trace_cb_list = NULL;
89 xbt_dynar_t STag_surfxml_trace_c_connect_cb_list = NULL;
90 xbt_dynar_t ETag_surfxml_trace_c_connect_cb_list = NULL;
91 xbt_dynar_t STag_surfxml_random_cb_list = NULL;
92 xbt_dynar_t ETag_surfxml_random_cb_list = NULL;
93 xbt_dynar_t STag_surfxml_AS_cb_list = NULL;  // addded by david
94 xbt_dynar_t ETag_surfxml_AS_cb_list = NULL;  // addded by david
95 xbt_dynar_t STag_surfxml_ASroute_cb_list = NULL;  // addded by david
96 xbt_dynar_t ETag_surfxml_ASroute_cb_list = NULL;  // addded by david
97
98 /* Stores the sets defined in the XML */
99 xbt_dict_t set_list = NULL;
100
101 xbt_dict_t current_property_set = NULL;
102
103 /* For the route:multi tag */
104 xbt_dict_t route_table = NULL;
105 xbt_dict_t route_multi_table = NULL;
106 xbt_dynar_t route_multi_elements = NULL;
107 static xbt_dynar_t route_link_list = NULL;
108 xbt_dynar_t links = NULL;
109 xbt_dynar_t keys = NULL;
110
111 xbt_dict_t random_data_list = NULL;
112
113 static xbt_dynar_t surf_input_buffer_stack = NULL;
114 static xbt_dynar_t surf_file_to_parse_stack = NULL;
115
116 static XBT_INLINE void surfxml_call_cb_functions(xbt_dynar_t);
117
118 YY_BUFFER_STATE surf_input_buffer;
119 FILE *surf_file_to_parse = NULL;
120
121 static void convert_route_multi_to_routes(void);
122 static void parse_route_elem(void);
123 static void parse_Stag_foreach(void);
124 static void parse_sets(void);
125 static void parse_Stag_route_multi(void);
126 static void parse_Etag_route_multi(void);
127 static void parse_Stag_trace(void);
128 static void parse_Etag_trace(void);
129 static void parse_Stag_trace_c_connect(void);
130 static void init_randomness(void);
131 static void add_randomness(void);
132
133 void surf_parse_free_callbacks(void)
134 {
135   xbt_dynar_free(&STag_surfxml_platform_cb_list);
136   xbt_dynar_free(&ETag_surfxml_platform_cb_list);
137   xbt_dynar_free(&STag_surfxml_host_cb_list);
138   xbt_dynar_free(&ETag_surfxml_host_cb_list);
139   xbt_dynar_free(&STag_surfxml_router_cb_list);
140   xbt_dynar_free(&ETag_surfxml_router_cb_list);
141   xbt_dynar_free(&STag_surfxml_link_cb_list);
142   xbt_dynar_free(&ETag_surfxml_link_cb_list);
143   xbt_dynar_free(&STag_surfxml_route_cb_list);
144   xbt_dynar_free(&ETag_surfxml_route_cb_list);
145   xbt_dynar_free(&STag_surfxml_link_c_ctn_cb_list);
146   xbt_dynar_free(&ETag_surfxml_link_c_ctn_cb_list);
147   xbt_dynar_free(&STag_surfxml_process_cb_list);
148   xbt_dynar_free(&ETag_surfxml_process_cb_list);
149   xbt_dynar_free(&STag_surfxml_argument_cb_list);
150   xbt_dynar_free(&ETag_surfxml_argument_cb_list);
151   xbt_dynar_free(&STag_surfxml_prop_cb_list);
152   xbt_dynar_free(&ETag_surfxml_prop_cb_list);
153   xbt_dynar_free(&STag_surfxml_set_cb_list);
154   xbt_dynar_free(&ETag_surfxml_set_cb_list);
155   xbt_dynar_free(&STag_surfxml_foreach_cb_list);
156   xbt_dynar_free(&ETag_surfxml_foreach_cb_list);
157   xbt_dynar_free(&STag_surfxml_route_c_multi_cb_list);
158   xbt_dynar_free(&ETag_surfxml_route_c_multi_cb_list);
159   xbt_dynar_free(&STag_surfxml_cluster_cb_list);
160   xbt_dynar_free(&ETag_surfxml_cluster_cb_list);
161   xbt_dynar_free(&STag_surfxml_trace_cb_list);
162   xbt_dynar_free(&ETag_surfxml_trace_cb_list);
163   xbt_dynar_free(&STag_surfxml_trace_c_connect_cb_list);
164   xbt_dynar_free(&ETag_surfxml_trace_c_connect_cb_list);
165   xbt_dynar_free(&STag_surfxml_random_cb_list);
166   xbt_dynar_free(&ETag_surfxml_random_cb_list);
167   xbt_dynar_free(&STag_surfxml_AS_cb_list);  // addded by david
168   xbt_dynar_free(&ETag_surfxml_AS_cb_list);  // addded by david
169   xbt_dynar_free(&STag_surfxml_ASroute_cb_list);  // addded by david
170   xbt_dynar_free(&ETag_surfxml_ASroute_cb_list);  // addded by david
171 }
172
173 void surf_parse_reset_parser(void)
174 {
175   surf_parse_free_callbacks();
176   STag_surfxml_platform_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
177   ETag_surfxml_platform_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
178   STag_surfxml_host_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
179   ETag_surfxml_host_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
180   STag_surfxml_router_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
181   ETag_surfxml_router_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
182   STag_surfxml_link_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
183   ETag_surfxml_link_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
184   STag_surfxml_route_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
185   ETag_surfxml_route_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
186   STag_surfxml_link_c_ctn_cb_list =
187     xbt_dynar_new(sizeof(void_f_void_t), NULL);
188   ETag_surfxml_link_c_ctn_cb_list =
189     xbt_dynar_new(sizeof(void_f_void_t), NULL);
190   STag_surfxml_process_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
191   ETag_surfxml_process_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
192   STag_surfxml_argument_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
193   ETag_surfxml_argument_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
194   STag_surfxml_prop_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
195   ETag_surfxml_prop_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
196   STag_surfxml_set_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
197   ETag_surfxml_set_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
198   STag_surfxml_foreach_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
199   ETag_surfxml_foreach_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
200   STag_surfxml_route_c_multi_cb_list =
201     xbt_dynar_new(sizeof(void_f_void_t), NULL);
202   ETag_surfxml_route_c_multi_cb_list =
203     xbt_dynar_new(sizeof(void_f_void_t), NULL);
204   STag_surfxml_cluster_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
205   ETag_surfxml_cluster_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
206   STag_surfxml_trace_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
207   ETag_surfxml_trace_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
208   STag_surfxml_trace_c_connect_cb_list =
209     xbt_dynar_new(sizeof(void_f_void_t), NULL);
210   ETag_surfxml_trace_c_connect_cb_list =
211     xbt_dynar_new(sizeof(void_f_void_t), NULL);
212   STag_surfxml_random_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
213   ETag_surfxml_random_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
214   STag_surfxml_AS_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);  // addded by david
215   ETag_surfxml_AS_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);  // addded by david
216   STag_surfxml_ASroute_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);  // addded by david
217   ETag_surfxml_ASroute_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);  // addded by david
218 }
219
220 void STag_surfxml_include(void)
221 {
222   xbt_dynar_push(surf_input_buffer_stack, &surf_input_buffer);
223   xbt_dynar_push(surf_file_to_parse_stack, &surf_file_to_parse);
224
225   surf_file_to_parse = surf_fopen(A_surfxml_include_file, "r");
226   xbt_assert1((surf_file_to_parse), "Unable to open \"%s\"\n",
227               A_surfxml_include_file);
228   surf_input_buffer = surf_parse__create_buffer(surf_file_to_parse, 10);
229   surf_parse__switch_to_buffer(surf_input_buffer);
230   printf("STAG\n");
231   fflush(NULL);
232 }
233
234 void ETag_surfxml_include(void)
235 {
236   printf("ETAG\n");
237   fflush(NULL);
238   surf_parse__delete_buffer(surf_input_buffer);
239   fclose(surf_file_to_parse);
240   xbt_dynar_pop(surf_file_to_parse_stack, &surf_file_to_parse);
241   xbt_dynar_pop(surf_input_buffer_stack, &surf_input_buffer);
242 }
243
244 void STag_surfxml_platform(void)
245 {
246   double version = 0.0;
247
248   sscanf(A_surfxml_platform_version, "%lg", &version);
249
250   xbt_assert0((version >= 1.0), "******* BIG FAT WARNING *********\n "
251               "You're using an ancient XML file. "
252               "Since SimGrid 3.1, units are Bytes, Flops, and seconds "
253               "instead of MBytes, MFlops and seconds. "
254               "A script (surfxml_update.pl) to help you convert your old "
255               "platform files "
256               "is available in the contrib/platform_generation directory "
257               "of the simgrid repository. Please check also out the "
258               "SURF section of the ChangeLog for the 3.1 version. "
259               "Last, do not forget to also update your values for "
260               "the calls to MSG_task_create (if any).");
261   xbt_assert0((version >= 2.0), "******* BIG FAT WARNING *********\n "
262               "You're using an old XML file. "
263               "A script (surfxml_update.pl) to help you convert your old "
264               "platform files "
265               "is available in the contrib/platform_generation directory "
266               "of the simgrid repository.");
267
268   surfxml_call_cb_functions(STag_surfxml_platform_cb_list);
269
270 }
271
272 void ETag_surfxml_platform(void)
273 {
274   convert_route_multi_to_routes();
275
276   surfxml_call_cb_functions(ETag_surfxml_platform_cb_list);
277
278   xbt_dict_free(&random_data_list);
279 }
280
281 void STag_surfxml_host(void)
282 {
283   surfxml_call_cb_functions(STag_surfxml_host_cb_list);
284
285 }
286
287 void ETag_surfxml_host(void)
288 {
289   surfxml_call_cb_functions(ETag_surfxml_host_cb_list);
290 }
291
292 void STag_surfxml_router(void)
293 {
294   surfxml_call_cb_functions(STag_surfxml_router_cb_list);
295 }
296
297 void ETag_surfxml_router(void)
298 {
299   surfxml_call_cb_functions(ETag_surfxml_router_cb_list);
300 }
301
302 void STag_surfxml_link(void)
303 {
304   surfxml_call_cb_functions(STag_surfxml_link_cb_list);
305 }
306
307 void ETag_surfxml_link(void)
308 {
309   surfxml_call_cb_functions(ETag_surfxml_link_cb_list);
310 }
311
312 void STag_surfxml_route(void)
313 {
314   surfxml_call_cb_functions(STag_surfxml_route_cb_list);
315 }
316
317 void ETag_surfxml_route(void)
318 {
319   surfxml_call_cb_functions(ETag_surfxml_route_cb_list);
320 }
321
322 void STag_surfxml_link_c_ctn(void)
323 {
324   surfxml_call_cb_functions(STag_surfxml_link_c_ctn_cb_list);
325 }
326
327 void ETag_surfxml_link_c_ctn(void)
328 {
329   surfxml_call_cb_functions(ETag_surfxml_link_c_ctn_cb_list);
330 }
331
332 void STag_surfxml_process(void)
333 {
334   surfxml_call_cb_functions(STag_surfxml_process_cb_list);
335 }
336
337 void ETag_surfxml_process(void)
338 {
339   surfxml_call_cb_functions(ETag_surfxml_process_cb_list);
340 }
341
342 void STag_surfxml_argument(void)
343 {
344   surfxml_call_cb_functions(STag_surfxml_argument_cb_list);
345 }
346
347 void ETag_surfxml_argument(void)
348 {
349   surfxml_call_cb_functions(ETag_surfxml_argument_cb_list);
350 }
351
352 void STag_surfxml_prop(void)
353 {
354   surfxml_call_cb_functions(STag_surfxml_prop_cb_list);
355 }
356
357 void ETag_surfxml_prop(void)
358 {
359   surfxml_call_cb_functions(ETag_surfxml_prop_cb_list);
360 }
361
362 void STag_surfxml_set(void)
363 {
364   surfxml_call_cb_functions(STag_surfxml_set_cb_list);
365 }
366
367 void ETag_surfxml_set(void)
368 {
369   surfxml_call_cb_functions(ETag_surfxml_set_cb_list);
370 }
371
372 void STag_surfxml_foreach(void)
373 {
374   /* Save the current buffer */
375   surfxml_bufferstack_push(0);
376   surfxml_call_cb_functions(STag_surfxml_foreach_cb_list);
377 }
378
379 void ETag_surfxml_foreach(void)
380 {
381   surfxml_call_cb_functions(ETag_surfxml_foreach_cb_list);
382
383   /* free the temporary dynar and restore original */
384   xbt_dynar_free(&STag_surfxml_host_cb_list);
385   STag_surfxml_host_cb_list = main_STag_surfxml_host_cb_list;
386
387   /* free the temporary dynar and restore original */
388   xbt_dynar_free(&STag_surfxml_link_cb_list);
389   STag_surfxml_link_cb_list = main_STag_surfxml_link_cb_list;
390 }
391
392 void STag_surfxml_route_c_multi(void)
393 {
394   surfxml_call_cb_functions(STag_surfxml_route_c_multi_cb_list);
395 }
396
397 void ETag_surfxml_route_c_multi(void)
398 {
399   surfxml_call_cb_functions(ETag_surfxml_route_c_multi_cb_list);
400 }
401
402 void STag_surfxml_cluster(void)
403 {
404   surfxml_call_cb_functions(STag_surfxml_cluster_cb_list);
405 }
406
407 void ETag_surfxml_cluster(void)
408 {
409   surfxml_call_cb_functions(ETag_surfxml_cluster_cb_list);
410 }
411
412 void STag_surfxml_trace(void)
413 {
414   surfxml_call_cb_functions(STag_surfxml_trace_cb_list);
415 }
416
417 void ETag_surfxml_trace(void)
418 {
419   surfxml_call_cb_functions(ETag_surfxml_trace_cb_list);
420 }
421
422 void STag_surfxml_trace_c_connect(void)
423 {
424   surfxml_call_cb_functions(STag_surfxml_trace_c_connect_cb_list);
425 }
426
427 void ETag_surfxml_trace_c_connect(void)
428 {
429   surfxml_call_cb_functions(ETag_surfxml_trace_c_connect_cb_list);
430 }
431
432 void STag_surfxml_random(void)
433 {
434   surfxml_call_cb_functions(STag_surfxml_random_cb_list);
435 }
436
437 void ETag_surfxml_random(void)
438 {
439   surfxml_call_cb_functions(ETag_surfxml_random_cb_list);
440 }
441
442 void STag_surfxml_AS(void)   // addded by david
443 {
444   surfxml_call_cb_functions(STag_surfxml_AS_cb_list);
445 }
446
447 void ETag_surfxml_AS(void)   // addded by david
448 {
449   surfxml_call_cb_functions(ETag_surfxml_AS_cb_list);
450 }
451
452 void STag_surfxml_ASroute(void)   // addded by david
453 {
454   surfxml_call_cb_functions(STag_surfxml_ASroute_cb_list);
455 }
456
457 void ETag_surfxml_ASroute(void)   // addded by david
458 {
459   surfxml_call_cb_functions(ETag_surfxml_ASroute_cb_list);
460 }
461
462 void surf_parse_open(const char *file)
463 {
464   static int warned = 0;        /* warn only once */
465   if (!file) {
466     if (!warned) {
467       WARN0
468         ("Bypassing the XML parser since surf_parse_open received a NULL pointer. If it is not what you want, go fix your code.");
469       warned = 1;
470     }
471     return;
472   }
473   surf_file_to_parse = surf_fopen(file, "r");
474   xbt_assert1((surf_file_to_parse), "Unable to open \"%s\"\n", file);
475
476   if (!surf_input_buffer_stack)
477     surf_input_buffer_stack = xbt_dynar_new(sizeof(YY_BUFFER_STATE), NULL);
478   if (!surf_file_to_parse_stack)
479     surf_file_to_parse_stack = xbt_dynar_new(sizeof(FILE *), NULL);
480
481   surf_input_buffer = surf_parse__create_buffer(surf_file_to_parse, 10);
482   surf_parse__switch_to_buffer(surf_input_buffer);
483   surf_parse_lineno = 1;
484 }
485
486 void surf_parse_close(void)
487 {
488   if (surf_input_buffer_stack)
489     xbt_dynar_free(&surf_input_buffer_stack);
490   if (surf_file_to_parse_stack)
491     xbt_dynar_free(&surf_file_to_parse_stack);
492
493   if (surf_file_to_parse) {
494     surf_parse__delete_buffer(surf_input_buffer);
495     fclose(surf_file_to_parse);
496   }
497 }
498
499 static int _surf_parse(void)
500 {
501   return surf_parse_lex();
502 }
503
504 int_f_void_t surf_parse = _surf_parse;
505
506 void surf_parse_error(char *msg)
507 {
508   fprintf(stderr, "Parse error on line %d: %s\n", surf_parse_lineno, msg);
509   abort();
510 }
511
512
513 void surf_parse_get_double(double *value, const char *string)
514 {
515   int ret = 0;
516
517   ret = sscanf(string, "%lg", value);
518   if (ret != 1)
519     surf_parse_error(bprintf("%s is not a double", string));
520 }
521
522 void surf_parse_get_int(int *value, const char *string)
523 {
524   int ret = 0;
525
526   ret = sscanf(string, "%d", value);
527   if (ret != 1)
528     surf_parse_error(bprintf("%s is not an integer", string));
529 }
530
531 void parse_properties(void)
532 {
533   char *value = NULL;
534
535   if (!current_property_set)
536     current_property_set = xbt_dict_new();
537
538   value = xbt_strdup(A_surfxml_prop_value);
539   xbt_dict_set(current_property_set, A_surfxml_prop_id, value, free);
540 }
541
542 void surfxml_add_callback(xbt_dynar_t cb_list, void_f_void_t function)
543 {
544   xbt_dynar_push(cb_list, &function);
545 }
546
547 void surfxml_del_callback(xbt_dynar_t* p_cb_list, void_f_void_t function)
548 {
549   xbt_dynar_t new_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
550   unsigned int it;
551   void_f_void_t func;
552   xbt_dynar_foreach(*p_cb_list,it,func) {
553     if( func != function )
554       xbt_dynar_push(new_cb_list, &func);
555   }
556   xbt_dynar_free(p_cb_list);
557   *p_cb_list = new_cb_list;
558 }
559
560 static XBT_INLINE void surfxml_call_cb_functions(xbt_dynar_t cb_list)
561 {
562   unsigned int iterator;
563   void_f_void_t fun;
564   xbt_dynar_foreach(cb_list, iterator, fun) {
565     (*fun) ();
566   }
567 }
568
569 static void parse_route_set_endpoints(void)
570 {
571   route_link_list = xbt_dynar_new(sizeof(char *), NULL);
572 }
573
574 static void init_data(void)
575 {
576   xbt_dict_free(&route_table);
577   xbt_dynar_free(&route_link_list);
578   route_table = xbt_dict_new();
579
580   if (!surfxml_bufferstack_stack)
581     surfxml_bufferstack_stack = xbt_dynar_new(sizeof(char *), NULL);
582   route_multi_table = xbt_dict_new();
583   route_multi_elements = xbt_dynar_new(sizeof(char *), NULL);
584   traces_set_list = xbt_dict_new();
585   if (set_list == NULL)
586     set_list = xbt_dict_new();
587
588   trace_connect_list_host_avail = xbt_dict_new();
589   trace_connect_list_power = xbt_dict_new();
590   trace_connect_list_link_avail = xbt_dict_new();
591   trace_connect_list_bandwidth = xbt_dict_new();
592   trace_connect_list_latency = xbt_dict_new();
593
594   random_data_list = xbt_dict_new();
595 //   surfxml_add_callback(STag_surfxml_prop_cb_list, &parse_properties);
596 //   surfxml_add_callback(ETag_surfxml_link_c_ctn_cb_list, &parse_route_elem);
597 //   surfxml_add_callback(STag_surfxml_route_cb_list, &parse_route_set_endpoints);
598 //   surfxml_add_callback(STag_surfxml_set_cb_list, &parse_sets);
599 //   surfxml_add_callback(STag_surfxml_route_c_multi_cb_list, &parse_Stag_route_multi);
600 //   surfxml_add_callback(ETag_surfxml_route_c_multi_cb_list, &parse_Etag_route_multi);
601 //   surfxml_add_callback(STag_surfxml_foreach_cb_list, &parse_Stag_foreach);
602 //   surfxml_add_callback(STag_surfxml_trace_cb_list, &parse_Stag_trace);
603 //   surfxml_add_callback(ETag_surfxml_trace_cb_list, &parse_Etag_trace);
604 //   surfxml_add_callback(STag_surfxml_trace_c_connect_cb_list, &parse_Stag_trace_c_connect);
605 //   surfxml_add_callback(STag_surfxml_random_cb_list, &init_randomness);
606 //   surfxml_add_callback(ETag_surfxml_random_cb_list, &add_randomness);
607 }
608
609 static void free_data(void)
610 {
611   char *key, *data;
612   xbt_dict_cursor_t cursor = NULL;
613   char *name;
614   unsigned int cpt = 0;
615
616   xbt_dict_foreach(route_table, cursor, key, data) {
617     xbt_dynar_t links = (xbt_dynar_t) data;
618     char *name;
619     unsigned int cpt = 0;
620
621     xbt_dynar_foreach(links, cpt, name) free(name);
622     xbt_dynar_free(&links);
623   }
624   xbt_dict_free(&route_table);
625   route_link_list = NULL;
626
627   xbt_dict_free(&route_multi_table);
628
629   xbt_dynar_foreach(route_multi_elements, cpt, name) free(name);
630   xbt_dynar_free(&route_multi_elements);
631
632   xbt_dict_foreach(set_list, cursor, key, data) {
633     xbt_dynar_t set = (xbt_dynar_t) data;
634
635     xbt_dynar_foreach(set, cpt, name) free(name);
636     xbt_dynar_free(&set);
637   }
638   xbt_dict_free(&set_list);
639
640   xbt_dynar_free(&surfxml_bufferstack_stack);
641
642   xbt_dict_free(&traces_set_list);
643   xbt_dict_free(&trace_connect_list_host_avail);
644   xbt_dict_free(&trace_connect_list_power);
645   xbt_dict_free(&trace_connect_list_link_avail);
646   xbt_dict_free(&trace_connect_list_bandwidth);
647   xbt_dict_free(&trace_connect_list_latency);
648   xbt_dict_free(&traces_set_list);
649 }
650
651 void parse_platform_file(const char *file)
652 {
653   int parse_status;
654   surf_parse_open(file);
655   init_data();
656   parse_status = surf_parse();
657   free_data();
658   surf_parse_close();
659   if (parse_status)
660     xbt_dict_free(&random_data_list);
661   xbt_assert1(!parse_status, "Parse error in %s", file);
662 }
663
664 /* Functions to bypass route tag. Used by the route:multi tag */
665
666 static void parse_make_temporary_route(const char *src, const char *dst,
667                                        int action)
668 {
669   int AX_ptr = 0;
670
671   A_surfxml_route_action = action;
672   SURFXML_BUFFER_SET(route_src, src);
673   SURFXML_BUFFER_SET(route_dst, dst);
674 }
675
676 /* Functions for the sets and foreach tags */
677
678 static void parse_sets(void)
679 {
680   char *id, *suffix, *prefix, *radical;
681   int start, end;
682   xbt_dynar_t radical_elements;
683   xbt_dynar_t radical_ends;
684   xbt_dynar_t current_set;
685   char *value, *groups;
686   int i;
687   unsigned int iter;
688
689   id = xbt_strdup(A_surfxml_set_id);
690   prefix = xbt_strdup(A_surfxml_set_prefix);
691   suffix = xbt_strdup(A_surfxml_set_suffix);
692   radical = xbt_strdup(A_surfxml_set_radical);
693
694   if (xbt_dict_get_or_null(set_list, id))
695     surf_parse_error(bprintf
696                      ("Set '%s' declared several times in the platform file.",
697                       id));
698
699   current_set = xbt_dynar_new(sizeof(char *), NULL);
700
701   radical_elements = xbt_str_split(radical, ",");
702   xbt_dynar_foreach(radical_elements, iter, groups) {
703
704     radical_ends = xbt_str_split(groups, "-");
705     switch (xbt_dynar_length(radical_ends)) {
706     case 1:
707       surf_parse_get_int(&start, xbt_dynar_get_as(radical_ends, 0, char *));
708       value = bprintf("%s%d%s", prefix, start, suffix);
709       xbt_dynar_push(current_set, &value);
710       break;
711
712     case 2:
713
714       surf_parse_get_int(&start, xbt_dynar_get_as(radical_ends, 0, char *));
715       surf_parse_get_int(&end, xbt_dynar_get_as(radical_ends, 1, char *));
716
717
718       for (i = start; i <= end; i++) {
719         value = bprintf("%s%d%s", prefix, i, suffix);
720         xbt_dynar_push(current_set, &value);
721       }
722       break;
723
724     default:
725       surf_parse_error(xbt_strdup("Malformed radical"));
726     }
727
728     xbt_dynar_free(&radical_ends);
729   }
730
731   xbt_dict_set(set_list, id, current_set, NULL);
732
733   xbt_dynar_free(&radical_elements);
734   free(radical);
735   free(suffix);
736   free(prefix);
737   free(id);
738 }
739
740 static void parse_host_foreach(void){
741
742   xbt_dynar_t names = NULL;
743   unsigned int cpt = 0;
744   char *name;
745   xbt_dict_cursor_t cursor = NULL;
746   char *key, *data;
747
748   const char *surfxml_host_power = A_surfxml_host_power;
749   const char *surfxml_host_availability = A_surfxml_host_availability;
750   const char *surfxml_host_availability_file = A_surfxml_host_availability_file;
751   const char *surfxml_host_state_file = A_surfxml_host_state_file;
752
753   xbt_dict_t cluster_host_props = current_property_set;
754
755   names = xbt_dict_get_or_null(set_list, foreach_set_name);
756   if (!names)
757     surf_parse_error(bprintf("Set name '%s' used in <foreach> not found.",
758                              foreach_set_name));
759   if (strcmp(A_surfxml_host_id, "$1"))
760     surf_parse_error(bprintf
761                      ("The host id within <foreach> should point to the foreach set_id (use $1 instead of %s)",
762                       A_surfxml_host_id));
763
764
765   /* foreach name in set call the main host callback */
766   xbt_dynar_foreach(names, cpt, name) {
767     int AX_ptr = 0; /* needed by the SURFXML_BUFFER_SET macro */
768
769     surfxml_bufferstack_push(1);
770
771     SURFXML_BUFFER_SET(host_id, name);
772     SURFXML_BUFFER_SET(host_power, surfxml_host_power /*hostPower */ );
773     SURFXML_BUFFER_SET(host_availability, surfxml_host_availability);
774     SURFXML_BUFFER_SET(host_availability_file, surfxml_host_availability_file);
775     SURFXML_BUFFER_SET(host_state_file, surfxml_host_state_file);
776
777     surfxml_call_cb_functions(main_STag_surfxml_host_cb_list);
778
779     xbt_dict_foreach(cluster_host_props, cursor, key, data) {
780       xbt_dict_set(current_property_set, xbt_strdup(key), xbt_strdup(data),
781                    free);
782     }
783
784     /* Call the (unmodified) callbacks of </host>, if any */
785     surfxml_call_cb_functions(ETag_surfxml_host_cb_list);
786     surfxml_bufferstack_pop(1);
787   }
788
789   current_property_set = xbt_dict_new();
790
791   surfxml_bufferstack_pop(0);
792 }
793
794 static void parse_link_foreach(void) {
795   const char *surfxml_link_bandwidth = A_surfxml_link_bandwidth;
796   const char *surfxml_link_bandwidth_file = A_surfxml_link_bandwidth_file;
797   const char *surfxml_link_latency = A_surfxml_link_latency;
798   const char *surfxml_link_latency_file = A_surfxml_link_latency_file;
799   const char *surfxml_link_state_file = A_surfxml_link_state_file;
800
801   xbt_dynar_t names = NULL;
802   unsigned int cpt = 0;
803   char *name;
804   xbt_dict_cursor_t cursor = NULL;
805   char *key, *data;
806
807   xbt_dict_t cluster_link_props = current_property_set;
808
809   names = xbt_dict_get_or_null(set_list, foreach_set_name);
810   if (!names)
811     surf_parse_error(bprintf("Set name '%s' used in <foreach> not found.",
812                              foreach_set_name));
813   if (strcmp(A_surfxml_link_id, "$1"))
814     surf_parse_error(bprintf
815                      ("The host id within <foreach> should point to the foreach set_id (use $1 instead of %s)",
816                       A_surfxml_link_id));
817
818   /* for each name in set call the main link callback */
819   xbt_dynar_foreach(names, cpt, name) {
820     int AX_ptr = 0; /* needed by the SURFXML_BUFFER_SET */
821
822     surfxml_bufferstack_push(1);
823
824     SURFXML_BUFFER_SET(link_id, name);
825     SURFXML_BUFFER_SET(link_bandwidth, surfxml_link_bandwidth);
826     SURFXML_BUFFER_SET(link_bandwidth_file, surfxml_link_bandwidth_file);
827     SURFXML_BUFFER_SET(link_latency, surfxml_link_latency);
828     SURFXML_BUFFER_SET(link_latency_file, surfxml_link_latency_file);
829     SURFXML_BUFFER_SET(link_state_file, surfxml_link_state_file);
830
831     surfxml_call_cb_functions(main_STag_surfxml_link_cb_list);
832
833     xbt_dict_foreach(cluster_link_props, cursor, key, data) {
834       xbt_dict_set(current_property_set, xbt_strdup(key), xbt_strdup(data),
835                    free);
836     }
837
838     /* Call the (unmodified) callbacks of </link>, if any */
839     surfxml_call_cb_functions(ETag_surfxml_link_cb_list);
840     surfxml_bufferstack_pop(1);
841   }
842
843   current_property_set = xbt_dict_new();
844
845   surfxml_bufferstack_pop(0);
846   free(foreach_set_name);
847   foreach_set_name = NULL;
848 }
849
850 static void parse_Stag_foreach(void)
851 {
852   /* save the host & link callbacks */
853   main_STag_surfxml_host_cb_list = STag_surfxml_host_cb_list;
854   main_STag_surfxml_link_cb_list = STag_surfxml_link_cb_list;
855
856   /* redefine host & link callbacks to be used only by the foreach tag */
857   STag_surfxml_host_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
858   STag_surfxml_link_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
859
860   surfxml_add_callback(STag_surfxml_host_cb_list, &parse_host_foreach);
861   surfxml_add_callback(STag_surfxml_link_cb_list, &parse_link_foreach);
862
863   /* get set name */
864   foreach_set_name = xbt_strdup(A_surfxml_foreach_set_id);
865 }
866
867 /* Route:multi functions */
868
869 static int route_multi_size = 0;
870 static char *src_name, *dst_name;
871 static int is_symmetric_route;
872
873 static void parse_route_elem(void)
874 {
875   char *val;
876
877   val = xbt_strdup(A_surfxml_link_c_ctn_id);
878
879   xbt_dynar_push(route_link_list, &val);
880   //INFO2("Push %s (size now:%ld)",val,xbt_dynar_length(route_link_list));
881 }
882
883 static void parse_Stag_route_multi(void)
884 {
885   src_name = xbt_strdup(A_surfxml_route_c_multi_src);
886   dst_name = xbt_strdup(A_surfxml_route_c_multi_dst);
887   route_action = A_surfxml_route_c_multi_action;
888   is_symmetric_route = A_surfxml_route_c_multi_symmetric;
889   route_multi_size++;
890
891   route_link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
892 }
893
894 /*
895    This function is used to append or override the contents of an already existing route in the case a new one with its name is found.
896    The decision is based upon the value of action specified in the xml route:multi attribute action
897  */
898 void manage_route(xbt_dict_t routing_table, const char *route_name,
899                   int action, int isMultiRoute)
900 {
901   unsigned int cpt;
902   xbt_dynar_t links;
903   char *value;
904
905   /* get already existing list if it exists */
906   links = xbt_dict_get_or_null(routing_table, route_name);
907   DEBUG3("ROUTE: %s (action:%s; len:%ld)", route_name,
908       (action==A_surfxml_route_action_OVERRIDE?"override":(
909           action==A_surfxml_route_action_PREPEND?"prepend":"postpend")),
910        (links?xbt_dynar_length(links):0));
911
912   if (links != NULL) {
913     switch (action) {
914     case A_surfxml_route_action_PREPEND:       /* add existing links at the end; route_link_list + links */
915       xbt_dynar_foreach(links, cpt, value) {
916         xbt_dynar_push(route_link_list, &value);
917       }
918       xbt_dynar_free(&links);
919       break;
920     case A_surfxml_route_action_POSTPEND:      /* add existing links in front; links + route_link_list */
921         xbt_dynar_foreach(route_link_list, cpt, value) {
922         xbt_dynar_push(links, &value);
923       }
924       xbt_dynar_free(&route_link_list);
925       route_link_list = links;
926       break;
927     case A_surfxml_route_action_OVERRIDE:
928       xbt_dynar_free(&links);
929       break;
930     default:
931       xbt_die(bprintf("While dealing with routes of %s, got action=%d. Please report this bug.",
932           route_name,action));
933       break;
934     }
935
936   }
937   /* this is the final route; do not add if name is a set; add only if name is in set list */
938   if (!isMultiRoute) {
939     xbt_dict_set(routing_table, route_name, route_link_list, NULL);
940   }
941 }
942
943 static void parse_Etag_route_multi(void)
944 {
945   char *route_name;
946
947   route_name =
948     bprintf("%s#%s#%d#%d#%d", src_name, dst_name, route_action,
949             is_symmetric_route, route_multi_size);
950
951   xbt_dynar_push(route_multi_elements, &route_name);
952
953   /* Add route */
954   xbt_dict_set(route_multi_table, route_name, route_link_list, NULL);
955   /* add symmetric if it is the case */
956   if (is_symmetric_route == 1) {
957     char *symmetric_name =
958       bprintf("%s#%s#%d#%d#%d", dst_name, src_name, route_action,
959               !is_symmetric_route, route_multi_size);
960
961     xbt_dict_set(route_multi_table, symmetric_name, route_link_list, NULL);
962     xbt_dynar_push(route_multi_elements, &symmetric_name);
963     is_symmetric_route = 0;
964   }
965   free(src_name);
966   free(dst_name);
967 }
968
969 static void add_multi_links(const char *src, const char *dst,
970                             xbt_dynar_t links, const char *src_name,
971                             const char *dst_name)
972 {
973   unsigned int cpt;
974   char *value, *val;
975
976   surfxml_bufferstack_push(1);
977
978   parse_make_temporary_route(src_name, dst_name, route_action);
979   surfxml_call_cb_functions(STag_surfxml_route_cb_list);
980   DEBUG2("\tADDING ROUTE: %s -> %s", src_name, dst_name);
981   /* Build link list */
982   xbt_dynar_foreach(links, cpt, value) {
983     if (strcmp(value, src) == 0)
984       val = xbt_strdup(src_name);
985     else if (strcmp(value, dst) == 0)
986       val = xbt_strdup(dst_name);
987     else if (strcmp(value, "$dst") == 0)
988       val = xbt_strdup(dst_name);
989     else if (strcmp(value, "$src") == 0)
990       val = xbt_strdup(src_name);
991     else
992       val = xbt_strdup(value);
993     DEBUG1("\t\tELEMENT: %s", val);
994     xbt_dynar_push(route_link_list, &val);
995   }
996   surfxml_call_cb_functions(ETag_surfxml_route_cb_list);
997   surfxml_bufferstack_pop(1);
998 }
999
1000 static void convert_route_multi_to_routes(void)
1001 {
1002   xbt_dict_cursor_t cursor_w;
1003   int symmetric;
1004   unsigned int cpt, cpt2, cursor;
1005   char *src_host_name, *dst_host_name, *key, *src, *dst, *val, *key_w,
1006     *data_w;
1007   const char *sep = "#";
1008   xbt_dict_t set = NULL;
1009   xbt_dynar_t src_names = NULL, dst_names = NULL, links;
1010
1011   if (!route_multi_elements)
1012     return;
1013
1014   if (surf_cpu_model)
1015     set = surf_model_resource_set(surf_cpu_model);
1016   if (surf_workstation_model != NULL &&
1017       surf_model_resource_set(surf_workstation_model) != NULL &&
1018       xbt_dict_length(surf_model_resource_set(surf_workstation_model)) > 0)
1019     set = surf_model_resource_set(surf_workstation_model);
1020
1021
1022   surfxml_bufferstack_push(0);
1023   /* Get all routes in the exact order they were entered in the platform file */
1024   xbt_dynar_foreach(route_multi_elements, cursor, key) {
1025     /* Get links for the route */
1026     links = (xbt_dynar_t) xbt_dict_get_or_null(route_multi_table, key);
1027     keys = xbt_str_split_str(key, sep);
1028     /* Get route ends */
1029     src = xbt_dynar_get_as(keys, 0, char *);
1030     dst = xbt_dynar_get_as(keys, 1, char *);
1031     route_action = atoi(xbt_dynar_get_as(keys, 2, char *));
1032     symmetric = atoi(xbt_dynar_get_as(keys, 3, char *));
1033
1034     /* Create the dynar of src and dst hosts for the new routes */
1035     /* NOTE: src and dst can be either set names or simple host names */
1036     src_names = (xbt_dynar_t) xbt_dict_get_or_null(set_list, src);
1037     dst_names = (xbt_dynar_t) xbt_dict_get_or_null(set_list, dst);
1038     /* Add to dynar even if they are simple names */
1039     if (src_names == NULL) {
1040       src_names = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
1041       val = xbt_strdup(src);
1042       xbt_dynar_push(src_names, &val);
1043       if (strcmp(val, "$*") != 0 && NULL == xbt_dict_get_or_null(set, val))
1044         THROW3(unknown_error, 0,
1045                "(In route:multi (%s -> %s) source %s does not exist (not a set or a host)",
1046                src, dst, src);
1047     }
1048     if (dst_names == NULL) {
1049       dst_names = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
1050       val = xbt_strdup(dst);
1051       if (strcmp(val, "$*") != 0 && NULL == xbt_dict_get_or_null(set, val))
1052         THROW3(unknown_error, 0,
1053                "(In route:multi (%s -> %s) destination %s does not exist (not a set or a host)",
1054                src, dst, dst);
1055       xbt_dynar_push(dst_names, &val);
1056     }
1057
1058     /* Build the routes */
1059     DEBUG2("ADDING MULTI ROUTE: %s -> %s", xbt_dynar_get_as(keys, 0, char *),
1060            xbt_dynar_get_as(keys, 1, char *));
1061     xbt_dynar_foreach(src_names, cpt, src_host_name) {
1062       xbt_dynar_foreach(dst_names, cpt2, dst_host_name) {
1063         /* If dst is $* then set this route to have its dst point to all hosts */
1064         if (strcmp(src_host_name, "$*") != 0
1065             && strcmp(dst_host_name, "$*") == 0) {
1066           xbt_dict_foreach(set, cursor_w, key_w, data_w) {
1067             //int n = xbt_dynar_member(src_names, (char*)key_w);
1068             add_multi_links(src, dst, links, src_host_name, key_w);
1069           }
1070         }
1071         /* If src is $* then set this route to have its dst point to all hosts */
1072         if (strcmp(src_host_name, "$*") == 0
1073             && strcmp(dst_host_name, "$*") != 0) {
1074           xbt_dict_foreach(set, cursor_w, key_w, data_w) {
1075             // if (!symmetric || (symmetric && !contains(dst_names, key_w)))
1076             add_multi_links(src, dst, links, key_w, dst_host_name);
1077           }
1078         }
1079         /* if none of them are equal to $* */
1080         if (strcmp(src_host_name, "$*") != 0
1081             && strcmp(dst_host_name, "$*") != 0) {
1082           add_multi_links(src, dst, links, src_host_name, dst_host_name);
1083         }
1084       }
1085     }
1086     xbt_dynar_free(&keys);
1087   }
1088   surfxml_bufferstack_pop(0);
1089 }
1090
1091
1092 /* Trace management functions */
1093
1094 static double trace_periodicity = -1.0;
1095 static char *trace_file = NULL;
1096 static char *trace_id;
1097
1098 static void parse_Stag_trace(void)
1099 {
1100   trace_id = strdup(A_surfxml_trace_id);
1101   trace_file = strdup(A_surfxml_trace_file);
1102   surf_parse_get_double(&trace_periodicity, A_surfxml_trace_periodicity);
1103 }
1104
1105 static void parse_Etag_trace(void)
1106 {
1107   tmgr_trace_t trace;
1108   if (!trace_file || strcmp(trace_file, "") != 0) {
1109     trace = tmgr_trace_new(trace_file);
1110   } else {
1111     if (strcmp(surfxml_pcdata, "") == 0)
1112       trace = NULL;
1113     else
1114       trace =
1115         tmgr_trace_new_from_string(trace_id, surfxml_pcdata,
1116                                    trace_periodicity);
1117   }
1118   xbt_dict_set(traces_set_list, trace_id, (void *) trace, NULL);
1119 }
1120
1121 static void parse_Stag_trace_c_connect(void)
1122 {
1123   xbt_assert2(xbt_dict_get_or_null
1124               (traces_set_list, A_surfxml_trace_c_connect_trace),
1125               "Cannot connect trace %s to %s: trace unknown",
1126               A_surfxml_trace_c_connect_trace,
1127               A_surfxml_trace_c_connect_element);
1128
1129   switch (A_surfxml_trace_c_connect_kind) {
1130   case A_surfxml_trace_c_connect_kind_HOST_AVAIL:
1131     xbt_dict_set(trace_connect_list_host_avail,
1132                  A_surfxml_trace_c_connect_trace,
1133                  xbt_strdup(A_surfxml_trace_c_connect_element), free);
1134     break;
1135   case A_surfxml_trace_c_connect_kind_POWER:
1136     xbt_dict_set(trace_connect_list_power, A_surfxml_trace_c_connect_trace,
1137                  xbt_strdup(A_surfxml_trace_c_connect_element), free);
1138     break;
1139   case A_surfxml_trace_c_connect_kind_LINK_AVAIL:
1140     xbt_dict_set(trace_connect_list_link_avail,
1141                  A_surfxml_trace_c_connect_trace,
1142                  xbt_strdup(A_surfxml_trace_c_connect_element), free);
1143     break;
1144   case A_surfxml_trace_c_connect_kind_BANDWIDTH:
1145     xbt_dict_set(trace_connect_list_bandwidth,
1146                  A_surfxml_trace_c_connect_trace,
1147                  xbt_strdup(A_surfxml_trace_c_connect_element), free);
1148     break;
1149   case A_surfxml_trace_c_connect_kind_LATENCY:
1150     xbt_dict_set(trace_connect_list_latency, A_surfxml_trace_c_connect_trace,
1151                  xbt_strdup(A_surfxml_trace_c_connect_element), free);
1152     break;
1153   default:
1154     xbt_die(bprintf("Cannot connect trace %s to %s: kind of trace unknown",
1155                     A_surfxml_trace_c_connect_trace,
1156                     A_surfxml_trace_c_connect_element));
1157   }
1158 }
1159
1160 /* Random tag functions */
1161
1162 double get_cpu_power(const char *power)
1163 {
1164   double power_scale = 0.0;
1165   const char *p, *q;
1166   char *generator;
1167   random_data_t random = NULL;
1168   /* randomness is inserted like this: power="$rand(my_random)" */
1169   if (((p = strstr(power, "$rand(")) != NULL)
1170       && ((q = strstr(power, ")")) != NULL)) {
1171     if (p < q) {
1172       generator = xbt_malloc(q - (p + 6) + 1);
1173       memcpy(generator, p + 6, q - (p + 6));
1174       generator[q - (p + 6)] = '\0';
1175       xbt_assert1((random =
1176                    xbt_dict_get_or_null(random_data_list, generator)),
1177                   "Random generator %s undefined", generator);
1178       power_scale = random_generate(random);
1179     }
1180   } else {
1181     surf_parse_get_double(&power_scale, power);
1182   }
1183   return power_scale;
1184 }
1185
1186 double random_min, random_max, random_mean, random_std_deviation,
1187   random_generator;
1188 char *random_id;
1189
1190 static void init_randomness(void)
1191 {
1192   random_id = A_surfxml_random_id;
1193   surf_parse_get_double(&random_min, A_surfxml_random_min);
1194   surf_parse_get_double(&random_max, A_surfxml_random_max);
1195   surf_parse_get_double(&random_mean, A_surfxml_random_mean);
1196   surf_parse_get_double(&random_std_deviation,
1197                         A_surfxml_random_std_deviation);
1198   random_generator = A_surfxml_random_generator;
1199 }
1200
1201 static void add_randomness(void)
1202 {
1203   /* If needed aditional properties can be added by using the prop tag */
1204   random_data_t random =
1205     random_new(random_generator, 0, random_min, random_max, random_mean,
1206                random_std_deviation);
1207   xbt_dict_set(random_data_list, random_id, (void *) random, NULL);
1208 }
1209
1210 /**
1211  * create CPU resource via CPU Model
1212  */
1213 void surf_host_create_resource(char *name, double power_peak,
1214         double power_scale,
1215         tmgr_trace_t power_trace,
1216         e_surf_resource_state_t state_initial,
1217         tmgr_trace_t state_trace,
1218         xbt_dict_t cpu_properties)
1219 {
1220         return surf_cpu_model->extension.cpu.
1221                 create_resource(name,power_peak,power_scale,power_trace,state_initial,state_trace,cpu_properties);
1222 }
1223
1224 /*
1225  * create CPU resource via worsktation_ptask_L07 model
1226  */
1227
1228 void surf_wsL07_host_create_resource(char *name, double power_peak,
1229         double power_scale,
1230         tmgr_trace_t power_trace,
1231         e_surf_resource_state_t state_initial,
1232         tmgr_trace_t state_trace,
1233         xbt_dict_t cpu_properties)
1234 {
1235         surf_workstation_model->extension.workstation.
1236                 cpu_create_resource(name,power_peak,power_scale,power_trace,state_initial,state_trace,cpu_properties);
1237 }
1238 /*
1239  * create link resource via network Model
1240  */
1241 void surf_link_create_resource(char *name,
1242         double bw_initial,
1243         tmgr_trace_t bw_trace,
1244         double lat_initial,
1245         tmgr_trace_t lat_trace,
1246         e_surf_resource_state_t
1247         state_initial,
1248         tmgr_trace_t state_trace,
1249         e_surf_link_sharing_policy_t policy,
1250         xbt_dict_t properties)
1251 {
1252         return surf_network_model->extension.network.
1253              create_resource(name,bw_initial,bw_trace,lat_initial,lat_trace,
1254                          state_initial,state_trace,policy,properties);
1255
1256 }
1257
1258 /*
1259  * create link resource via workstation_ptask_L07 model
1260  */
1261
1262 void surf_wsL07_link_create_resource(char *name,
1263                   double bw_initial,
1264                   tmgr_trace_t bw_trace,
1265                   double lat_initial,
1266                   tmgr_trace_t lat_trace,
1267                   e_surf_resource_state_t
1268                   state_initial,
1269                   tmgr_trace_t state_trace,
1270                   e_surf_link_sharing_policy_t
1271                   policy, xbt_dict_t properties)
1272 {
1273         return surf_workstation_model->extension.workstation.
1274         link_create_resource(name,bw_initial,bw_trace,lat_initial,lat_trace,
1275                                                 state_initial,state_trace,policy,properties);
1276 }
1277
1278
1279 /**
1280  * Route: add route element bypassing the parser :
1281  * same job as parse_route_elem
1282  */
1283
1284 void surf_add_route_element(char* link_ctn_id)
1285 {
1286         char *val;
1287         val = xbt_strdup(link_ctn_id);
1288         xbt_dynar_push(route_link_list,&val);
1289 }
1290 /**
1291  * set route
1292  */
1293 void surf_route_set_resource(char *source_id,char *destination_id,xbt_dynar_t links_id,int action)
1294 {
1295         route_link_list = xbt_dynar_new(sizeof(char *), NULL);
1296         //routing_add_route(source_id,destination_id,links_id,action); // COMMENTED BY DAVID
1297
1298 }
1299
1300 /**
1301  * add host to routing host list
1302  */
1303 void surf_route_add_host(char *host_id)
1304 {
1305         //routing_add_host(host_id); // COMMENTED BY DAVID
1306 }
1307
1308 /*
1309  * Add Traces
1310  */
1311 void surf_add_host_traces(void)
1312 {
1313         return surf_cpu_model->extension.cpu.
1314                      add_traces();
1315 }
1316
1317 void surf_add_link_traces(void)
1318 {
1319         return surf_network_model->extension.network.
1320                          add_traces();
1321 }
1322
1323 void surf_wsL07_add_traces(void)
1324 {
1325         return surf_workstation_model->extension.workstation.
1326                         add_traces();
1327 }
1328 /**
1329  * set routes
1330  */
1331 void surf_set_routes(void)
1332 {
1333         //routing_set_routes(); // COMMENTED BY DAVID
1334 }
1335