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