1 #define PETSC_DLL 2 /* 3 Provides a general mechanism to allow one to register new routines in 4 dynamic libraries for many of the PETSc objects (including, e.g., KSP and PC). 5 */ 6 #include "petsc.h" /*I "petsc.h" I*/ 7 #include "petscsys.h" 8 9 #undef __FUNCT__ 10 #define __FUNCT__ "PetscFListGetPathAndFunction" 11 PetscErrorCode PETSC_DLLEXPORT PetscFListGetPathAndFunction(const char name[],char *path[],char *function[]) 12 { 13 PetscErrorCode ierr; 14 char work[PETSC_MAX_PATH_LEN],*lfunction; 15 16 PetscFunctionBegin; 17 ierr = PetscStrncpy(work,name,256);CHKERRQ(ierr); 18 ierr = PetscStrchr(work,':',&lfunction);CHKERRQ(ierr); 19 if (lfunction != work && lfunction && lfunction[1] != ':') { 20 lfunction[0] = 0; 21 ierr = PetscStrallocpy(work,path);CHKERRQ(ierr); 22 ierr = PetscStrallocpy(lfunction+1,function);CHKERRQ(ierr); 23 } else { 24 *path = 0; 25 ierr = PetscStrallocpy(name,function);CHKERRQ(ierr); 26 } 27 PetscFunctionReturn(0); 28 } 29 30 #if defined(PETSC_USE_DYNAMIC_LIBRARIES) 31 32 /* 33 This is the list used by the DLRegister routines 34 */ 35 PetscDLLibrary DLLibrariesLoaded = 0; 36 37 #undef __FUNCT__ 38 #define __FUNCT__ "PetscLoadDynamicLibrary" 39 static PetscErrorCode PETSC_DLLEXPORT PetscLoadDynamicLibrary(const char *name,PetscTruth *found) 40 { 41 char libs[PETSC_MAX_PATH_LEN],dlib[PETSC_MAX_PATH_LEN]; 42 PetscErrorCode ierr; 43 44 PetscFunctionBegin; 45 ierr = PetscStrcpy(libs,"${PETSC_LIB_DIR}/libpetsc");CHKERRQ(ierr); 46 ierr = PetscStrcat(libs,name);CHKERRQ(ierr); 47 ierr = PetscDLLibraryRetrieve(PETSC_COMM_WORLD,libs,dlib,1024,found);CHKERRQ(ierr); 48 if (*found) { 49 ierr = PetscDLLibraryAppend(PETSC_COMM_WORLD,&DLLibrariesLoaded,dlib);CHKERRQ(ierr); 50 } else { 51 ierr = PetscStrcpy(libs,"${PETSC_DIR}/${PETSC_ARCH}/lib/libpetsc");CHKERRQ(ierr); 52 ierr = PetscStrcat(libs,name);CHKERRQ(ierr); 53 ierr = PetscDLLibraryRetrieve(PETSC_COMM_WORLD,libs,dlib,1024,found);CHKERRQ(ierr); 54 if (*found) { 55 ierr = PetscDLLibraryAppend(PETSC_COMM_WORLD,&DLLibrariesLoaded,dlib);CHKERRQ(ierr); 56 } 57 } 58 PetscFunctionReturn(0); 59 } 60 61 #undef __FUNCT__ 62 #define __FUNCT__ "PetscInitialize_DynamicLibraries" 63 /* 64 PetscInitialize_DynamicLibraries - Adds the default dynamic link libraries to the 65 search path. 66 */ 67 PetscErrorCode PETSC_DLLEXPORT PetscInitialize_DynamicLibraries(void) 68 { 69 char *libname[32]; 70 PetscErrorCode ierr; 71 PetscInt nmax,i; 72 PetscTruth found; 73 74 PetscFunctionBegin; 75 76 nmax = 32; 77 ierr = PetscOptionsGetStringArray(PETSC_NULL,"-dll_prepend",libname,&nmax,PETSC_NULL);CHKERRQ(ierr); 78 for (i=0; i<nmax; i++) { 79 ierr = PetscDLLibraryPrepend(PETSC_COMM_WORLD,&DLLibrariesLoaded,libname[i]);CHKERRQ(ierr); 80 ierr = PetscFree(libname[i]);CHKERRQ(ierr); 81 } 82 83 ierr = PetscLoadDynamicLibrary("",&found);CHKERRQ(ierr); 84 if (!found) SETERRQ(PETSC_ERR_FILE_OPEN,"Unable to locate PETSc dynamic library \n You cannot move the dynamic libraries!"); 85 ierr = PetscLoadDynamicLibrary("vec",&found);CHKERRQ(ierr); 86 if (!found) SETERRQ(PETSC_ERR_FILE_OPEN,"Unable to locate PETSc Vec dynamic library \n You cannot move the dynamic libraries!"); 87 ierr = PetscLoadDynamicLibrary("mat",&found);CHKERRQ(ierr); 88 if (!found) SETERRQ(PETSC_ERR_FILE_OPEN,"Unable to locate PETSc Mat dynamic library \n You cannot move the dynamic libraries!"); 89 ierr = PetscLoadDynamicLibrary("dm",&found);CHKERRQ(ierr); 90 if (!found) SETERRQ(PETSC_ERR_FILE_OPEN,"Unable to locate PETSc DM dynamic library \n You cannot move the dynamic libraries!"); 91 ierr = PetscLoadDynamicLibrary("ksp",&found);CHKERRQ(ierr); 92 if (!found) SETERRQ(PETSC_ERR_FILE_OPEN,"Unable to locate PETSc KSP dynamic library \n You cannot move the dynamic libraries!"); 93 ierr = PetscLoadDynamicLibrary("snes",&found);CHKERRQ(ierr); 94 if (!found) SETERRQ(PETSC_ERR_FILE_OPEN,"Unable to locate PETSc SNES dynamic library \n You cannot move the dynamic libraries!"); 95 ierr = PetscLoadDynamicLibrary("ts",&found);CHKERRQ(ierr); 96 if (!found) SETERRQ(PETSC_ERR_FILE_OPEN,"Unable to locate PETSc TS dynamic library \n You cannot move the dynamic libraries!"); 97 98 ierr = PetscLoadDynamicLibrary("mesh",&found);CHKERRQ(ierr); 99 ierr = PetscLoadDynamicLibrary("contrib",&found);CHKERRQ(ierr); 100 101 nmax = 32; 102 ierr = PetscOptionsGetStringArray(PETSC_NULL,"-dll_append",libname,&nmax,PETSC_NULL);CHKERRQ(ierr); 103 for (i=0; i<nmax; i++) { 104 ierr = PetscDLLibraryAppend(PETSC_COMM_WORLD,&DLLibrariesLoaded,libname[i]);CHKERRQ(ierr); 105 ierr = PetscDLLibraryCCAAppend(PETSC_COMM_WORLD,&DLLibrariesLoaded,libname[i]);CHKERRQ(ierr); 106 ierr = PetscFree(libname[i]);CHKERRQ(ierr); 107 } 108 PetscFunctionReturn(0); 109 } 110 111 #undef __FUNCT__ 112 #define __FUNCT__ "PetscFinalize_DynamicLibraries" 113 /* 114 PetscFinalize_DynamicLibraries - Closes the opened dynamic libraries. 115 */ 116 PetscErrorCode PetscFinalize_DynamicLibraries(void) 117 { 118 PetscErrorCode ierr; 119 PetscTruth flg; 120 121 PetscFunctionBegin; 122 ierr = PetscOptionsHasName(PETSC_NULL,"-dll_view",&flg);CHKERRQ(ierr); 123 if (flg) { 124 ierr = PetscDLLibraryPrintPath();CHKERRQ(ierr); 125 } 126 ierr = PetscDLLibraryClose(DLLibrariesLoaded);CHKERRQ(ierr); 127 PetscFunctionReturn(0); 128 } 129 130 #else /* not using dynamic libraries */ 131 132 #undef __FUNCT__ 133 #define __FUNCT__ "PetscInitalize_DynamicLibraries" 134 PetscErrorCode PETSC_DLLEXPORT PetscInitialize_DynamicLibraries(void) 135 { 136 PetscErrorCode ierr; 137 138 PetscFunctionBegin; 139 /* 140 This just initializes the most basic PETSc stuff. 141 142 The classes, from PetscDraw to PetscTS, are initialized the first 143 time an XXCreate() is called. 144 */ 145 ierr = PetscInitializePackage(PETSC_NULL);CHKERRQ(ierr); 146 PetscFunctionReturn(0); 147 } 148 #undef __FUNCT__ 149 #define __FUNCT__ "PetscFinalize_DynamicLibraries" 150 PetscErrorCode PetscFinalize_DynamicLibraries(void) 151 { 152 PetscFunctionBegin; 153 154 PetscFunctionReturn(0); 155 } 156 #endif 157 158 /* ------------------------------------------------------------------------------*/ 159 struct _n_PetscFList { 160 void (*routine)(void); /* the routine */ 161 char *path; /* path of link library containing routine */ 162 char *name; /* string to identify routine */ 163 char *rname; /* routine name in dynamic library */ 164 PetscFList next; /* next pointer */ 165 PetscFList next_list; /* used to maintain list of all lists for freeing */ 166 }; 167 168 /* 169 Keep a linked list of PetscFLists so that we can destroy all the left-over ones. 170 */ 171 static PetscFList dlallhead = 0; 172 173 #undef __FUNCT__ 174 #define __FUNCT__ "PetscFListAdd" 175 /*@C 176 PetscFListAddDynamic - Given a routine and a string id, saves that routine in the 177 specified registry. 178 179 Not Collective 180 181 Input Parameters: 182 + fl - pointer registry 183 . name - string to identify routine 184 . rname - routine name in dynamic library 185 - fnc - function pointer (optional if using dynamic libraries) 186 187 Notes: 188 To remove a registered routine, pass in a PETSC_NULL rname and fnc(). 189 190 Users who wish to register new classes for use by a particular PETSc 191 component (e.g., SNES) should generally call the registration routine 192 for that particular component (e.g., SNESRegisterDynamic()) instead of 193 calling PetscFListAddDynamic() directly. 194 195 ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, or ${any environmental variable} 196 occuring in pathname will be replaced with appropriate values. 197 198 Level: developer 199 200 .seealso: PetscFListDestroy(), SNESRegisterDynamic(), KSPRegisterDynamic(), 201 PCRegisterDynamic(), TSRegisterDynamic(), PetscFList 202 @*/ 203 PetscErrorCode PETSC_DLLEXPORT PetscFListAdd(PetscFList *fl,const char name[],const char rname[],void (*fnc)(void)) 204 { 205 PetscFList entry,ne; 206 PetscErrorCode ierr; 207 char *fpath,*fname; 208 209 PetscFunctionBegin; 210 211 if (!*fl) { 212 ierr = PetscNew(struct _n_PetscFList,&entry);CHKERRQ(ierr); 213 ierr = PetscStrallocpy(name,&entry->name);CHKERRQ(ierr); 214 ierr = PetscFListGetPathAndFunction(rname,&fpath,&fname);CHKERRQ(ierr); 215 entry->path = fpath; 216 entry->rname = fname; 217 entry->routine = fnc; 218 entry->next = 0; 219 *fl = entry; 220 221 /* add this new list to list of all lists */ 222 if (!dlallhead) { 223 dlallhead = *fl; 224 (*fl)->next_list = 0; 225 } else { 226 ne = dlallhead; 227 dlallhead = *fl; 228 (*fl)->next_list = ne; 229 } 230 } else { 231 /* search list to see if it is already there */ 232 ne = *fl; 233 while (ne) { 234 PetscTruth founddup; 235 236 ierr = PetscStrcmp(ne->name,name,&founddup);CHKERRQ(ierr); 237 if (founddup) { /* found duplicate */ 238 ierr = PetscFListGetPathAndFunction(rname,&fpath,&fname);CHKERRQ(ierr); 239 ierr = PetscStrfree(ne->path);CHKERRQ(ierr); 240 ierr = PetscStrfree(ne->rname);CHKERRQ(ierr); 241 ne->path = fpath; 242 ne->rname = fname; 243 ne->routine = fnc; 244 PetscFunctionReturn(0); 245 } 246 if (ne->next) ne = ne->next; else break; 247 } 248 /* create new entry and add to end of list */ 249 ierr = PetscNew(struct _n_PetscFList,&entry);CHKERRQ(ierr); 250 ierr = PetscStrallocpy(name,&entry->name);CHKERRQ(ierr); 251 ierr = PetscFListGetPathAndFunction(rname,&fpath,&fname);CHKERRQ(ierr); 252 entry->path = fpath; 253 entry->rname = fname; 254 entry->routine = fnc; 255 entry->next = 0; 256 ne->next = entry; 257 } 258 259 PetscFunctionReturn(0); 260 } 261 262 #undef __FUNCT__ 263 #define __FUNCT__ "PetscFListDestroy" 264 /*@ 265 PetscFListDestroy - Destroys a list of registered routines. 266 267 Input Parameter: 268 . fl - pointer to list 269 270 Level: developer 271 272 .seealso: PetscFListAddDynamic(), PetscFList 273 @*/ 274 PetscErrorCode PETSC_DLLEXPORT PetscFListDestroy(PetscFList *fl) 275 { 276 PetscFList next,entry,tmp = dlallhead; 277 PetscErrorCode ierr; 278 279 PetscFunctionBegin; 280 CHKMEMQ; 281 if (!*fl) PetscFunctionReturn(0); 282 283 if (!dlallhead) { 284 PetscFunctionReturn(0); 285 } 286 287 /* 288 Remove this entry from the master DL list (if it is in it) 289 */ 290 if (dlallhead == *fl) { 291 if (dlallhead->next_list) { 292 dlallhead = dlallhead->next_list; 293 } else { 294 dlallhead = 0; 295 } 296 } else { 297 while (tmp->next_list != *fl) { 298 tmp = tmp->next_list; 299 if (!tmp->next_list) break; 300 } 301 if (tmp->next_list) tmp->next_list = tmp->next_list->next_list; 302 } 303 304 /* free this list */ 305 entry = *fl; 306 while (entry) { 307 next = entry->next; 308 ierr = PetscStrfree(entry->path);CHKERRQ(ierr); 309 ierr = PetscFree(entry->name);CHKERRQ(ierr); 310 ierr = PetscFree(entry->rname);CHKERRQ(ierr); 311 ierr = PetscFree(entry);CHKERRQ(ierr); 312 entry = next; 313 } 314 *fl = 0; 315 PetscFunctionReturn(0); 316 } 317 318 /* 319 Destroys all the function lists that anyone has every registered, such as KSPList, VecList, etc. 320 */ 321 #undef __FUNCT__ 322 #define __FUNCT__ "PetscFListDestroyAll" 323 PetscErrorCode PETSC_DLLEXPORT PetscFListDestroyAll(void) 324 { 325 PetscFList tmp2,tmp1 = dlallhead; 326 PetscErrorCode ierr; 327 328 PetscFunctionBegin; 329 while (tmp1) { 330 tmp2 = tmp1->next_list; 331 ierr = PetscFListDestroy(&tmp1);CHKERRQ(ierr); 332 tmp1 = tmp2; 333 } 334 dlallhead = 0; 335 PetscFunctionReturn(0); 336 } 337 338 #undef __FUNCT__ 339 #define __FUNCT__ "PetscFListFind" 340 /*@C 341 PetscFListFind - Given a name, finds the matching routine. 342 343 Input Parameters: 344 + fl - pointer to list 345 . comm - processors looking for routine 346 - name - name string 347 348 Output Parameters: 349 . r - the routine 350 351 Level: developer 352 353 .seealso: PetscFListAddDynamic(), PetscFList 354 @*/ 355 PetscErrorCode PETSC_DLLEXPORT PetscFListFind(PetscFList fl,MPI_Comm comm,const char name[],void (**r)(void)) 356 { 357 PetscFList entry = fl; 358 PetscErrorCode ierr; 359 char *function,*path; 360 #if defined(PETSC_USE_DYNAMIC_LIBRARIES) 361 char *newpath; 362 #endif 363 PetscTruth flg,f1,f2,f3; 364 365 PetscFunctionBegin; 366 if (!name) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to find routine with null name"); 367 368 *r = 0; 369 ierr = PetscFListGetPathAndFunction(name,&path,&function);CHKERRQ(ierr); 370 371 /* 372 If path then append it to search libraries 373 */ 374 #if defined(PETSC_USE_DYNAMIC_LIBRARIES) 375 if (path) { 376 ierr = PetscDLLibraryAppend(comm,&DLLibrariesLoaded,path);CHKERRQ(ierr); 377 } 378 #endif 379 380 while (entry) { 381 flg = PETSC_FALSE; 382 if (path && entry->path) { 383 ierr = PetscStrcmp(path,entry->path,&f1);CHKERRQ(ierr); 384 ierr = PetscStrcmp(function,entry->rname,&f2);CHKERRQ(ierr); 385 ierr = PetscStrcmp(function,entry->name,&f3);CHKERRQ(ierr); 386 flg = (PetscTruth) ((f1 && f2) || (f1 && f3)); 387 } else if (!path) { 388 ierr = PetscStrcmp(function,entry->name,&f1);CHKERRQ(ierr); 389 ierr = PetscStrcmp(function,entry->rname,&f2);CHKERRQ(ierr); 390 flg = (PetscTruth) (f1 || f2); 391 } else { 392 ierr = PetscStrcmp(function,entry->name,&flg);CHKERRQ(ierr); 393 if (flg) { 394 ierr = PetscFree(function);CHKERRQ(ierr); 395 ierr = PetscStrallocpy(entry->rname,&function);CHKERRQ(ierr); 396 } else { 397 ierr = PetscStrcmp(function,entry->rname,&flg);CHKERRQ(ierr); 398 } 399 } 400 401 if (flg) { 402 403 if (entry->routine) { 404 *r = entry->routine; 405 ierr = PetscStrfree(path);CHKERRQ(ierr); 406 ierr = PetscFree(function);CHKERRQ(ierr); 407 PetscFunctionReturn(0); 408 } 409 410 if ((path && entry->path && f3) || (!path && f1)) { /* convert name of function (alias) to actual function name */ 411 ierr = PetscFree(function);CHKERRQ(ierr); 412 ierr = PetscStrallocpy(entry->rname,&function);CHKERRQ(ierr); 413 } 414 415 /* it is not yet in memory so load from dynamic library */ 416 #if defined(PETSC_USE_DYNAMIC_LIBRARIES) 417 newpath = path; 418 if (!path) newpath = entry->path; 419 ierr = PetscDLLibrarySym(comm,&DLLibrariesLoaded,newpath,entry->rname,(void **)r);CHKERRQ(ierr); 420 if (*r) { 421 entry->routine = *r; 422 ierr = PetscStrfree(path);CHKERRQ(ierr); 423 ierr = PetscFree(function);CHKERRQ(ierr); 424 PetscFunctionReturn(0); 425 } else { 426 (*PetscErrorPrintf)("Unable to find function. Search path:\n"); 427 ierr = PetscDLLibraryPrintPath();CHKERRQ(ierr); 428 SETERRQ1(PETSC_ERR_PLIB,"Unable to find function:%s: either it is mis-spelled or dynamic library is not in path",entry->rname); 429 } 430 #endif 431 } 432 entry = entry->next; 433 } 434 435 #if defined(PETSC_USE_DYNAMIC_LIBRARIES) 436 /* Function never registered; try for it anyway */ 437 ierr = PetscDLLibrarySym(comm,&DLLibrariesLoaded,path,function,(void **)r);CHKERRQ(ierr); 438 ierr = PetscStrfree(path);CHKERRQ(ierr); 439 if (*r) { 440 ierr = PetscFListAdd(&fl,name,name,*r);CHKERRQ(ierr); 441 } 442 #endif 443 ierr = PetscFree(function);CHKERRQ(ierr); 444 PetscFunctionReturn(0); 445 } 446 447 #undef __FUNCT__ 448 #define __FUNCT__ "PetscFListView" 449 /*@ 450 PetscFListView - prints out contents of an PetscFList 451 452 Collective over MPI_Comm 453 454 Input Parameters: 455 + list - the list of functions 456 - viewer - currently ignored 457 458 Level: developer 459 460 .seealso: PetscFListAddDynamic(), PetscFListPrintTypes(), PetscFList 461 @*/ 462 PetscErrorCode PETSC_DLLEXPORT PetscFListView(PetscFList list,PetscViewer viewer) 463 { 464 PetscErrorCode ierr; 465 PetscTruth iascii; 466 467 PetscFunctionBegin; 468 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 469 PetscValidPointer(list,1); 470 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2); 471 472 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 473 if (!iascii) SETERRQ(PETSC_ERR_SUP,"Only ASCII viewer supported"); 474 475 while (list) { 476 if (list->path) { 477 ierr = PetscViewerASCIIPrintf(viewer," %s %s %s\n",list->path,list->name,list->rname);CHKERRQ(ierr); 478 } else { 479 ierr = PetscViewerASCIIPrintf(viewer," %s %s\n",list->name,list->rname);CHKERRQ(ierr); 480 } 481 list = list->next; 482 } 483 ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 484 PetscFunctionReturn(0); 485 } 486 487 #undef __FUNCT__ 488 #define __FUNCT__ "PetscFListGet" 489 /*@ 490 PetscFListGet - Gets an array the contains the entries in PetscFList, this is used 491 by help etc. 492 493 Collective over MPI_Comm 494 495 Input Parameter: 496 . list - list of types 497 498 Output Parameter: 499 + array - array of names 500 - n - length of array 501 502 Notes: 503 This allocates the array so that must be freed. BUT the individual entries are 504 not copied so should not be freed. 505 506 Level: developer 507 508 .seealso: PetscFListAddDynamic(), PetscFList 509 @*/ 510 PetscErrorCode PETSC_DLLEXPORT PetscFListGet(PetscFList list,char ***array,int *n) 511 { 512 PetscErrorCode ierr; 513 PetscInt count = 0; 514 PetscFList klist = list; 515 516 PetscFunctionBegin; 517 while (list) { 518 list = list->next; 519 count++; 520 } 521 ierr = PetscMalloc((count+1)*sizeof(char *),array);CHKERRQ(ierr); 522 count = 0; 523 while (klist) { 524 (*array)[count] = klist->name; 525 klist = klist->next; 526 count++; 527 } 528 (*array)[count] = 0; 529 *n = count+1; 530 531 PetscFunctionReturn(0); 532 } 533 534 535 #undef __FUNCT__ 536 #define __FUNCT__ "PetscFListPrintTypes" 537 /*@C 538 PetscFListPrintTypes - Prints the methods available. 539 540 Collective over MPI_Comm 541 542 Input Parameters: 543 + comm - the communicator (usually MPI_COMM_WORLD) 544 . fd - file to print to, usually stdout 545 . prefix - prefix to prepend to name (optional) 546 . name - option string (for example, "-ksp_type") 547 . text - short description of the object (for example, "Krylov solvers") 548 . man - name of manual page that discusses the object (for example, "KSPCreate") 549 - list - list of types 550 551 Level: developer 552 553 .seealso: PetscFListAddDynamic(), PetscFList 554 @*/ 555 PetscErrorCode PETSC_DLLEXPORT PetscFListPrintTypes(PetscFList list,MPI_Comm comm,FILE *fd,const char prefix[],const char name[],const char text[],const char man[]) 556 { 557 PetscErrorCode ierr; 558 PetscInt count = 0; 559 char p[64]; 560 561 PetscFunctionBegin; 562 if (!fd) fd = PETSC_STDOUT; 563 564 ierr = PetscStrcpy(p,"-");CHKERRQ(ierr); 565 if (prefix) {ierr = PetscStrcat(p,prefix);CHKERRQ(ierr);} 566 ierr = PetscFPrintf(comm,fd," %s%s %s:(one of)",p,name+1,text);CHKERRQ(ierr); 567 568 while (list) { 569 ierr = PetscFPrintf(comm,fd," %s",list->name);CHKERRQ(ierr); 570 list = list->next; 571 count++; 572 if (count == 8) {ierr = PetscFPrintf(comm,fd,"\n ");CHKERRQ(ierr);} 573 } 574 ierr = PetscFPrintf(comm,fd," (%s)\n",man);CHKERRQ(ierr); 575 PetscFunctionReturn(0); 576 } 577 578 #undef __FUNCT__ 579 #define __FUNCT__ "PetscFListDuplicate" 580 /*@ 581 PetscFListDuplicate - Creates a new list from a given object list. 582 583 Input Parameters: 584 . fl - pointer to list 585 586 Output Parameters: 587 . nl - the new list (should point to 0 to start, otherwise appends) 588 589 Level: developer 590 591 .seealso: PetscFList, PetscFListAdd(), PetscFlistDestroy() 592 593 @*/ 594 PetscErrorCode PETSC_DLLEXPORT PetscFListDuplicate(PetscFList fl,PetscFList *nl) 595 { 596 PetscErrorCode ierr; 597 char path[PETSC_MAX_PATH_LEN]; 598 599 PetscFunctionBegin; 600 while (fl) { 601 /* this is silly, rebuild the complete pathname */ 602 if (fl->path) { 603 ierr = PetscStrcpy(path,fl->path);CHKERRQ(ierr); 604 ierr = PetscStrcat(path,":");CHKERRQ(ierr); 605 ierr = PetscStrcat(path,fl->name);CHKERRQ(ierr); 606 } else { 607 ierr = PetscStrcpy(path,fl->name);CHKERRQ(ierr); 608 } 609 ierr = PetscFListAdd(nl,path,fl->rname,fl->routine);CHKERRQ(ierr); 610 fl = fl->next; 611 } 612 PetscFunctionReturn(0); 613 } 614 615 616 #undef __FUNCT__ 617 #define __FUNCT__ "PetscFListConcat" 618 /* 619 PetscFListConcat - joins name of a libary, and the path where it is located 620 into a single string. 621 622 Input Parameters: 623 . path - path to the library name. 624 . name - name of the library 625 626 Output Parameters: 627 . fullname - the name that is the union of the path and the library name, 628 delimited by a semicolon, i.e., path:name 629 630 Notes: 631 If the path is NULL, assumes that the name, specified also includes 632 the path as path:name 633 634 */ 635 PetscErrorCode PETSC_DLLEXPORT PetscFListConcat(const char path[],const char name[],char fullname[]) 636 { 637 PetscErrorCode ierr; 638 PetscFunctionBegin; 639 if (path) { 640 ierr = PetscStrcpy(fullname,path);CHKERRQ(ierr); 641 ierr = PetscStrcat(fullname,":");CHKERRQ(ierr); 642 ierr = PetscStrcat(fullname,name);CHKERRQ(ierr); 643 } else { 644 ierr = PetscStrcpy(fullname,name);CHKERRQ(ierr); 645 } 646 PetscFunctionReturn(0); 647 } 648