Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot//simgrid/simgrid
[simgrid.git] / src / surf / surf_routing.c
1 /* Copyright (c) 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 #ifdef HAVE_PCRE_LIB
8 #include <pcre.h>               /* regular expression library */
9 #endif
10 #include "surf_routing_private.h"
11
12 static xbt_dict_t patterns = NULL;
13 static xbt_dict_t random_value = NULL;
14
15 /* Global vars */
16 routing_global_t global_routing = NULL;
17 routing_component_t current_routing = NULL;
18 model_type_t current_routing_model = NULL;
19
20 /* global parse functions */
21 xbt_dynar_t link_list = NULL;    /* temporary store of current list link of a route */
22 static const char *src = NULL;        /* temporary store the source name of a route */
23 static const char *dst = NULL;        /* temporary store the destination name of a route */
24 static char *gw_src = NULL;     /* temporary store the gateway source name of a route */
25 static char *gw_dst = NULL;     /* temporary store the gateway destination name of a route */
26 static double_f_cpvoid_t get_link_latency = NULL;
27
28 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route, surf, "Routing part of surf");
29
30 static void routing_parse_Scluster(void);       /* cluster bypass */
31 static void routing_parse_Speer(void);          /* peer bypass */
32 static void routing_parse_Srandom(void);        /* random bypass */
33 static void routing_parse_Erandom(void);        /* random bypass */
34
35 static void routing_parse_Sconfig(void);        /* config Tag */
36 static void routing_parse_Econfig(void);        /* config Tag */
37
38 static char* replace_random_parameter(char * chaine);
39 static void clean_dict_random(void);
40
41 /* this lines are only for replace use like index in the model table */
42 typedef enum {
43   SURF_MODEL_FULL = 0,
44   SURF_MODEL_FLOYD,
45   SURF_MODEL_DIJKSTRA,
46   SURF_MODEL_DIJKSTRACACHE,
47   SURF_MODEL_NONE,
48 #ifdef HAVE_PCRE_LIB
49   SURF_MODEL_RULEBASED
50 #endif
51 } e_routing_types;
52
53 struct s_model_type routing_models[] = { {"Full",
54                                           "Full routing data (fast, large memory requirements, fully expressive)",
55                                           model_full_create,
56                                           model_full_load,
57                                           model_full_unload,
58                                           model_full_end},
59 {"Floyd",
60  "Floyd routing data (slow initialization, fast lookup, lesser memory requirements, shortest path routing only)",
61  model_floyd_create, model_floyd_load, model_floyd_unload,
62  model_floyd_end},
63 {"Dijkstra",
64  "Dijkstra routing data (fast initialization, slow lookup, small memory requirements, shortest path routing only)",
65  model_dijkstra_create, model_dijkstra_both_load,
66  model_dijkstra_both_unload, model_dijkstra_both_end},
67 {"DijkstraCache",
68  "Dijkstra routing data (fast initialization, fast lookup, small memory requirements, shortest path routing only)",
69  model_dijkstracache_create, model_dijkstra_both_load,
70  model_dijkstra_both_unload, model_dijkstra_both_end},
71 {"none", "No routing (usable with Constant network only)",
72  model_none_create, model_none_load, model_none_unload, model_none_end},
73 #ifdef HAVE_PCRE_LIB
74 {"RuleBased", "Rule-Based routing data (...)", model_rulebased_create,
75  model_rulebased_load, model_rulebased_unload, model_rulebased_end},
76 {"Vivaldi", "Vivaldi routing", model_rulebased_create,
77   model_rulebased_load, model_rulebased_unload, model_rulebased_end},
78 #endif
79 {NULL, NULL, NULL, NULL, NULL, NULL}
80 };
81
82 static double euclidean_dist_comp(int index, xbt_dynar_t src, xbt_dynar_t dst)
83 {
84         double src_coord, dst_coord;
85
86         src_coord = atof(xbt_dynar_get_as(src, index, char *));
87         dst_coord = atof(xbt_dynar_get_as(dst, index, char *));
88
89         return (src_coord-dst_coord)*(src_coord-dst_coord);
90
91 }
92
93 static double base_vivaldi_get_latency (const char *src, const char *dst)
94 {
95   double euclidean_dist;
96   xbt_dynar_t src_ctn, dst_ctn;
97   src_ctn = xbt_lib_get_or_null(host_lib, src, COORD_HOST_LEVEL);
98   if(!src_ctn) src_ctn = xbt_lib_get_or_null(as_router_lib, src, COORD_ASR_LEVEL);
99   dst_ctn = xbt_lib_get_or_null(host_lib, dst, COORD_HOST_LEVEL);
100   if(!dst_ctn) dst_ctn = xbt_lib_get_or_null(as_router_lib, dst, COORD_ASR_LEVEL);
101
102   if(dst_ctn == NULL || src_ctn == NULL)
103   xbt_die("Coord src '%s' :%p   dst '%s' :%p",src,src_ctn,dst,dst_ctn);
104
105   euclidean_dist = sqrt (euclidean_dist_comp(0,src_ctn,dst_ctn)+euclidean_dist_comp(1,src_ctn,dst_ctn))
106                                  + fabs(atof(xbt_dynar_get_as(src_ctn, 2, char *)))+fabs(atof(xbt_dynar_get_as(dst_ctn, 2, char *)));
107
108   xbt_assert(euclidean_dist>=0, "Euclidean Dist is less than 0\"%s\" and \"%.2f\"", src, euclidean_dist);
109
110   return euclidean_dist;
111 }
112
113 static double vivaldi_get_link_latency (routing_component_t rc,const char *src, const char *dst, route_extended_t e_route)
114 {
115   if(get_network_element_type(src) == SURF_NETWORK_ELEMENT_AS) {
116           int need_to_clean = e_route?0:1;
117           double latency;
118           e_route = e_route?e_route:(*(rc->get_route)) (rc, src, dst);
119           latency = base_vivaldi_get_latency(e_route->src_gateway,e_route->dst_gateway);
120           if(need_to_clean) generic_free_extended_route(e_route);
121           return latency;
122   } else {
123           return base_vivaldi_get_latency(src,dst);
124   }
125 }
126
127 /**
128  * \brief Add a "host" to the network element list
129  */
130 static void parse_S_host(const char *host_id, const char* coord)
131 {
132   network_element_info_t info = NULL;
133   if (current_routing->hierarchy == SURF_ROUTING_NULL)
134     current_routing->hierarchy = SURF_ROUTING_BASE;
135   xbt_assert(!xbt_lib_get_or_null(host_lib, host_id,ROUTING_HOST_LEVEL),
136               "Reading a host, processing unit \"%s\" already exists",
137               host_id);
138   xbt_assert(current_routing->set_processing_unit,
139               "no defined method \"set_processing_unit\" in \"%s\"",
140               current_routing->name);
141   (*(current_routing->set_processing_unit)) (current_routing, host_id);
142   info = xbt_new0(s_network_element_info_t, 1);
143   info->rc_component = current_routing;
144   info->rc_type = SURF_NETWORK_ELEMENT_HOST;
145   xbt_lib_set(host_lib,host_id,ROUTING_HOST_LEVEL,(void *) info);
146   if (strcmp(coord,"")) {
147         if(!COORD_HOST_LEVEL) xbt_die("To use coordinates, you must set configuration 'coordinates' to 'yes'");
148     xbt_dynar_t ctn = xbt_str_split_str(coord, " ");
149     xbt_dynar_shrink(ctn, 0);
150     xbt_lib_set(host_lib,host_id,COORD_HOST_LEVEL,(void *) ctn);
151   }
152 }
153
154 static void parse_E_host(void)
155 {
156          xbt_dict_cursor_t cursor = NULL;
157           char *key;
158           char *elem;
159
160           xbt_dict_foreach(current_property_set, cursor, key, elem) {
161                   XBT_DEBUG("property : %s = %s",key,elem);
162                 }
163 }
164
165 /*
166  * \brief Add a host to the network element list from XML
167  */
168 static void parse_S_host_XML(void)
169 {
170         parse_S_host(A_surfxml_host_id, A_surfxml_host_coordinates);
171 }
172 static void parse_E_host_XML(void)
173 {
174         parse_E_host();
175 }
176
177 /*
178  * \brief Add a host to the network element list from lua script
179  */
180 static void parse_S_host_lua(const char *host_id, const char *coord)
181 {
182   parse_S_host(host_id, coord);
183 }
184
185
186 /**
187  * \brief Add a "router" to the network element list
188  */
189 static void parse_S_router(const char *router_id)
190 {
191   network_element_info_t info = NULL;
192
193   if (current_routing->hierarchy == SURF_ROUTING_NULL)
194     current_routing->hierarchy = SURF_ROUTING_BASE;
195   xbt_assert(!xbt_lib_get_or_null(as_router_lib,A_surfxml_router_id, ROUTING_ASR_LEVEL),
196               "Reading a router, processing unit \"%s\" already exists",
197               router_id);
198   xbt_assert(current_routing->set_processing_unit,
199               "no defined method \"set_processing_unit\" in \"%s\"",
200               current_routing->name);
201   (*(current_routing->set_processing_unit)) (current_routing,
202                                              router_id);
203   info = xbt_new0(s_network_element_info_t, 1);
204   info->rc_component = current_routing;
205   info->rc_type = SURF_NETWORK_ELEMENT_ROUTER;
206
207   xbt_lib_set(as_router_lib,router_id,ROUTING_ASR_LEVEL,(void *) info);
208   if (strcmp(A_surfxml_router_coordinates,"")) {
209         if(!COORD_ASR_LEVEL) xbt_die("To use coordinates, you must set configuration 'coordinates' to 'yes'");
210     xbt_dynar_t ctn = xbt_str_split_str(A_surfxml_router_coordinates, " ");
211     xbt_dynar_shrink(ctn, 0);
212     xbt_lib_set(as_router_lib,router_id,COORD_ASR_LEVEL,(void *) ctn);
213   }
214 }
215
216 /**
217  * brief Add a "router" to the network element list from XML description
218  */
219 static void parse_S_router_XML(void)
220 {
221         return parse_S_router(A_surfxml_router_id);
222 }
223
224 /**
225  * brief Add a "router" to the network element list from XML description
226  */
227 static void parse_S_router_lua(const char* router_id)
228 {
229         return parse_S_router(router_id);
230 }
231
232 /**
233  * \brief Set the endponints for a route
234  */
235 static void parse_S_route_new_and_endpoints(const char *src_id, const char *dst_id)
236 {
237   if (src != NULL && dst != NULL && link_list != NULL)
238     THROWF(arg_error, 0, "Route between %s to %s can not be defined",
239            src_id, dst_id);
240   src = src_id;
241   dst = dst_id;
242   xbt_assert(strlen(src) > 0 || strlen(dst) > 0,
243               "Some limits are null in the route between \"%s\" and \"%s\"",
244               src, dst);
245   link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
246 }
247
248 /**
249  * \brief Set the endpoints for a route from XML
250  */
251 static void parse_S_route_new_and_endpoints_XML(void)
252 {
253   parse_S_route_new_and_endpoints(A_surfxml_route_src,
254                                   A_surfxml_route_dst);
255 }
256
257 /**
258  * \brief Set the endpoints for a route from lua
259  */
260 static void parse_S_route_new_and_endpoints_lua(const char *id_src, const char *id_dst)
261 {
262   parse_S_route_new_and_endpoints(id_src, id_dst);
263 }
264
265 /**
266  * \brief Set the endponints and gateways for a ASroute
267  */
268 static void parse_S_ASroute_new_and_endpoints(void)
269 {
270   if (src != NULL && dst != NULL && link_list != NULL)
271     THROWF(arg_error, 0, "Route between %s to %s can not be defined",
272            A_surfxml_ASroute_src, A_surfxml_ASroute_dst);
273   src = A_surfxml_ASroute_src;
274   dst = A_surfxml_ASroute_dst;
275   gw_src = A_surfxml_ASroute_gw_src;
276   gw_dst = A_surfxml_ASroute_gw_dst;
277   xbt_assert(strlen(src) > 0 || strlen(dst) > 0 || strlen(gw_src) > 0
278               || strlen(gw_dst) > 0,
279               "Some limits are null in the route between \"%s\" and \"%s\"",
280               src, dst);
281   link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
282 }
283
284 /**
285  * \brief Set the endponints for a bypassRoute
286  */
287 static void parse_S_bypassRoute_new_and_endpoints(void)
288 {
289   if (src != NULL && dst != NULL && link_list != NULL)
290     THROWF(arg_error, 0,
291            "Bypass Route between %s to %s can not be defined",
292            A_surfxml_bypassRoute_src, A_surfxml_bypassRoute_dst);
293   src = A_surfxml_bypassRoute_src;
294   dst = A_surfxml_bypassRoute_dst;
295   gw_src = A_surfxml_bypassRoute_gw_src;
296   gw_dst = A_surfxml_bypassRoute_gw_dst;
297   xbt_assert(strlen(src) > 0 || strlen(dst) > 0 || strlen(gw_src) > 0
298               || strlen(gw_dst) > 0,
299               "Some limits are null in the route between \"%s\" and \"%s\"",
300               src, dst);
301   link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
302 }
303
304 /**
305  * \brief Set a new link on the actual list of link for a route or ASroute
306  */
307 static void parse_E_link_ctn_new_elem(const char *link_id)
308 {
309   char *val;
310   val = xbt_strdup(link_id);
311   xbt_dynar_push(link_list, &val);
312 }
313
314 /**
315  * \brief Set a new link on the actual list of link for a route or ASroute from XML
316  */
317
318 static void parse_E_link_ctn_new_elem_XML(void)
319 {
320   if (A_surfxml_link_ctn_direction == A_surfxml_link_ctn_direction_NONE)
321     parse_E_link_ctn_new_elem(A_surfxml_link_ctn_id);
322   if (A_surfxml_link_ctn_direction == A_surfxml_link_ctn_direction_UP) {
323     char *link_id = bprintf("%s_UP", A_surfxml_link_ctn_id);
324     parse_E_link_ctn_new_elem(link_id);
325     free(link_id);
326   }
327   if (A_surfxml_link_ctn_direction == A_surfxml_link_ctn_direction_DOWN) {
328     char *link_id = bprintf("%s_DOWN", A_surfxml_link_ctn_id);
329     parse_E_link_ctn_new_elem(link_id);
330     free(link_id);
331   }
332 }
333
334 /**
335  * \brief Set a new link on the actual list of link for a route or ASroute from lua
336  */
337 static void parse_E_link_c_ctn_new_elem_lua(const char *link_id)
338 {
339   parse_E_link_ctn_new_elem(link_id);
340 }
341
342 /**
343  * \brief Store the route by calling the set_route function of the current routing component
344  */
345 static void parse_E_route_store_route(void)
346 {
347   name_route_extended_t route = xbt_new0(s_name_route_extended_t, 1);
348   route->generic_route.link_list = link_list;
349   xbt_assert(current_routing->set_route,
350               "no defined method \"set_route\" in \"%s\"",
351               current_routing->name);
352   (*(current_routing->set_route)) (current_routing, src, dst, route);
353   link_list = NULL;
354   src = NULL;
355   dst = NULL;
356 }
357
358 /**
359  * \brief Store the ASroute by calling the set_ASroute function of the current routing component
360  */
361 static void parse_E_ASroute_store_route(void)
362 {
363   name_route_extended_t e_route = xbt_new0(s_name_route_extended_t, 1);
364   e_route->generic_route.link_list = link_list;
365   e_route->src_gateway = xbt_strdup(gw_src);
366   e_route->dst_gateway = xbt_strdup(gw_dst);
367   xbt_assert(current_routing->set_ASroute,
368               "no defined method \"set_ASroute\" in \"%s\"",
369               current_routing->name);
370   (*(current_routing->set_ASroute)) (current_routing, src, dst, e_route);
371   link_list = NULL;
372   src = NULL;
373   dst = NULL;
374   gw_src = NULL;
375   gw_dst = NULL;
376 }
377
378 /**
379  * \brief Store the bypass route by calling the set_bypassroute function of the current routing component
380  */
381 static void parse_E_bypassRoute_store_route(void)
382 {
383   route_extended_t e_route = xbt_new0(s_route_extended_t, 1);
384   e_route->generic_route.link_list = link_list;
385   e_route->src_gateway = xbt_strdup(gw_src);
386   e_route->dst_gateway = xbt_strdup(gw_dst);
387   xbt_assert(current_routing->set_bypassroute,
388               "no defined method \"set_bypassroute\" in \"%s\"",
389               current_routing->name);
390   (*(current_routing->set_bypassroute)) (current_routing, src, dst,
391                                          e_route);
392   link_list = NULL;
393   src = NULL;
394   dst = NULL;
395   gw_src = NULL;
396   gw_dst = NULL;
397 }
398
399 /**
400  * \brief Make a new routing component
401  *
402  * make the new structure and
403  * set the parsing functions to allows parsing the part of the routing tree
404  */
405 static void parse_S_AS(char *AS_id, char *AS_routing)
406 {
407   routing_component_t new_routing;
408   model_type_t model = NULL;
409   char *wanted = AS_routing;
410   int cpt;
411   /* seach the routing model */
412   for (cpt = 0; routing_models[cpt].name; cpt++)
413     if (!strcmp(wanted, routing_models[cpt].name))
414       model = &routing_models[cpt];
415   /* if its not exist, error */
416   if (model == NULL) {
417     fprintf(stderr, "Routing model %s not found. Existing models:\n",
418             wanted);
419     for (cpt = 0; routing_models[cpt].name; cpt++)
420       if (!strcmp(wanted, routing_models[cpt].name))
421         fprintf(stderr, "   %s: %s\n", routing_models[cpt].name,
422                 routing_models[cpt].desc);
423     xbt_die(NULL);
424   }
425
426   /* make a new routing component */
427   new_routing = (routing_component_t) (*(model->create)) ();
428   new_routing->routing = model;
429   new_routing->hierarchy = SURF_ROUTING_NULL;
430   new_routing->name = xbt_strdup(AS_id);
431   new_routing->routing_sons = xbt_dict_new();
432
433   /* Hack for Vivaldi */
434   if(!strcmp(model->name,"Vivaldi"))
435         new_routing->get_latency = vivaldi_get_link_latency;
436
437   if (current_routing == NULL && global_routing->root == NULL) {
438
439     /* it is the first one */
440     new_routing->routing_father = NULL;
441     global_routing->root = new_routing;
442
443   } else if (current_routing != NULL && global_routing->root != NULL) {
444
445     xbt_assert(!xbt_dict_get_or_null
446                 (current_routing->routing_sons, AS_id),
447                 "The AS \"%s\" already exists", AS_id);
448     /* it is a part of the tree */
449     new_routing->routing_father = current_routing;
450     /* set the father behavior */
451     if (current_routing->hierarchy == SURF_ROUTING_NULL)
452       current_routing->hierarchy = SURF_ROUTING_RECURSIVE;
453     /* add to the sons dictionary */
454     xbt_dict_set(current_routing->routing_sons, AS_id,
455                  (void *) new_routing, NULL);
456     /* add to the father element list */
457     (*(current_routing->set_autonomous_system)) (current_routing, AS_id);
458     /* unload the prev parse rules */
459     (*(current_routing->routing->unload)) ();
460
461   } else {
462     THROWF(arg_error, 0, "All defined components must be belong to a AS");
463   }
464   /* set the new parse rules */
465   (*(new_routing->routing->load)) ();
466   /* set the new current component of the tree */
467   current_routing = new_routing;
468 }
469
470 /*
471  * Detect the routing model type of the routing component from XML platforms
472  */
473 static void parse_S_AS_XML(void)
474 {
475   parse_S_AS(A_surfxml_AS_id, A_surfxml_AS_routing);
476 }
477
478 /*
479  * define the routing model type of routing component from lua script
480  */
481 static void parse_S_AS_lua(char *id, char *mode)
482 {
483   parse_S_AS(id, mode);
484 }
485
486
487 /**
488  * \brief Finish the creation of a new routing component
489  *
490  * When you finish to read the routing component, other structures must be created. 
491  * the "end" method allow to do that for any routing model type
492  */
493 static void parse_E_AS(const char *AS_id)
494 {
495
496   if (current_routing == NULL) {
497     THROWF(arg_error, 0, "Close AS(%s), that never open", AS_id);
498   } else {
499     network_element_info_t info = NULL;
500     xbt_assert(!xbt_lib_get_or_null(as_router_lib,current_routing->name, ROUTING_ASR_LEVEL),
501                 "The AS \"%s\" already exists",current_routing->name);
502     info = xbt_new0(s_network_element_info_t, 1);
503     info->rc_component = current_routing->routing_father;
504     info->rc_type = SURF_NETWORK_ELEMENT_AS;
505     xbt_lib_set(as_router_lib,current_routing->name,ROUTING_ASR_LEVEL,(void *) info);
506
507     (*(current_routing->routing->unload)) ();
508     (*(current_routing->routing->end)) ();
509     current_routing = current_routing->routing_father;
510     if (current_routing != NULL)
511       (*(current_routing->routing->load)) ();
512   }
513 }
514
515 /*
516  * \brief Finish the creation of a new routing component from XML
517  */
518 static void parse_E_AS_XML(void)
519 {
520   parse_E_AS(A_surfxml_AS_id);
521 }
522
523 /*
524  * \brief Finish the creation of a new routing component from lua
525  */
526 static void parse_E_AS_lua(const char *id)
527 {
528   parse_E_AS(id);
529 }
530
531 /* Aux Business methods */
532
533 /**
534  * \brief Get the AS name of the element
535  *
536  * \param name the host name
537  *
538  */
539 static char* elements_As_name(const char *name)
540 {
541   routing_component_t as_comp;
542
543   /* (1) find the as where the host is located */
544   as_comp = ((network_element_info_t)
545             xbt_lib_get_or_null(host_lib,name, ROUTING_HOST_LEVEL))->rc_component;
546   return as_comp->name;
547 }
548
549
550 /**
551  * \brief Get the AS father and the first elements of the chain
552  *
553  * \param src the source host name 
554  * \param dst the destination host name
555  * 
556  * Get the common father of the to processing units, and the first different 
557  * father in the chain
558  */
559 static xbt_dynar_t elements_father(const char *src, const char *dst)
560 {
561
562   xbt_assert(src && dst, "bad parameters for \"elements_father\" method");
563
564   xbt_dynar_t result = xbt_dynar_new(sizeof(char *), NULL);
565
566   routing_component_t src_as, dst_as;
567   int index_src, index_dst, index_father_src, index_father_dst;
568   xbt_dynar_t path_src = NULL;
569   xbt_dynar_t path_dst = NULL;
570   routing_component_t current = NULL;
571   routing_component_t *current_src = NULL;
572   routing_component_t *current_dst = NULL;
573   routing_component_t *father = NULL;
574
575   /* (1) find the as where the src and dst are located */
576   void * src_data = xbt_lib_get_or_null(host_lib,src, ROUTING_HOST_LEVEL);
577   void * dst_data = xbt_lib_get_or_null(host_lib,dst, ROUTING_HOST_LEVEL);
578   if(!src_data) src_data = xbt_lib_get_or_null(as_router_lib,src, ROUTING_ASR_LEVEL);
579   if(!dst_data) dst_data = xbt_lib_get_or_null(as_router_lib,dst, ROUTING_ASR_LEVEL);
580   src_as = ((network_element_info_t)src_data)->rc_component;
581   dst_as = ((network_element_info_t)dst_data)->rc_component;
582
583   xbt_assert(src_as
584               && dst_as,
585               "Ask for route \"from\"(%s) or \"to\"(%s) no found", src,
586               dst);
587
588   /* (2) find the path to the root routing component */
589   path_src = xbt_dynar_new(sizeof(routing_component_t), NULL);
590   current = src_as;
591   while (current != NULL) {
592     xbt_dynar_push(path_src, &current);
593     current = current->routing_father;
594   }
595   path_dst = xbt_dynar_new(sizeof(routing_component_t), NULL);
596   current = dst_as;
597   while (current != NULL) {
598     xbt_dynar_push(path_dst, &current);
599     current = current->routing_father;
600   }
601
602   /* (3) find the common father */
603   index_src = path_src->used - 1;
604   index_dst = path_dst->used - 1;
605   current_src = xbt_dynar_get_ptr(path_src, index_src);
606   current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
607   while (index_src >= 0 && index_dst >= 0 && *current_src == *current_dst) {
608     current_src = xbt_dynar_get_ptr(path_src, index_src);
609     current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
610     index_src--;
611     index_dst--;
612   }
613   index_src++;
614   index_dst++;
615   current_src = xbt_dynar_get_ptr(path_src, index_src);
616   current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
617
618   /* (4) they are not in the same routing component, make the path */
619   index_father_src = index_src + 1;
620   index_father_dst = index_dst + 1;
621
622   if (*current_src == *current_dst)
623     father = current_src;
624   else
625     father = xbt_dynar_get_ptr(path_src, index_father_src);
626
627   /* (5) result generation */
628   xbt_dynar_push(result, father);       /* first same the father of src and dst */
629   xbt_dynar_push(result, current_src);  /* second the first different father of src */
630   xbt_dynar_push(result, current_dst);  /* three  the first different father of dst */
631
632   xbt_dynar_free(&path_src);
633   xbt_dynar_free(&path_dst);
634
635   return result;
636 }
637
638 /* Global Business methods */
639
640 /**
641  * \brief Recursive function for get_route
642  *
643  * \param src the source host name 
644  * \param dst the destination host name
645  * 
646  * This function is called by "get_route". It allows to walk recursively
647  * through the routing components tree.
648  */
649 static route_extended_t _get_route(const char *src, const char *dst)
650 {
651
652   void *link;
653   unsigned int cpt = 0;
654
655   XBT_DEBUG("Solve route  \"%s\" to \"%s\"", src, dst);
656
657   xbt_assert(src && dst, "bad parameters for \"_get_route\" method");
658
659   route_extended_t e_route, e_route_cnt, e_route_src = NULL, e_route_dst =
660       NULL;
661
662   xbt_dynar_t elem_father_list = elements_father(src, dst);
663
664   routing_component_t common_father =
665       xbt_dynar_get_as(elem_father_list, 0, routing_component_t);
666   routing_component_t src_father =
667       xbt_dynar_get_as(elem_father_list, 1, routing_component_t);
668   routing_component_t dst_father =
669       xbt_dynar_get_as(elem_father_list, 2, routing_component_t);
670
671   e_route = xbt_new0(s_route_extended_t, 1);
672   e_route->src_gateway = NULL;
673   e_route->dst_gateway = NULL;
674   e_route->generic_route.link_list =
675       xbt_dynar_new(global_routing->size_of_link, NULL);
676
677   if (src_father == dst_father) {       /* SURF_ROUTING_BASE */
678
679         e_route_cnt =
680           (*(common_father->get_route)) (common_father, src, dst);
681         xbt_assert(e_route_cnt, "no route between \"%s\" and \"%s\"", src,
682                           dst);
683           // FIXME (optim): faire une copie et pas une série de push
684         xbt_dynar_foreach(e_route_cnt->generic_route.link_list, cpt, link) {
685         xbt_dynar_push(e_route->generic_route.link_list, &link);
686         }
687         generic_free_extended_route(e_route_cnt);
688
689   } else {                      /* SURF_ROUTING_RECURSIVE */
690
691     route_extended_t e_route_bypass = NULL;
692
693     if (common_father->get_bypass_route)
694       e_route_bypass =
695           (*(common_father->get_bypass_route)) (common_father, src, dst);
696
697     if (e_route_bypass)
698       e_route_cnt = e_route_bypass;
699     else
700       e_route_cnt =
701           (*(common_father->get_route)) (common_father, src_father->name,
702                                          dst_father->name);
703
704     xbt_assert(e_route_cnt, "no route between \"%s\" and \"%s\"",
705                 src_father->name, dst_father->name);
706
707     xbt_assert((e_route_cnt->src_gateway == NULL) ==
708                 (e_route_cnt->dst_gateway == NULL),
709                 "bad gateway for route between \"%s\" and \"%s\"", src,
710                 dst);
711
712     if (strcmp(src, e_route_cnt->src_gateway)) {
713       e_route_src = _get_route(src, e_route_cnt->src_gateway);
714       xbt_assert(e_route_src, "no route between \"%s\" and \"%s\"", src,
715                   e_route_cnt->src_gateway);
716       xbt_dynar_foreach(e_route_src->generic_route.link_list, cpt, link) {
717         xbt_dynar_push(e_route->generic_route.link_list, &link);
718       }
719     }
720
721     xbt_dynar_foreach(e_route_cnt->generic_route.link_list, cpt, link) {
722       xbt_dynar_push(e_route->generic_route.link_list, &link);
723     }
724
725     if (strcmp(e_route_cnt->dst_gateway, dst)) {
726       e_route_dst = _get_route(e_route_cnt->dst_gateway, dst);
727       xbt_assert(e_route_dst, "no route between \"%s\" and \"%s\"",
728                   e_route_cnt->dst_gateway, dst);
729       xbt_dynar_foreach(e_route_dst->generic_route.link_list, cpt, link) {
730         xbt_dynar_push(e_route->generic_route.link_list, &link);
731       }
732     }
733
734     e_route->src_gateway = xbt_strdup(e_route_cnt->src_gateway);
735     e_route->dst_gateway = xbt_strdup(e_route_cnt->dst_gateway);
736
737     generic_free_extended_route(e_route_src);
738     generic_free_extended_route(e_route_cnt);
739     generic_free_extended_route(e_route_dst);
740   }
741
742   xbt_dynar_free(&elem_father_list);
743
744   return e_route;
745 }
746
747 static double _get_latency(const char *src, const char *dst)
748 {
749   double latency, latency_src, latency_dst = 0.0;
750
751   XBT_DEBUG("Solve route  \"%s\" to \"%s\"", src, dst);
752   xbt_assert(src && dst, "bad parameters for \"_get_route\" method");
753
754   route_extended_t e_route_cnt;
755
756   xbt_dynar_t elem_father_list = elements_father(src, dst);
757
758   routing_component_t common_father =
759       xbt_dynar_get_as(elem_father_list, 0, routing_component_t);
760   routing_component_t src_father =
761       xbt_dynar_get_as(elem_father_list, 1, routing_component_t);
762   routing_component_t dst_father =
763       xbt_dynar_get_as(elem_father_list, 2, routing_component_t);
764
765   if (src_father == dst_father) {       /* SURF_ROUTING_BASE */
766
767       latency =
768           (*(common_father->get_latency)) (common_father, src, dst, NULL);
769       xbt_assert(latency>=0, "no route between \"%s\" and \"%s\"", src,
770                   dst);
771
772   } else {                      /* SURF_ROUTING_RECURSIVE */
773      route_extended_t e_route_bypass = NULL;
774     if (common_father->get_bypass_route)
775       e_route_bypass =
776           (*(common_father->get_bypass_route)) (common_father, src, dst);
777
778     xbt_assert(!e_route_bypass,"Bypass cannot work yet with get_latency");
779                                                  
780     e_route_cnt =
781           (*(common_father->get_route)) (common_father, src_father->name,
782                                          dst_father->name);
783
784     xbt_assert(e_route_cnt, "no route between \"%s\" and \"%s\"",
785                 src_father->name, dst_father->name);
786
787     xbt_assert((e_route_cnt->src_gateway == NULL) ==
788                 (e_route_cnt->dst_gateway == NULL),
789                 "bad gateway for route between \"%s\" and \"%s\"", src,
790                 dst);
791
792     latency = (*(common_father->get_latency)) (common_father, src_father->name, dst_father->name, e_route_cnt);
793
794     xbt_assert(latency>=0, "no route between \"%s\" and \"%s\"",
795                 src_father->name, dst_father->name);
796
797     if (strcmp(src,e_route_cnt->src_gateway)) {
798
799       latency_src = _get_latency(src, e_route_cnt->src_gateway);
800       xbt_assert(latency_src>=0, "no route between \"%s\" and \"%s\"", src,
801                   e_route_cnt->src_gateway);
802       latency += latency_src;
803     }
804
805     if (strcmp(e_route_cnt->dst_gateway,dst)) {
806     
807       latency_dst = _get_latency(e_route_cnt->dst_gateway, dst);
808       xbt_assert(latency_dst>=0, "no route between \"%s\" and \"%s\"",
809                   e_route_cnt->dst_gateway, dst);
810       latency += latency_dst;
811     }
812         
813   }
814
815   xbt_dynar_free(&elem_father_list);
816
817   return latency;
818 }
819
820 /**
821  * \brief Generic method: find a route between hosts
822  *
823  * \param src the source host name 
824  * \param dst the destination host name
825  * 
826  * walk through the routing components tree and find a route between hosts
827  * by calling the differents "get_route" functions in each routing component.
828  * No need to free the returned dynar. It will be freed at the next call.
829  */
830 static xbt_dynar_t get_route(const char *src, const char *dst)
831 {
832
833   route_extended_t e_route;
834
835   e_route = _get_route(src, dst);
836   xbt_assert(e_route, "no route between \"%s\" and \"%s\"", src, dst);
837
838   if (global_routing->last_route)
839     xbt_dynar_free(&(global_routing->last_route));
840   global_routing->last_route = e_route->generic_route.link_list;
841
842   if (e_route->src_gateway)
843     xbt_free(e_route->src_gateway);
844   if (e_route->dst_gateway)
845     xbt_free(e_route->dst_gateway);
846
847   xbt_free(e_route);
848
849   return global_routing->last_route;
850 }
851
852 /**
853  * \brief Generic method: find a route between hosts
854  *
855  * \param src the source host name
856  * \param dst the destination host name
857  *
858  * walk through the routing components tree and find a route between hosts
859  * by calling the differents "get_route" functions in each routing component.
860  * Leaves the caller the responsability to clean the returned dynar.
861  */
862 static xbt_dynar_t get_route_no_cleanup(const char *src, const char *dst)
863 {
864         xbt_dynar_t d = get_route(src,dst);
865         global_routing->last_route = NULL;
866         return d;
867 }
868
869 /*Get Latency*/
870 static double get_latency(const char *src, const char *dst)
871 {
872
873   double latency = -1.0;
874   latency = _get_latency(src, dst);
875   xbt_assert(latency>=0.0, "no route between \"%s\" and \"%s\"", src, dst);
876   return latency;
877 }
878
879 /**
880  * \brief Recursive function for finalize
881  *
882  * \param rc the source host name 
883  * 
884  * This fuction is call by "finalize". It allow to finalize the 
885  * AS or routing components. It delete all the structures.
886  */
887 static void _finalize(routing_component_t rc)
888 {
889   if (rc) {
890     xbt_dict_cursor_t cursor = NULL;
891     char *key;
892     routing_component_t elem;
893     xbt_dict_foreach(rc->routing_sons, cursor, key, elem) {
894       _finalize(elem);
895     }
896     xbt_dict_t tmp_sons = rc->routing_sons;
897     char *tmp_name = rc->name;
898     xbt_dict_free(&tmp_sons);
899     xbt_free(tmp_name);
900     xbt_assert(rc->finalize, "no defined method \"finalize\" in \"%s\"",
901                 current_routing->name);
902     (*(rc->finalize)) (rc);
903   }
904 }
905
906 /**
907  * \brief Generic method: delete all the routing structures
908  * 
909  * walk through the routing components tree and delete the structures
910  * by calling the differents "finalize" functions in each routing component
911  */
912 static void finalize(void)
913 {
914   /* delete recursibly all the tree */
915   _finalize(global_routing->root);
916   /* delete last_route */
917   xbt_dynar_free(&(global_routing->last_route));
918   /* delete global routing structure */
919   xbt_free(global_routing);
920 }
921
922 static xbt_dynar_t recursive_get_onelink_routes(routing_component_t rc)
923 {
924   xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
925
926   //adding my one link routes
927   unsigned int cpt;
928   void *link;
929   xbt_dynar_t onelink_mine = rc->get_onelink_routes(rc);
930   if (onelink_mine) {
931     xbt_dynar_foreach(onelink_mine, cpt, link) {
932       xbt_dynar_push(ret, &link);
933     }
934   }
935   //recursing
936   char *key;
937   xbt_dict_cursor_t cursor = NULL;
938   routing_component_t rc_child;
939   xbt_dict_foreach(rc->routing_sons, cursor, key, rc_child) {
940     xbt_dynar_t onelink_child = recursive_get_onelink_routes(rc_child);
941     if (onelink_child) {
942       xbt_dynar_foreach(onelink_child, cpt, link) {
943         xbt_dynar_push(ret, &link);
944       }
945     }
946   }
947   return ret;
948 }
949
950 static xbt_dynar_t get_onelink_routes(void)
951 {
952   return recursive_get_onelink_routes(global_routing->root);
953 }
954
955 e_surf_network_element_type_t get_network_element_type(const char
956                                                               *name)
957 {
958   network_element_info_t rc = NULL;
959
960   rc = xbt_lib_get_or_null(host_lib, name, ROUTING_HOST_LEVEL);
961   if(rc) return rc->rc_type;
962
963   rc = xbt_lib_get_or_null(as_router_lib, name, ROUTING_ASR_LEVEL);
964   if(rc) return rc->rc_type;
965
966   return SURF_NETWORK_ELEMENT_NULL;
967 }
968
969 /**
970  * \brief Generic method: create the global routing schema
971  * 
972  * Make a global routing structure and set all the parsing functions.
973  */
974 void routing_model_create(size_t size_of_links, void *loopback, double_f_cpvoid_t get_link_latency_fun)
975 {
976   /* config the uniq global routing */
977   global_routing = xbt_new0(s_routing_global_t, 1);
978   global_routing->root = NULL;
979   global_routing->get_route = get_route;
980   global_routing->get_latency = get_latency;
981   global_routing->get_route_no_cleanup = get_route_no_cleanup;
982   global_routing->get_onelink_routes = get_onelink_routes;
983   global_routing->get_network_element_type = get_network_element_type;
984   global_routing->finalize = finalize;
985   global_routing->loopback = loopback;
986   global_routing->size_of_link = size_of_links;
987   global_routing->last_route = NULL;
988   get_link_latency = get_link_latency_fun;
989   /* no current routing at moment */
990   current_routing = NULL;
991
992   /* parse generic elements */
993   surfxml_add_callback(STag_surfxml_host_cb_list, &parse_S_host_XML);
994   surfxml_add_callback(ETag_surfxml_host_cb_list, &parse_E_host_XML);
995   surfxml_add_callback(STag_surfxml_router_cb_list, &parse_S_router_XML);
996
997   surfxml_add_callback(STag_surfxml_route_cb_list,
998                        &parse_S_route_new_and_endpoints_XML);
999   surfxml_add_callback(STag_surfxml_ASroute_cb_list,
1000                        &parse_S_ASroute_new_and_endpoints);
1001   surfxml_add_callback(STag_surfxml_bypassRoute_cb_list,
1002                        &parse_S_bypassRoute_new_and_endpoints);
1003
1004   surfxml_add_callback(ETag_surfxml_link_ctn_cb_list,
1005                        &parse_E_link_ctn_new_elem_XML);
1006
1007   surfxml_add_callback(ETag_surfxml_route_cb_list,
1008                        &parse_E_route_store_route);
1009   surfxml_add_callback(ETag_surfxml_ASroute_cb_list,
1010                        &parse_E_ASroute_store_route);
1011   surfxml_add_callback(ETag_surfxml_bypassRoute_cb_list,
1012                        &parse_E_bypassRoute_store_route);
1013
1014   surfxml_add_callback(STag_surfxml_AS_cb_list, &parse_S_AS_XML);
1015   surfxml_add_callback(ETag_surfxml_AS_cb_list, &parse_E_AS_XML);
1016
1017   surfxml_add_callback(STag_surfxml_cluster_cb_list,
1018                        &routing_parse_Scluster);
1019
1020   surfxml_add_callback(STag_surfxml_peer_cb_list,
1021                          &routing_parse_Speer);
1022
1023   surfxml_add_callback(ETag_surfxml_platform_cb_list,
1024                                                   &clean_dict_random);
1025
1026 #ifdef HAVE_TRACING
1027   instr_routing_define_callbacks();
1028 #endif
1029 }
1030
1031 void surf_parse_add_callback_config(void)
1032 {
1033         surfxml_add_callback(STag_surfxml_config_cb_list, &routing_parse_Sconfig);
1034         surfxml_add_callback(ETag_surfxml_config_cb_list, &routing_parse_Econfig);
1035         surfxml_add_callback(STag_surfxml_prop_cb_list, &parse_properties_XML);
1036         surfxml_add_callback(STag_surfxml_AS_cb_list, &surf_parse_models_setup);
1037         surfxml_add_callback(STag_surfxml_random_cb_list, &routing_parse_Srandom);
1038 }
1039
1040 void surf_parse_models_setup()
1041 {
1042         routing_parse_Erandom();
1043         surfxml_del_callback(STag_surfxml_AS_cb_list, surf_parse_models_setup);
1044         surf_config_models_setup(platform_filename);
1045         free(platform_filename);
1046 }
1047
1048 /* ************************************************** */
1049 /* ********** PATERN FOR NEW ROUTING **************** */
1050
1051 /* The minimal configuration of a new routing model need the next functions,
1052  * also you need to set at the start of the file, the new model in the model
1053  * list. Remember keep the null ending of the list.
1054  */
1055 /*** Routing model structure ***/
1056 // typedef struct {
1057 //   s_routing_component_t generic_routing;
1058 //   /* things that your routing model need */
1059 // } s_routing_component_NEW_t,*routing_component_NEW_t;
1060
1061 /*** Parse routing model functions ***/
1062 // static void model_NEW_set_processing_unit(routing_component_t rc, const char* name) {}
1063 // static void model_NEW_set_autonomous_system(routing_component_t rc, const char* name) {}
1064 // static void model_NEW_set_route(routing_component_t rc, const char* src, const char* dst, route_t route) {}
1065 // static void model_NEW_set_ASroute(routing_component_t rc, const char* src, const char* dst, route_extended_t route) {}
1066 // static void model_NEW_set_bypassroute(routing_component_t rc, const char* src, const char* dst, route_extended_t e_route) {}
1067
1068 /*** Business methods ***/
1069 // static route_extended_t NEW_get_route(routing_component_t rc, const char* src,const char* dst) {return NULL;}
1070 // static route_extended_t NEW_get_bypass_route(routing_component_t rc, const char* src,const char* dst) {return NULL;}
1071 // static void NEW_finalize(routing_component_t rc) { xbt_free(rc);}
1072
1073 /*** Creation routing model functions ***/
1074 // static void* model_NEW_create(void) {
1075 //   routing_component_NEW_t new_component =  xbt_new0(s_routing_component_NEW_t,1);
1076 //   new_component->generic_routing.set_processing_unit = model_NEW_set_processing_unit;
1077 //   new_component->generic_routing.set_autonomous_system = model_NEW_set_autonomous_system;
1078 //   new_component->generic_routing.set_route = model_NEW_set_route;
1079 //   new_component->generic_routing.set_ASroute = model_NEW_set_ASroute;
1080 //   new_component->generic_routing.set_bypassroute = model_NEW_set_bypassroute;
1081 //   new_component->generic_routing.get_route = NEW_get_route;
1082 //   new_component->generic_routing.get_bypass_route = NEW_get_bypass_route;
1083 //   new_component->generic_routing.finalize = NEW_finalize;
1084 //   /* initialization of internal structures */
1085 //   return new_component;
1086 // } /* mandatory */
1087 // static void  model_NEW_load(void) {}   /* mandatory */
1088 // static void  model_NEW_unload(void) {} /* mandatory */
1089 // static void  model_NEW_end(void) {}    /* mandatory */
1090
1091 /* ************************************************************************** */
1092 /* ************************* GENERIC PARSE FUNCTIONS ************************ */
1093
1094 void generic_set_processing_unit(routing_component_t rc,
1095                                         const char *name)
1096 {
1097   XBT_DEBUG("Load process unit \"%s\"", name);
1098   int *id = xbt_new0(int, 1);
1099   xbt_dict_t _to_index;
1100   _to_index = current_routing->to_index;
1101   *id = xbt_dict_length(_to_index);
1102   xbt_dict_set(_to_index, name, id, xbt_free);
1103 }
1104
1105 void generic_set_autonomous_system(routing_component_t rc,
1106                                           const char *name)
1107 {
1108   XBT_DEBUG("Load Autonomous system \"%s\"", name);
1109   int *id = xbt_new0(int, 1);
1110   xbt_dict_t _to_index;
1111   _to_index = current_routing->to_index;
1112   *id = xbt_dict_length(_to_index);
1113   xbt_dict_set(_to_index, name, id, xbt_free);
1114 }
1115
1116 int surf_pointer_resource_cmp(const void *a, const void *b)
1117 {
1118   return a != b;
1119 }
1120
1121 int surf_link_resource_cmp(const void *a, const void *b)
1122 {
1123   return !!memcmp(a,b,global_routing->size_of_link);
1124 }
1125
1126 void generic_set_bypassroute(routing_component_t rc,
1127                                     const char *src, const char *dst,
1128                                     route_extended_t e_route)
1129 {
1130   XBT_DEBUG("Load bypassRoute from \"%s\" to \"%s\"", src, dst);
1131   xbt_dict_t dict_bypassRoutes = rc->bypassRoutes;
1132   char *route_name;
1133
1134   route_name = bprintf("%s#%s", src, dst);
1135   xbt_assert(xbt_dynar_length(e_route->generic_route.link_list) > 0,
1136               "Invalid count of links, must be greater than zero (%s,%s)",
1137               src, dst);
1138   xbt_assert(!xbt_dict_get_or_null(dict_bypassRoutes, route_name),
1139               "The bypass route between \"%s\"(\"%s\") and \"%s\"(\"%s\") already exists",
1140               src, e_route->src_gateway, dst, e_route->dst_gateway);
1141
1142   route_extended_t new_e_route =
1143       generic_new_extended_route(SURF_ROUTING_RECURSIVE, e_route, 0);
1144   xbt_dynar_free(&(e_route->generic_route.link_list));
1145   xbt_free(e_route);
1146
1147   xbt_dict_set(dict_bypassRoutes, route_name, new_e_route,
1148                (void (*)(void *)) generic_free_extended_route);
1149   xbt_free(route_name);
1150 }
1151
1152 /* ************************************************************************** */
1153 /* *********************** GENERIC BUSINESS METHODS ************************* */
1154
1155 double generic_get_link_latency(routing_component_t rc,
1156                                        const char *src, const char *dst,
1157                                        route_extended_t route)
1158 {
1159         int need_to_clean = route?0:1;
1160         void * link;
1161         unsigned int i;
1162         double latency = 0.0;
1163
1164         route = route?route:rc->get_route(rc,src,dst);
1165
1166         xbt_dynar_foreach(route->generic_route.link_list,i,link) {
1167                 latency += get_link_latency(link);
1168         }
1169         if(need_to_clean) generic_free_extended_route(route);
1170   return latency;
1171 }
1172
1173 xbt_dynar_t generic_get_onelink_routes(routing_component_t rc)
1174 {
1175   xbt_die("\"generic_get_onelink_routes\" not implemented yet");
1176 }
1177
1178 route_extended_t generic_get_bypassroute(routing_component_t rc,
1179                                                 const char *src,
1180                                                 const char *dst)
1181 {
1182   xbt_dict_t dict_bypassRoutes = rc->bypassRoutes;
1183   routing_component_t src_as, dst_as;
1184   int index_src, index_dst;
1185   xbt_dynar_t path_src = NULL;
1186   xbt_dynar_t path_dst = NULL;
1187   routing_component_t current = NULL;
1188   routing_component_t *current_src = NULL;
1189   routing_component_t *current_dst = NULL;
1190
1191   /* (1) find the as where the src and dst are located */
1192   void * src_data = xbt_lib_get_or_null(host_lib,src, ROUTING_HOST_LEVEL);
1193   void * dst_data = xbt_lib_get_or_null(host_lib,dst, ROUTING_HOST_LEVEL);
1194   if(!src_data) src_data = xbt_lib_get_or_null(as_router_lib,src, ROUTING_ASR_LEVEL);
1195   if(!dst_data) dst_data = xbt_lib_get_or_null(as_router_lib,dst, ROUTING_ASR_LEVEL);
1196
1197   if(src_data == NULL || dst_data == NULL)
1198           xbt_die("Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",
1199                      src, dst, rc->name);
1200
1201   src_as = ((network_element_info_t)src_data)->rc_component;
1202   dst_as = ((network_element_info_t)dst_data)->rc_component;
1203
1204   /* (2) find the path to the root routing component */
1205   path_src = xbt_dynar_new(sizeof(routing_component_t), NULL);
1206   current = src_as;
1207   while (current != NULL) {
1208     xbt_dynar_push(path_src, &current);
1209     current = current->routing_father;
1210   }
1211   path_dst = xbt_dynar_new(sizeof(routing_component_t), NULL);
1212   current = dst_as;
1213   while (current != NULL) {
1214     xbt_dynar_push(path_dst, &current);
1215     current = current->routing_father;
1216   }
1217
1218   /* (3) find the common father */
1219   index_src = path_src->used - 1;
1220   index_dst = path_dst->used - 1;
1221   current_src = xbt_dynar_get_ptr(path_src, index_src);
1222   current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
1223   while (index_src >= 0 && index_dst >= 0 && *current_src == *current_dst) {
1224     routing_component_t *tmp_src, *tmp_dst;
1225     tmp_src = xbt_dynar_pop_ptr(path_src);
1226     tmp_dst = xbt_dynar_pop_ptr(path_dst);
1227     index_src--;
1228     index_dst--;
1229     current_src = xbt_dynar_get_ptr(path_src, index_src);
1230     current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
1231   }
1232
1233   int max_index_src = path_src->used - 1;
1234   int max_index_dst = path_dst->used - 1;
1235
1236   int max_index = max(max_index_src, max_index_dst);
1237   int i, max;
1238
1239   route_extended_t e_route_bypass = NULL;
1240
1241   for (max = 0; max <= max_index; max++) {
1242     for (i = 0; i < max; i++) {
1243       if (i <= max_index_src && max <= max_index_dst) {
1244         char *route_name = bprintf("%s#%s",
1245                                    (*(routing_component_t *)
1246                                     (xbt_dynar_get_ptr
1247                                      (path_src, i)))->name,
1248                                    (*(routing_component_t *)
1249                                     (xbt_dynar_get_ptr
1250                                      (path_dst, max)))->name);
1251         e_route_bypass =
1252             xbt_dict_get_or_null(dict_bypassRoutes, route_name);
1253         xbt_free(route_name);
1254       }
1255       if (e_route_bypass)
1256         break;
1257       if (max <= max_index_src && i <= max_index_dst) {
1258         char *route_name = bprintf("%s#%s",
1259                                    (*(routing_component_t *)
1260                                     (xbt_dynar_get_ptr
1261                                      (path_src, max)))->name,
1262                                    (*(routing_component_t *)
1263                                     (xbt_dynar_get_ptr
1264                                      (path_dst, i)))->name);
1265         e_route_bypass =
1266             xbt_dict_get_or_null(dict_bypassRoutes, route_name);
1267         xbt_free(route_name);
1268       }
1269       if (e_route_bypass)
1270         break;
1271     }
1272
1273     if (e_route_bypass)
1274       break;
1275
1276     if (max <= max_index_src && max <= max_index_dst) {
1277       char *route_name = bprintf("%s#%s",
1278                                  (*(routing_component_t *)
1279                                   (xbt_dynar_get_ptr
1280                                    (path_src, max)))->name,
1281                                  (*(routing_component_t *)
1282                                   (xbt_dynar_get_ptr
1283                                    (path_dst, max)))->name);
1284       e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes, route_name);
1285       xbt_free(route_name);
1286     }
1287     if (e_route_bypass)
1288       break;
1289   }
1290
1291   xbt_dynar_free(&path_src);
1292   xbt_dynar_free(&path_dst);
1293
1294   route_extended_t new_e_route = NULL;
1295
1296   if (e_route_bypass) {
1297     void *link;
1298     unsigned int cpt = 0;
1299     new_e_route = xbt_new0(s_route_extended_t, 1);
1300     new_e_route->src_gateway = xbt_strdup(e_route_bypass->src_gateway);
1301     new_e_route->dst_gateway = xbt_strdup(e_route_bypass->dst_gateway);
1302     new_e_route->generic_route.link_list =
1303         xbt_dynar_new(global_routing->size_of_link, NULL);
1304     xbt_dynar_foreach(e_route_bypass->generic_route.link_list, cpt, link) {
1305       xbt_dynar_push(new_e_route->generic_route.link_list, &link);
1306     }
1307   }
1308
1309   return new_e_route;
1310 }
1311
1312 /* ************************************************************************** */
1313 /* ************************* GENERIC AUX FUNCTIONS ************************** */
1314
1315 route_t
1316 generic_new_route(e_surf_routing_hierarchy_t hierarchy,
1317                            void *data, int order)
1318 {
1319
1320   char *link_name;
1321   route_t new_route;
1322   unsigned int cpt;
1323   xbt_dynar_t links = NULL, links_id = NULL;
1324
1325   new_route = xbt_new0(s_route_t, 1);
1326   new_route->link_list =
1327       xbt_dynar_new(global_routing->size_of_link, NULL);
1328
1329   xbt_assert(hierarchy == SURF_ROUTING_BASE,
1330               "the hierarchy type is not SURF_ROUTING_BASE");
1331
1332   links = ((route_t) data)->link_list;
1333
1334
1335   links_id = new_route->link_list;
1336
1337   xbt_dynar_foreach(links, cpt, link_name) {
1338
1339     void *link =
1340                 xbt_lib_get_or_null(link_lib, link_name, SURF_LINK_LEVEL);
1341     if (link) {
1342       if (order)
1343         xbt_dynar_push(links_id, &link);
1344       else
1345         xbt_dynar_unshift(links_id, &link);
1346     } else
1347       THROWF(mismatch_error, 0, "Link %s not found", link_name);
1348   }
1349
1350   return new_route;
1351 }
1352
1353 route_extended_t
1354 generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
1355                            void *data, int order)
1356 {
1357
1358   char *link_name;
1359   route_extended_t e_route, new_e_route;
1360   route_t route;
1361   unsigned int cpt;
1362   xbt_dynar_t links = NULL, links_id = NULL;
1363
1364   new_e_route = xbt_new0(s_route_extended_t, 1);
1365   new_e_route->generic_route.link_list =
1366       xbt_dynar_new(global_routing->size_of_link, NULL);
1367   new_e_route->src_gateway = NULL;
1368   new_e_route->dst_gateway = NULL;
1369
1370   xbt_assert(hierarchy == SURF_ROUTING_BASE
1371               || hierarchy == SURF_ROUTING_RECURSIVE,
1372               "the hierarchy type is not defined");
1373
1374   if (hierarchy == SURF_ROUTING_BASE) {
1375
1376     route = (route_t) data;
1377     links = route->link_list;
1378
1379   } else if (hierarchy == SURF_ROUTING_RECURSIVE) {
1380
1381     e_route = (route_extended_t) data;
1382     xbt_assert(e_route->src_gateway
1383                 && e_route->dst_gateway, "bad gateway, is null");
1384     links = e_route->generic_route.link_list;
1385
1386     /* remeber not erase the gateway names */
1387     new_e_route->src_gateway = strdup(e_route->src_gateway);
1388     new_e_route->dst_gateway = strdup(e_route->dst_gateway);
1389   }
1390
1391   links_id = new_e_route->generic_route.link_list;
1392
1393   xbt_dynar_foreach(links, cpt, link_name) {
1394
1395     void *link =
1396                 xbt_lib_get_or_null(link_lib, link_name, SURF_LINK_LEVEL);
1397     if (link) {
1398       if (order)
1399         xbt_dynar_push(links_id, &link);
1400       else
1401         xbt_dynar_unshift(links_id, &link);
1402     } else
1403       THROWF(mismatch_error, 0, "Link %s not found", link_name);
1404   }
1405
1406   return new_e_route;
1407 }
1408
1409 void generic_free_route(route_t route)
1410 {
1411   if (route) {
1412     xbt_dynar_free(&(route->link_list));
1413     xbt_free(route);
1414   }
1415 }
1416
1417 void generic_free_extended_route(route_extended_t e_route)
1418 {
1419   if (e_route) {
1420     xbt_dynar_free(&(e_route->generic_route.link_list));
1421     if (e_route->src_gateway)
1422       xbt_free(e_route->src_gateway);
1423     if (e_route->dst_gateway)
1424       xbt_free(e_route->dst_gateway);
1425     xbt_free(e_route);
1426   }
1427 }
1428
1429 static routing_component_t generic_as_exist(routing_component_t find_from,
1430                                             routing_component_t to_find)
1431 {
1432   //return to_find; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
1433   xbt_dict_cursor_t cursor = NULL;
1434   char *key;
1435   int found = 0;
1436   routing_component_t elem;
1437   xbt_dict_foreach(find_from->routing_sons, cursor, key, elem) {
1438     if (to_find == elem || generic_as_exist(elem, to_find)) {
1439       found = 1;
1440       break;
1441     }
1442   }
1443   if (found)
1444     return to_find;
1445   return NULL;
1446 }
1447
1448 routing_component_t
1449 generic_autonomous_system_exist(routing_component_t rc, char *element)
1450 {
1451   //return rc; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
1452   routing_component_t element_as, result, elem;
1453   xbt_dict_cursor_t cursor = NULL;
1454   char *key;
1455   element_as = ((network_element_info_t)
1456                 xbt_lib_get_or_null(as_router_lib, element, ROUTING_ASR_LEVEL))->rc_component;
1457   result = ((routing_component_t) - 1);
1458   if (element_as != rc)
1459     result = generic_as_exist(rc, element_as);
1460
1461   int found = 0;
1462   if (result) {
1463     xbt_dict_foreach(element_as->routing_sons, cursor, key, elem) {
1464       found = !strcmp(elem->name, element);
1465       if (found)
1466         break;
1467     }
1468     if (found)
1469       return element_as;
1470   }
1471   return NULL;
1472 }
1473
1474 routing_component_t
1475 generic_processing_units_exist(routing_component_t rc, char *element)
1476 {
1477   routing_component_t element_as;
1478   element_as = ((network_element_info_t)
1479                 xbt_lib_get_or_null(host_lib,
1480                  element, ROUTING_HOST_LEVEL))->rc_component;
1481   if (element_as == rc)
1482     return element_as;
1483   return generic_as_exist(rc, element_as);
1484 }
1485
1486 void generic_src_dst_check(routing_component_t rc, const char *src,
1487                                   const char *dst)
1488 {
1489
1490   void * src_data = xbt_lib_get_or_null(host_lib,src, ROUTING_HOST_LEVEL);
1491   void * dst_data = xbt_lib_get_or_null(host_lib,dst, ROUTING_HOST_LEVEL);
1492   if(!src_data) src_data = xbt_lib_get_or_null(as_router_lib,src, ROUTING_ASR_LEVEL);
1493   if(!dst_data) dst_data = xbt_lib_get_or_null(as_router_lib,dst, ROUTING_ASR_LEVEL);
1494
1495   if(src_data == NULL || dst_data == NULL)
1496           xbt_die("Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",
1497                      src, dst, rc->name);
1498
1499   routing_component_t src_as = ((network_element_info_t)src_data)->rc_component;
1500   routing_component_t dst_as = ((network_element_info_t)dst_data)->rc_component;
1501
1502   if(src_as != dst_as)
1503           xbt_die("The src(%s in %s) and dst(%s in %s) are in differents AS",
1504               src, src_as->name, dst, dst_as->name);
1505   if(rc != dst_as)
1506          xbt_die("The routing component of src'%s' and dst'%s' is not the same as the network elements belong (%s?=%s?=%s)",
1507      src,dst,src_as->name, dst_as->name,rc->name);
1508 }
1509
1510 static void routing_parse_Sconfig(void)
1511 {
1512   XBT_DEBUG("START configuration name = %s",A_surfxml_config_id);
1513 }
1514
1515 static void routing_parse_Econfig(void)
1516 {
1517   xbt_dict_cursor_t cursor = NULL;
1518   char *key;
1519   char *elem;
1520   char *cfg;
1521   xbt_dict_foreach(current_property_set, cursor, key, elem) {
1522           cfg = bprintf("%s:%s",key,elem);
1523           if(xbt_cfg_is_default_value(_surf_cfg_set, key))
1524                   xbt_cfg_set_parse(_surf_cfg_set, cfg);
1525           else
1526                   XBT_INFO("The custom configuration '%s' is already define by user!",key);
1527           free(cfg);
1528   }
1529   XBT_DEBUG("End configuration name = %s",A_surfxml_config_id);
1530 }
1531
1532 static void routing_parse_Scluster(void)
1533 {
1534   static int AX_ptr = 0;
1535
1536   char *cluster_id = A_surfxml_cluster_id;
1537   char *cluster_prefix = A_surfxml_cluster_prefix;
1538   char *cluster_suffix = A_surfxml_cluster_suffix;
1539   char *cluster_radical = A_surfxml_cluster_radical;
1540   char *cluster_power = A_surfxml_cluster_power;
1541   char *cluster_core = A_surfxml_cluster_core;
1542   char *cluster_bw = A_surfxml_cluster_bw;
1543   char *cluster_lat = A_surfxml_cluster_lat;
1544   char *temp_cluster_bw = NULL;
1545   char *temp_cluster_lat = NULL;
1546   char *temp_cluster_power = NULL;
1547   char *cluster_bb_bw = A_surfxml_cluster_bb_bw;
1548   char *cluster_bb_lat = A_surfxml_cluster_bb_lat;
1549   char *cluster_availability_file = A_surfxml_cluster_availability_file;
1550   char *cluster_state_file = A_surfxml_cluster_state_file;
1551   char *host_id, *groups, *link_id = NULL;
1552   char *router_id, *link_backbone;
1553   char *availability_file = xbt_strdup(cluster_availability_file);
1554   char *state_file = xbt_strdup(cluster_state_file);
1555
1556   if(xbt_dict_size(patterns)==0)
1557           patterns = xbt_dict_new();
1558
1559   xbt_dict_set(patterns,"id",cluster_id,NULL);
1560   xbt_dict_set(patterns,"prefix",cluster_prefix,NULL);
1561   xbt_dict_set(patterns,"suffix",cluster_suffix,NULL);
1562
1563 #ifdef HAVE_PCRE_LIB
1564   char *route_src_dst;
1565 #endif
1566   unsigned int iter;
1567   int start, end, i;
1568   xbt_dynar_t radical_elements;
1569   xbt_dynar_t radical_ends;
1570   int cluster_sharing_policy = AX_surfxml_cluster_sharing_policy;
1571   int cluster_bb_sharing_policy = AX_surfxml_cluster_bb_sharing_policy;
1572
1573 #ifndef HAVE_PCRE_LIB
1574   xbt_dynar_t tab_elements_num = xbt_dynar_new(sizeof(int), NULL);
1575   char *route_src, *route_dst;
1576   int j;
1577 #endif
1578
1579   static unsigned int surfxml_buffer_stack_stack_ptr = 1;
1580   static unsigned int surfxml_buffer_stack_stack[1024];
1581
1582   surfxml_buffer_stack_stack[0] = 0;
1583
1584   surfxml_bufferstack_push(1);
1585
1586   SURFXML_BUFFER_SET(AS_id, cluster_id);
1587 #ifdef HAVE_PCRE_LIB
1588   SURFXML_BUFFER_SET(AS_routing, "RuleBased");
1589   XBT_DEBUG("<AS id=\"%s\"\trouting=\"RuleBased\">", cluster_id);
1590 #else
1591   SURFXML_BUFFER_SET(AS_routing, "Full");
1592   XBT_DEBUG("<AS id=\"%s\"\trouting=\"Full\">", cluster_id);
1593 #endif
1594   SURFXML_START_TAG(AS);
1595
1596   radical_elements = xbt_str_split(cluster_radical, ",");
1597   xbt_dynar_foreach(radical_elements, iter, groups) {
1598     radical_ends = xbt_str_split(groups, "-");
1599     switch (xbt_dynar_length(radical_ends)) {
1600     case 1:
1601       surf_parse_get_int(&start,
1602                          xbt_dynar_get_as(radical_ends, 0, char *));
1603       host_id = bprintf("%s%d%s", cluster_prefix, start, cluster_suffix);
1604 #ifndef HAVE_PCRE_LIB
1605       xbt_dynar_push_as(tab_elements_num, int, start);
1606 #endif
1607       link_id = bprintf("%s_link_%d", cluster_id, start);
1608
1609       xbt_dict_set(patterns, "radical", bprintf("%d", start), xbt_free);
1610       temp_cluster_power = xbt_strdup(cluster_power);
1611       temp_cluster_power = replace_random_parameter(temp_cluster_power);
1612       XBT_DEBUG("<host\tid=\"%s\"\tpower=\"%s\">", host_id, temp_cluster_power);
1613       A_surfxml_host_state = A_surfxml_host_state_ON;
1614       SURFXML_BUFFER_SET(host_id, host_id);
1615       SURFXML_BUFFER_SET(host_power, temp_cluster_power);
1616       SURFXML_BUFFER_SET(host_core, cluster_core);
1617       SURFXML_BUFFER_SET(host_availability, "1.0");
1618       SURFXML_BUFFER_SET(host_coordinates, "");
1619       xbt_free(availability_file);
1620       availability_file = xbt_strdup(cluster_availability_file);
1621       xbt_free(state_file);
1622       state_file = xbt_strdup(cluster_state_file);
1623       XBT_DEBUG("\tavailability_file=\"%s\"",xbt_str_varsubst(availability_file,patterns));
1624       XBT_DEBUG("\tstate_file=\"%s\"",xbt_str_varsubst(state_file,patterns));
1625       SURFXML_BUFFER_SET(host_availability_file, xbt_str_varsubst(availability_file,patterns));
1626       SURFXML_BUFFER_SET(host_state_file, xbt_str_varsubst(state_file,patterns));
1627       XBT_DEBUG("</host>");
1628       SURFXML_START_TAG(host);
1629       SURFXML_END_TAG(host);
1630
1631
1632       temp_cluster_bw = xbt_strdup(cluster_bw);
1633       temp_cluster_bw = replace_random_parameter(temp_cluster_bw);
1634       temp_cluster_lat = xbt_strdup(cluster_lat);
1635       temp_cluster_lat = replace_random_parameter(temp_cluster_lat);
1636       XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>", link_id,temp_cluster_bw, cluster_lat);
1637       A_surfxml_link_state = A_surfxml_link_state_ON;
1638       A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
1639       if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
1640           {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FULLDUPLEX;}
1641       if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FATPIPE)
1642           {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FATPIPE;}
1643       SURFXML_BUFFER_SET(link_id, link_id);
1644       SURFXML_BUFFER_SET(link_bandwidth, temp_cluster_bw);
1645       SURFXML_BUFFER_SET(link_latency, temp_cluster_lat);
1646       SURFXML_BUFFER_SET(link_bandwidth_file, "");
1647       SURFXML_BUFFER_SET(link_latency_file, "");
1648       SURFXML_BUFFER_SET(link_state_file, "");
1649       SURFXML_START_TAG(link);
1650       SURFXML_END_TAG(link);
1651
1652       xbt_free(temp_cluster_bw);
1653       xbt_free(temp_cluster_lat);
1654       xbt_free(temp_cluster_power);
1655       free(link_id);
1656       free(host_id);
1657       break;
1658
1659     case 2:
1660
1661       surf_parse_get_int(&start,
1662                          xbt_dynar_get_as(radical_ends, 0, char *));
1663       surf_parse_get_int(&end, xbt_dynar_get_as(radical_ends, 1, char *));
1664       for (i = start; i <= end; i++) {
1665         host_id = bprintf("%s%d%s", cluster_prefix, i, cluster_suffix);
1666 #ifndef HAVE_PCRE_LIB
1667         xbt_dynar_push_as(tab_elements_num, int, i);
1668 #endif
1669         link_id = bprintf("%s_link_%d", cluster_id, i);
1670
1671         xbt_dict_set(patterns, "radical", bprintf("%d", i), xbt_free);
1672         temp_cluster_power = xbt_strdup(cluster_power);
1673         temp_cluster_power = replace_random_parameter(temp_cluster_power);
1674         XBT_DEBUG("<host\tid=\"%s\"\tpower=\"%s\">", host_id, temp_cluster_power);
1675         A_surfxml_host_state = A_surfxml_host_state_ON;
1676         SURFXML_BUFFER_SET(host_id, host_id);
1677         SURFXML_BUFFER_SET(host_power, temp_cluster_power);
1678         SURFXML_BUFFER_SET(host_core, cluster_core);
1679         SURFXML_BUFFER_SET(host_availability, "1.0");
1680         SURFXML_BUFFER_SET(host_coordinates, "");
1681         xbt_free(availability_file);
1682         availability_file = xbt_strdup(cluster_availability_file);
1683         xbt_free(state_file);
1684         state_file = xbt_strdup(cluster_state_file);
1685         XBT_DEBUG("\tavailability_file=\"%s\"",xbt_str_varsubst(availability_file,patterns));
1686         XBT_DEBUG("\tstate_file=\"%s\"",xbt_str_varsubst(state_file,patterns));
1687         SURFXML_BUFFER_SET(host_availability_file, xbt_str_varsubst(availability_file,patterns));
1688         SURFXML_BUFFER_SET(host_state_file, xbt_str_varsubst(state_file,patterns));
1689         XBT_DEBUG("</host>");
1690         SURFXML_START_TAG(host);
1691         SURFXML_END_TAG(host);
1692
1693         xbt_free(temp_cluster_power);
1694
1695         temp_cluster_bw = xbt_strdup(cluster_bw);
1696         temp_cluster_bw = replace_random_parameter(temp_cluster_bw);
1697         temp_cluster_lat = xbt_strdup(cluster_lat);
1698         temp_cluster_lat = replace_random_parameter(temp_cluster_lat);
1699         XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>", link_id,temp_cluster_bw, cluster_lat);
1700         A_surfxml_link_state = A_surfxml_link_state_ON;
1701         A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
1702         if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
1703             {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FULLDUPLEX;}
1704         if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FATPIPE)
1705             {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FATPIPE;}
1706         SURFXML_BUFFER_SET(link_id, link_id);
1707         SURFXML_BUFFER_SET(link_bandwidth, temp_cluster_bw);
1708         SURFXML_BUFFER_SET(link_latency, temp_cluster_lat);
1709         SURFXML_BUFFER_SET(link_bandwidth_file, "");
1710         SURFXML_BUFFER_SET(link_latency_file, "");
1711         SURFXML_BUFFER_SET(link_state_file, "");
1712         SURFXML_START_TAG(link);
1713         SURFXML_END_TAG(link);
1714
1715         xbt_free(temp_cluster_bw);
1716         xbt_free(temp_cluster_lat);
1717         free(link_id);
1718         free(host_id);
1719       }
1720       break;
1721
1722     default:
1723       XBT_DEBUG("Malformed radical");
1724     }
1725
1726     xbt_dynar_free(&radical_ends);
1727   }
1728   xbt_dynar_free(&radical_elements);
1729
1730   XBT_DEBUG(" ");
1731   router_id =
1732       bprintf("%s%s_router%s", cluster_prefix, cluster_id,
1733               cluster_suffix);
1734   //link_router = bprintf("%s_link_%s_router", cluster_id, cluster_id);
1735   link_backbone = bprintf("%s_backbone", cluster_id);
1736
1737   XBT_DEBUG("<router id=\"%s\"/>", router_id);
1738   SURFXML_BUFFER_SET(router_id, router_id);
1739   SURFXML_BUFFER_SET(router_coordinates, "");
1740   SURFXML_START_TAG(router);
1741   SURFXML_END_TAG(router);
1742
1743   //TODO
1744 //  xbt_dict_set(patterns, "radical", xbt_strdup("_router"), xbt_free);
1745 //  temp_cluster_bw = xbt_strdup(cluster_bw);
1746 //  temp_cluster_bw = replace_random_parameter(temp_cluster_bw);
1747 //  temp_cluster_lat = xbt_strdup(cluster_lat);
1748 //  temp_cluster_lat = replace_random_parameter(temp_cluster_lat);
1749 //  XBT_DEBUG("<link\tid=\"%s\" bw=\"%s\" lat=\"%s\"/>", link_router,temp_cluster_bw, temp_cluster_lat);
1750 //  A_surfxml_link_state = A_surfxml_link_state_ON;
1751 //  A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
1752 //  if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
1753 //  {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FULLDUPLEX;}
1754 //  if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FATPIPE)
1755 //  {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FATPIPE;}
1756 //  SURFXML_BUFFER_SET(link_id, link_router);
1757 //  SURFXML_BUFFER_SET(link_bandwidth, temp_cluster_bw);
1758 //  SURFXML_BUFFER_SET(link_latency, temp_cluster_lat);
1759 //  SURFXML_BUFFER_SET(link_bandwidth_file, "");
1760 //  SURFXML_BUFFER_SET(link_latency_file, "");
1761 //  SURFXML_BUFFER_SET(link_state_file, "");
1762 //  SURFXML_START_TAG(link);
1763 //  SURFXML_END_TAG(link);
1764
1765 //  xbt_free(temp_cluster_bw);
1766 //  xbt_free(temp_cluster_lat);
1767
1768   XBT_DEBUG("<link\tid=\"%s\" bw=\"%s\" lat=\"%s\"/>", link_backbone,cluster_bb_bw, cluster_bb_lat);
1769   A_surfxml_link_state = A_surfxml_link_state_ON;
1770   A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
1771   if(cluster_bb_sharing_policy == A_surfxml_cluster_bb_sharing_policy_FATPIPE)
1772   {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FATPIPE;}
1773   SURFXML_BUFFER_SET(link_id, link_backbone);
1774   SURFXML_BUFFER_SET(link_bandwidth, cluster_bb_bw);
1775   SURFXML_BUFFER_SET(link_latency, cluster_bb_lat);
1776   SURFXML_BUFFER_SET(link_bandwidth_file, "");
1777   SURFXML_BUFFER_SET(link_latency_file, "");
1778   SURFXML_BUFFER_SET(link_state_file, "");
1779   SURFXML_START_TAG(link);
1780   SURFXML_END_TAG(link);
1781
1782   XBT_DEBUG(" ");
1783
1784 #ifdef HAVE_PCRE_LIB
1785   char *new_suffix = xbt_strdup("");
1786
1787   radical_elements = xbt_str_split(cluster_suffix, ".");
1788   xbt_dynar_foreach(radical_elements, iter, groups) {
1789     if (strcmp(groups, "")) {
1790       char *old_suffix = new_suffix;
1791       new_suffix = bprintf("%s\\.%s", old_suffix, groups);
1792       free(old_suffix);
1793     }
1794   }
1795   route_src_dst = bprintf("%s(.*)%s", cluster_prefix, new_suffix);
1796   xbt_dynar_free(&radical_elements);
1797   free(new_suffix);
1798
1799   char *pcre_link_src = bprintf("%s_link_$1src", cluster_id);
1800   char *pcre_link_backbone = bprintf("%s_backbone", cluster_id);
1801   char *pcre_link_dst = bprintf("%s_link_$1dst", cluster_id);
1802
1803   //from router to router
1804   XBT_DEBUG("<route\tsrc=\"%s\"\tdst=\"%s\"", router_id, router_id);
1805   XBT_DEBUG("symmetrical=\"NO\">");
1806   SURFXML_BUFFER_SET(route_src, router_id);
1807   SURFXML_BUFFER_SET(route_dst, router_id);
1808   A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
1809   SURFXML_START_TAG(route);
1810
1811   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_backbone);
1812   SURFXML_BUFFER_SET(link_ctn_id, pcre_link_backbone);
1813   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
1814   SURFXML_START_TAG(link_ctn);
1815   SURFXML_END_TAG(link_ctn);
1816
1817   XBT_DEBUG("</route>");
1818   SURFXML_END_TAG(route);
1819
1820   //from host to router
1821   XBT_DEBUG("<route\tsrc=\"%s\"\tdst=\"%s\"", route_src_dst, router_id);
1822   XBT_DEBUG("symmetrical=\"NO\">");
1823   SURFXML_BUFFER_SET(route_src, route_src_dst);
1824   SURFXML_BUFFER_SET(route_dst, router_id);
1825   A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
1826   SURFXML_START_TAG(route);
1827
1828   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_src);
1829   SURFXML_BUFFER_SET(link_ctn_id, pcre_link_src);
1830   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
1831   if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
1832   {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_UP;}
1833   SURFXML_START_TAG(link_ctn);
1834   SURFXML_END_TAG(link_ctn);
1835
1836   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_backbone);
1837   SURFXML_BUFFER_SET(link_ctn_id, pcre_link_backbone);
1838   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
1839   SURFXML_START_TAG(link_ctn);
1840   SURFXML_END_TAG(link_ctn);
1841
1842   XBT_DEBUG("</route>");
1843   SURFXML_END_TAG(route);
1844
1845   //from router to host
1846   XBT_DEBUG("<route\tsrc=\"%s\"\tdst=\"%s\"", router_id, route_src_dst);
1847   XBT_DEBUG("symmetrical=\"NO\">");
1848   SURFXML_BUFFER_SET(route_src, router_id);
1849   SURFXML_BUFFER_SET(route_dst, route_src_dst);
1850   A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
1851   SURFXML_START_TAG(route);
1852
1853   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_backbone);
1854   SURFXML_BUFFER_SET(link_ctn_id, pcre_link_backbone);
1855   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
1856   SURFXML_START_TAG(link_ctn);
1857   SURFXML_END_TAG(link_ctn);
1858
1859   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_dst);
1860   SURFXML_BUFFER_SET(link_ctn_id, pcre_link_dst);
1861   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
1862   if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
1863   {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_UP;}
1864   SURFXML_START_TAG(link_ctn);
1865   SURFXML_END_TAG(link_ctn);
1866
1867   XBT_DEBUG("</route>");
1868   SURFXML_END_TAG(route);
1869
1870   //from host to host
1871   XBT_DEBUG("<route\tsrc=\"%s\"\tdst=\"%s\"", route_src_dst, route_src_dst);
1872   XBT_DEBUG("symmetrical=\"NO\">");
1873   SURFXML_BUFFER_SET(route_src, route_src_dst);
1874   SURFXML_BUFFER_SET(route_dst, route_src_dst);
1875   A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
1876   SURFXML_START_TAG(route);
1877
1878   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_src);
1879   SURFXML_BUFFER_SET(link_ctn_id, pcre_link_src);
1880   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
1881   if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
1882   {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_UP;}
1883   SURFXML_START_TAG(link_ctn);
1884   SURFXML_END_TAG(link_ctn);
1885
1886   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_backbone);
1887   SURFXML_BUFFER_SET(link_ctn_id, pcre_link_backbone);
1888   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
1889   SURFXML_START_TAG(link_ctn);
1890   SURFXML_END_TAG(link_ctn);
1891
1892   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_dst);
1893   SURFXML_BUFFER_SET(link_ctn_id, pcre_link_dst);
1894   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
1895   if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
1896   {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_DOWN;}
1897   SURFXML_START_TAG(link_ctn);
1898   SURFXML_END_TAG(link_ctn);
1899
1900   XBT_DEBUG("</route>");
1901   SURFXML_END_TAG(route);
1902
1903   free(pcre_link_dst);
1904   free(pcre_link_backbone);
1905   free(pcre_link_src);
1906   free(route_src_dst);
1907 #else
1908   for (i = 0; i <= xbt_dynar_length(tab_elements_num); i++) {
1909     for (j = 0; j <= xbt_dynar_length(tab_elements_num); j++) {
1910       if (i == xbt_dynar_length(tab_elements_num)) {
1911         route_src = router_id;
1912       } else {
1913         route_src =
1914             bprintf("%s%d%s", cluster_prefix,
1915                     xbt_dynar_get_as(tab_elements_num, i, int),
1916                     cluster_suffix);
1917       }
1918
1919       if (j == xbt_dynar_length(tab_elements_num)) {
1920         route_dst = router_id;
1921       } else {
1922         route_dst =
1923             bprintf("%s%d%s", cluster_prefix,
1924                     xbt_dynar_get_as(tab_elements_num, j, int),
1925                     cluster_suffix);
1926       }
1927
1928       XBT_DEBUG("<route\tsrc=\"%s\"\tdst=\"%s\"", route_src, route_dst);
1929       XBT_DEBUG("symmetrical=\"NO\">");
1930       SURFXML_BUFFER_SET(route_src, route_src);
1931       SURFXML_BUFFER_SET(route_dst, route_dst);
1932       A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
1933       SURFXML_START_TAG(route);
1934
1935       if (i != xbt_dynar_length(tab_elements_num)){
1936           route_src =
1937                 bprintf("%s_link_%d", cluster_id,
1938                         xbt_dynar_get_as(tab_elements_num, i, int));
1939                   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", route_src);
1940                   SURFXML_BUFFER_SET(link_ctn_id, route_src);
1941                   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
1942                   if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
1943                   {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_UP;}
1944                   SURFXML_START_TAG(link_ctn);
1945                   SURFXML_END_TAG(link_ctn);
1946                   free(route_src);
1947       }
1948
1949       XBT_DEBUG("<link_ctn\tid=\"%s_backbone\"/>", cluster_id);
1950       SURFXML_BUFFER_SET(link_ctn_id, bprintf("%s_backbone", cluster_id));
1951       A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
1952       SURFXML_START_TAG(link_ctn);
1953       SURFXML_END_TAG(link_ctn);
1954
1955       if (j != xbt_dynar_length(tab_elements_num)) {
1956           route_dst =
1957                 bprintf("%s_link_%d", cluster_id,
1958                         xbt_dynar_get_as(tab_elements_num, j, int));
1959                   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", route_dst);
1960                   SURFXML_BUFFER_SET(link_ctn_id, route_dst);
1961                   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
1962                   if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
1963                   {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_DOWN;}
1964                   SURFXML_START_TAG(link_ctn);
1965                   SURFXML_END_TAG(link_ctn);
1966                   free(route_dst);
1967       }
1968
1969       XBT_DEBUG("</route>");
1970       SURFXML_END_TAG(route);
1971     }
1972   }
1973   xbt_dynar_free(&tab_elements_num);
1974
1975 #endif
1976
1977   free(router_id);
1978   free(link_backbone);
1979   //free(link_router);
1980   xbt_dict_free(&patterns);
1981   free(availability_file);
1982   free(state_file);
1983
1984   XBT_DEBUG("</AS>");
1985   SURFXML_END_TAG(AS);
1986   XBT_DEBUG(" ");
1987
1988   surfxml_bufferstack_pop(1);
1989 }
1990 /*
1991  * This function take a string and replace parameters from patterns dict.
1992  * It returns the new value.
1993  */
1994 static char* replace_random_parameter(char * string)
1995 {
1996   char *test_string = NULL;
1997
1998   if(xbt_dict_size(random_value)==0)
1999     return string;
2000
2001   string = xbt_str_varsubst(string, patterns); // for patterns of cluster
2002   test_string = bprintf("${%s}", string);
2003   test_string = xbt_str_varsubst(test_string,random_value); //Add ${xxxxx} for random Generator
2004
2005   if (strcmp(test_string,"")) { //if not empty, keep this value.
2006     xbt_free(string);
2007     string = test_string;
2008   } //In other case take old value (without ${})
2009   else
2010         free(test_string);
2011   return string;
2012 }
2013
2014 static void clean_dict_random(void)
2015 {
2016         xbt_dict_free(&random_value);
2017         xbt_dict_free(&patterns);
2018 }
2019
2020 static void routing_parse_Speer(void)
2021 {
2022   static int AX_ptr = 0;
2023
2024   char *peer_id = A_surfxml_peer_id;
2025   char *peer_power = A_surfxml_peer_power;
2026   char *peer_bw_in = A_surfxml_peer_bw_in;
2027   char *peer_bw_out = A_surfxml_peer_bw_out;
2028   char *peer_lat = A_surfxml_peer_lat;
2029   char *peer_coord = A_surfxml_peer_coordinates;
2030   char *peer_state_file = A_surfxml_peer_state_file;
2031   char *peer_availability_file = A_surfxml_peer_availability_file;
2032
2033   char *host_id = NULL;
2034   char *router_id, *link_router, *link_backbone, *link_id_up, *link_id_down;
2035
2036   static unsigned int surfxml_buffer_stack_stack_ptr = 1;
2037   static unsigned int surfxml_buffer_stack_stack[1024];
2038
2039   surfxml_buffer_stack_stack[0] = 0;
2040
2041   surfxml_bufferstack_push(1);
2042
2043   SURFXML_BUFFER_SET(AS_id, peer_id);
2044
2045   SURFXML_BUFFER_SET(AS_routing, "Full");
2046   XBT_DEBUG("<AS id=\"%s\"\trouting=\"Full\">", peer_id);
2047
2048   SURFXML_START_TAG(AS);
2049
2050   XBT_DEBUG(" ");
2051   host_id = bprintf("peer_%s", peer_id);
2052   router_id = bprintf("router_%s", peer_id);
2053   link_id_up = bprintf("link_%s_up", peer_id);
2054   link_id_down = bprintf("link_%s_down", peer_id);
2055
2056   link_router = bprintf("%s_link_router", peer_id);
2057   link_backbone = bprintf("%s_backbone", peer_id);
2058
2059   XBT_DEBUG("<host\tid=\"%s\"\tpower=\"%s\"/>", host_id, peer_power);
2060   A_surfxml_host_state = A_surfxml_host_state_ON;
2061   SURFXML_BUFFER_SET(host_id, host_id);
2062   SURFXML_BUFFER_SET(host_power, peer_power);
2063   SURFXML_BUFFER_SET(host_availability, "1.0");
2064   SURFXML_BUFFER_SET(host_availability_file, peer_availability_file);
2065   SURFXML_BUFFER_SET(host_state_file, peer_state_file);
2066   SURFXML_BUFFER_SET(host_coordinates, "");
2067   SURFXML_START_TAG(host);
2068   SURFXML_END_TAG(host);
2069
2070   XBT_DEBUG("<router id=\"%s\"\tcoordinates=\"%s\"/>", router_id, peer_coord);
2071   SURFXML_BUFFER_SET(router_id, router_id);
2072   SURFXML_BUFFER_SET(router_coordinates, peer_coord);
2073   SURFXML_START_TAG(router);
2074   SURFXML_END_TAG(router);
2075
2076   XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>", link_id_up, peer_bw_in, peer_lat);
2077   A_surfxml_link_state = A_surfxml_link_state_ON;
2078   A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
2079   SURFXML_BUFFER_SET(link_id, link_id_up);
2080   SURFXML_BUFFER_SET(link_bandwidth, peer_bw_in);
2081   SURFXML_BUFFER_SET(link_latency, peer_lat);
2082   SURFXML_BUFFER_SET(link_bandwidth_file, "");
2083   SURFXML_BUFFER_SET(link_latency_file, "");
2084   SURFXML_BUFFER_SET(link_state_file, "");
2085   SURFXML_START_TAG(link);
2086   SURFXML_END_TAG(link);
2087
2088   XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>", link_id_down, peer_bw_out, peer_lat);
2089   A_surfxml_link_state = A_surfxml_link_state_ON;
2090   A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
2091   SURFXML_BUFFER_SET(link_id, link_id_down);
2092   SURFXML_BUFFER_SET(link_bandwidth, peer_bw_out);
2093   SURFXML_BUFFER_SET(link_latency, peer_lat);
2094   SURFXML_BUFFER_SET(link_bandwidth_file, "");
2095   SURFXML_BUFFER_SET(link_latency_file, "");
2096   SURFXML_BUFFER_SET(link_state_file, "");
2097   SURFXML_START_TAG(link);
2098   SURFXML_END_TAG(link);
2099
2100   XBT_DEBUG(" ");
2101
2102   // begin here
2103   XBT_DEBUG("<route\tsrc=\"%s\"\tdst=\"%s\"", host_id, router_id);
2104   XBT_DEBUG("symmetrical=\"NO\">");
2105   SURFXML_BUFFER_SET(route_src, host_id);
2106   SURFXML_BUFFER_SET(route_dst, router_id);
2107   A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
2108   SURFXML_START_TAG(route);
2109
2110   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", link_id_up);
2111   SURFXML_BUFFER_SET(link_ctn_id, link_id_up);
2112   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
2113   SURFXML_START_TAG(link_ctn);
2114   SURFXML_END_TAG(link_ctn);
2115
2116   XBT_DEBUG("</route>");
2117   SURFXML_END_TAG(route);
2118
2119   //Opposite Route
2120   XBT_DEBUG("<route\tsrc=\"%s\"\tdst=\"%s\"", router_id, host_id);
2121   XBT_DEBUG("symmetrical=\"NO\">");
2122   SURFXML_BUFFER_SET(route_src, router_id);
2123   SURFXML_BUFFER_SET(route_dst, host_id);
2124   A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
2125   SURFXML_START_TAG(route);
2126
2127   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", link_id_down);
2128   SURFXML_BUFFER_SET(link_ctn_id, link_id_down);
2129   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
2130   SURFXML_START_TAG(link_ctn);
2131   SURFXML_END_TAG(link_ctn);
2132
2133   XBT_DEBUG("</route>");
2134   SURFXML_END_TAG(route);
2135
2136   XBT_DEBUG("</AS>");
2137   SURFXML_END_TAG(AS);
2138   XBT_DEBUG(" ");
2139
2140   //xbt_dynar_free(&tab_elements_num);
2141         free(host_id);
2142         free(router_id);
2143         free(link_router);
2144         free(link_backbone);
2145         free(link_id_up);
2146         free(link_id_down);
2147   surfxml_bufferstack_pop(1);
2148 }
2149
2150 static void routing_parse_Srandom(void)
2151 {
2152           double mean, std, min, max, seed;
2153           char *random_id = A_surfxml_random_id;
2154           char *random_radical = A_surfxml_random_radical;
2155           char *rd_name = NULL;
2156           char *rd_value;
2157           surf_parse_get_double(&mean,A_surfxml_random_mean);
2158           surf_parse_get_double(&std,A_surfxml_random_std_deviation);
2159           surf_parse_get_double(&min,A_surfxml_random_min);
2160           surf_parse_get_double(&max,A_surfxml_random_max);
2161           surf_parse_get_double(&seed,A_surfxml_random_seed);
2162
2163           double res = 0;
2164           int i = 0;
2165           random_data_t random = xbt_new0(s_random_data_t, 1);
2166           char *tmpbuf;
2167
2168           xbt_dynar_t radical_elements;
2169           unsigned int iter;
2170           char *groups;
2171           int start, end;
2172           xbt_dynar_t radical_ends;
2173
2174           random->generator = A_surfxml_random_generator;
2175           random->seed = seed;
2176           random->min = min;
2177           random->max = max;
2178
2179           /* Check user stupidities */
2180           if (max < min)
2181             THROWF(arg_error, 0, "random->max < random->min (%f < %f)", max, min);
2182           if (mean < min)
2183             THROWF(arg_error, 0, "random->mean < random->min (%f < %f)", mean,
2184                    min);
2185           if (mean > max)
2186             THROWF(arg_error, 0, "random->mean > random->max (%f > %f)", mean,
2187                    max);
2188
2189           /* normalize the mean and standard deviation before storing */
2190           random->mean = (mean - min) / (max - min);
2191           random->std = std / (max - min);
2192
2193           if (random->mean * (1 - random->mean) < random->std * random->std)
2194             THROWF(arg_error, 0, "Invalid mean and standard deviation (%f and %f)",
2195                    random->mean, random->std);
2196
2197           XBT_DEBUG("id = '%s' min = '%f' max = '%f' mean = '%f' std_deviatinon = '%f' generator = '%d' seed = '%ld' radical = '%s'",
2198           random_id,
2199           random->min,
2200           random->max,
2201           random->mean,
2202           random->std,
2203           random->generator,
2204           random->seed,
2205           random_radical);
2206
2207           if(xbt_dict_size(random_value)==0)
2208                   random_value = xbt_dict_new();
2209
2210           if(!strcmp(random_radical,""))
2211           {
2212                   res = random_generate(random);
2213                   rd_value = bprintf("%f",res);
2214                   xbt_dict_set(random_value, random_id, rd_value, free);
2215           }
2216           else
2217           {
2218                   radical_elements = xbt_str_split(random_radical, ",");
2219                   xbt_dynar_foreach(radical_elements, iter, groups) {
2220                         radical_ends = xbt_str_split(groups, "-");
2221                         switch (xbt_dynar_length(radical_ends)) {
2222                         case 1:
2223                                           xbt_assert(!xbt_dict_get_or_null(random_value,random_id),"Custom Random '%s' already exists !",random_id);
2224                                           res = random_generate(random);
2225                                           tmpbuf = bprintf("%s%d",random_id,atoi(xbt_dynar_getfirst_as(radical_ends,char *)));
2226                                           xbt_dict_set(random_value, tmpbuf, bprintf("%f",res), free);
2227                                           xbt_free(tmpbuf);
2228                                           break;
2229
2230                         case 2:   surf_parse_get_int(&start,
2231                                                                                  xbt_dynar_get_as(radical_ends, 0, char *));
2232                                           surf_parse_get_int(&end, xbt_dynar_get_as(radical_ends, 1, char *));
2233                                           for (i = start; i <= end; i++) {
2234                                                   xbt_assert(!xbt_dict_get_or_null(random_value,random_id),"Custom Random '%s' already exists !",bprintf("%s%d",random_id,i));
2235                                                   res = random_generate(random);
2236                           tmpbuf = bprintf("%s%d",random_id,i);
2237                                                   xbt_dict_set(random_value, tmpbuf, bprintf("%f",res), free);
2238                           xbt_free(tmpbuf);
2239                                           }
2240                                           break;
2241                         default:
2242                                 XBT_INFO("Malformed radical");
2243                         }
2244                         res = random_generate(random);
2245                         rd_name  = bprintf("%s_router",random_id);
2246                         rd_value = bprintf("%f",res);
2247                         xbt_dict_set(random_value, rd_name, rd_value, free);
2248
2249                         xbt_dynar_free(&radical_ends);
2250                   }
2251                   free(rd_name);
2252                   xbt_dynar_free(&radical_elements);
2253           }
2254 }
2255
2256 static void routing_parse_Erandom(void)
2257 {
2258         xbt_dict_cursor_t cursor = NULL;
2259         char *key;
2260         char *elem;
2261
2262         xbt_dict_foreach(random_value, cursor, key, elem) {
2263           XBT_DEBUG("%s = %s",key,elem);
2264         }
2265
2266 }
2267
2268
2269 /*
2270  * New methods to init the routing model component from the lua script
2271  */
2272
2273 /*
2274  * calling parse_S_AS_lua with lua values
2275  */
2276 void routing_AS_init(const char *AS_id, const char *AS_routing)
2277 {
2278   parse_S_AS_lua((char *) AS_id, (char *) AS_routing);
2279 }
2280
2281 /*
2282  * calling parse_E_AS_lua to fisnish the creation of routing component
2283  */
2284 void routing_AS_end(const char *AS_id)
2285 {
2286   parse_E_AS_lua((char *) AS_id);
2287 }
2288
2289 /*
2290  * add a host to the network element list
2291  */
2292
2293 void routing_add_host(const char *host_id)
2294 {
2295   parse_S_host_lua((char *) host_id, (char*)""); // FIXME propagate coordinate system to lua
2296 }
2297
2298 /*
2299  * Set a new link on the actual list of link for a route or ASroute
2300  */
2301 void routing_add_link(const char *link_id)
2302 {
2303   parse_E_link_c_ctn_new_elem_lua((char *) link_id);
2304 }
2305
2306 /*
2307  *Set the endpoints for a route
2308  */
2309 void routing_set_route(const char *src_id, const char *dst_id)
2310 {
2311   parse_S_route_new_and_endpoints_lua(src_id, dst_id);
2312 }
2313
2314 /*
2315  * Store the route by calling parse_E_route_store_route
2316  */
2317 void routing_store_route(void)
2318 {
2319   parse_E_route_store_route();
2320 }