1 2 #include <petsc/private/viewerimpl.h> /*I "petscsys.h" I*/ 3 4 typedef struct { 5 char *string; /* string where info is stored */ 6 char *head; /* pointer to begining of unused portion */ 7 size_t curlen,maxlen; 8 PetscBool ownstring; /* string viewer is responsable for freeing the string */ 9 } PetscViewer_String; 10 11 static PetscErrorCode PetscViewerDestroy_String(PetscViewer viewer) 12 { 13 PetscViewer_String *vstr = (PetscViewer_String*)viewer->data; 14 PetscErrorCode ierr; 15 16 PetscFunctionBegin; 17 if (vstr->ownstring) { 18 ierr = PetscFree(vstr->string);CHKERRQ(ierr); 19 } 20 ierr = PetscFree(vstr);CHKERRQ(ierr); 21 PetscFunctionReturn(0); 22 } 23 24 /*@C 25 PetscViewerStringSPrintf - Prints information to a PetscViewer string. 26 27 Logically Collective on PetscViewer (Hmmm, each processor maintains a separate string) 28 29 Input Parameters: 30 + v - a string PetscViewer, formed by PetscViewerStringOpen() 31 - format - the format of the input 32 33 Level: developer 34 35 Fortran Note: 36 This routine is not supported in Fortran. 37 38 .seealso: PetscViewerStringOpen(), PetscViewerStringGetStringRead(), PetscViewerStringSetString(), PETSCVIEWERSTRING 39 @*/ 40 PetscErrorCode PetscViewerStringSPrintf(PetscViewer viewer,const char format[],...) 41 { 42 va_list Argp; 43 size_t fullLength; 44 size_t shift,cshift; 45 PetscErrorCode ierr; 46 PetscBool isstring; 47 char tmp[4096]; 48 PetscViewer_String *vstr = (PetscViewer_String*)viewer->data; 49 50 PetscFunctionBegin; 51 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 52 PetscValidCharPointer(format,2); 53 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 54 if (!isstring) PetscFunctionReturn(0); 55 if (!vstr->string) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerStringSetString() before using"); 56 57 va_start(Argp,format); 58 ierr = PetscVSNPrintf(tmp,4096,format,&fullLength,Argp);CHKERRQ(ierr); 59 va_end(Argp); 60 ierr = PetscStrlen(tmp,&shift);CHKERRQ(ierr); 61 cshift = shift+1; 62 if (cshift >= vstr->maxlen - vstr->curlen - 1) cshift = vstr->maxlen - vstr->curlen - 1; 63 ierr = PetscStrncpy(vstr->head,tmp,cshift);CHKERRQ(ierr); 64 vstr->head += shift; 65 vstr->curlen += shift; 66 PetscFunctionReturn(0); 67 } 68 69 /*@C 70 PetscViewerStringOpen - Opens a string as a PetscViewer. This is a very 71 simple PetscViewer; information on the object is simply stored into 72 the string in a fairly nice way. 73 74 Collective 75 76 Input Parameters: 77 + comm - the communicator 78 . string - the string to use 79 - len - the string length 80 81 Output Parameter: 82 . lab - the PetscViewer 83 84 Level: advanced 85 86 Fortran Note: 87 This routine is not supported in Fortran. 88 89 .seealso: PetscViewerDestroy(), PetscViewerStringSPrintf(), PetscViewerStringGetStringRead(), PetscViewerStringSetString(), PETSCVIEWERSTRING 90 @*/ 91 PetscErrorCode PetscViewerStringOpen(MPI_Comm comm,char string[],size_t len,PetscViewer *lab) 92 { 93 PetscErrorCode ierr; 94 95 PetscFunctionBegin; 96 ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr); 97 ierr = PetscViewerSetType(*lab,PETSCVIEWERSTRING);CHKERRQ(ierr); 98 ierr = PetscViewerStringSetString(*lab,string,len);CHKERRQ(ierr); 99 PetscFunctionReturn(0); 100 } 101 102 PetscErrorCode PetscViewerGetSubViewer_String(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer) 103 { 104 PetscViewer_String *vstr = (PetscViewer_String*)viewer->data; 105 PetscErrorCode ierr; 106 107 PetscFunctionBegin; 108 ierr = PetscViewerStringOpen(PETSC_COMM_SELF,vstr->head,vstr->maxlen-vstr->curlen,sviewer);CHKERRQ(ierr); 109 PetscFunctionReturn(0); 110 } 111 112 PetscErrorCode PetscViewerRestoreSubViewer_String(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer) 113 { 114 PetscErrorCode ierr; 115 PetscViewer_String *iviewer = (PetscViewer_String*)(*sviewer)->data; 116 PetscViewer_String *vstr = (PetscViewer_String*)viewer->data; 117 118 PetscFunctionBegin; 119 vstr->head = iviewer->head; 120 vstr->curlen += iviewer->curlen; 121 ierr = PetscViewerDestroy(sviewer);CHKERRQ(ierr); 122 PetscFunctionReturn(0); 123 } 124 125 /*MC 126 PETSCVIEWERSTRING - A viewer that writes to a string 127 128 .seealso: PetscViewerStringOpen(), PetscViewerStringSPrintf(), PetscViewerSocketOpen(), PetscViewerDrawOpen(), PETSCVIEWERSOCKET, 129 PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY, PETSCVIEWERDRAW, 130 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, 131 PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType() 132 133 Level: beginner 134 M*/ 135 136 PETSC_EXTERN PetscErrorCode PetscViewerCreate_String(PetscViewer v) 137 { 138 PetscViewer_String *vstr; 139 PetscErrorCode ierr; 140 141 PetscFunctionBegin; 142 v->ops->destroy = PetscViewerDestroy_String; 143 v->ops->view = NULL; 144 v->ops->flush = NULL; 145 v->ops->getsubviewer = PetscViewerGetSubViewer_String; 146 v->ops->restoresubviewer = PetscViewerRestoreSubViewer_String; 147 ierr = PetscNewLog(v,&vstr);CHKERRQ(ierr); 148 v->data = (void*)vstr; 149 vstr->string = NULL; 150 PetscFunctionReturn(0); 151 } 152 153 /*@C 154 155 PetscViewerStringGetStringRead - Returns the string that a string viewer uses 156 157 Logically Collective on PetscViewer 158 159 Input Parameter: 160 . viewer - string viewer 161 162 Output Parameters: 163 + string - the string, optional use NULL if you do not need 164 - len - the length of the string, optional use NULL if you do 165 166 Notes: Do not write to the string nor free it 167 168 Level: advanced 169 170 .seealso: PetscViewerStringOpen(), PETSCVIEWERSTRING, PetscViewerStringSetString(), PetscViewerStringSPrintf(), 171 PetscViewerStringSetOwnString() 172 @*/ 173 PetscErrorCode PetscViewerStringGetStringRead(PetscViewer viewer,const char *string[],size_t *len) 174 { 175 PetscViewer_String *vstr = (PetscViewer_String*)viewer->data; 176 PetscErrorCode ierr; 177 PetscBool isstring; 178 179 PetscFunctionBegin; 180 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 181 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 182 if (!isstring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Only for PETSCVIEWERSTRING"); 183 if (string) *string = vstr->string; 184 if (len) *len = vstr->maxlen; 185 PetscFunctionReturn(0); 186 } 187 188 /*@C 189 190 PetscViewerStringSetString - sets the string that a string viewer will print to 191 192 Logically Collective on PetscViewer 193 194 Input Parameters: 195 + viewer - string viewer you wish to attach string to 196 . string - the string to print data into 197 - len - the length of the string 198 199 Notes: The function does not copy the string, it uses it directly therefore you cannot free 200 the string until the viewer is destroyed. If you call PetscViewerStringSetOwnString() the ownership 201 passes to the viewer and it will be responsable for freeing it. In this case the string must be 202 obtained with PetscMalloc(). 203 204 Level: advanced 205 206 .seealso: PetscViewerStringOpen(), PETSCVIEWERSTRING, PetscViewerStringGetStringRead(), PetscViewerStringSPrintf(), 207 PetscViewerStringSetOwnString() 208 @*/ 209 PetscErrorCode PetscViewerStringSetString(PetscViewer viewer,char string[],size_t len) 210 { 211 PetscViewer_String *vstr = (PetscViewer_String*)viewer->data; 212 PetscErrorCode ierr; 213 PetscBool isstring; 214 215 PetscFunctionBegin; 216 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 217 PetscValidCharPointer(string,2); 218 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 219 if (!isstring) PetscFunctionReturn(0); 220 if (len <= 2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"String must have length at least 2"); 221 222 ierr = PetscArrayzero(string,len);CHKERRQ(ierr); 223 vstr->string = string; 224 vstr->head = string; 225 vstr->curlen = 0; 226 vstr->maxlen = len; 227 PetscFunctionReturn(0); 228 } 229 230 /*@C 231 232 PetscViewerStringSetOwnString - tells the viewer that it now owns the string and is responsible for freeing it 233 234 Logically Collective on PetscViewer 235 236 Input Parameters: 237 . viewer - string viewer 238 239 Notes: If you call this the string must have been obtained with PetscMalloc() and you cannot free the string 240 241 Level: advanced 242 243 .seealso: PetscViewerStringOpen(), PETSCVIEWERSTRING, PetscViewerStringGetStringRead(), PetscViewerStringSPrintf(), 244 PetscViewerStringSetString() 245 @*/ 246 PetscErrorCode PetscViewerStringSetOwnString(PetscViewer viewer) 247 { 248 PetscViewer_String *vstr = (PetscViewer_String*)viewer->data; 249 PetscErrorCode ierr; 250 PetscBool isstring; 251 252 PetscFunctionBegin; 253 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 254 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 255 if (!isstring) PetscFunctionReturn(0); 256 257 vstr->ownstring = PETSC_TRUE; 258 PetscFunctionReturn(0); 259 } 260 261