1 #include <../src/sys/classes/draw/utils/axisimpl.h> /*I "petscdraw.h" I*/
2
3 PetscClassId PETSC_DRAWAXIS_CLASSID = 0;
4
5 /*@
6 PetscDrawAxisCreate - Generate the axis data structure.
7
8 Collective on PetscDraw
9
10 Input Parameters:
11 . win - PetscDraw object where axis to to be made
12
13 Ouput Parameters:
14 . axis - the axis datastructure
15
16 Notes:
17 the MPI communicator that owns the underlying draw object owns the PetscDrawAxis object, but calls to set PetscDrawAxis options are ignored by all processes
18 except the first MPI process in the communicator
19
20 Level: advanced
21
22 .seealso: PetscDrawLGCreate(), PetscDrawLG, PetscDrawSPCreate(), PetscDrawSP, PetscDrawHGCreate(), PetscDrawHG, PetscDrawBarCreate(), PetscDrawBar, PetscDrawLGGetAxis(), PetscDrawSPGetAxis(),
23 PetscDrawHGGetAxis(), PetscDrawBarGetAxis(), PetscDrawAxis, PetscDrawAxisDestroy(), PetscDrawAxisSetColors(), PetscDrawAxisSetLabels(), PetscDrawAxisSetLimits(), PetscDrawAxisGetLimits(), PetscDrawAxisSetHoldLimits(),
24 PetscDrawAxisDraw()
25 @*/
PetscDrawAxisCreate(PetscDraw draw,PetscDrawAxis * axis)26 PetscErrorCode PetscDrawAxisCreate(PetscDraw draw,PetscDrawAxis *axis)
27 {
28 PetscDrawAxis ad;
29 PetscErrorCode ierr;
30
31 PetscFunctionBegin;
32 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
33 PetscValidPointer(axis,2);
34
35 ierr = PetscHeaderCreate(ad,PETSC_DRAWAXIS_CLASSID,"DrawAxis","Draw Axis","Draw",PetscObjectComm((PetscObject)draw),PetscDrawAxisDestroy,NULL);CHKERRQ(ierr);
36 ierr = PetscLogObjectParent((PetscObject)draw,(PetscObject)ad);CHKERRQ(ierr);
37
38 ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr);
39 ad->win = draw;
40
41 ad->xticks = PetscADefTicks;
42 ad->yticks = PetscADefTicks;
43 ad->xlabelstr = PetscADefLabel;
44 ad->ylabelstr = PetscADefLabel;
45 ad->ac = PETSC_DRAW_BLACK;
46 ad->tc = PETSC_DRAW_BLACK;
47 ad->cc = PETSC_DRAW_BLACK;
48 ad->xlabel = NULL;
49 ad->ylabel = NULL;
50 ad->toplabel = NULL;
51
52 *axis = ad;
53 PetscFunctionReturn(0);
54 }
55
56 /*@
57 PetscDrawAxisDestroy - Frees the space used by an axis structure.
58
59 Collective on PetscDrawAxis
60
61 Input Parameters:
62 . axis - the axis context
63
64 Level: advanced
65
66 .seealso: PetscDrawAxisCreate(), PetscDrawAxis
67 @*/
PetscDrawAxisDestroy(PetscDrawAxis * axis)68 PetscErrorCode PetscDrawAxisDestroy(PetscDrawAxis *axis)
69 {
70 PetscErrorCode ierr;
71
72 PetscFunctionBegin;
73 if (!*axis) PetscFunctionReturn(0);
74 PetscValidHeaderSpecific(*axis,PETSC_DRAWAXIS_CLASSID,1);
75 if (--((PetscObject)(*axis))->refct > 0) {*axis = NULL; PetscFunctionReturn(0);}
76
77 ierr = PetscFree((*axis)->toplabel);CHKERRQ(ierr);
78 ierr = PetscFree((*axis)->xlabel);CHKERRQ(ierr);
79 ierr = PetscFree((*axis)->ylabel);CHKERRQ(ierr);
80 ierr = PetscDrawDestroy(&(*axis)->win);CHKERRQ(ierr);
81 ierr = PetscHeaderDestroy(axis);CHKERRQ(ierr);
82 PetscFunctionReturn(0);
83 }
84
85 /*@
86 PetscDrawAxisSetColors - Sets the colors to be used for the axis,
87 tickmarks, and text.
88
89 Logically Collective on PetscDrawAxis
90
91 Input Parameters:
92 + axis - the axis
93 . ac - the color of the axis lines
94 . tc - the color of the tick marks
95 - cc - the color of the text strings
96
97 Level: advanced
98
99 .seealso: PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisSetLabels(), PetscDrawAxisDraw(), PetscDrawAxisSetLimits()
100 @*/
PetscDrawAxisSetColors(PetscDrawAxis axis,int ac,int tc,int cc)101 PetscErrorCode PetscDrawAxisSetColors(PetscDrawAxis axis,int ac,int tc,int cc)
102 {
103 PetscFunctionBegin;
104 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
105 PetscValidLogicalCollectiveInt(axis,ac,2);
106 PetscValidLogicalCollectiveInt(axis,tc,3);
107 PetscValidLogicalCollectiveInt(axis,cc,4);
108 axis->ac = ac; axis->tc = tc; axis->cc = cc;
109 PetscFunctionReturn(0);
110 }
111
112 /*@C
113 PetscDrawAxisSetLabels - Sets the x and y axis labels.
114
115 Logically Collective on PetscDrawAxis
116
117 Input Parameters:
118 + axis - the axis
119 . top - the label at the top of the image
120 - xlabel,ylabel - the labes for the x and y axis
121
122 Notes:
123 Must be called before PetscDrawAxisDraw() or PetscDrawLGDraw()
124 There should be no newlines in the arguments
125
126 Level: advanced
127
128 .seealso: PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisSetColors(), PetscDrawAxisDraw(), PetscDrawAxisSetLimits()
129 @*/
PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[])130 PetscErrorCode PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[])
131 {
132 PetscErrorCode ierr;
133
134 PetscFunctionBegin;
135 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
136 ierr = PetscFree(axis->xlabel);CHKERRQ(ierr);
137 ierr = PetscFree(axis->ylabel);CHKERRQ(ierr);
138 ierr = PetscFree(axis->toplabel);CHKERRQ(ierr);
139 ierr = PetscStrallocpy(xlabel,&axis->xlabel);CHKERRQ(ierr);
140 ierr = PetscStrallocpy(ylabel,&axis->ylabel);CHKERRQ(ierr);
141 ierr = PetscStrallocpy(top,&axis->toplabel);CHKERRQ(ierr);
142 PetscFunctionReturn(0);
143 }
144
145 /*@
146 PetscDrawAxisSetLimits - Sets the limits (in user coords) of the axis
147
148 Logically Collective on PetscDrawAxis
149
150 Input Parameters:
151 + axis - the axis
152 . xmin,xmax - limits in x
153 - ymin,ymax - limits in y
154
155 Options Database:
156 . -drawaxis_hold - hold the initial set of axis limits for future plotting
157
158 Level: advanced
159
160 .seealso: PetscDrawAxisSetHoldLimits(), PetscDrawAxisGetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()
161
162 @*/
PetscDrawAxisSetLimits(PetscDrawAxis axis,PetscReal xmin,PetscReal xmax,PetscReal ymin,PetscReal ymax)163 PetscErrorCode PetscDrawAxisSetLimits(PetscDrawAxis axis,PetscReal xmin,PetscReal xmax,PetscReal ymin,PetscReal ymax)
164 {
165 PetscErrorCode ierr;
166
167 PetscFunctionBegin;
168 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
169 if (axis->hold) PetscFunctionReturn(0);
170 axis->xlow = xmin;
171 axis->xhigh= xmax;
172 axis->ylow = ymin;
173 axis->yhigh= ymax;
174 ierr = PetscOptionsHasName(((PetscObject)axis)->options,((PetscObject)axis)->prefix,"-drawaxis_hold",&axis->hold);CHKERRQ(ierr);
175 PetscFunctionReturn(0);
176 }
177
178 /*@
179 PetscDrawAxisGetLimits - Gets the limits (in user coords) of the axis
180
181 Not Collective
182
183 Input Parameters:
184 + axis - the axis
185 . xmin,xmax - limits in x
186 - ymin,ymax - limits in y
187
188 Level: advanced
189
190 .seealso: PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisSetHoldLimits(), PetscDrawAxisSetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()
191
192 @*/
PetscDrawAxisGetLimits(PetscDrawAxis axis,PetscReal * xmin,PetscReal * xmax,PetscReal * ymin,PetscReal * ymax)193 PetscErrorCode PetscDrawAxisGetLimits(PetscDrawAxis axis,PetscReal *xmin,PetscReal *xmax,PetscReal *ymin,PetscReal *ymax)
194 {
195 PetscFunctionBegin;
196 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
197 if (xmin) *xmin = axis->xlow;
198 if (xmax) *xmax = axis->xhigh;
199 if (ymin) *ymin = axis->ylow;
200 if (ymax) *ymax = axis->yhigh;
201 PetscFunctionReturn(0);
202 }
203
204 /*@
205 PetscDrawAxisSetHoldLimits - Causes an axis to keep the same limits until this is called
206 again
207
208 Logically Collective on PetscDrawAxis
209
210 Input Parameters:
211 + axis - the axis
212 - hold - PETSC_TRUE - hold current limits, PETSC_FALSE allow limits to be changed
213
214 Level: advanced
215
216 Notes:
217 Once this has been called with PETSC_TRUE the limits will not change if you call
218 PetscDrawAxisSetLimits() until you call this with PETSC_FALSE
219
220 .seealso: PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisGetLimits(), PetscDrawAxisSetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()
221
222 @*/
PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold)223 PetscErrorCode PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold)
224 {
225 PetscFunctionBegin;
226 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
227 PetscValidLogicalCollectiveBool(axis,hold,2);
228 axis->hold = hold;
229 PetscFunctionReturn(0);
230 }
231
232 /*@
233 PetscDrawAxisDraw - PetscDraws an axis.
234
235 Collective on PetscDrawAxis
236
237 Input Parameter:
238 . axis - Axis structure
239
240 Level: advanced
241
242 Note:
243 This draws the actual axis. The limits etc have already been set.
244 By picking special routines for the ticks and labels, special
245 effects may be generated. These routines are part of the Axis
246 structure (axis).
247
248 .seealso: PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisGetLimits(), PetscDrawAxisSetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()
249
250 @*/
PetscDrawAxisDraw(PetscDrawAxis axis)251 PetscErrorCode PetscDrawAxisDraw(PetscDrawAxis axis)
252 {
253 int i,ntick,numx,numy,ac,tc,cc;
254 PetscMPIInt rank;
255 size_t len,ytlen=0;
256 PetscReal coors[4],tickloc[MAXSEGS],sep,tw,th;
257 PetscReal xl,xr,yl,yr,dxl=0,dyl=0,dxr=0,dyr=0;
258 char *p;
259 PetscDraw draw;
260 PetscBool isnull;
261 PetscErrorCode ierr;
262
263 PetscFunctionBegin;
264 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
265 ierr = PetscDrawIsNull(axis->win,&isnull);CHKERRQ(ierr);
266 if (isnull) PetscFunctionReturn(0);
267 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)axis),&rank);CHKERRQ(ierr);
268
269 draw = axis->win;
270
271 ac = axis->ac; tc = axis->tc; cc = axis->cc;
272 if (axis->xlow == axis->xhigh) {axis->xlow -= .5; axis->xhigh += .5;}
273 if (axis->ylow == axis->yhigh) {axis->ylow -= .5; axis->yhigh += .5;}
274
275 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
276 if (rank) goto finally;
277
278 /* get cannonical string size */
279 ierr = PetscDrawSetCoordinates(draw,0,0,1,1);CHKERRQ(ierr);
280 ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
281 /* lower spacing */
282 if (axis->xlabelstr) dyl += 1.5*th;
283 if (axis->xlabel) dyl += 1.5*th;
284 /* left spacing */
285 if (axis->ylabelstr) dxl += 7.5*tw;
286 if (axis->ylabel) dxl += 2.0*tw;
287 /* right and top spacing */
288 if (axis->xlabelstr) dxr = 2.5*tw;
289 if (axis->ylabelstr) dyr = 0.5*th;
290 if (axis->toplabel) dyr = 1.5*th;
291 /* extra spacing */
292 dxl += 0.7*tw; dxr += 0.5*tw;
293 dyl += 0.2*th; dyr += 0.2*th;
294 /* determine coordinates */
295 xl = (dxl*axis->xhigh + dxr*axis->xlow - axis->xlow) / (dxl + dxr - 1);
296 xr = (dxl*axis->xhigh + dxr*axis->xlow - axis->xhigh) / (dxl + dxr - 1);
297 yl = (dyl*axis->yhigh + dyr*axis->ylow - axis->ylow) / (dyl + dyr - 1);
298 yr = (dyl*axis->yhigh + dyr*axis->ylow - axis->yhigh) / (dyl + dyr - 1);
299 ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
300 ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
301
302 /* PetscDraw the axis lines */
303 ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);CHKERRQ(ierr);
304 ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);CHKERRQ(ierr);
305 ierr = PetscDrawLine(draw,axis->xlow,axis->yhigh,axis->xhigh,axis->yhigh,ac);CHKERRQ(ierr);
306 ierr = PetscDrawLine(draw,axis->xhigh,axis->ylow,axis->xhigh,axis->yhigh,ac);CHKERRQ(ierr);
307
308 /* PetscDraw the top label */
309 if (axis->toplabel) {
310 PetscReal x = (axis->xlow + axis->xhigh)/2, y = axis->yhigh + 0.5*th;
311 ierr = PetscDrawStringCentered(draw,x,y,cc,axis->toplabel);CHKERRQ(ierr);
312 }
313
314 /* PetscDraw the X ticks and labels */
315 if (axis->xticks) {
316 numx = (int)(.15*(axis->xhigh-axis->xlow)/tw); numx = PetscClipInterval(numx,2,6);
317 ierr = (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr);
318 /* PetscDraw in tick marks */
319 for (i=0; i<ntick; i++) {
320 ierr = PetscDrawLine(draw,tickloc[i],axis->ylow,tickloc[i],axis->ylow+.5*th,tc);CHKERRQ(ierr);
321 ierr = PetscDrawLine(draw,tickloc[i],axis->yhigh,tickloc[i],axis->yhigh-.5*th,tc);CHKERRQ(ierr);
322 }
323 /* label ticks */
324 if (axis->xlabelstr) {
325 for (i=0; i<ntick; i++) {
326 if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
327 else if (i > 0) sep = tickloc[i] - tickloc[i-1];
328 else sep = 0.0;
329 ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr);
330 ierr = PetscDrawStringCentered(draw,tickloc[i],axis->ylow-1.5*th,cc,p);CHKERRQ(ierr);
331 }
332 }
333 }
334 if (axis->xlabel) {
335 PetscReal x = (axis->xlow + axis->xhigh)/2, y = axis->ylow - 1.5*th;
336 if (axis->xlabelstr) y -= 1.5*th;
337 ierr = PetscDrawStringCentered(draw,x,y,cc,axis->xlabel);CHKERRQ(ierr);
338 }
339
340 /* PetscDraw the Y ticks and labels */
341 if (axis->yticks) {
342 numy = (int)(.50*(axis->yhigh-axis->ylow)/th); numy = PetscClipInterval(numy,2,6);
343 ierr = (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr);
344 /* PetscDraw in tick marks */
345 for (i=0; i<ntick; i++) {
346 ierr = PetscDrawLine(draw,axis->xlow,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);CHKERRQ(ierr);
347 ierr = PetscDrawLine(draw,axis->xhigh,tickloc[i],axis->xhigh-.5*tw,tickloc[i],tc);CHKERRQ(ierr);
348 }
349 /* label ticks */
350 if (axis->ylabelstr) {
351 for (i=0; i<ntick; i++) {
352 if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
353 else if (i > 0) sep = tickloc[i] - tickloc[i-1];
354 else sep = 0.0;
355 ierr = (*axis->ylabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr);
356 ierr = PetscStrlen(p,&len);CHKERRQ(ierr); ytlen = PetscMax(ytlen,len);
357 ierr = PetscDrawString(draw,axis->xlow-(len+.5)*tw,tickloc[i]-.5*th,cc,p);CHKERRQ(ierr);
358 }
359 }
360 }
361 if (axis->ylabel) {
362 PetscReal x = axis->xlow - 2.0*tw, y = (axis->ylow + axis->yhigh)/2;
363 if (axis->ylabelstr) x -= (ytlen+.5)*tw;
364 ierr = PetscStrlen(axis->ylabel,&len);CHKERRQ(ierr);
365 ierr = PetscDrawStringVertical(draw,x,y+len*th/2,cc,axis->ylabel);CHKERRQ(ierr);
366 }
367
368 ierr = PetscDrawGetCoordinates(draw,&coors[0],&coors[1],&coors[2],&coors[3]);CHKERRQ(ierr);
369 finally:
370 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
371 ierr = MPI_Bcast(coors,4,MPIU_REAL,0,PetscObjectComm((PetscObject)draw));CHKERRQ(ierr);
372 ierr = PetscDrawSetCoordinates(draw,coors[0],coors[1],coors[2],coors[3]);CHKERRQ(ierr);
373 PetscFunctionReturn(0);
374 }
375
376 /*
377 Removes all zeros but one from .0000
378 */
PetscStripe0(char * buf)379 PetscErrorCode PetscStripe0(char *buf)
380 {
381 PetscErrorCode ierr;
382 size_t n;
383 PetscBool flg;
384 char *str;
385
386 PetscFunctionBegin;
387 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
388 ierr = PetscStrendswith(buf,"e00",&flg);CHKERRQ(ierr);
389 if (flg) buf[n-3] = 0;
390 ierr = PetscStrstr(buf,"e0",&str);CHKERRQ(ierr);
391 if (str) {
392 buf[n-2] = buf[n-1];
393 buf[n-1] = 0;
394 }
395 ierr = PetscStrstr(buf,"e-0",&str);CHKERRQ(ierr);
396 if (str) {
397 buf[n-2] = buf[n-1];
398 buf[n-1] = 0;
399 }
400 PetscFunctionReturn(0);
401 }
402
403 /*
404 Removes all zeros but one from .0000
405 */
PetscStripAllZeros(char * buf)406 PetscErrorCode PetscStripAllZeros(char *buf)
407 {
408 PetscErrorCode ierr;
409 size_t i,n;
410
411 PetscFunctionBegin;
412 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
413 if (buf[0] != '.') PetscFunctionReturn(0);
414 for (i=1; i<n; i++) {
415 if (buf[i] != '0') PetscFunctionReturn(0);
416 }
417 buf[0] = '0';
418 buf[1] = 0;
419 PetscFunctionReturn(0);
420 }
421
422 /*
423 Removes trailing zeros
424 */
PetscStripTrailingZeros(char * buf)425 PetscErrorCode PetscStripTrailingZeros(char *buf)
426 {
427 PetscErrorCode ierr;
428 char *found;
429 size_t i,n,m = PETSC_MAX_INT;
430
431 PetscFunctionBegin;
432 /* if there is an e in string DO NOT strip trailing zeros */
433 ierr = PetscStrchr(buf,'e',&found);CHKERRQ(ierr);
434 if (found) PetscFunctionReturn(0);
435
436 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
437 /* locate decimal point */
438 for (i=0; i<n; i++) {
439 if (buf[i] == '.') {m = i; break;}
440 }
441 /* if not decimal point then no zeros to remove */
442 if (m == PETSC_MAX_INT) PetscFunctionReturn(0);
443 /* start at right end of string removing 0s */
444 for (i=n-1; i>m; i++) {
445 if (buf[i] != '0') PetscFunctionReturn(0);
446 buf[i] = 0;
447 }
448 PetscFunctionReturn(0);
449 }
450
451 /*
452 Removes leading 0 from 0.22 or -0.22
453 */
PetscStripInitialZero(char * buf)454 PetscErrorCode PetscStripInitialZero(char *buf)
455 {
456 PetscErrorCode ierr;
457 size_t i,n;
458
459 PetscFunctionBegin;
460 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
461 if (buf[0] == '0') {
462 for (i=0; i<n; i++) buf[i] = buf[i+1];
463 } else if (buf[0] == '-' && buf[1] == '0') {
464 for (i=1; i<n; i++) buf[i] = buf[i+1];
465 }
466 PetscFunctionReturn(0);
467 }
468
469 /*
470 Removes the extraneous zeros in numbers like 1.10000e6
471 */
PetscStripZeros(char * buf)472 PetscErrorCode PetscStripZeros(char *buf)
473 {
474 PetscErrorCode ierr;
475 size_t i,j,n;
476
477 PetscFunctionBegin;
478 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
479 if (n<5) PetscFunctionReturn(0);
480 for (i=1; i<n-1; i++) {
481 if (buf[i] == 'e' && buf[i-1] == '0') {
482 for (j=i; j<n+1; j++) buf[j-1] = buf[j];
483 ierr = PetscStripZeros(buf);CHKERRQ(ierr);
484 PetscFunctionReturn(0);
485 }
486 }
487 PetscFunctionReturn(0);
488 }
489
490 /*
491 Removes the plus in something like 1.1e+2 or 1.1e+02
492 */
PetscStripZerosPlus(char * buf)493 PetscErrorCode PetscStripZerosPlus(char *buf)
494 {
495 PetscErrorCode ierr;
496 size_t i,j,n;
497
498 PetscFunctionBegin;
499 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
500 if (n<5) PetscFunctionReturn(0);
501 for (i=1; i<n-2; i++) {
502 if (buf[i] == '+') {
503 if (buf[i+1] == '0') {
504 for (j=i+1; j<n; j++) buf[j-1] = buf[j+1];
505 PetscFunctionReturn(0);
506 } else {
507 for (j=i+1; j<n+1; j++) buf[j-1] = buf[j];
508 PetscFunctionReturn(0);
509 }
510 } else if (buf[i] == '-') {
511 if (buf[i+1] == '0') {
512 for (j=i+1; j<n; j++) buf[j] = buf[j+1];
513 PetscFunctionReturn(0);
514 }
515 }
516 }
517 PetscFunctionReturn(0);
518 }
519