Develop and Download Open Source Software

Browse Subversion Repository

Contents of /format.pas

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations) (download) (as text)
Mon Nov 7 12:03:00 2011 UTC (12 years, 4 months ago) by shiraishikazuo
File MIME type: text/x-pascal
File size: 11661 byte(s)


1 unit format;
2 {$IFDEF FPC}
3 {$MODE DELPHI}{$H+}
4 {$ENDIF}
5
6 interface
7 uses arithmet;
8
9 type
10 NumericComponents =record
11 sign:char;
12 exp:integer;
13 digits:ansistring;
14 end;
15
16 function literals(const form:ansistring; var i:integer):ansistring;
17
18 function componentsN(const n:number):NumericComponents;
19
20 function formatNum(const n:NumericComponents;
21 form:ansistring; var i:integer;var code:integer):ansistring;
22
23 function formatStr(const s:AnsiString;
24 const form:ansistring; var i:integer;var code:integer):ansistring;
25
26 function formatEx(const x:extended;
27 const form:ansistring; var i:integer;var code:integer):ansistring;
28
29
30 function TestFormatString(const form:string):boolean;
31 procedure TestFormatItem(const form:string);
32
33 const
34 nonliteral:set of char=['#', '$', '%', '*', '+', '-', '.' , '<' , '>' , '^'];
35
36 implementation
37 uses
38 MyUtils, base;
39
40
41 function literals(const form:ansistring; var i:integer):ansistring;
42 var
43 i0:integer;
44 begin
45 i0:=i;
46 while (i<=length(form)) and not (form[i] in nonliteral) do
47 begin
48 //if IsDBCSLeadByte(byte(form[i])) then inc(i,2) else inc(i)
49 ReadMBC(i,form);
50 Inc(i);
51 end;
52 literals:=copy(form,i0,i-i0);
53
54 end;
55
56
57
58 function componentsN(const n:number):NumericComponents;
59 begin
60 with result do
61 begin
62 ConvertToString(n,Digits,exp);
63 if sgn(@n)>=0 then
64 sign:='+'
65 else
66 sign:='-';
67 end;
68 end;
69
70
71
72
73
74 function formatNum(const n:NumericComponents;
75 form:ansistring; var i:integer;var code:integer):ansistring;
76 var
77 exrad:ansistring;
78 intpart:ansistring;
79 DecimalPointPos:integer;
80 intplaces,MinIntPlaces,fractplaces:integer;
81 exradplaces:integer;
82 exp,p,j :integer;
83 i0,LengthOfFormatItem:integer;
84 FloatingCharacter1:string[1];
85 FloatingCharacter2:string[1];
86 DigitPlace:string[1];
87 sign :string[1];
88 comma:string[1];
89 UseComma:Boolean;
90 fformat,Eformat:boolean;
91 begin
92 result:='';
93 code:=0;
94
95 if (form='') or (i>Length(form)) then setexception(8202);
96
97 {evaluate the format-item}
98 i0:=i;
99
100 // ������������������������
101 if form[i] in ['<','>'] then
102 if (length(form)>i) and (form[i+1] in ['$','+','-','#','*','%']) then
103 form[i]:=form[i+1]
104 else
105 form[i]:='#';
106
107 //���������������������
108 FloatingCharacter1:='';
109 FloatingCharacter2:='';
110 if (form[i] in ['+','-','$']) then
111 begin
112 FloatingCharacter1:=form[i];
113 inc(i);
114 while form[i]=FloatingCharacter1 do inc(i);
115 if (FloatingCharacter1='$') and (form[i] in ['+','-'])
116 or (form[i]='$') then
117 begin
118 FloatingCharacter2:=form[i];
119 inc(i);
120 end;
121 end;
122 ;
123
124 //������������������ ���������������������
125 intplaces:=0;
126 MinIntPlaces:=0;
127 UseComma:=false;
128 DigitPlace:='';
129 if form[i] in ['#','%','*'] then DigitPlace:=form[i];
130 while form[i]=DigitPlace do
131 begin
132 inc(intplaces);
133 if DigitPlace[1] in ['%','*'] then inc(MinIntPlaces);
134 inc(i);
135 if form[i]=',' then begin inc(i); UseComma:=true end; //���������
136 end;
137
138 // ���������
139 Fformat:=false;
140 fractplaces:=0;
141 DecimalPointPos:=i;
142 if form[i]='.' then
143 begin
144 Fformat:=true;
145 inc(i);
146 while (i<=length(form)) and (form[i]='#') do
147 begin
148 inc(i);
149 inc(fractplaces)
150 end;
151 end;
152
153 // ���������
154 Eformat:=false;
155 exradplaces:=0;
156 while (form[i]='^') do
157 begin
158 Eformat:=true;
159 inc(exradplaces);
160 inc(i);
161 end;
162 LengthOfFormatItem:=i-i0;
163
164 //syntax check
165 {
166 if (form[i] =',')
167 or (Fformat and (intplaces=0) and (fractplaces=0))
168 or (exradplaces in [1,2]) then
169 setexception(8201) ;
170 }
171 if i=i0 then
172 setexception(8202) ;
173
174
175
176 {evaluate the number}
177 result:=n.digits;
178 exp:=n.exp;
179 sign:=n.sign;
180
181 {generate}
182
183 case Eformat of
184 false:
185 begin
186 roundstring(result,exp+fractplaces,exp);
187 if exp>=0 then
188 begin
189 intpart:=copy(result,1,exp);
190 result:=copy(result,exp+1,maxint);
191 while length(intpart)<exp do intpart:=intpart+'0';
192 end
193 else if result<>'' then
194 begin
195 intpart:='';
196 while exp<0 do
197 begin
198 result:='0'+result;
199 inc(exp)
200 end;
201 end
202 else
203 result:=StringOfChar('0',fractplaces) ;
204 end;
205 true: {E-format}
206 begin
207 roundstring(result,intplaces+fractplaces,exp) ;
208 if length(result)>0 then
209 exp:=exp-intplaces
210 else
211 exp:=0;
212 intpart:=copy(result,1,intplaces);
213 while length(intpart)<intplaces do intpart:=intpart+'0';
214 result:=copy(result,intplaces+1,fractplaces);
215 end;
216 end;
217
218 while length(result)<fractplaces do result:=result+'0';
219
220 if (intplaces>0) and (length(intpart)+length(result)=0) then intpart:='0';
221 if EFormat then while length(intpart)<intplaces do intpart:='0'+intpart;
222 if DigitPlace='%' then
223 while length(intpart)<MinIntPlaces do intpart:='0'+intpart;
224 if DigitPlace='*' then
225 while length(intpart)<MinIntPlaces do intpart:='*'+intpart;
226 if JISFormat then
227 while length(intpart)<IntPlaces do intpart:=' '+intpart;
228
229 //���������������
230 if UseComma then
231 begin
232 comma:=',';
233 j:=DecimalPointPos-1;
234 p:=length(intpart)+1;
235 while i0<j do
236 begin
237 if form[j]=',' then
238 begin
239 if (p=0) or not (intpart[p-1] in ['0'..'9']) then
240 begin
241 if form[j-1]='#' then comma:=' ';
242 if form[j-1]='*' then comma:='*';
243 end;
244 if (comma<>' ') or JISFormat then
245 insert(comma,intpart,p);
246 dec(j)
247 end;
248 dec(j);
249 if p>0 then dec(p);
250 end;
251 end;
252
253 {composite}
254 if Fformat then
255 result:=intpart+'.'+result
256 else
257 result:=intpart;
258
259 {exrad}
260 if Eformat then
261 begin
262 result:=result+'E';
263 if exp>=0 then
264 result:=result+'+'
265 else
266 begin result:=result+'-'; exp:=-exp end;
267 str(exp,exrad);
268 while length(exrad)<exradplaces-2 do exrad:='0'+exrad;
269 result:=result+exrad;
270 if length(exrad)>exradplaces-2 then code:=8204;
271 end;
272
273 {floating Character}
274 if (FloatingCharacter2='$') then result:='$'+result;
275 if (sign='-') or (FloatingCharacter2='+')
276 or (FloatingCharacter1='+') then result:=sign+result;
277 if (FloatingCharacter1='$') then result:='$'+result;
278
279 {leading spaces}
280 while length(result)<LengthOfFormatItem do result:=' '+result;
281
282 if (length(result)>LengthOfFormatItem) and (code=0) then code:=8203;
283
284 {error marks}
285 if (code<>0) then
286 begin
287 result:='';
288 while length(result)<LengthOfFormatItem do result:=result+'*';
289 end;
290
291 end;
292
293
294
295 function testItem(const form:string; var i:integer):boolean;
296 var
297 digitp:char;
298 iform,fform:boolean;
299 begin
300 result:=false;
301 iform:=false;
302 fform:=false;
303 if form[i] in ['<','>'] then //���������
304 begin
305 inc(i);
306 if (form[i] in ['<','>']) or not (form[i] in nonliteral) then
307 begin //���������������
308 result:=true;
309 exit;
310 end;
311 end;
312 if form[i] in ['+','-','$'] then //���������������
313 begin
314 digitp:=form[i];
315 while form[i]=digitp do inc(i);
316 if digitp='$' then
317 begin if form[i] in ['+','-'] then inc(i) end
318 else
319 if form[i]='$' then inc(i);
320 end;
321 digitp:=form[i]; // ���������������
322 if digitp in ['*','#','%'] then //������������������
323 begin
324 iform:=true;
325 while (form[i]=digitp) or
326 (form[i]=',') and (form[i+1]=digitp)
327 do inc(i);
328 end;
329 if form[i]='.' then //������������������
330 begin
331 inc(i);
332 if not iform and (form[i]<>'#') then exit;
333 fform:=true;
334 while form[i]='#' do inc(i);
335 end;
336 if (iform or fform) and (form[i]='^') then
337 begin
338 inc(i); if form[i]<>'^' then exit;
339 inc(i); if form[i]<>'^' then exit;
340 while form[i]='^' do inc(i); //������������������
341 end;
342 if form[i] in [',','^'] then exit; //������
343 result:=iform or fform;
344 end;
345
346
347
348 function formatStr(const s:AnsiString;
349 const form:ansistring; var i:integer;var code:integer):ansistring;
350 var
351 c:char;
352 i0:integer;
353 count:integer;
354 d:integer;
355 begin
356 result:='';
357 code:=0;
358 if (form='') or (i>Length(form)) then begin setexception(8202);exit end;
359 c:=form[i]; // ������������������
360 i0:=i;
361
362 TestItem(form,i) ;
363
364 count:=i-i0;
365 if i=i0 then
366 setexception(8202) ;
367
368 if length(s)>count then
369 begin
370 code:=8203;
371 while count>0 do begin result:=result+'*'; dec(count) end;
372 end
373 else if c='<' then
374 begin
375 result:=s;
376 while length(result)<count do result:=result+' '
377 end
378 else if c='>' then
379 begin
380 result:=s;
381 while length(result)<count do result:=' '+result
382 end
383 else
384 begin
385 result:=s;
386 d:=1;
387 while length(result)<count do
388 if d>0 then
389 begin result:=result+' ' ; d:=-d end
390 else
391 begin result:=' '+result ; d:=-d end;
392 end;
393 end;
394
395 function TestFormatString(const form:string):boolean;
396 var i,i0:integer;
397 begin
398 result:=false;
399 i:=1;
400 while (i<=length(form)) and not (form[i] in nonliteral) do
401 begin
402 //if IsDBCSLeadByte(byte(form[i])) then inc(i,2) else inc(i)
403 ReadMBC(i,form);
404 Inc(i);
405 end;
406 while i<=length(form) do
407 begin
408 i0:=i;
409 if not TestItem(form,i) then exit;
410 while (i<=length(form)) and not (form[i] in nonliteral) do
411 begin
412 //if IsDBCSLeadByte(byte(form[i])) then inc(i,2) else inc(i)
413 ReadMBC(i,form);
414 Inc(i);
415 end;
416 if i0=i then break;
417 end;
418 result:=(i>length(form))
419 end;
420
421 procedure TestFormatItem(const form:string);
422 var
423 i:integer;
424 begin
425 i:=1;
426 if not testItem(form, i) or (i<=length(form)) then
427 setexception(8201);
428 end;
429
430 function formatEx(const x:extended;
431 const form:ansistring; var i:integer;var code:integer):ansistring;
432 var
433 n:number;
434 begin
435 convert(x,n);
436 result:=formatnum(componentsN(n),form,i,code);
437 end;
438
439
440 end.

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26