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 129 .seealso: PetscViewerStringOpen(), PetscViewerStringSPrintf(), PetscViewerSocketOpen(), PetscViewerDrawOpen(), PETSCVIEWERSOCKET, 130 PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY, PETSCVIEWERDRAW, 131 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, 132 PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType() 133 134 Level: beginner 135 M*/ 136 137 PETSC_EXTERN PetscErrorCode PetscViewerCreate_String(PetscViewer v) 138 { 139 PetscViewer_String *vstr; 140 PetscErrorCode ierr; 141 142 PetscFunctionBegin; 143 v->ops->destroy = PetscViewerDestroy_String; 144 v->ops->view = NULL; 145 v->ops->flush = NULL; 146 v->ops->getsubviewer = PetscViewerGetSubViewer_String; 147 v->ops->restoresubviewer = PetscViewerRestoreSubViewer_String; 148 ierr = PetscNewLog(v,&vstr);CHKERRQ(ierr); 149 v->data = (void*)vstr; 150 vstr->string = NULL; 151 PetscFunctionReturn(0); 152 } 153 154 /*@C 155 156 PetscViewerStringGetStringRead - Returns the string that a string viewer uses 157 158 Logically Collective on PetscViewer 159 160 Input Parameter: 161 . viewer - string viewer 162 163 Output Parameters: 164 + string - the string, optional use NULL if you do not need 165 - len - the length of the string, optional use NULL if you do 166 167 Notes: Do not write to the string nor free it 168 169 Level: advanced 170 171 .seealso: PetscViewerStringOpen(), PETSCVIEWERSTRING, PetscViewerStringSetString(), PetscViewerStringSPrintf(), 172 PetscViewerStringSetOwnString() 173 @*/ 174 PetscErrorCode PetscViewerStringGetStringRead(PetscViewer viewer,const char *string[],size_t *len) 175 { 176 PetscViewer_String *vstr = (PetscViewer_String*)viewer->data; 177 PetscErrorCode ierr; 178 PetscBool isstring; 179 180 PetscFunctionBegin; 181 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 182 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 183 if (!isstring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Only for PETSCVIEWERSTRING"); 184 if (string) *string = vstr->string; 185 if (len) *len = vstr->maxlen; 186 PetscFunctionReturn(0); 187 } 188 189 /*@C 190 191 PetscViewerStringSetString - sets the string that a string viewer will print to 192 193 Logically Collective on PetscViewer 194 195 Input Parameters: 196 + viewer - string viewer you wish to attach string to 197 . string - the string to print data into 198 - len - the length of the string 199 200 Notes: The function does not copy the string, it uses it directly therefore you cannot free 201 the string until the viewer is destroyed. If you call PetscViewerStringSetOwnString() the ownership 202 passes to the viewer and it will be responsable for freeing it. In this case the string must be 203 obtained with PetscMalloc(). 204 205 Level: advanced 206 207 .seealso: PetscViewerStringOpen(), PETSCVIEWERSTRING, PetscViewerStringGetStringRead(), PetscViewerStringSPrintf(), 208 PetscViewerStringSetOwnString() 209 @*/ 210 PetscErrorCode PetscViewerStringSetString(PetscViewer viewer,char string[],size_t len) 211 { 212 PetscViewer_String *vstr = (PetscViewer_String*)viewer->data; 213 PetscErrorCode ierr; 214 PetscBool isstring; 215 216 PetscFunctionBegin; 217 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 218 PetscValidCharPointer(string,2); 219 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 220 if (!isstring) PetscFunctionReturn(0); 221 if (len <= 2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"String must have length at least 2"); 222 223 ierr = PetscArrayzero(string,len);CHKERRQ(ierr); 224 vstr->string = string; 225 vstr->head = string; 226 vstr->curlen = 0; 227 vstr->maxlen = len; 228 PetscFunctionReturn(0); 229 } 230 231 /*@C 232 233 PetscViewerStringSetOwnString - tells the viewer that it now owns the string and is responsible for freeing it 234 235 Logically Collective on PetscViewer 236 237 Input Parameters: 238 . viewer - string viewer 239 240 Notes: If you call this the string must have been obtained with PetscMalloc() and you cannot free the string 241 242 Level: advanced 243 244 .seealso: PetscViewerStringOpen(), PETSCVIEWERSTRING, PetscViewerStringGetStringRead(), PetscViewerStringSPrintf(), 245 PetscViewerStringSetString() 246 @*/ 247 PetscErrorCode PetscViewerStringSetOwnString(PetscViewer viewer) 248 { 249 PetscViewer_String *vstr = (PetscViewer_String*)viewer->data; 250 PetscErrorCode ierr; 251 PetscBool isstring; 252 253 PetscFunctionBegin; 254 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 255 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 256 if (!isstring) PetscFunctionReturn(0); 257 258 vstr->ownstring = PETSC_TRUE; 259 PetscFunctionReturn(0); 260 } 261 262 263 264 265 266