nfs-ganesha 1.4
|
00001 #ifdef HAVE_CONFIG_H 00002 #include "config.h" 00003 #endif 00004 00005 #include <unistd.h> 00006 #include <stdlib.h> 00007 #include <stdio.h> 00008 00009 #include <string.h> 00010 00011 #include <search.h> 00012 00013 #include <limits.h> 00014 #include <ctype.h> 00015 00016 #include "nodelist.h" 00017 #include "nodelist_internals.h" 00018 00019 #define MAX_LONG_INT_STRING_SIZE 128 00020 00031 int 00032 nodelist_nodelist_equal_patterns(nodelist_nodelist_t * first_list, 00033 nodelist_nodelist_t * second_list) 00034 { 00035 int fstatus = 1; 00036 fstatus = nodelist_nodepattern_equals(&(first_list->pattern), &(second_list->pattern)); 00037 return fstatus; 00038 } 00039 00050 int 00051 nodelist_nodelist_non_recursive_intersects(nodelist_nodelist_t * first_list, 00052 nodelist_nodelist_t * second_list) 00053 { 00054 00055 int fstatus = 0; 00056 int same_pattern = 0; 00057 00058 /* first list must not be empty */ 00059 if(first_list->rangelist.ranges_nb <= 0) 00060 return fstatus; 00061 00062 /* test if the two lists represent the same node name pattern (prefix...suffix) */ 00063 same_pattern = nodelist_nodelist_equal_patterns(first_list, second_list); 00064 00065 /* we go further only if they represent the same node name pattern */ 00066 if(same_pattern) 00067 { 00068 /* now we just have to test if ranges array intersect */ 00069 fstatus = nodelist_rangelist_intersects(&(first_list->rangelist), 00070 &(second_list->rangelist)); 00071 } 00072 00073 return fstatus; 00074 } 00075 00086 int 00087 nodelist_nodelist_intersects(nodelist_nodelist_t * first_list, 00088 nodelist_nodelist_t * second_list) 00089 { 00090 00091 int fstatus = 0; 00092 nodelist_nodelist_t *list1; 00093 nodelist_nodelist_t *list2; 00094 00095 list2 = second_list; 00096 /* we have to check that at least one sub list of the second arg list */ 00097 /* intersects with one sublist of the fist arg */ 00098 while(list2 != NULL) 00099 { 00100 list1 = first_list; 00101 while(list1 != NULL) 00102 { 00103 fstatus = nodelist_nodelist_non_recursive_intersects(list1, list2); 00104 /* intersects! break! */ 00105 if(fstatus) 00106 break; 00107 list1 = list1->next; 00108 } 00109 /* intersects! break! */ 00110 if(fstatus) 00111 break; 00112 list2 = list2->next; 00113 } 00114 00115 return fstatus; 00116 } 00117 00128 int 00129 nodelist_nodelist_non_recursive_includes(nodelist_nodelist_t * first_list, 00130 nodelist_nodelist_t * second_list) 00131 { 00132 int fstatus = 0; 00133 int same_pattern = 0; 00134 /* lists must not be empty */ 00135 if(first_list->rangelist.ranges_nb <= 0 || second_list->rangelist.ranges_nb <= 0) 00136 return fstatus; 00137 /* test if the two lists represent the same node name pattern (prefix...suffix) */ 00138 same_pattern = nodelist_nodelist_equal_patterns(first_list, second_list); 00139 00140 /* we go further only if they represent the same node name pattern */ 00141 if(same_pattern) 00142 { 00143 /* now we juste have to test if second list ranges are included in the first list ranges */ 00144 fstatus = 00145 nodelist_rangelist_includes(&(first_list->rangelist), 00146 &(second_list->rangelist)); 00147 } 00148 return fstatus; 00149 } 00150 00161 int 00162 nodelist_nodelist_includes(nodelist_nodelist_t * first_list, 00163 nodelist_nodelist_t * second_list) 00164 { 00165 int fstatus = 0; 00166 nodelist_nodelist_t *list1; 00167 nodelist_nodelist_t *list2; 00168 00169 list2 = second_list; 00170 /* we have to check that every node list in the second arg */ 00171 /* are included in one list of the fist arg */ 00172 while(list2 != NULL) 00173 { 00174 list1 = first_list; 00175 while(list1 != NULL) 00176 { 00177 fstatus = nodelist_nodelist_non_recursive_includes(list1, list2); 00178 /* included! go to next second list sublist */ 00179 if(fstatus) 00180 break; 00181 list1 = list1->next; 00182 } 00183 /* this second list sublist is not included, so break with fstatus=0 */ 00184 if(fstatus == 0) 00185 break; 00186 list2 = list2->next; 00187 } 00188 return fstatus; 00189 } 00190 00201 int nodelist_nodelist_add_ids(nodelist_nodelist_t * nodelist, char *idlist) 00202 { 00203 int fstatus = 0; 00204 fstatus = nodelist_rangelist_add_list(&(nodelist->rangelist), idlist); 00205 return fstatus; 00206 } 00207 00208 int nodelist_common_split_nodelist_entry(char *list, char **p_prefix, char **p_idlist, 00209 char **p_suffix) 00210 { 00211 00212 int fstatus = 0; 00213 00214 char *list_end; 00215 00216 char *prefix = NULL; 00217 char *prefix_begin; 00218 char *prefix_end; 00219 char *suffix = NULL; 00220 char *suffix_begin; 00221 00222 char *idlist = NULL; 00223 char *idlist_begin; 00224 char *idlist_end; 00225 00226 /* create working copy of input list */ 00227 list_end = list + (strlen(list)); 00228 prefix_begin = list; 00229 prefix_end = list; 00230 00231 /* get prefix */ 00232 prefix = (char *)malloc((strlen(list) + 1) * sizeof(char)); 00233 if(prefix != NULL) 00234 { 00235 while(*prefix_end != '[' && !isdigit(*prefix_end) && prefix_end < list_end) 00236 prefix_end++; 00237 if(prefix_end != prefix_begin && prefix_end <= list_end) 00238 { 00239 memcpy(prefix, list, (prefix_end - prefix_begin) * sizeof(char)); 00240 prefix[prefix_end - prefix_begin] = '\0'; 00241 } 00242 else 00243 { 00244 xfree(prefix); 00245 } 00246 } 00247 else 00248 { 00249 fstatus = -1; 00250 } 00251 00252 /* get idlist */ 00253 /* search for idlist begin */ 00254 if(prefix != NULL) 00255 idlist_begin = prefix_end; 00256 else 00257 idlist_begin = list; 00258 while(*idlist_begin == '[' && idlist_begin < list_end) 00259 idlist_begin++; 00260 idlist_end = idlist_begin; 00261 if(idlist_begin < list_end) 00262 { 00263 /* search for idlist end */ 00264 while((isdigit(*idlist_end) || *idlist_end == ',' || *idlist_end == '-') 00265 && idlist_end < list_end) 00266 { 00267 idlist_end++; 00268 } 00269 /* remove trailing dash, like in node%d-eth */ 00270 if(*(idlist_end - 1) == '-') 00271 { 00272 idlist_end--; 00273 while(*(idlist_end - 1) == '-') 00274 idlist_end--; 00275 } 00276 /* dump idlist */ 00277 idlist = (char *)malloc((idlist_end - idlist_begin + 1) * sizeof(char)); 00278 if(idlist != NULL) 00279 { 00280 memcpy(idlist, idlist_begin, (idlist_end - idlist_begin) * sizeof(char)); 00281 idlist[idlist_end - idlist_begin] = '\0'; 00282 } 00283 else 00284 { 00285 fstatus = -1; 00286 } 00287 } 00288 00289 /* get suffix */ 00290 /* search for suffix begin */ 00291 suffix_begin = idlist_end; 00292 while(*suffix_begin == ']' && suffix_begin < list_end) 00293 suffix_begin++; 00294 /* dump suffix */ 00295 if(suffix_begin != list_end) 00296 { 00297 suffix = (char *)malloc((list_end - suffix_begin + 1) * sizeof(char)); 00298 if(suffix != NULL) 00299 { 00300 memcpy(suffix, suffix_begin, (list_end - suffix_begin) * sizeof(char)); 00301 suffix[list_end - suffix_begin] = '\0'; 00302 } 00303 else 00304 { 00305 fstatus = -1; 00306 } 00307 } 00308 00309 if(fstatus != 0) 00310 { 00311 xfree(prefix); 00312 xfree(idlist); 00313 xfree(suffix); 00314 } 00315 00316 *p_prefix = prefix; 00317 *p_idlist = idlist; 00318 *p_suffix = suffix; 00319 00320 return fstatus; 00321 } 00322 00323 int nodelist_nodelist_init(nodelist_nodelist_t * nodelist, char **lists, int lists_nb) 00324 { 00325 00326 int fstatus = 0; 00327 int i; 00328 char *list; 00329 00330 int operation = 1; /* 1=add 2=remove */ 00331 00332 nodelist->next = NULL; 00333 fstatus += nodelist_rangelist_init(&(nodelist->rangelist)); 00334 fstatus += nodelist_nodepattern_init(&(nodelist->pattern)); 00335 00336 if(fstatus == 0) 00337 { 00338 for(i = 0; i < lists_nb; i++) 00339 { 00340 list = lists[i]; 00341 00342 /* set operation if required */ 00343 if(strlen(list) == 1) 00344 { 00345 if(*list == '-') 00346 { 00347 operation = 2; 00348 continue; 00349 } 00350 if(*list == '+') 00351 { 00352 operation = 1; 00353 continue; 00354 } 00355 else 00356 operation = 1; 00357 } 00358 00359 /* do action */ 00360 switch (operation) 00361 { 00362 00363 case 1: 00364 fstatus += nodelist_nodelist_add_nodes(nodelist, list); 00365 break; 00366 00367 case 2: 00368 nodelist_nodelist_remove_nodes(nodelist, list); 00369 break; 00370 00371 } 00372 00373 /* setting default operation */ 00374 operation = 1; 00375 } 00376 } 00377 00378 if(fstatus) 00379 return -1; 00380 else 00381 return fstatus; 00382 } 00383 00384 int nodelist_nodelist_free_contents(nodelist_nodelist_t * nodelist) 00385 { 00386 00387 int fstatus = -1; 00388 00389 if(nodelist->next != NULL) 00390 nodelist_nodelist_free_contents(nodelist->next); 00391 nodelist->next = NULL; 00392 nodelist_nodepattern_free_contents(&(nodelist->pattern)); 00393 nodelist_rangelist_free_contents(&(nodelist->rangelist)); 00394 00395 fstatus = 0; 00396 00397 return fstatus; 00398 00399 } 00400 00411 int 00412 nodelist_nodelist_copy(nodelist_nodelist_t * dest_list, nodelist_nodelist_t * src_list) 00413 { 00414 int fstatus = -1; 00415 00416 nodelist_nodelist_t **pwldest; 00417 nodelist_nodelist_t **pwlsrc; 00418 00419 nodelist_nodelist_free_contents(dest_list); 00420 00421 pwldest = &dest_list; 00422 if(nodelist_nodelist_init(*pwldest, NULL, 0) == 0) 00423 { 00424 00425 if(src_list->pattern.prefix == NULL && src_list->pattern.suffix == NULL) 00426 { 00427 // second list is empty... so initialization will be sufficient 00428 fstatus = 0; 00429 } 00430 else 00431 { 00432 00433 pwlsrc = &src_list; 00434 while(*pwlsrc != NULL) 00435 { 00436 fstatus = -1; 00437 00438 if(nodelist_nodepattern_init_by_copy 00439 (&((*pwldest)->pattern), &((*pwlsrc)->pattern)) != 0) 00440 { 00441 // unable to copy pattern, break 00442 fstatus = -2; 00443 break; 00444 } 00445 else 00446 { 00447 if((*pwlsrc)->pattern.basic != 1) 00448 { 00449 // add ids 00450 if(nodelist_rangelist_init_by_copy 00451 (&((*pwldest)->rangelist), &((*pwlsrc)->rangelist)) != 0) 00452 { 00453 // unable to copy range list, break 00454 fstatus = -3; 00455 break; 00456 } 00457 } 00458 pwldest = &((*pwldest)->next); 00459 fstatus = 0; 00460 } 00461 00462 pwlsrc = &((*pwlsrc)->next); 00463 } 00464 00465 if(fstatus != 0) 00466 nodelist_nodelist_free_contents(dest_list); 00467 00468 } 00469 00470 } 00471 00472 return fstatus; 00473 } 00474 00484 int nodelist_nodelist_is_empty(nodelist_nodelist_t * nodelist) 00485 { 00486 00487 if(nodelist->pattern.prefix == NULL && nodelist->pattern.suffix == NULL) 00488 { 00489 return 1; 00490 } 00491 else 00492 { 00493 return 0; 00494 } 00495 00496 } 00497 00508 int 00509 nodelist_nodelist_add_nodelist(nodelist_nodelist_t * nodelist, 00510 nodelist_nodelist_t * second_list) 00511 { 00512 int fstatus = -1; 00513 00514 nodelist_nodelist_t **pwldest; 00515 nodelist_nodelist_t **pwlsrc; 00516 00517 /* If second list is emty, nothing to add */ 00518 if(nodelist_nodelist_is_empty(second_list)) 00519 { 00520 return 0; 00521 } 00522 00523 /* If nodelist is empty, duplicate second_list! */ 00524 if(nodelist_nodelist_is_empty(nodelist)) 00525 { 00526 fstatus = nodelist_nodelist_copy(nodelist, second_list); 00527 } 00528 /* we have to add each second list sublist to the first one */ 00529 else 00530 { 00531 00532 pwlsrc = &second_list; 00533 while(*pwlsrc != NULL) 00534 { 00535 00536 /* try to add src sublist to an existant dest list sublist */ 00537 pwldest = &nodelist; 00538 while(*pwldest != NULL) 00539 { 00540 00541 /* if patterns equal, try to add ids and break */ 00542 if(nodelist_nodepattern_equals 00543 ((&(*pwldest)->pattern), &((*pwlsrc)->pattern))) 00544 { 00545 if((*pwldest)->pattern.padding < (*pwlsrc)->pattern.padding) 00546 nodelist_nodepattern_set_padding(&((*pwldest)->pattern), 00547 (*pwlsrc)->pattern.padding); 00548 fstatus = 00549 nodelist_rangelist_add_rangelist(&((*pwldest)->rangelist), 00550 &((*pwlsrc)->rangelist)); 00551 break; 00552 } 00553 00554 pwldest = &((*pwldest)->next); /* increment dst sublist */ 00555 } 00556 00557 /* add a new sublist to dest list if no equivalent pattern list was found */ 00558 if(*pwldest == NULL) 00559 { 00560 *pwldest = (nodelist_nodelist_t *) malloc(sizeof(nodelist_nodelist_t)); 00561 if(*pwldest != NULL) 00562 { 00563 fstatus = nodelist_nodelist_init(*pwldest, NULL, 0); 00564 if(fstatus == 0) 00565 { 00566 fstatus = 00567 nodelist_nodepattern_init_by_copy(&((*pwldest)->pattern), 00568 &((*pwlsrc)->pattern)); 00569 if(fstatus == 0) 00570 { 00571 fstatus = 00572 nodelist_rangelist_add_rangelist(&((*pwldest)->rangelist), 00573 &((*pwlsrc)->rangelist)); 00574 } 00575 } 00576 } 00577 } 00578 00579 /* fstatus != 0 means that an error occured, break */ 00580 if(fstatus != 0) 00581 { 00582 break; 00583 } 00584 00585 pwlsrc = &((*pwlsrc)->next); /* increment src sublist */ 00586 } 00587 00588 } 00589 00590 return fstatus; 00591 } 00592 00603 int 00604 nodelist_nodelist_remove_nodelist(nodelist_nodelist_t * nodelist, 00605 nodelist_nodelist_t * second_list) 00606 { 00607 int fstatus = -1; 00608 00609 int add_flag; 00610 00611 nodelist_nodelist_t worklist; 00612 nodelist_nodelist_t **pwldest; 00613 nodelist_nodelist_t **pwlsrc; 00614 00615 /* If second list is emty, nothing to remove */ 00616 if(nodelist_nodelist_is_empty(second_list)) 00617 { 00618 return 0; 00619 } 00620 00621 /* If nodelist is empty, nothing to remove */ 00622 if(nodelist_nodelist_is_empty(nodelist)) 00623 { 00624 return 0; 00625 } 00626 /* we have to remove each second list sublist from the first one */ 00627 else 00628 { 00629 00630 /* initialize work list by copying the first nodelist */ 00631 fstatus = nodelist_nodelist_init(&worklist, NULL, 0); 00632 if(fstatus == 0) 00633 { 00634 00635 pwldest = &nodelist; 00636 while(*pwldest != NULL) 00637 { 00638 00639 add_flag = 1; 00640 pwlsrc = &second_list; 00641 while(*pwlsrc != NULL) 00642 { 00643 00644 /* if patterns equal, try to remove ids and break */ 00645 if(nodelist_nodepattern_equals 00646 ((&(*pwldest)->pattern), &((*pwlsrc)->pattern))) 00647 { 00648 add_flag = 0; 00649 if((*pwldest)->pattern.basic == 0) 00650 { 00651 fstatus += 00652 nodelist_rangelist_remove_rangelist(& 00653 ((*pwldest)->rangelist), 00654 &((*pwlsrc)-> 00655 rangelist)); 00656 } 00657 else 00658 fstatus = 0; 00659 fprintf(stdout, "fstatus %d\n", fstatus); 00660 break; 00661 } 00662 00663 pwlsrc = &((*pwlsrc)->next); /* increment src sublist */ 00664 } 00665 00666 if(fstatus) 00667 break; 00668 00669 if(add_flag == 1) 00670 { 00671 fstatus += nodelist_nodelist_add_nodelist(&worklist, *pwldest); 00672 } 00673 00674 if(fstatus) 00675 break; 00676 00677 pwldest = &((*pwldest)->next); /* increment dest sublist */ 00678 } 00679 00680 if(fstatus == 0) 00681 { 00682 fstatus = nodelist_nodelist_copy(nodelist, &worklist); 00683 } 00684 00685 nodelist_nodelist_free_contents(&worklist); 00686 } 00687 00688 } 00689 00690 return fstatus; 00691 } 00692 00693 int nodelist_nodelist_add_nodes(nodelist_nodelist_t * nodelist, char *list) 00694 { 00695 00696 int fstatus = -1; 00697 int status; 00698 00699 char *prefix; 00700 char *idlist; 00701 char *suffix; 00702 00703 int token_nb, i; 00704 char *token; 00705 00706 nodelist_nodelist_t wlist; 00707 00708 if(nodelist_common_string_get_tokens_quantity(list, ",", &token_nb) == 0) 00709 { 00710 token = NULL; 00711 00712 for(i = 1; i <= token_nb; i++) 00713 { 00714 if(nodelist_common_string_get_token(list, ",", i, &token) == 0) 00715 { 00716 00717 status = 00718 nodelist_common_split_nodelist_entry(token, &prefix, &idlist, &suffix); 00719 if(status) 00720 { 00721 fstatus = -1; 00722 } 00723 else 00724 { 00725 fstatus = nodelist_nodelist_init(&wlist, NULL, 0); 00726 if(fstatus == 0) 00727 { 00728 nodelist_nodepattern_set_prefix(&(wlist.pattern), prefix); 00729 nodelist_nodepattern_set_suffix(&(wlist.pattern), suffix); 00730 if(idlist != NULL) 00731 { 00732 wlist.pattern.basic = 0; 00733 fstatus = nodelist_nodelist_add_ids(&wlist, idlist); 00734 nodelist_nodepattern_set_padding(&(wlist.pattern), fstatus); 00735 fstatus = 0; 00736 } 00737 00738 fstatus = nodelist_nodelist_add_nodelist(nodelist, &wlist); 00739 00740 nodelist_nodelist_free_contents(&wlist); 00741 } 00742 00743 xfree(prefix); 00744 xfree(suffix); 00745 xfree(idlist); 00746 } 00747 00748 free(token); 00749 } 00750 token = NULL; 00751 } 00752 00753 } 00754 00755 return fstatus; 00756 00757 } 00758 00759 int nodelist_nodelist_remove_nodes(nodelist_nodelist_t * nodelist, char *list) 00760 { 00761 00762 int fstatus = -1; 00763 int status; 00764 00765 char *prefix; 00766 char *idlist; 00767 char *suffix; 00768 00769 int token_nb, i; 00770 char *token; 00771 00772 nodelist_nodelist_t wlist; 00773 00774 if(nodelist_common_string_get_tokens_quantity(list, ",", &token_nb) == 0) 00775 { 00776 token = NULL; 00777 for(i = 1; i <= token_nb; i++) 00778 { 00779 if(nodelist_common_string_get_token(list, ",", i, &token) == 0) 00780 { 00781 00782 status = 00783 nodelist_common_split_nodelist_entry(token, &prefix, &idlist, &suffix); 00784 if(status) 00785 { 00786 fstatus = -1; 00787 } 00788 else 00789 { 00790 fstatus = nodelist_nodelist_init(&wlist, NULL, 0); 00791 if(fstatus == 0) 00792 { 00793 nodelist_nodepattern_set_prefix(&(wlist.pattern), prefix); 00794 nodelist_nodepattern_set_suffix(&(wlist.pattern), suffix); 00795 if(idlist != NULL) 00796 { 00797 wlist.pattern.basic = 0; 00798 fstatus = nodelist_nodelist_add_ids(&wlist, idlist); 00799 nodelist_nodepattern_set_padding(&(wlist.pattern), fstatus); 00800 fstatus = 0; 00801 } 00802 00803 fstatus = nodelist_nodelist_remove_nodelist(nodelist, &wlist); 00804 00805 nodelist_nodelist_free_contents(&wlist); 00806 } 00807 00808 xfree(prefix); 00809 xfree(suffix); 00810 xfree(idlist); 00811 } 00812 00813 free(token); 00814 } 00815 token = NULL; 00816 } 00817 00818 } 00819 00820 return fstatus; 00821 00822 } 00823 00824 int nodelist_nodelist_add_nodes_range(nodelist_nodelist_t * nodelist, long int from_id, 00825 long int to_id) 00826 { 00827 00828 int fstatus = -1; 00829 00830 nodelist_range_t r; 00831 00832 if(from_id <= to_id) 00833 { 00834 r.from = from_id; 00835 r.to = to_id; 00836 } 00837 else 00838 { 00839 r.from = to_id; 00840 r.to = from_id; 00841 } 00842 00843 fstatus = nodelist_rangelist_add_range(&(nodelist->rangelist), &r); 00844 00845 return fstatus; 00846 00847 } 00848 00849 long int nodelist_nodelist_non_recursive_nodes_quantity(nodelist_nodelist_t * nodelist) 00850 { 00851 00852 long int quantity; 00853 long int i; 00854 00855 quantity = 0; 00856 if(nodelist->pattern.basic == 1) 00857 { 00858 quantity++; 00859 } 00860 else 00861 { 00862 for(i = 0; i < nodelist->rangelist.ranges_nb; i++) 00863 { 00864 quantity += 00865 (nodelist->rangelist.array[i].to - nodelist->rangelist.array[i].from + 1); 00866 } 00867 } 00868 00869 return quantity; 00870 } 00871 00872 long int nodelist_nodelist_nodes_quantity(nodelist_nodelist_t * nodelist) 00873 { 00874 00875 long int quantity; 00876 00877 nodelist_nodelist_t *nlist; 00878 00879 quantity = 0; 00880 nlist = nodelist; 00881 while(nlist != NULL) 00882 { 00883 quantity += nodelist_nodelist_non_recursive_nodes_quantity(nlist); 00884 nlist = nlist->next; 00885 } 00886 00887 return quantity; 00888 } 00889 00890 int nodelist_nodelist_get_extended_string(nodelist_nodelist_t * nodelist, char **p_string) 00891 { 00892 00893 int fstatus = 0; 00894 00895 nodelist_nodelist_t *nlist; 00896 00897 char *node_string; 00898 size_t node_string_size; 00899 00900 char *output_string; 00901 size_t output_string_size = 1024; 00902 00903 long int i, j; 00904 00905 char id_print_format[128]; 00906 00907 char *prefix; 00908 char *suffix; 00909 00910 output_string = (char *)malloc(output_string_size * sizeof(char)); 00911 if(output_string) 00912 { 00913 output_string[0] = '\0'; 00914 00915 /* node list sublist loop */ 00916 nlist = nodelist; 00917 while(nlist != NULL) 00918 { 00919 00920 /* build sublist padded id format */ 00921 prefix = nlist->pattern.prefix; 00922 suffix = nlist->pattern.suffix; 00923 snprintf(id_print_format, 128, "%%s%%0.%uu%%s", nlist->pattern.padding); 00924 00925 node_string_size = 0; 00926 if(prefix != NULL) 00927 node_string_size += strlen(prefix); 00928 if(suffix != NULL) 00929 node_string_size += strlen(suffix); 00930 node_string_size += MAX_LONG_INT_STRING_SIZE; 00931 node_string = (char *)malloc(node_string_size * sizeof(char)); 00932 if(node_string != NULL) 00933 { 00934 00935 if(nlist->pattern.basic == 1) 00936 { 00937 /* add basic node */ 00938 snprintf(node_string, node_string_size, "%s%s", 00939 (prefix == NULL) ? "" : prefix, 00940 (suffix == NULL) ? "" : suffix); 00941 if(nodelist_common_string_appends_and_extends 00942 (&output_string, &output_string_size, node_string_size, node_string, 00943 ",")) 00944 { 00945 fstatus = -1; 00946 } 00947 else 00948 { 00949 fstatus = 0; 00950 } 00951 } 00952 else 00953 { 00954 /* add enumerated nodes */ 00955 for(i = 0; i < nlist->rangelist.ranges_nb; i++) 00956 { 00957 for(j = nlist->rangelist.array[i].from; 00958 j <= nlist->rangelist.array[i].to; j++) 00959 { 00960 00961 snprintf(node_string, node_string_size, id_print_format, 00962 (prefix == NULL) ? "" : prefix, j, 00963 (suffix == NULL) ? "" : suffix); 00964 if(nodelist_common_string_appends_and_extends 00965 (&output_string, &output_string_size, node_string_size, 00966 node_string, ",")) 00967 { 00968 fstatus = -1; 00969 } 00970 else 00971 { 00972 fstatus = 0; 00973 } 00974 } 00975 } 00976 } 00977 00978 free(node_string); 00979 } 00980 00981 nlist = nlist->next; 00982 } 00983 00984 if(fstatus != 0) 00985 { 00986 free(output_string); 00987 } 00988 else 00989 { 00990 *p_string = output_string; 00991 } 00992 } 00993 00994 return fstatus; 00995 } 00996 00997 int nodelist_nodelist_get_compacted_string(nodelist_nodelist_t * nodelist, 00998 char **p_string) 00999 { 01000 01001 int fstatus = -1; 01002 01003 nodelist_nodelist_t *nlist; 01004 01005 int brackets_flag; 01006 01007 char *range_string; 01008 size_t range_string_size; 01009 01010 char *ranges_string; 01011 size_t ranges_string_size; 01012 01013 char *output_string; 01014 size_t output_string_size = 1024; 01015 01016 long int nodes_nb; 01017 long int i; 01018 01019 long int from, to; 01020 01021 char id_print_format[128]; 01022 char id_range_print_format[128]; 01023 01024 char *prefix; 01025 char *suffix; 01026 01027 /* initialize output string */ 01028 output_string = (char *)malloc(output_string_size * sizeof(char)); 01029 if(output_string) 01030 { 01031 output_string[0] = '\0'; 01032 01033 /* node list sublist loop */ 01034 nlist = nodelist; 01035 while(nlist != NULL) 01036 { 01037 01038 prefix = nlist->pattern.prefix; 01039 suffix = nlist->pattern.suffix; 01040 01041 nodes_nb = nodelist_nodelist_non_recursive_nodes_quantity(nlist); 01042 if(nodes_nb == 0) 01043 { 01044 free(output_string); 01045 return fstatus; 01046 } 01047 else if(nodes_nb == 1) 01048 brackets_flag = 0; 01049 else 01050 brackets_flag = 1; 01051 01052 if(nlist->pattern.basic == 1) 01053 { 01054 /* in case of basic node, just add it */ 01055 ranges_string_size = 1; // \0 01056 if(prefix != NULL) 01057 ranges_string_size += strlen(prefix); 01058 if(suffix != NULL) 01059 ranges_string_size += strlen(suffix); 01060 ranges_string = (char *)malloc(ranges_string_size * sizeof(char)); 01061 if(ranges_string != NULL) 01062 { 01063 snprintf(ranges_string, ranges_string_size, "%s%s", 01064 (prefix == NULL) ? "" : prefix, 01065 (suffix == NULL) ? "" : suffix); 01066 fstatus = 0; 01067 } 01068 } 01069 else 01070 { 01071 /* enumerated sublist */ 01072 snprintf(id_print_format, 128, "%%0.%uu", nlist->pattern.padding); 01073 snprintf(id_range_print_format, 128, "%%0.%uu-%%0.%uu", 01074 nlist->pattern.padding, nlist->pattern.padding); 01075 01076 range_string_size = 0; 01077 range_string_size = 2 * MAX_LONG_INT_STRING_SIZE + 2; 01078 01079 ranges_string_size = 1024; 01080 ranges_string = (char *)malloc(ranges_string_size * sizeof(char)); 01081 if(ranges_string != NULL) 01082 { 01083 ranges_string[0] = '\0'; 01084 /* add prefix */ 01085 if(prefix != NULL) 01086 nodelist_common_string_appends_and_extends(&ranges_string, 01087 &ranges_string_size, 01088 strlen(prefix), prefix, 01089 ""); 01090 if(brackets_flag) 01091 nodelist_common_string_appends_and_extends(&ranges_string, 01092 &ranges_string_size, 1, 01093 "[", ""); 01094 range_string = (char *)malloc(range_string_size * sizeof(char)); 01095 if(range_string != NULL) 01096 { 01097 range_string[0] = '\0'; 01098 for(i = 0; i < nlist->rangelist.ranges_nb; i++) 01099 { 01100 from = nlist->rangelist.array[i].from; 01101 to = nlist->rangelist.array[i].to; 01102 if(from == to) 01103 snprintf(range_string, range_string_size, id_print_format, 01104 from); 01105 else 01106 snprintf(range_string, range_string_size, 01107 id_range_print_format, from, to); 01108 if(i == 0) 01109 fstatus = 01110 nodelist_common_string_appends_and_extends(&ranges_string, 01111 &ranges_string_size, 01112 range_string_size, 01113 range_string, 01114 ""); 01115 else 01116 fstatus = 01117 nodelist_common_string_appends_and_extends(&ranges_string, 01118 &ranges_string_size, 01119 range_string_size, 01120 range_string, 01121 ","); 01122 if(fstatus) 01123 { 01124 fstatus = -1; 01125 break; 01126 } 01127 else 01128 { 01129 fstatus = 0; 01130 } 01131 } 01132 free(range_string); 01133 } 01134 if(brackets_flag) 01135 nodelist_common_string_appends_and_extends(&ranges_string, 01136 &ranges_string_size, 1, 01137 "]", ""); 01138 /* add suffix */ 01139 if(suffix != NULL) 01140 nodelist_common_string_appends_and_extends(&ranges_string, 01141 &ranges_string_size, 01142 strlen(suffix), suffix, 01143 ""); 01144 } 01145 } 01146 01147 /* add current list to global list */ 01148 if(ranges_string == NULL) 01149 { 01150 fstatus = -1; 01151 break; 01152 } 01153 if(nodelist_common_string_appends_and_extends 01154 (&output_string, &output_string_size, ranges_string_size, ranges_string, 01155 ",")) 01156 { 01157 fstatus = -1; 01158 free(ranges_string); 01159 break; 01160 } 01161 01162 /* go to next sublist */ 01163 nlist = nlist->next; 01164 } 01165 01166 if(fstatus != 0) 01167 { 01168 free(output_string); 01169 } 01170 else 01171 { 01172 *p_string = output_string; 01173 } 01174 } 01175 01176 return fstatus; 01177 } 01178 01193 int nodelist_nodepattern_init(nodelist_nodepattern_t * np) 01194 { 01195 np->padding = 0; 01196 np->prefix = NULL; 01197 np->suffix = NULL; 01198 np->basic = 1; 01199 return 0; 01200 } 01201 01214 int 01215 nodelist_nodepattern_init_by_copy(nodelist_nodepattern_t * np, 01216 nodelist_nodepattern_t * npin) 01217 { 01218 int fstatus = -1; 01219 np->padding = npin->padding; 01220 np->basic = npin->basic; 01221 np->prefix = NULL; 01222 np->suffix = NULL; 01223 if(npin->prefix != NULL) 01224 { 01225 np->prefix = strdup(npin->prefix); 01226 if(np->prefix == NULL) 01227 { 01228 nodelist_nodepattern_free_contents(np); 01229 return fstatus; 01230 } 01231 } 01232 if(npin->suffix != NULL) 01233 { 01234 np->suffix = strdup(npin->suffix); 01235 if(np->suffix == NULL) 01236 { 01237 nodelist_nodepattern_free_contents(np); 01238 return fstatus; 01239 } 01240 } 01241 fstatus = 0; 01242 return fstatus; 01243 } 01244 01253 int nodelist_nodepattern_free_contents(nodelist_nodepattern_t * np) 01254 { 01255 np->padding = 0; 01256 xfree(np->prefix); 01257 xfree(np->suffix); 01258 np->basic = 1; 01259 return 0; 01260 } 01261 01271 int nodelist_nodepattern_set_padding(nodelist_nodepattern_t * np, int padding) 01272 { 01273 int fstatus = -1; 01274 if(np != NULL) 01275 { 01276 np->padding = padding; 01277 fstatus = 0; 01278 } 01279 return fstatus; 01280 } 01281 01291 int nodelist_nodepattern_set_prefix(nodelist_nodepattern_t * np, char *prefix) 01292 { 01293 int fstatus = -1; 01294 if(np != NULL && prefix != NULL) 01295 { 01296 xfree(np->prefix); 01297 np->prefix = strdup(prefix); 01298 if(np->prefix != NULL) 01299 fstatus = 0; 01300 } 01301 return fstatus; 01302 } 01303 01313 int nodelist_nodepattern_set_suffix(nodelist_nodepattern_t * np, char *suffix) 01314 { 01315 int fstatus = -1; 01316 if(np != NULL && suffix != NULL) 01317 { 01318 xfree(np->suffix); 01319 np->suffix = strdup(suffix); 01320 if(np->suffix != NULL) 01321 fstatus = 0; 01322 } 01323 return fstatus; 01324 } 01325 01334 int nodelist_nodepattern_set_basic(nodelist_nodepattern_t * np) 01335 { 01336 int fstatus = -1; 01337 if(np != NULL) 01338 { 01339 np->basic = 1; 01340 fstatus = 0; 01341 } 01342 return fstatus; 01343 } 01344 01353 int nodelist_nodepattern_unset_basic(nodelist_nodepattern_t * np) 01354 { 01355 int fstatus = -1; 01356 if(np != NULL) 01357 { 01358 np->basic = 0; 01359 fstatus = 0; 01360 } 01361 return fstatus; 01362 } 01363 01374 int 01375 nodelist_nodepattern_equals(nodelist_nodepattern_t * np1, nodelist_nodepattern_t * np2) 01376 { 01377 int fstatus = -1; 01378 if(np1 != NULL && np2 != NULL) 01379 { 01380 fstatus = 0; 01381 /* /\* same padding ? *\/ */ 01382 /* if(np1->padding!=np2->padding) */ 01383 /* return fstatus; */ 01384 /* same basic flag ? */ 01385 if(np1->basic != np2->basic) 01386 return fstatus; 01387 /* same prefix or lack of prefix ? */ 01388 if(np1->prefix != NULL && np2->prefix != NULL) 01389 { 01390 if(strcmp(np1->prefix, np2->prefix) != 0) 01391 return fstatus; 01392 } 01393 else if(np1->prefix == NULL && np2->prefix != NULL) 01394 { 01395 return fstatus; 01396 } 01397 else if(np1->prefix != NULL && np2->prefix == NULL) 01398 { 01399 return fstatus; 01400 } 01401 /* same suffix or lack of suffix ? */ 01402 if(np1->suffix != NULL && np2->suffix != NULL) 01403 { 01404 if(strcmp(np1->suffix, np2->suffix) != 0) 01405 return fstatus; 01406 } 01407 else if(np1->suffix == NULL && np2->suffix != NULL) 01408 { 01409 return fstatus; 01410 } 01411 else if(np1->suffix != NULL && np2->suffix == NULL) 01412 { 01413 return fstatus; 01414 } 01415 /* ok, they are the same pattern */ 01416 fstatus = 1; 01417 } 01418 return fstatus; 01419 } 01420