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 responsible 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; No Fortran Support
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: .seealso: [](sec_viewers), `PETSCVIEWERSTRING`, `PetscViewerStringOpen()`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSetString()`
35: @*/
36: PetscErrorCode PetscViewerStringSPrintf(PetscViewer viewer, const char format[], ...)
37: {
38: va_list Argp;
39: size_t fullLength;
40: size_t shift, cshift;
41: PetscBool isstring;
42: char tmp[4096];
43: PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
47: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
48: if (!isstring) return 0;
51: va_start(Argp, format);
52: PetscVSNPrintf(tmp, 4096, format, &fullLength, Argp);
53: va_end(Argp);
54: PetscStrlen(tmp, &shift);
55: cshift = shift + 1;
56: if (cshift >= vstr->maxlen - vstr->curlen - 1) cshift = vstr->maxlen - vstr->curlen - 1;
57: PetscStrncpy(vstr->head, tmp, cshift);
58: vstr->head += shift;
59: vstr->curlen += shift;
60: return 0;
61: }
63: /*@C
64: PetscViewerStringOpen - Opens a string as a `PETSCVIEWERSTRING` `PetscViewer`. This is a very
65: simple `PetscViewer`; information on the object is simply stored into
66: the string in a fairly nice way.
68: Collective; No Fortran Support
70: Input Parameters:
71: + comm - the communicator
72: . string - the string to use
73: - len - the string length
75: Output Parameter:
76: . lab - the `PetscViewer`
78: Level: advanced
80: .seealso: [](sec_viewers), `PETSCVIEWERSTRING`, `PetscViewerDestroy()`, `PetscViewerStringSPrintf()`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSetString()`
81: @*/
82: PetscErrorCode PetscViewerStringOpen(MPI_Comm comm, char string[], size_t len, PetscViewer *lab)
83: {
84: PetscViewerCreate(comm, lab);
85: PetscViewerSetType(*lab, PETSCVIEWERSTRING);
86: PetscViewerStringSetString(*lab, string, len);
87: return 0;
88: }
90: PetscErrorCode PetscViewerGetSubViewer_String(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
91: {
92: PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
94: PetscViewerStringOpen(PETSC_COMM_SELF, vstr->head, vstr->maxlen - vstr->curlen, sviewer);
95: return 0;
96: }
98: PetscErrorCode PetscViewerRestoreSubViewer_String(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
99: {
100: PetscViewer_String *iviewer = (PetscViewer_String *)(*sviewer)->data;
101: PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
103: vstr->head = iviewer->head;
104: vstr->curlen += iviewer->curlen;
105: PetscViewerDestroy(sviewer);
106: return 0;
107: }
109: /*MC
110: PETSCVIEWERSTRING - A viewer that writes to a string
112: Level: beginner
114: .seealso: [](sec_viewers), `PetscViewerStringOpen()`, `PetscViewerStringSPrintf()`, `PetscViewerSocketOpen()`, `PetscViewerDrawOpen()`, `PETSCVIEWERSOCKET`,
115: `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`, `PETSCVIEWERDRAW`,
116: `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`,
117: `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
118: M*/
120: PETSC_EXTERN PetscErrorCode PetscViewerCreate_String(PetscViewer v)
121: {
122: PetscViewer_String *vstr;
124: v->ops->destroy = PetscViewerDestroy_String;
125: v->ops->view = NULL;
126: v->ops->flush = NULL;
127: v->ops->getsubviewer = PetscViewerGetSubViewer_String;
128: v->ops->restoresubviewer = PetscViewerRestoreSubViewer_String;
129: PetscNew(&vstr);
130: v->data = (void *)vstr;
131: vstr->string = NULL;
132: return 0;
133: }
135: /*@C
137: PetscViewerStringGetStringRead - Returns the string that a `PETSCVIEWERSTRING` uses
139: Logically Collective
141: Input Parameter:
142: . viewer - `PETSCVIEWERSTRING` viewer
144: Output Parameters:
145: + string - the string, optional use NULL if you do not need
146: - len - the length of the string, optional use NULL if you do
148: Level: advanced
150: Note:
151: Do not write to the string nor free it
153: .seealso: [](sec_viewers), `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringSetString()`, `PetscViewerStringSPrintf()`,
154: `PetscViewerStringSetOwnString()`
155: @*/
156: PetscErrorCode PetscViewerStringGetStringRead(PetscViewer viewer, const char *string[], size_t *len)
157: {
158: PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
159: PetscBool isstring;
162: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
164: if (string) *string = vstr->string;
165: if (len) *len = vstr->maxlen;
166: return 0;
167: }
169: /*@C
171: PetscViewerStringSetString - sets the string that a string viewer will print to
173: Logically Collective
175: Input Parameters:
176: + viewer - string viewer you wish to attach string to
177: . string - the string to print data into
178: - len - the length of the string
180: Level: advanced
182: Note:
183: The function does not copy the string, it uses it directly therefore you cannot free
184: the string until the viewer is destroyed. If you call `PetscViewerStringSetOwnString()` the ownership
185: passes to the viewer and it will be responsible for freeing it. In this case the string must be
186: obtained with `PetscMalloc()`.
188: .seealso: [](sec_viewers), `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSPrintf()`,
189: `PetscViewerStringSetOwnString()`
190: @*/
191: PetscErrorCode PetscViewerStringSetString(PetscViewer viewer, char string[], size_t len)
192: {
193: PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
194: PetscBool isstring;
198: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
199: if (!isstring) return 0;
202: PetscArrayzero(string, len);
203: vstr->string = string;
204: vstr->head = string;
205: vstr->curlen = 0;
206: vstr->maxlen = len;
207: return 0;
208: }
210: /*@C
212: PetscViewerStringSetOwnString - tells the viewer that it now owns the string and is responsible for freeing it
214: Logically Collective
216: Input Parameters:
217: . viewer - string viewer
219: Level: advanced
221: Note:
222: If you call this the string must have been obtained with `PetscMalloc()` and you cannot free the string
224: .seealso: [](sec_viewers), `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSPrintf()`,
225: `PetscViewerStringSetString()`
226: @*/
227: PetscErrorCode PetscViewerStringSetOwnString(PetscViewer viewer)
228: {
229: PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
230: PetscBool isstring;
233: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
234: if (!isstring) return 0;
236: vstr->ownstring = PETSC_TRUE;
237: return 0;
238: }