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