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 if (!fl) PetscFunctionReturn(0); 311 312 if (!dlallhead) { 313 PetscFunctionReturn(0); 314 } 315 316 /* 317 Remove this entry from the master DL list (if it is in it) 318 */ 319 if (dlallhead == fl) { 320 if (dlallhead->next_list) { 321 dlallhead = dlallhead->next_list; 322 } else { 323 dlallhead = 0; 324 } 325 } else { 326 while (tmp->next_list != fl) { 327 tmp = tmp->next_list; 328 if (!tmp->next_list) break; 329 } 330 if (tmp->next_list) tmp->next_list = tmp->next_list->next_list; 331 } 332 333 /* free this list */ 334 entry = fl; 335 while (entry) { 336 next = entry->next; 337 ierr = PetscStrfree(entry->path);CHKERRQ(ierr); 338 ierr = PetscFree(entry->name);CHKERRQ(ierr); 339 ierr = PetscFree(entry->rname);CHKERRQ(ierr); 340 ierr = PetscFree(entry);CHKERRQ(ierr); 341 entry = next; 342 } 343 PetscFunctionReturn(0); 344 } 345 346 /* 347 Destroys all the function lists that anyone has every registered, such as KSPList, VecList, etc. 348 */ 349 #undef __FUNCT__ 350 #define __FUNCT__ "PetscFListDestroyAll" 351 PetscErrorCode PETSC_DLLEXPORT PetscFListDestroyAll(void) 352 { 353 PetscFList tmp2,tmp1 = dlallhead; 354 PetscErrorCode ierr; 355 356 PetscFunctionBegin; 357 while (tmp1) { 358 tmp2 = tmp1->next_list; 359 ierr = PetscFListDestroy(tmp1);CHKERRQ(ierr); 360 tmp1 = tmp2; 361 } 362 dlallhead = 0; 363 PetscFunctionReturn(0); 364 } 365 366 #undef __FUNCT__ 367 #define __FUNCT__ "PetscFListFind" 368 /*@C 369 PetscFListFind - Given a name, finds the matching routine. 370 371 Input Parameters: 372 + comm - processors looking for routine 373 . fl - pointer to list 374 - name - name string 375 376 Output Parameters: 377 . r - the routine 378 379 Level: developer 380 381 .seealso: PetscFListAddDynamic(), PetscFList 382 @*/ 383 PetscErrorCode PETSC_DLLEXPORT PetscFListFind(MPI_Comm comm,PetscFList fl,const char name[],void (**r)(void)) 384 { 385 PetscFList entry = fl; 386 PetscErrorCode ierr; 387 char *function,*path; 388 #if defined(PETSC_USE_DYNAMIC_LIBRARIES) 389 char *newpath; 390 #endif 391 PetscTruth flg,f1,f2,f3; 392 393 PetscFunctionBegin; 394 if (!name) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to find routine with null name"); 395 396 *r = 0; 397 ierr = PetscFListGetPathAndFunction(name,&path,&function);CHKERRQ(ierr); 398 399 /* 400 If path then append it to search libraries 401 */ 402 #if defined(PETSC_USE_DYNAMIC_LIBRARIES) 403 if (path) { 404 ierr = PetscDLLibraryAppend(comm,&DLLibrariesLoaded,path);CHKERRQ(ierr); 405 } 406 #endif 407 408 while (entry) { 409 flg = PETSC_FALSE; 410 if (path && entry->path) { 411 ierr = PetscStrcmp(path,entry->path,&f1);CHKERRQ(ierr); 412 ierr = PetscStrcmp(function,entry->rname,&f2);CHKERRQ(ierr); 413 ierr = PetscStrcmp(function,entry->name,&f3);CHKERRQ(ierr); 414 flg = (PetscTruth) ((f1 && f2) || (f1 && f3)); 415 } else if (!path) { 416 ierr = PetscStrcmp(function,entry->name,&f1);CHKERRQ(ierr); 417 ierr = PetscStrcmp(function,entry->rname,&f2);CHKERRQ(ierr); 418 flg = (PetscTruth) (f1 || f2); 419 } else { 420 ierr = PetscStrcmp(function,entry->name,&flg);CHKERRQ(ierr); 421 if (flg) { 422 ierr = PetscFree(function);CHKERRQ(ierr); 423 ierr = PetscStrallocpy(entry->rname,&function);CHKERRQ(ierr); 424 } else { 425 ierr = PetscStrcmp(function,entry->rname,&flg);CHKERRQ(ierr); 426 } 427 } 428 429 if (flg) { 430 431 if (entry->routine) { 432 *r = entry->routine; 433 ierr = PetscStrfree(path);CHKERRQ(ierr); 434 ierr = PetscFree(function);CHKERRQ(ierr); 435 PetscFunctionReturn(0); 436 } 437 438 if ((path && entry->path && f3) || (!path && f1)) { /* convert name of function (alias) to actual function name */ 439 ierr = PetscFree(function);CHKERRQ(ierr); 440 ierr = PetscStrallocpy(entry->rname,&function);CHKERRQ(ierr); 441 } 442 443 /* it is not yet in memory so load from dynamic library */ 444 #if defined(PETSC_USE_DYNAMIC_LIBRARIES) 445 newpath = path; 446 if (!path) newpath = entry->path; 447 ierr = PetscDLLibrarySym(comm,&DLLibrariesLoaded,newpath,entry->rname,(void **)r);CHKERRQ(ierr); 448 if (*r) { 449 entry->routine = *r; 450 ierr = PetscStrfree(path);CHKERRQ(ierr); 451 ierr = PetscFree(function);CHKERRQ(ierr); 452 PetscFunctionReturn(0); 453 } else { 454 PetscErrorPrintf("Unable to find function. Search path:\n"); 455 ierr = PetscDLLibraryPrintPath();CHKERRQ(ierr); 456 SETERRQ1(PETSC_ERR_PLIB,"Unable to find function:%s: either it is mis-spelled or dynamic library is not in path",entry->rname); 457 } 458 #endif 459 } 460 entry = entry->next; 461 } 462 463 #if defined(PETSC_USE_DYNAMIC_LIBRARIES) 464 /* Function never registered; try for it anyway */ 465 ierr = PetscDLLibrarySym(comm,&DLLibrariesLoaded,path,function,(void **)r);CHKERRQ(ierr); 466 ierr = PetscStrfree(path);CHKERRQ(ierr); 467 if (*r) { 468 ierr = PetscFListAdd(&fl,name,name,*r);CHKERRQ(ierr); 469 } 470 #endif 471 ierr = PetscFree(function);CHKERRQ(ierr); 472 PetscFunctionReturn(0); 473 } 474 475 #undef __FUNCT__ 476 #define __FUNCT__ "PetscFListView" 477 /*@ 478 PetscFListView - prints out contents of an PetscFList 479 480 Collective over MPI_Comm 481 482 Input Parameters: 483 + list - the list of functions 484 - viewer - currently ignored 485 486 Level: developer 487 488 .seealso: PetscFListAddDynamic(), PetscFListPrintTypes(), PetscFList 489 @*/ 490 PetscErrorCode PETSC_DLLEXPORT PetscFListView(PetscFList list,PetscViewer viewer) 491 { 492 PetscErrorCode ierr; 493 PetscTruth iascii; 494 495 PetscFunctionBegin; 496 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 497 PetscValidPointer(list,1); 498 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2); 499 500 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 501 if (!iascii) SETERRQ(PETSC_ERR_SUP,"Only ASCII viewer supported"); 502 503 while (list) { 504 if (list->path) { 505 ierr = PetscViewerASCIIPrintf(viewer," %s %s %s\n",list->path,list->name,list->rname);CHKERRQ(ierr); 506 } else { 507 ierr = PetscViewerASCIIPrintf(viewer," %s %s\n",list->name,list->rname);CHKERRQ(ierr); 508 } 509 list = list->next; 510 } 511 ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 512 PetscFunctionReturn(0); 513 } 514 515 #undef __FUNCT__ 516 #define __FUNCT__ "PetscFListGet" 517 /*@ 518 PetscFListGet - Gets an array the contains the entries in PetscFList, this is used 519 by help etc. 520 521 Collective over MPI_Comm 522 523 Input Parameter: 524 . list - list of types 525 526 Output Parameter: 527 + array - array of names 528 - n - length of array 529 530 Notes: 531 This allocates the array so that must be freed. BUT the individual entries are 532 not copied so should not be freed. 533 534 Level: developer 535 536 .seealso: PetscFListAddDynamic(), PetscFList 537 @*/ 538 PetscErrorCode PETSC_DLLEXPORT PetscFListGet(PetscFList list,char ***array,int *n) 539 { 540 PetscErrorCode ierr; 541 PetscInt count = 0; 542 PetscFList klist = list; 543 544 PetscFunctionBegin; 545 while (list) { 546 list = list->next; 547 count++; 548 } 549 ierr = PetscMalloc((count+1)*sizeof(char *),array);CHKERRQ(ierr); 550 count = 0; 551 while (klist) { 552 (*array)[count] = klist->name; 553 klist = klist->next; 554 count++; 555 } 556 (*array)[count] = 0; 557 *n = count+1; 558 559 PetscFunctionReturn(0); 560 } 561 562 563 #undef __FUNCT__ 564 #define __FUNCT__ "PetscFListPrintTypes" 565 /*@C 566 PetscFListPrintTypes - Prints the methods available. 567 568 Collective over MPI_Comm 569 570 Input Parameters: 571 + comm - the communicator (usually MPI_COMM_WORLD) 572 . fd - file to print to, usually stdout 573 . prefix - prefix to prepend to name (optional) 574 . name - option string (for example, "-ksp_type") 575 . text - short description of the object (for example, "Krylov solvers") 576 . man - name of manual page that discusses the object (for example, "KSPCreate") 577 - list - list of types 578 579 Level: developer 580 581 .seealso: PetscFListAddDynamic(), PetscFList 582 @*/ 583 PetscErrorCode PETSC_DLLEXPORT PetscFListPrintTypes(MPI_Comm comm,FILE *fd,const char prefix[],const char name[],const char text[],const char man[],PetscFList list) 584 { 585 PetscErrorCode ierr; 586 PetscInt count = 0; 587 char p[64]; 588 589 PetscFunctionBegin; 590 if (!fd) fd = stdout; 591 592 ierr = PetscStrcpy(p,"-");CHKERRQ(ierr); 593 if (prefix) {ierr = PetscStrcat(p,prefix);CHKERRQ(ierr);} 594 ierr = PetscFPrintf(comm,fd," %s%s %s:(one of)",p,name+1,text);CHKERRQ(ierr); 595 596 while (list) { 597 ierr = PetscFPrintf(comm,fd," %s",list->name);CHKERRQ(ierr); 598 list = list->next; 599 count++; 600 if (count == 8) {ierr = PetscFPrintf(comm,fd,"\n ");CHKERRQ(ierr);} 601 } 602 ierr = PetscFPrintf(comm,fd," (%s)\n",man);CHKERRQ(ierr); 603 PetscFunctionReturn(0); 604 } 605 606 #undef __FUNCT__ 607 #define __FUNCT__ "PetscFListDuplicate" 608 /*@ 609 PetscFListDuplicate - Creates a new list from a given object list. 610 611 Input Parameters: 612 . fl - pointer to list 613 614 Output Parameters: 615 . nl - the new list (should point to 0 to start, otherwise appends) 616 617 Level: developer 618 619 .seealso: PetscFList, PetscFListAdd(), PetscFlistDestroy() 620 621 @*/ 622 PetscErrorCode PETSC_DLLEXPORT PetscFListDuplicate(PetscFList fl,PetscFList *nl) 623 { 624 PetscErrorCode ierr; 625 char path[PETSC_MAX_PATH_LEN]; 626 627 PetscFunctionBegin; 628 while (fl) { 629 /* this is silly, rebuild the complete pathname */ 630 if (fl->path) { 631 ierr = PetscStrcpy(path,fl->path);CHKERRQ(ierr); 632 ierr = PetscStrcat(path,":");CHKERRQ(ierr); 633 ierr = PetscStrcat(path,fl->name);CHKERRQ(ierr); 634 } else { 635 ierr = PetscStrcpy(path,fl->name);CHKERRQ(ierr); 636 } 637 ierr = PetscFListAdd(nl,path,fl->rname,fl->routine);CHKERRQ(ierr); 638 fl = fl->next; 639 } 640 PetscFunctionReturn(0); 641 } 642 643 644 #undef __FUNCT__ 645 #define __FUNCT__ "PetscFListConcat" 646 /* 647 PetscFListConcat - joins name of a libary, and the path where it is located 648 into a single string. 649 650 Input Parameters: 651 . path - path to the library name. 652 . name - name of the library 653 654 Output Parameters: 655 . fullname - the name that is the union of the path and the library name, 656 delimited by a semicolon, i.e., path:name 657 658 Notes: 659 If the path is NULL, assumes that the name, specified also includes 660 the path as path:name 661 662 */ 663 PetscErrorCode PETSC_DLLEXPORT PetscFListConcat(const char path[],const char name[],char fullname[]) 664 { 665 PetscErrorCode ierr; 666 PetscFunctionBegin; 667 if (path) { 668 ierr = PetscStrcpy(fullname,path);CHKERRQ(ierr); 669 ierr = PetscStrcat(fullname,":");CHKERRQ(ierr); 670 ierr = PetscStrcat(fullname,name);CHKERRQ(ierr); 671 } else { 672 ierr = PetscStrcpy(fullname,name);CHKERRQ(ierr); 673 } 674 PetscFunctionReturn(0); 675 } 676