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