Actual source code: stringv.c
2: #include <petsc/private/viewerimpl.h>
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;
11: static PetscErrorCode PetscViewerDestroy_String(PetscViewer viewer)
12: {
13: PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
15: if (vstr->ownstring) PetscFree(vstr->string);
16: PetscFree(vstr);
17: return 0;
18: }
20: /*@C
21: PetscViewerStringSPrintf - Prints information to a `PETSCVIEWERSTRING` `PetscViewer` object
23: Logically Collective on viewer
25: Input Parameters:
26: + v - a string `PetscViewer`, formed by `PetscViewerStringOpen()`
27: - format - the format of the input
29: Level: developer
31: Note:
32: Though this is collective each MPI rank maintains a separate string
34: Fortran Note:
35: This routine is not supported in Fortran.
37: .seealso: `PETSCVIEWERSTRING`, `PetscViewerStringOpen()`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSetString()`
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;
50: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
51: if (!isstring) return 0;
54: va_start(Argp, format);
55: PetscVSNPrintf(tmp, 4096, format, &fullLength, Argp);
56: va_end(Argp);
57: PetscStrlen(tmp, &shift);
58: cshift = shift + 1;
59: if (cshift >= vstr->maxlen - vstr->curlen - 1) cshift = vstr->maxlen - vstr->curlen - 1;
60: PetscStrncpy(vstr->head, tmp, cshift);
61: vstr->head += shift;
62: vstr->curlen += shift;
63: return 0;
64: }
66: /*@C
67: PetscViewerStringOpen - Opens a string as a `PETSCVIEWERSTRING` `PetscViewer`. This is a very
68: simple `PetscViewer`; information on the object is simply stored into
69: the string in a fairly nice way.
71: Collective
73: Input Parameters:
74: + comm - the communicator
75: . string - the string to use
76: - len - the string length
78: Output Parameter:
79: . lab - the `PetscViewer`
81: Level: advanced
83: Fortran Note:
84: This routine is not supported in Fortran.
86: .seealso: `PETSCVIEWERSTRING`, `PetscViewerDestroy()`, `PetscViewerStringSPrintf()`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSetString()`
87: @*/
88: PetscErrorCode PetscViewerStringOpen(MPI_Comm comm, char string[], size_t len, PetscViewer *lab)
89: {
90: PetscViewerCreate(comm, lab);
91: PetscViewerSetType(*lab, PETSCVIEWERSTRING);
92: PetscViewerStringSetString(*lab, string, len);
93: return 0;
94: }
96: PetscErrorCode PetscViewerGetSubViewer_String(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
97: {
98: PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
100: PetscViewerStringOpen(PETSC_COMM_SELF, vstr->head, vstr->maxlen - vstr->curlen, sviewer);
101: return 0;
102: }
104: PetscErrorCode PetscViewerRestoreSubViewer_String(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
105: {
106: PetscViewer_String *iviewer = (PetscViewer_String *)(*sviewer)->data;
107: PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
109: vstr->head = iviewer->head;
110: vstr->curlen += iviewer->curlen;
111: PetscViewerDestroy(sviewer);
112: return 0;
113: }
115: /*MC
116: PETSCVIEWERSTRING - A viewer that writes to a string
118: Level: beginner
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: M*/
126: PETSC_EXTERN PetscErrorCode PetscViewerCreate_String(PetscViewer v)
127: {
128: PetscViewer_String *vstr;
130: v->ops->destroy = PetscViewerDestroy_String;
131: v->ops->view = NULL;
132: v->ops->flush = NULL;
133: v->ops->getsubviewer = PetscViewerGetSubViewer_String;
134: v->ops->restoresubviewer = PetscViewerRestoreSubViewer_String;
135: PetscNew(&vstr);
136: v->data = (void *)vstr;
137: vstr->string = NULL;
138: return 0;
139: }
141: /*@C
143: PetscViewerStringGetStringRead - Returns the string that a `PETSCVIEWERSTRING` uses
145: Logically Collective on viewer
147: Input Parameter:
148: . viewer - `PETSCVIEWERSTRING` viewer
150: Output Parameters:
151: + string - the string, optional use NULL if you do not need
152: - len - the length of the string, optional use NULL if you do
154: Note:
155: Do not write to the string nor free it
157: Level: advanced
159: .seealso: `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringSetString()`, `PetscViewerStringSPrintf()`,
160: `PetscViewerStringSetOwnString()`
161: @*/
162: PetscErrorCode PetscViewerStringGetStringRead(PetscViewer viewer, const char *string[], size_t *len)
163: {
164: PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
165: PetscBool isstring;
168: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
170: if (string) *string = vstr->string;
171: if (len) *len = vstr->maxlen;
172: return 0;
173: }
175: /*@C
177: PetscViewerStringSetString - sets the string that a string viewer will print to
179: Logically Collective on viewer
181: Input Parameters:
182: + viewer - string viewer you wish to attach string to
183: . string - the string to print data into
184: - len - the length of the string
186: Note: The function does not copy the string, it uses it directly therefore you cannot free
187: the string until the viewer is destroyed. If you call `PetscViewerStringSetOwnString()` the ownership
188: passes to the viewer and it will be responsable for freeing it. In this case the string must be
189: obtained with `PetscMalloc()`.
191: Level: advanced
193: .seealso: `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSPrintf()`,
194: `PetscViewerStringSetOwnString()`
195: @*/
196: PetscErrorCode PetscViewerStringSetString(PetscViewer viewer, char string[], size_t len)
197: {
198: PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
199: PetscBool isstring;
203: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
204: if (!isstring) return 0;
207: PetscArrayzero(string, len);
208: vstr->string = string;
209: vstr->head = string;
210: vstr->curlen = 0;
211: vstr->maxlen = len;
212: return 0;
213: }
215: /*@C
217: PetscViewerStringSetOwnString - tells the viewer that it now owns the string and is responsible for freeing it
219: Logically Collective on viewer
221: Input Parameters:
222: . viewer - string viewer
224: Note:
225: If you call this the string must have been obtained with `PetscMalloc()` and you cannot free the string
227: Level: advanced
229: .seealso: `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSPrintf()`,
230: `PetscViewerStringSetString()`
231: @*/
232: PetscErrorCode PetscViewerStringSetOwnString(PetscViewer viewer)
233: {
234: PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
235: PetscBool isstring;
238: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
239: if (!isstring) return 0;
241: vstr->ownstring = PETSC_TRUE;
242: return 0;
243: }