Annotation of freem/mlib/%ulstring.m, revision 1.2
1.2 ! snw 1: %ulstring ;VCL/SNW-STRING LIBRARY; 03/09/25 06:30 PM
! 2: ;0.0;FreeM;****FREEM**;Serena Willis @2025
! 3: ;
! 4: ; $Id$
! 5: ; String library
! 6: ;
! 7: ;
! 8: ; Author: Serena Willis <snw@coherent-logic.com>
! 9: ; Copyright (C) 1998 MUG Deutschland
! 10: ; Copyright (C) 2023, 2025 Coherent Logic Development LLC
! 11: ;
! 12: ;
! 13: ; This file is part of FreeM.
! 14: ;
! 15: ; FreeM is free software: you can redistribute it and/or modify
! 16: ; it under the terms of the GNU Affero Public License as published by
! 17: ; the Free Software Foundation, either version 3 of the License, or
! 18: ; (at your option) any later version.
! 19: ;
! 20: ; FreeM is distributed in the hope that it will be useful,
! 21: ; but WITHOUT ANY WARRANTY; without even the implied warranty of
! 22: ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 23: ; GNU Affero Public License for more details.
! 24: ;
! 25: ; You should have received a copy of the GNU Affero Public License
! 26: ; along with FreeM. If not, see <https://www.gnu.org/licenses/>.
! 27: ;
! 28: ; $Log$
! 29: ;
! 30: ; SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC
! 31: ; SPDX-License-Identifier: AGPL-3.0-or-later
! 32: ;
! 33: ; STRING library - version 0.5.0.1
! 34: ;
! 35: ; Unless otherwise noted, the code below
! 36: ; was approved in document X11/95-11
! 37: ;
! 38: ; If corrections have been applied,
! 39: ; first the original line appears,
! 40: ; with three semicolons at the beginning of the line.
! 41: ;
! 42: ; Then the source of the correction is acknowledged,
! 43: ; then the corrected line appears, followed by a
! 44: ; line containing three semicolons.
! 45: ;
! 46: ;
! 47: ;
1.1 snw 48: PRODUCE(IN,SPEC,MAX) ;
49: NEW VALUE,AGAIN,P1,P2,I,COUNT
50: SET VALUE=IN,COUNT=0
51: FOR DO QUIT:'AGAIN
52: . SET AGAIN=0
53: . SET I=""
54: . FOR SET I=$ORDER(SPEC(I)) QUIT:I="" DO QUIT:COUNT<0
55: . . QUIT:$GET(SPEC(I,1))=""
56: . . QUIT:'($DATA(SPEC(I,2))#2)
57: . . FOR QUIT:VALUE'[SPEC(I,1) DO QUIT:COUNT<0
58: . . . SET P1=$PIECE(VALUE,SPEC(I,1),1)
59: . . . SET P2=$PIECE(VALUE,SPEC(I,1),2,$LENGTH(VALUE))
60: . . . SET VALUE=P1_SPEC(I,2)_P2,AGAIN=1
61: . . . SET COUNT=COUNT+1
62: . . . IF $DATA(MAX),COUNT>MAX SET COUNT=-1,AGAIN=0
63: . . . QUIT
64: . . QUIT
65: . QUIT
66: QUIT VALUE
67: ;===
68: ;
69: ;
70: REPLACE(IN,SPEC) ;
71: NEW L,MASK,K,I,LT,F,VALUE
72: SET L=$LENGTH(IN),MASK=$JUSTIFY("",L)
73: SET I="" FOR SET I=$ORDER(SPEC(I)) QUIT:I="" DO
74: . QUIT:'($DATA(SPEC(I,1))#2)
75: . QUIT:SPEC(I,1)=""
76: . QUIT:'($DATA(SPEC(I,2))#2)
77: . SET LT=$LENGTH(SPEC(I,1))
78: . SET F=0 FOR SET F=$FIND(IN,SPEC(I,1),F) QUIT:F<1 DO
79: . . QUIT:$E(MASK,F-LT,F-1)["X"
80: . . SET VALUE(F-LT)=SPEC(I,2)
81: . . SET $EXTRACT(MASK,F-LT,F-1)=$TRANSLATE($JUSTIFY("",LT)," ","X")
82: . . QUIT
83: . QUIT
84: SET VALUE="" FOR K=1:1:L DO
85: . IF $EXTRACT(MASK,K)=" " SET VALUE=VALUE_$EXTRACT(IN,K) QUIT
86: . SET:$DATA(VALUE(K)) VALUE=VALUE_VALUE(K)
87: . QUIT
88: QUIT VALUE
89: ;===
90: ;
91: ;
92: FORMAT(V,L) ;
93: ;
94: ; The code below was approved in document X11/SC13/1998-10
95: ;
96: NEW C,CD,CM,CS,DP,E,EX,FL,FM,FO,GL,GV1,GV2,GVL,GVM,GX,I,J,K,ST,TV,TY,V1,V2,VP
97: ;
98: ; Load up Format Directives from ^$FORMAT or ^SYSTEM("FORMAT")
99: DO:'$DATA(^$FORMAT) %INFORM
100: SET (FM,K)="",EX=0,EXS="EXS"
101: ;
102: ; Extract the working values from the command string
103: DO %PRELOAD
104: ;
105: ; Process the directives
106: DO %EVALU8
107: ;
108: ; Error Handling
109: DO:EX %ERROR
110: XECUTE:$LENGTH(EXS) "K "_EXS
111: QUIT K
112: ;
113: ; CM - Command Array
114: ; CS - Command String
115: ; DP - Decimal Pointer
116: ; EX - Exit Flag
117: ; EXS - KILL Exit String
118: ; FL - Field Length
119: ; FM - Format String
120: ; FO - Format Option Array
121: ; K - Return Output String
122: ; L - List of Directives
123: ; ST - String Extraction String
124: ; V - Input Value
125: ;
126: %PRELOAD ; Load the defaults prior to the application of directives
127: SET K=""
128: ; Load System Defaults
129: FOR SET K=$ORDER(^$SYSTEM("FORMAT",K)) QUIT:K="" DO
130: . SET FO(K)=^$SYSTEM("FORMAT",K)
131: . QUIT
132: ; Load Process Defaults
133: FOR SET K=$ORDER(^$FORMAT(K)) QUIT:K="" SET FO(K)=^$FORMAT(K)
134: SET (CS,L)=$GET(L)
135: ; Load Argument Overrides from the List of Directives
136: ; 1. Tokenize the Laterals
137: DO:L[""""
138: . SET CS=""
139: . FOR J=2:2:$LENGTH(L,"""") DO
140: . . SET ST=$GET(ST)+1,ST(ST)=$PIECE(L,"""",J)
141: . . SET:ST(ST)="" ST(ST)=""""
142: . . SET CS=CS_$PIECE(L,"""",J-1)_"%%"_ST_"%%"
143: . . QUIT
144: . SET CS=CS_$PIECE(L,"""",J+1)
145: . QUIT
146: ; 2. Evaluate the Directives
147: NEW C,L,X
148: FOR J=1:1:$LENGTH(CS,":") DO QUIT:EX
149: . SET CD=$PIECE(CS,":",J)
150: . SET X=$PIECE(CD,"="),TV=$PIECE(CD,"=",2,999)
151: . IF X="" SET EX=1 QUIT
152: . ; Uppercase Symbol Names Only
153: . SET TY=$TRANSLATE(X,"abcdefghijklm","ABCDEFGHIJKLM")
154: . SET TY=$TRANSLATE(TY,"nopqrstuvwxyz","NOPQRSTUVWXYZ")
155: . D
156: . . ; To bullet proof, Establish an error trap to %ERREX
157: . . IF ($LENGTH(TV,"%%")>1) DO %LOADTV SET FO(TY)=TV QUIT
158: . . IF TV="" SET FO(TY)="" QUIT
159: . . ; 3. Set the Directive in the FO array
160: . . SET FO(TY)=@TV
161: . . QUIT
162: . QUIT
163: ; 4) Construct a KILL Exit String for directives not in default list
164: NEW C,E
165: SET (C,E)=""
166: FOR SET C=$ORDER(FO(C)) QUIT:C="" SET @C=FO(C),E=E_C_","
167: SET EXS=E_"EXS"
168: SET:$DATA(FM) FL=$LENGTH(FM)
169: QUIT
170: ;
171: ; DC - Decimal Character
172: ; DP - Decimal Position
173: ; EX - Abnormal Condition Exit
174: ; FL - Format Length
175: ; FM - Format Mask
176: ; GV1 - Integer Portion
177: ; GV2 - Fractional Portion
178: ; K - Output Buffer
179: ; NOD - No Decimal
180: ; SV - Sign Value (1 = Positive, 0 = Negative)
181: ; V - Input Value
182: %EVALU8 ; Evaluate the input for loading into the output string
183: NEW NOD
184: SET SV=1
185: SET NOD='(FM["d")
186: SET:V<0 SV=0
187: SET V1=$PIECE(V,"."),V2=$PIECE(V,".",2),(GV1,GV2)=""
188: DO:FM'=""
189: . SET FL=$LENGTH(FM),DP=$FIND(FM,"d")-1
190: . SET:(DP<1) DP=$LENGTH(FM)
191: . QUIT
192: NEW C
193: DO %GETV1,%GETV2:'(NOD!EX)
194: QUIT:EX
195: ;
196: SET K=GV1_DC_GV2
197: SET:NOD K=GV1
198: IF $GET(FC)'="" SET:K[" " K=$TRANSLATE(K," ",FC)
199: SET:$LENGTH(K)'=FL EX=1
200: QUIT
201: ;
202: %GETV1 ; Get the integer portion of the value and lay it in GV1
203: NEW CP,SP
204: IF $GET(SL)'="" NEW SC SET SC=SL
205: ; 1) Set the Integer Portion of the Mask (GVM) and Length (GVL)
206: SET GVM=$PIECE(FM,"d"),GVL=$LENGTH(GVM),GL=0
207: ; 2) Get the absolute value of V1
208: SET:$EXTRACT(V1)="-" V1=$EXTRACT(V1,2,999)
209: ; 3) Establish Blank Mask, GV1
210: SET GV1=$J("",GVL),VP=$LENGTH(V1),(CP,SP)=1
211: ;
212: ; Rounding of Integer (NO DECIMAL PORTION)
213: SET:$PIECE(FM,"d",2)="" V1=$EXTRACT((V+.5)\1,1,$LENGTH(V1))
214: ; 4) Extract value for each position in the mask and set it
215: FOR L=GVL:-1:1 SET C=$EXTRACT(GVM,L) DO QUIT:EX
216: . SET GX=0
217: . DO %TRANSV1
218: . QUIT:GX!EX
219: . ;
220: . SET:GC'=" " $EXTRACT(GV1,L)=GC
221: . QUIT
222: SET:VP EX=1
223: QUIT
224: ;
225: %GETV2 ; Get the fractional portion of the value and lay it in GV2
226: NEW CP,SP
227: IF $GET(SR)'="" NEW SC SET SC=SR
228: SET GVM=$PIECE(FM,"d",2),GVL=$LENGTH(GVM),GL=0,SP=1
229: DO:GVL<$LENGTH(V2) ; Rounding of Decimal
230: . NEW J,N
231: . SET N=$EXTRACT($TRANSLATE($J("",GVL)," ",0)_5_$TRANSLATE($J("",$LENGTH(V2))," ",0),1,$LENGTH(V2))
232: . SET V2=$EXTRACT(V2+N,1,$LENGTH(V2))
233: . QUIT
234: SET GV2=$J("",GVL),VP=1,CP=1
235: FOR L=1:1:GVL SET C=$EXTRACT(GVM,L) DO QUIT:EX
236: . SET GX=0
237: . DO %TRANSV2
238: . QUIT:GX!EX
239: . ;
240: . SET:GC'=" " $EXTRACT(GV2,L)=GC
241: . QUIT
242: QUIT
243: ;
244: ; C - Current Mask Character from the FM
245: ; CP - Character Position
246: ; L - Position within
247: ; VP - Value Position
248: ; (integer - Right to Left, fraction - Left to Right)
249: %TRANSV1 ; Translate the value into the mask
250: SET (GC,GL)=" "
251: QUIT:"x "[C
252: ;
253: ; Value Completed, Apply Currency/Float/etc, if requested
254: IF 'VP DO
255: . IF "c"[C DO QUIT
256: . . SET:$GET(CP)="" CP=$LENGTH(CS)
257: . . SET GC=$EXTRACT(CS,CP),CP=CP-1
258: . . SET:CP<1 CP=$LENGTH(CS)
259: . . QUIT
260: . IF GVM["f" DO QUIT
261: . . NEW F,I,LI,LX,X,Q
262: . . SET X=" ",LI=L,LX=0
263: . . DO ; Identify the Value Represented
264: . . . IF GVM["+"!(GVM["-") DO QUIT
265: . . . . SET:GVM["+" X="+"
266: . . . . SET:V<0 X="-"
267: . . . . QUIT
268: . . . IF GVM["(" DO:V<0 QUIT
269: . . . . SET X=" ",LX=1
270: . . . . QUIT
271: . . . QUIT
272: . . FOR I=L:1:GVL SET Q=$EXTRACT(GV1,I) QUIT:Q?1N QUIT:("("_DC)[Q DO
273: . . . SET F=$EXTRACT(GVM,I),LI=I
274: . . . SET:"fs("[F $EXTRACT(GV1,I)=X
275: . . . QUIT
276: . . SET BYE=1
277: . . SET:LX $EXTRACT(GV1,LI)="("
278: . . QUIT
279: . QUIT
280: IF C="+" SET GC="+" SET:'SV GC="-" SET GL=GC QUIT
281: IF C="-" SET:'SV GC="-" SET GL=GC QUIT
282: IF C="(" SET:'SV GC="(" SET GL=GC QUIT
283: IF C=")" SET:'SV GC=")" SET GL=GC QUIT
284: DO:VP
285: . IF C="c" DO QUIT
286: . . SET:$GET(CP)="" CP=$LENGTH(CS)
287: . . SET GC=$EXTRACT(CS,CP),CP=CP-1
288: . . SET:CP<1 SP=$LENGTH(CS)
289: . . QUIT
290: . IF "fn+-"[C SET GC=$EXTRACT(V1,VP),VP=VP-1 QUIT
291: . IF C="s" DO QUIT
292: . . SET:$GET(SP)="" SP=$LENGTH(SC)
293: . . SET GC=$EXTRACT(SC,SP),SP=SP-1
294: . . SET:SP<1 SP=$LENGTH(SC)
295: . . QUIT
296: . QUIT
297: QUIT
298: ;
299: ; "c" - Currency
300: ; "f" - Floating
301: ; "n" - Numeric
302: ; "s" - Separator
303: ; "+-()" - Sign Representations
304: ;
305: %TRANSV2 ; Translate the value into the mask
306: SET GC=" "
307: QUIT:"x "[C
308: ;
309: DO:VP
310: . IF "f"[C DO QUIT
311: . . SET:$GET(CP)="" CP=1
312: . . SET GC=$EXTRACT(CS,CP),CP=CP+1
313: . . SET:CP>$LENGTH(CS) CP=1
314: . . QUIT
315: . IF C="n" DO QUIT
316: . . SET GC=$EXTRACT(V2,VP),VP=VP+1
317: . . SET:VP>$LENGTH(V2) VP=0
318: . . QUIT
319: . IF C="s" DO QUIT
320: . . SET GC=$EXTRACT(SC,SP),SP=SP+1
321: . . SET:SP<$LENGTH(SP) SP=1
322: . . QUIT
323: . QUIT
324: IF "c"[C DO QUIT
325: . SET:$GET(CP)="" CP=1
326: . SET GC=$EXTRACT(CS,CP)
327: . SET:CP>$LENGTH(CS) GC=" "
328: . SET CP=CP+1
329: . QUIT
330: IF C="+" SET GC="+" SET:'SV GC="-" SET GL=GC QUIT
331: IF C="-" SET:'SV GC="-" SET GL=GC QUIT
332: IF C="(" SET:'SV GC="(" SET GL=GC QUIT
333: IF C=")" SET:'SV GC=")" SET GL=GC QUIT
334: QUIT
335: ;
336: %ERREX ; Error Exit point
337: DO %ERROR
338: QUIT K
339: ;
340: ; EC - Error Coded String (1 character or longer)
341: ; EL - Error Code Length
342: ; FL - Field Length
343: ; K - Output String, The Error Message goes here.
344: %ERROR ; %ERROR HANDLING
345: NEW C,E,EL,L
346: SET:$GET(FL)<1 FL=$$%FLDLNG(0)
347: SET E=$GET(EC),K="",L=1
348: SET:E="" E="*"
349: SET EL=$LENGTH(E)
350: FOR I=1:1:FL SET C=$EXTRACT(E,L),L=L+1 SET:L>EL L=1 SET K=K_C
351: QUIT
352: ;
353: %LOADTV ; Do the translation of the temporary value with the string
354: NEW X
355: SET X=""
356: FOR M=1:2:$LENGTH(TV,"%%") DO
357: . SET X=X_$PIECE(TV,"%%",M)
358: . SET N=$PIECE(TV,"%%",M+1)
359: . SET:N X=X_ST(N)
360: . QUIT
361: SET TV=X
362: QUIT
363: ;
364: %FLDLNG(F) ; FIELD LENGTH Callable from Just About Anywhere
365: SET F=$GET(F)
366: QUIT:F F
367: ;
368: SET F=$LENGTH($GET(FO("FM")))
369: IF 'F DO
370: . SET F=$GET(FO("FL"))
371: . IF 'F DO
372: . . SET F=$LENGTH($GET(^$FORMAT("FM")))
373: . . IF 'F DO
374: . . . SET F=$GET(^$FORMAT("FL"))
375: . . . IF 'F DO
376: . . . . SET F=$LENGTH($GET(^$SYSTEM("FORMAT","FM")))
377: . . . . IF 'F SET F=$GET(^$SYSTEM("FORMAT","FL"))
378: . . . . QUIT
379: . . . QUIT
380: . . QUIT
381: . QUIT
382: SET:'F F=10
383: QUIT F
384: ;
385: ; Format Default Load
386: ;
387: %INFORM ; Load up the defaults
388: NEW K,X
389: SET K="",X="FORMAT"
390: IF '$DATA(^$FORMAT) DO QUIT:$DATA(^$SYSTEM(X))
391: . IF '$DATA(^$SYSTEM(X)) DO QUIT
392: . . SET ^$FORMAT("SC")=",",^$FORMAT("DC")="."
393: . . SET ^$FORMAT("CS")="$",^$FORMAT("EC")="*"
394: . . QUIT
395: . MERGE ^$FORMAT=^$SYSTEM("FORMAT")
396: . QUIT
397: ; IF ^SYSTEM DOES NOT EXIST, CREATE IT
398: DO:'$DATA(^$SYSTEM(X))
399: . MERGE ^$SYSTEM("FORMAT")=^$FORMAT
400: . QUIT
401: QUIT
402: ;
403: ;===
404: ;
405: ;
406: CRC16(string,seed) ;
407: ;
408: ; The code below was approved in document X11/1998-32
409: ;
410: ; Polynomial x**16 + x**15 + x**2 + x**0
411: NEW I,J,R
412: IF '$DATA(seed) SET R=0
413: ELSE IF seed'<0,seed'>65535 SET R=seed\1
414: ELSE SET $ECODE=",M28,"
415: FOR I=1:1:$LENGTH(string) DO
416: . SET R=$$%XOR($ASCII(string,I),R,8)
417: . FOR J=0:1:7 DO
418: . . IF R#2 SET R=$$%XOR(R\2,40961,16)
419: . . ELSE SET R=R\2
420: . . QUIT
421: . QUIT
422: QUIT R
423: %XOR(a,b,w) NEW I,M,R
424: SET R=b,M=1
425: FOR I=1:1:w DO
426: . SET:a\M#2 R=R+$SELECT(R\M#2:-M,1:M)
427: . SET M=M+M
428: . QUIT
429: QUIT R
430: ;===
431: ;
432: ;
433: CRC32(string,seed) ;
434: ;
435: ; The code below was approved in document X11/1998-32
436: ;
437: ; Polynomial X**32 + X**26 + X**23 + X**22 +
438: ; + X**16 + X**12 + X**11 + X**10 +
439: ; + X**8 + X**7 + X**5 + X**4 +
440: ; + X**2 + X + 1
441: NEW I,J,R
442: IF '$DATA(seed) SET R=4294967295
443: ELSE IF seed'<0,seed'>4294967295 SET R=seed\1
444: ELSE SET $ECODE=",M28,"
445: FOR I=1:1:$LENGTH(string) DO
446: . SET R=$$%XOR($ASCII(string,I),R,8)
447: . FOR J=0:1:7 DO
448: . . IF R#2 SET R=$$%XOR(R\2,3988292384,32)
449: . . ELSE SET R=R\2
450: . . QUIT
451: . QUIT
452: QUIT 4294967295-R
453: ; ===
454: ;
455: ;
456: CRCCCITT(string,seed) ;
457: ;
458: ; The code below was approved in document X11/1998-32
459: ;
460: ; Polynomial x**16 + x**12 + x**5 + x**0
461: NEW I,J,R
462: IF '$DATA(seed) SET R=65535
463: ELSE IF seed'<0,seed'>65535 SET R=seed\1
464: ELSE SET $ECODE=",M28,"
465: FOR I=1:1:$LENGTH(string) DO
466: . SET R=$$%XOR($ASCII(string,I)*256,R,16)
467: . FOR J=0:1:7 DO
468: . . SET R=R+R
469: . . QUIT:R<65536
470: . . SET R=$$%XOR(4129,R-65536,13)
471: . . QUIT
472: . QUIT
473: QUIT R
474: ; ===
475: ;
476: ;
477: LOWER(A,CHARMOD) NEW lo,up,x,y
478: ;
479: ; The code below was approved in document X11/1998-21
480: ;
481: SET x=$GET(CHARMOD)
482: SET lo="abcdefghijklmnopqrstuvwxyz"
483: SET up="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
484: QUIT $TRANSLATE(A,up,lo)
485: IF x?1"^"1E.E DO
486: . SET x=$EXTRACT(x,2,$LENGTH(x))
487: . IF x?1"|".E DO
488: . . SET x=$REVERSE($EXTRACT(x,2,$LENGTH(x)))
489: . . SET y=$REVERSE($PIECE(x,"|",2,$LENGTH(x)+2))
490: . . SET x=$REVERSE($PIECE(x,"|",1))
491: . . SET x=$GET(^|y|$GLOBAL(x,"CHARACTER"))
492: . . QUIT
493: . ELSE SET x=$GET(^$GLOBAL(x,"CHARACTER"))
494: . QUIT
495: IF x="" SET x=^$JOB($JOB,"CHARACTER")
496: SET x=$GET(^$CHARACTER(x,"LOWER"))
497: IF x="" QUIT $TRANSLATE(A,up,lo)
498: SET @("x="_x_"(A)")
499: QUIT x
500: ; ===
501: ;
502: ;
503: PATCODE(A,PAT,CHARMOD) NEW x,y
504: ;
505: ; The code below was approved in document X11/1998-21
506: ;
507: SET x=$GET(CHARMOD)
508: IF x?1"^"1E.E DO
509: . SET x=$EXTRACT(x,2,$LENGTH(x))
510: . IF x?1"|".E DO
511: . . SET x=$REVERSE($EXTRACT(x,2,$LENGTH(x)))
512: . . SET y=$REVERSE($PIECE(x,"|",2,$LENGTH(x)+2))
513: . . SET x=$REVERSE($PIECE(x,"|",1))
514: . . SET x=$GET(^|y|$GLOBAL(x,"CHARACTER"))
515: . . QUIT
516: . ELSE SET x=$GET(^$GLOBAL(x,"CHARACTER"))
517: . QUIT
518: IF x="" SET x=^$JOB($JOB,"CHARACTER")
519: SET x=$GET(^$CHARACTER(x,"PATCODE",PAT))
520: IF x="" QUIT 0
521: SET @("x="_x_"(A)")
522: QUIT x
523: ; ===
524: ;
525: ;
526: UPPER(A,CHARMOD) NEW lo,up,x,y
527: ;
528: ; The code below was approved in document X11/1998-21
529: ;
530: SET x=$GET(CHARMOD)
531: SET lo="abcdefghijklmnopqrstuvwxyz"
532: SET up="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
533: QUIT $TRANSLATE(A,lo,up)
534: IF x?1"^"1E.E DO
535: . SET x=$EXTRACT(x,2,$LENGTH(x))
536: . IF x?1"|".E DO
537: . . SET x=$REVERSE($EXTRACT(x,2,$LENGTH(x)))
538: . . SET y=$REVERSE($PIECE(x,"|",2,$LENGTH(x)+2))
539: . . SET x=$REVERSE($PIECE(x,"|",1))
540: . . SET x=$GET(^|y|$GLOBAL(x,"CHARACTER"))
541: . . QUIT
542: . ELSE SET x=$GET(^$GLOBAL(x,"CHARACTER"))
543: . QUIT
544: IF x="" SET x=^$JOB($JOB,"CHARACTER")
545: SET x=$GET(^$CHARACTER(x,"UPPER"))
546: IF x="" QUIT $TRANSLATE(A,lo,up)
547: SET @("x="_x_"(A)")
548: QUIT x
549: ; ===
550: ;
551: ;
552:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>