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