COVERAGE SUMMARY
FILE SUMMARY
NameExecutedRoutines%ExecutedLines%Unexecuted
/home/matt/eu/rds/include/std/io.e152365.22%17125766.54%86
ROUTINE SUMMARY
RoutineExecutedLinesUnexecuted
writef()0310.00%31
get_dstring()0130.00%13
get_integer32()060.00%6
get_bytes()182378.26%5
writefln()050.00%5
get_integer16()040.00%4
process_lines()232785.19%4
put_integer16()040.00%4
put_integer32()040.00%4
byte_range()3650.00%3
flush()030.00%3
read_lines()212391.30%2
read_file()252696.15%1
write_file()252696.15%1
append_lines()99100.00%0
file_number()22100.00%0
file_position()22100.00%0
lock_file()22100.00%0
lock_type()22100.00%0
seek()22100.00%0
unlock_file()33100.00%0
where()22100.00%0
write_lines()1212100.00%0
LINE COVERAGE DETAIL
#Executed
1
-- (c) Copyright - See License.txt
2
--
3
--****
4
-- == I/O
5
--
6
-- <>
7
namespace io
8
9
include std/sort.e
10
include std/wildcard.e
11
include std/types.e
12
include std/machine.e
13
include std/text.e
14
include std/sequence.e
15
include std/error.e
16
17101
constant M_SEEK = 19,
18101
M_WHERE = 20,
19101
M_FLUSH = 60,
20101
M_LOCK_FILE = 61,
21101
M_UNLOCK_FILE = 62
22
23
--****
24
-- === Constants
25
26
--**
27
-- Standard Input
28
29101
public constant STDIN = 0
30
31
--**
32
-- Standard Output
33
34101
public constant STDOUT = 1
35
36
--**
37
-- Standard Error
38
39101
public constant STDERR = 2
40
41
--**
42
-- Screen (Standard Out)
43
44101
public constant SCREEN = 1
45
46
--**
47
-- End of file
48
49101
public constant EOF = (-1)
50
51
--****
52
-- === Read/Write Routines
53
54
--****
55
-- @[q_print|]
56
-- Signature:
57
-- procedure ? (no parentheses around the unique parameter)
58
--
59
-- Description:
60
-- Shorthand way of saying: ##pretty_print(STDOUT, x, {})## ~-- i.e. printing the value of an
61
-- expression to the standard output, with braces and indentation to show the structure.
62
--
63
-- Example 1:
64
--
65
-- ? {1, 2} + {3, 4} -- will display {4, 6}
66
--
67
--
68
-- See Also:
69
-- [[:print]]
70
71
--****
72
-- Signature:
73
-- procedure print(integer fn, object x)
74
--
75
-- Description:
76
-- Writes out a **text** representation of an object to a file or device.
77
-- If the object ##x## is a sequence, it uses braces **##{ , , , }##** to
78
-- show the structure.
79
--
80
-- Parameters:
81
-- # ##fn## : an integer, the handle to a file or device to output to
82
-- # ##x## : the object to print
83
--
84
-- Errors:
85
-- The target file or device must be open.
86
--
87
-- Comments:
88
-- This is not used to write to "binary" files as it only outputs text.
89
--
90
-- Example 1:
91
--
92
-- print(STDOUT, "ABC") -- output is: "{65,66,67}"
93
-- puts(STDOUT, "ABC") -- output is: "ABC"
94
-- print(STDOUT, 65) -- output is: "65"
95
-- puts(STDOUT, 65) -- output is: "A" (ASCII-65 ==> 'A')
96
-- puts(STDOUT, 65.1234) -- output is: "65.1234"
97
-- puts(STDOUT, 65.1234) -- output is: "A" (Converts to integer first)
98
--
99
--
100
-- Example 2:
101
--
102
-- print(STDOUT, repeat({10,20}, 3)) -- output is: {{10,20},{10,20},{10,20}}
103
--
104
--
105
-- See Also:
106
-- [[:q_print|?]], [[:puts]]
107
108
--****
109
-- Signature:
110
-- procedure printf(integer fn, sequence format, object values)
111
--
112
-- Description:
113
-- Print one or more values to a file or device, using a format string to embed them in and define how they should be represented.
114
--
115
-- Parameters:
116
-- # ##fn## : an integer, the handle to a file or device to output to
117
-- # ##format## : a sequence, the text to print. This text may contain format specifiers.
118
-- # ##values## : usually, a sequence of values. It should have as many elements as format specifiers in ##format##, as these values will be substituted to the specifiers.
119
--
120
-- Errors:
121
-- If there are less values to show than format specifiers, a run time error will occur.
122
--
123
-- The target file or device must be open.
124
--
125
-- Comments:
126
-- A format specifier is a string of characters starting with a percent sign ( ~%~ ) and ending
127
-- in a letter. Some extra information may come in the middle.
128
--
129
-- ##format## will be scanned for format specifiers. Whenever one is found, the current value
130
-- in ##values## will be turned into a string according to the format specifier. The resulting
131
-- string will be plugged in the result, as if replacing the modifier with the printed value.
132
-- Then moving on to next value and carrying the process on.
133
--
134
-- This way, ##printf##() always takes
135
-- exactly 3 arguments, no matter how many values are to be printed. Only the length of the last
136
-- argument, containing the values to be printed, will vary.
137
--
138
-- The basic format specifiers are...
139
--
140
-- * ##%d## ~-- print an atom as a decimal integer
141
-- * ##%x## ~-- print an atom as a hexadecimal integer. Negative numbers are printed
142
-- in two's complement, so -1 will print as FFFFFFFF
143
-- * ##%o## ~-- print an atom as an octal integer
144
-- * ##%s## ~-- print a sequence as a string of characters, or print an atom as a single
145
-- character
146
-- * ##%e## ~-- print an atom as a floating-point number with exponential notation
147
-- * ##%f## ~-- print an atom as a floating-point number with a decimal point but no exponent
148
-- * ##%g## ~-- print an atom as a floating-point number using whichever format seems
149
-- appropriate, given the magnitude of the number
150
-- * ##~%~%## ~-- print the '%' character itself. This is not an actual format specifier.
151
--
152
-- Field widths can be added to the basic formats, e.g. %5d, %8.2f, %10.4s. The number
153
-- before the decimal point is the minimum field width to be used. The number after
154
-- the decimal point is the precision to be used.
155
--
156
-- If the field width is negative, e.g. %-5d then the value will be left-justified
157
-- within the field. Normally it will be right-justified. If the field width
158
-- starts with a leading 0, e.g. %08d then leading zeros will be supplied to fill up
159
-- the field. If the field width starts with a '+' e.g. %+7d then a plus sign will
160
-- be printed for positive values.
161
--
162
-- Comments:
163
-- Watch out for the following common mistake:
164
--
165
--
166
-- name="John Smith"
167
-- printf(STDOUT, "%s", name) -- error!
168
--
169
--
170
-- This will print only the first character, J, of name, as each element of
171
-- name is taken to be a separate value to be formatted. You must say this instead:
172
--
173
--
174
-- name="John Smith"
175
-- printf(STDOUT, "%s", {name}) -- correct
176
--
177
--
178
-- Now, the third argument of ##printf##() is a one-element sequence containing the
179
-- item to be formatted.
180
--
181
-- If there is only one ##%## format specifier, and if the value it stands for is an atom, then ##values## may be simply that atom.
182
--
183
-- Example 1:
184
--
185
-- rate = 7.875
186
-- printf(my_file, "The interest rate is: %8.2f\n", rate)
187
--
188
-- -- The interest rate is: 7.88
189
--
190
--
191
-- Example 2:
192
--
193
-- name="John Smith"
194
-- score=97
195
-- printf(STDOUT, "%15s, %5d\n", {name, score})
196
--
197
-- -- John Smith, 97
198
--
199
--
200
-- Example 3:
201
--
202
-- printf(STDOUT, "%-10.4s $ %s", {"ABCDEFGHIJKLMNOP", "XXX"})
203
-- -- ABCD $ XXX
204
--
205
--
206
-- Example 4:
207
--
208
-- printf(STDOUT, "%d %e %f %g", 7.75) -- same value in different formats
209
--
210
-- -- 7 7.750000e+000 7.750000 7.75
211
--
212
--
213
-- See Also:
214
-- [[:sprintf]], [[:sprint]], [[:print]]
215
216
--****
217
-- Signature:
218
-- procedure puts(integer fn, object text)
219
--
220
-- Description:
221
-- Output, to a file or device, a single byte (atom) or sequence of bytes. The low order
222
-- 8-bits of each value is actually sent out. If outputting to the screen you will see text
223
-- characters displayed.
224
--
225
-- Parameters:
226
-- # ##fn## : an integer, the handle to an opened file or device
227
-- # ##text## : an object, either a single character or a sequence of characters.
228
--
229
-- Errors:
230
-- The target file or device must be open.
231
--
232
-- Comments:
233
-- When you output a sequence of bytes it must not have any (sub)sequences within it. It
234
-- must be a sequence of atoms only. (Typically a string of ASCII codes).
235
--
236
-- Avoid outputting 0's to the screen or to standard output. Your output might get truncated.
237
--
238
-- Remember that if the output file was opened in text mode, //Windows// will change ##\n## (10)
239
-- to ##\r\n## (13 10). Open the file in binary mode if this is not what you want.
240
--
241
-- Example 1:
242
--
243
-- puts(SCREEN, "Enter your first name: ")
244
--
245
--
246
-- Example 2:
247
--
248
-- puts(output, 'A') -- the single byte 65 will be sent to output
249
--
250
--
251
-- See Also:
252
-- [[:print]]
253
254
--****
255
-- Signature:
256
-- function getc(integer fn)
257
--
258
-- Description:
259
-- Get the next character (byte) from a file or device fn.
260
--
261
-- Parameters:
262
-- # ##fn## : an integer, the handle of the file or device to read from.
263
--
264
-- Returns:
265
-- An **integer**, the character read from the file, in the 0..255 range. If no character is left to read, [[:EOF]] is returned instead.
266
--
267
-- Errors:
268
-- The target file or device must be open.
269
--
270
-- Comments:
271
-- File input using ##getc##() is buffered, i.e. ##getc##() does not actually go out to the disk
272
-- for each character. Instead, a large block of characters will be read in at one time
273
-- and returned to you one by one from a memory buffer.
274
--
275
-- When ##getc##() reads from the keyboard, it will not see any characters until the user
276
-- presses Enter. Note that the user can type CTRL+Z, which the operating system treats
277
-- as "end of file". [[:EOF]] will be returned.
278
--
279
-- See Also:
280
-- [[:gets]], [[:get_key]]
281
282
--****
283
-- Signature:
284
-- function gets(integer fn)
285
--
286
-- Description:
287
-- Get the next sequence (one line, including '\n') of characters from a file or device.
288
-- Parameters:
289
-- # ##fn## : an integer, the handle of the file or device to read from.
290
--
291
-- Returns:
292
-- An **object**, either [[:EOF]] on end of file, or the next line of text from the file.
293
--
294
-- Errors:
295
-- The file or device must be open.
296
--
297
-- Comments:
298
-- The characters will have values from 0 to 255.
299
--
300
-- If the line had an end of line marker, a ~'\n'~ terminates the line. The last line of a file needs not have an end of line marker.
301
--
302
-- After reading a line of text from the keyboard, you should normally output a \n character,
303
-- e.g. puts(1, '\n'), before printing something. Only on the last line of the screen does the
304
-- operating system automatically scroll the screen and advance to the next line.
305
--
306
-- When your program reads from the keyboard, the user can type control-Z, which the operating
307
-- system treats as "end of file". [[:EOF]] will be returned.
308
--
309
-- Example 1:
310
--
311
-- sequence buffer
312
-- object line
313
-- integer fn
314
--
315
-- -- read a text file into a sequence
316
-- fn = open("my_file.txt", "r")
317
-- if fn = -1 then
318
-- puts(1, "Couldn't open my_file.txt\n")
319
-- abort(1)
320
-- end if
321
--
322
-- buffer = {}
323
-- while 1 do
324
-- line = gets(fn)
325
-- if atom(line) then
326
-- exit -- EOF is returned at end of file
327
-- end if
328
-- buffer = append(buffer, line)
329
-- end while
330
--
331
--
332
-- Example 2:
333
--
334
-- object line
335
--
336
-- puts(1, "What is your name?\n")
337
-- line = gets(0) -- read standard input (keyboard)
338
-- line = line[1..$-1] -- get rid of \n character at end
339
-- puts(1, '\n') -- necessary
340
-- puts(1, line & " is a nice name.\n")
341
--
342
--
343
-- See Also:
344
-- [[:getc]], [[:read_lines]]
345
346
--****
347
-- Signature:
348
-- function get_key()
349
--
350
-- Description:
351
-- Get the next keystroke without waiting for it or echoing it on the console.
352
--
353
-- Parameters:
354
-- # None.
355
--
356
-- Returns:
357
-- An **integer**, the code number for the key pressed. If there is no key
358
-- press waiting, then this returns -1.
359
--
360
-- See Also:
361
-- [[:gets]], [[:getc]]
362
363101
constant CHUNK = 100
364
365
--**
366
-- Read the next bytes from a file.
367
--
368
-- Parameters:
369
-- # ##fn## : an integer, the handle to an open file to read from.
370
-- # ##n## : a positive integer, the number of bytes to read.
371
--
372
-- Returns:
373
-- A **sequence**, of length at most ##n##, made of the bytes that could be read from the file.
374
--
375
-- Comments:
376
-- When ##n## > 0 and the function returns a sequence of length less than ##n## you know
377
-- you've reached the end of file. Eventually, an
378
-- empty sequence will be returned.
379
--
380
-- This function is normally used with files opened in binary mode, "rb".
381
-- This avoids the confusing situation in text mode where //Windows// will convert CR LF
382
-- pairs to LF.
383
--
384
-- Example 1:
385
--
386
--
387
-- integer fn
388
-- fn = open("temp", "rb") -- an existing file
389
--
390
-- sequence whole_file
391
-- whole_file = {}
392
--
393
-- sequence chunk
394
--
395
-- while 1 do
396
-- chunk = get_bytes(fn, 100) -- read 100 bytes at a time
397
-- whole_file &= chunk -- chunk might be empty, that's ok
398
-- if length(chunk) < 100 then
399
-- exit
400
-- end if
401
-- end while
402
--
403
-- close(fn)
404
-- ? length(whole_file) -- should match DIR size of "temp"
405
--
406
--
407
-- See Also:
408
-- [[:getc]], [[:gets]], [[:get_integer32]], [[:get_dstring]]
409
410138
411
sequence s
412
integer c, first, last
413
414138
if n = 0 then
41552
return {}
416
end if
417
41886
c = getc(fn)
41986
if c = EOF then
4200
return {}
421
end if
422
42386
s = repeat(c, n)
424
42586
last = 1
42686
while last < n do
427
-- for speed, read a chunk without checking for EOF
428110
first = last+1
429110
last = last+CHUNK
430110
if last > n then
43186
last = n
432
end if
433110
for i = first to last do
4345710
s[i] = getc(fn)
4355710
end for
436
-- check for EOF after each chunk
437110
if s[last] = EOF then
438
-- trim the EOF's and return
4390
while s[last] = EOF do
4400
last -= 1
4410
end while
4420
return s[1..last]
443
end if
444110
end while
44586
return s
446
end function
447
448
449
atom mem0, mem1, mem2, mem3
450101
mem0 = allocate(4)
451101
mem1 = mem0 + 1
452101
mem2 = mem0 + 2
453101
mem3 = mem0 + 3
454
455
--**
456
-- Read the next four bytes from a file and returns them as a single integer.
457
--
458
-- Parameters:
459
-- # ##fh## : an integer, the handle to an open file to read from.
460
--
461
-- Returns:
462
-- An **atom**, made of the bytes that could be read from the file.
463
--
464
-- Comments:
465
-- * This function is normally used with files opened in binary mode, "rb".
466
-- * Assumes that there at least four bytes available to be read.
467
--
468
-- Example 1:
469
--
470
--
471
-- integer fn
472
-- fn = open("temp", "rb") -- an existing file
473
--
474
-- atom file_type_code
475
-- file_type_code = get_integer32(fn)
476
--
477
--
478
-- See Also:
479
-- [[:getc]], [[:gets]], [[:get_bytes]], [[:get_dstring]]
480
4810
482
-- read the 4 bytes as a single integer value at current position in file
4830
poke(mem0, getc(fh))
4840
poke(mem1, getc(fh))
4850
poke(mem2, getc(fh))
4860
poke(mem3, getc(fh))
4870
return peek4u(mem0)
488
end function
489
490
--**
491
-- Read the next two bytes from a file and returns them as a single integer.
492
--
493
-- Parameters:
494
-- # ##fh## : an integer, the handle to an open file to read from.
495
--
496
-- Returns:
497
-- An **atom**, made of the bytes that could be read from the file.
498
--
499
-- Comments:
500
-- * This function is normally used with files opened in binary mode, "rb".
501
-- * Assumes that there at least two bytes available to be read.
502
--
503
-- Example 1:
504
--
505
--
506
-- integer fn
507
-- fn = open("temp", "rb") -- an existing file
508
--
509
-- atom file_type_code
510
-- file_type_code = get_integer16(fn)
511
--
512
--
513
-- See Also:
514
-- [[:getc]], [[:gets]], [[:get_bytes]], [[:get_dstring]]
515
5160
517
-- read the 4 bytes as a single integer value at current position in file
5180
poke(mem0, getc(fh))
5190
poke(mem1, getc(fh))
5200
return peek2u(mem0)
521
end function
522
523
--**
524
-- Write the supplied integer as four bytes to a file.
525
--
526
-- Parameters:
527
-- # ##fh## : an integer, the handle to an open file to write to.
528
-- # ##val## : an integer
529
--
530
-- Comments:
531
-- * This function is normally used with files opened in binary mode, "wb".
532
--
533
-- Example 1:
534
--
535
--
536
-- integer fn
537
-- fn = open("temp", "wb")
538
--
539
-- put_integer32(fn, 1234)
540
--
541
--
542
-- See Also:
543
-- [[:getc]], [[:gets]], [[:get_bytes]], [[:get_dstring]]
544
5450
5460
poke4(mem0, val)
5470
puts(fh, peek({mem0,4}))
5480
end procedure
549
550
--**
551
-- Write the supplied integer as two bytes to a file.
552
--
553
-- Parameters:
554
-- # ##fh## : an integer, the handle to an open file to write to.
555
-- # ##val## : an integer
556
--
557
-- Comments:
558
-- * This function is normally used with files opened in binary mode, "wb".
559
--
560
-- Example 1:
561
--
562
--
563
-- integer fn
564
-- fn = open("temp", "wb")
565
--
566
-- put_integer16(fn, 1234)
567
--
568
--
569
-- See Also:
570
-- [[:getc]], [[:gets]], [[:get_bytes]], [[:get_dstring]]
571
5720
5730
poke2(mem0, val)
5740
puts(fh, peek({mem0,2}))
5750
end procedure
576
577
--**
578
-- Read a delimited byte string from an opened file .
579
--
580
-- Parameters:
581
-- # ##fh## : an integer, the handle to an open file to read from.
582
-- # ##delim## : an integer, the delimiter that marks the end of a byte string.
583
-- If omitted, a zero is assumed.
584
--
585
-- Returns:
586
-- An **sequence**, made of the bytes that could be read from the file.
587
--
588
-- Comments:
589
-- * If the end-of-file is found before the delimiter, the delimiter is appended
590
-- to the returned string.
591
--
592
-- Example 1:
593
--
594
--
595
-- integer fn
596
-- fn = open("temp", "rb") -- an existing file
597
--
598
-- sequence text
599
-- text = get_dstring(fn) -- Get a zero-delimited string
600
-- text = get_dstring(fn, '$') -- Get a '$'-delimited string
601
--
602
--
603
-- See Also:
604
-- [[:getc]], [[:gets]], [[:get_bytes]], [[:get_integer32]]
605
6060
607
sequence s
608
integer c
609
integer i
610
6110
s = repeat(-1, 256)
6120
i = 0
6130
while c != delim with entry do
6140
i += 1
6150
if i > length(s) then
6160
s &= repeat(-1, 256)
617
end if
618
6190
if c = -1 then
6200
exit
621
end if
6220
s[i] = c
623
entry
6240
c = getc(fh)
6250
end while
626
6270
return s[1..i]
628
end function
629
630
--****
631
-- === Low Level File/Device Handling
632
633
--
634
-- Described under lock_file()
635
--
636
637101
public enum LOCK_SHARED, LOCK_EXCLUSIVE
638
639
--**
640
-- File number type
641
64223492
64323492
return f >= 0
644
end type
645
646
--**
647
-- File position type
648
64921501
65021501
return p >= -1
651
end type
652
653
654
--**
655
-- Lock Type
656
6575
6585
return t = LOCK_SHARED or t = LOCK_EXCLUSIVE
659
end type
660
661
--**
662
-- Byte Range Type
663
6644
6654
if length(r) = 0 then
6664
return 1
6670
elsif length(r) = 2 and r[1] <= r[2] then
6680
return 1
669
else
6700
return 0
671
end if
672
end type
673
674
--****
675
-- Signature:
676
-- function open(sequence path, sequence mode, integer cleanup = 0)
677
--
678
-- Description:
679
-- Open a file or device, to get the file number.
680
--
681
-- Parameters:
682
-- # ##path## : a string, the path to the file or device to open.
683
-- # ##mode## : a string, the mode being used o open the file.
684
-- # ##cleanup## : an integer, if 0, then the file must be manually closed by the
685
--coder. If 1, then the file will be closed when either the file handle's references
686
--goes to 0, or if called as a parameter to ##delete##().
687
--
688
-- Returns:
689
-- A small **integer**, -1 on failure, else 0 or more.
690
--
691
-- Errors:
692
-- There is a limit on the number of files that can be simultaneously opened, currently 40.
693
-- If this limit is reached, the next attempt to ##open##() a file will error out.
694
--
695
-- The length of ##path## should not exceed 1,024 characters.
696
--
697
-- Comments:
698
-- Possible modes are:
699
--
700
-- * ##"r"## ~-- open text file for reading
701
-- * ##"rb"## ~-- open binary file for reading
702
-- * ##"w"## ~-- create text file for writing
703
-- * ##"wb"## ~-- create binary file for writing
704
-- * ##"u"## ~-- open text file for update (reading and writing)
705
-- * ##"ub"## ~-- open binary file for update
706
-- * ##"a"## ~-- open text file for appending
707
-- * ##"ab"## ~-- open binary file for appending
708
--
709
-- Files opened for read or update must already exist. Files opened for write or append will
710
-- be created if necessary. A file opened for write will be set to 0 bytes. Output to a
711
-- file opened for append will start at the end of file.
712
--
713
-- On //Windows//, output to text files will have carriage-return characters automatically
714
-- added before linefeed characters. On input, these carriage-return characters are removed.
715
-- A control-Z character (ASCII 26) will signal an immediate end of file.
716
--
717
-- I/O to binary files is not modified in any way. Any byte values from 0 to 255 can be
718
-- read or written. On //Unix//, all files are binary files, so "r" mode and "rb"
719
-- mode are equivalent, as are "w" and "wb", "u" and "ub", and "a" and "ab".
720
--
721
-- Some typical devices that you can open on Windows are:
722
--
723
-- * ##"CON"## ~-- the console (screen)
724
-- * ##"AUX"## ~-- the serial auxiliary port
725
-- * ##"COM1"## ~-- serial port 1
726
-- * ##"COM2"## ~-- serial port 2
727
-- * ##"PRN"## ~-- the printer on the parallel port
728
-- * ##"NUL"## ~-- a non-existent device that accepts and discards output
729
--
730
-- Close a file or device when done with it, flushing out any still-buffered characters prior.
731
--
732
-- //WIN32// and //Unix//: Long filenames are fully supported for reading and writing and
733
-- creating.
734
--
735
-- //WIN32//: Be careful not to use the special device names in a file name, even if you add an
736
-- extension. e.g. ##CON.TXT##, ##CON.DAT##, ##CON.JPG## etc. all refer to the ##CON## device,
737
-- **not a file**.
738
--
739
-- Example 1:
740
--
741
-- integer file_num, file_num95
742
-- sequence first_line
743
-- constant ERROR = 2
744
--
745
-- file_num = open("my_file", "r")
746
-- if file_num = -1 then
747
-- puts(ERROR, "couldn't open my_file\n")
748
-- else
749
-- first_line = gets(file_num)
750
-- end if
751
--
752
-- file_num = open("PRN", "w") -- open printer for output
753
--
754
-- -- on Windows 95:
755
-- file_num95 = open("big_directory_name\\very_long_file_name.abcdefg",
756
-- "r")
757
-- if file_num95 != -1 then
758
-- puts(STDOUT, "it worked!\n")
759
-- end if
760
--
761
762
--****
763
-- Signature:
764
-- procedure close(atom fn)
765
--
766
-- Description:
767
-- Close a file or device and flush out any still-buffered characters.
768
--
769
-- Parameters:
770
-- # ##fn## : an integer, the handle to the file or device to query.
771
--
772
-- Errors:
773
-- The target file or device must be open.
774
--
775
-- Comments:
776
-- Any still-open files will be closed automatically when your program terminates.
777
778
--**
779
-- Seek (move) to any byte position in a file.
780
--
781
-- Parameters:
782
-- # ##fn## : an integer, the handle to the file or device to seek()
783
-- # ##pos## : an atom, either an absolute 0-based position or -1 to seek to end of file.
784
--
785
-- Returns:
786
-- An **integer**, 0 on success, 1 on failure.
787
--
788
-- Errors:
789
-- The target file or device must be open.
790
--
791
-- Comments:
792
-- For each open file, there is a current byte position that is updated as a result of I/O
793
-- operations on the file. The initial file position is 0 for files opened for read, write
794
-- or update. The initial position is the end of file for files opened for append.
795
-- It is possible to seek past the end of a file. If you seek past the end of the file, and
796
-- write some data, undefined bytes will be inserted into the gap between the original end
797
-- of file and your new data.
798
--
799
-- After seeking and reading (writing) a series of bytes, you may need to call seek()
800
-- explicitly before you switch to writing (reading) bytes, even though the file position
801
-- should already be what you want.
802
--
803
-- This function is normally used with files opened in binary mode. In text mode, Windows
804
-- converts CR LF to LF on input, and LF to CR LF on output, which can cause great confusion
805
-- when you are trying to count bytes because seek() counts the Windows end of line sequences
806
-- as two bytes, even if the file has been opened in text mode.
807
--
808
-- Example 1:
809
--
810
-- include std/io.e
811
--
812
-- integer fn
813
-- fn = open("my.data", "rb")
814
-- -- read and display first line of file 3 times:
815
-- for i = 1 to 3 do
816
-- puts(STDOUT, gets(fn))
817
-- if seek(fn, 0) then
818
-- puts(STDOUT, "rewind failed!\n")
819
-- end if
820
-- end for
821
--
822
--
823
-- See Also:
824
-- [[:get_bytes]], [[:puts]], [[:where]]
825
82621496
82721496
return machine_func(M_SEEK, {fn, pos})
828
end function
829
830
--**
831
-- Retrieves the current file position for an opened file or device.
832
--
833
-- Parameters:
834
-- # ##fn## : an integer, the handle to the file or device to query.
835
--
836
--
837
-- Returns:
838
-- An **atom**, the current byte position in the file.
839
--
840
-- Errors:
841
-- The target file or device must be open.
842
--
843
--
844
-- Comments:
845
-- The file position is is the place in the file where the next byte will be read from, or
846
-- written to. It is updated by reads, writes and seeks on the file. This procedure always
847
-- counts Windows end of line sequences (CR LF) as two bytes even when the file number has
848
-- been opened in text mode.
849
--
850
8511989
8521989
return machine_func(M_WHERE, fn)
853
end function
854
855
--**
856
-- Force writing any buffered data to an open file or device.
857
--
858
-- Parameters:
859
-- # ##fn## : an integer, the handle to the file or device to close.
860
--
861
-- Errors:
862
-- The target file or device must be open.
863
--
864
-- Comments:
865
-- When you write data to a file, Euphoria normally stores the data
866
-- in a memory buffer until a large enough chunk of data has accumulated.
867
-- This large chunk can then be written to disk very efficiently.
868
-- Sometimes you may want to force, or flush, all data out immediately,
869
-- even if the memory buffer is not full. To do this you must call flush(fn),
870
-- where fn is the file number of a file open for writing or appending.
871
--
872
-- When a file is closed, (see close()), all buffered data is flushed out.
873
-- When a program terminates, all open files are flushed and closed
874
-- automatically. Use flush() when another process may need to
875
-- see all of the data written so far, but you are not ready
876
-- to close the file yet. flush() is also used in crash routines, where files may not be closed in the cleanest possible way.
877
--
878
-- Example 1:
879
--
880
-- f = open("file.log", "w")
881
-- puts(f, "Record#1\n")
882
-- puts(STDOUT, "Press Enter when ready\n")
883
--
884
-- flush(f) -- This forces "Record #1" into "file.log" on disk.
885
-- -- Without this, "file.log" will appear to have
886
-- -- 0 characters when we stop for keyboard input.
887
--
888
-- s = gets(0) -- wait for keyboard input
889
--
890
--
891
-- See Also:
892
-- [[:close]], [[:crash_routine]]
893
8940
8950
machine_proc(M_FLUSH, fn)
8960
end procedure
897
898
--**
899
-- When multiple processes can simultaneously access a
900
-- file, some kind of locking mechanism may be needed to avoid mangling
901
-- the contents of the file, or causing erroneous data to be read from the file.
902
--
903
-- Parameters:
904
-- # ##fn## : an integer, the handle to the file or device to (partially) lock.
905
-- # ##t## : an integer which defines the kind of lock to apply.
906
-- # ##r## : a sequence, defining a section of the file to be locked, or {} for the whole file (the default).
907
--
908
-- Returns:
909
-- An **integer**, 0 on failure, 1 on success.
910
--
911
-- Errors:
912
-- The target file or device must be open.
913
--
914
-- Comments:
915
-- ##lock_file##() attempts to place a lock on an open file, ##fn##, to stop
916
-- other processes from using the file while your program is reading it
917
-- or writing it.
918
--
919
-- Under //Unix//, there are two types of locks that
920
-- you can request using the ##t## parameter. (Under //WIN32// the
921
-- parameter ##t## is ignored, but should be an integer.)
922
-- Ask for a **shared** lock when you intend to read a file, and you want to
923
-- temporarily block other processes from writing it. Ask for an
924
-- **exclusive** lock when you intend to write to a file and you want to temporarily
925
-- block other processes from reading or writing it. It's ok for many processes to
926
-- simultaneously have shared locks on the same file, but only one process
927
-- can have an exclusive lock, and that can happen only when no other
928
-- process has any kind of lock on the file. io.e contains the following declarations:
929
--
930
--
931
-- public enum
932
-- LOCK_SHARED,
933
-- LOCK_EXCLUSIVE
934
--
935
--
936
-- On ///WIN32// you can lock a specified portion of a file using the ##r## parameter.
937
-- ##r## is a sequence of the form: ##{first_byte, last_byte}##. It indicates the first byte and
938
-- last byte in the file, that the lock applies to. Specify the empty sequence ##{}##,
939
-- if you want to lock the whole file, or don't specify it at all, as this is the default. In the current release for //Unix//, locks
940
-- always apply to the whole file, and you should use this default value.
941
--
942
-- ##lock_file##() does not wait
943
-- for other processes to relinquish their locks. You may have to call it repeatedly,
944
-- before the lock request is granted.
945
--
946
-- On //Unix//, these locks are called advisory locks, which means they aren't enforced
947
-- by the operating system. It is up to the processes that use a particular file to cooperate
948
-- with each other. A process can access a file without first obtaining a lock on it. On
949
-- //WIN32// locks are enforced by the operating system.
950
--
951
-- Example 1:
952
--
953
-- include std/io.e
954
-- integer v
955
-- atom t
956
-- v = open("visitor_log", "a") -- open for append
957
-- t = time()
958
-- while not lock_file(v, LOCK_EXCLUSIVE, {}) do
959
-- if time() > t + 60 then
960
-- puts(STDOUT, "One minute already ... I can't wait forever!\n")
961
-- abort(1)
962
-- end if
963
-- sleep(5) -- let other processes run
964
-- end while
965
-- puts(v, "Yet another visitor\n")
966
-- unlock_file(v, {})
967
-- close(v)
968
--
969
--
970
-- See Also:
971
-- [[:unlock_file]]
972
9732
9742
return machine_func(M_LOCK_FILE, {fn, t, r})
975
end function
976
977
--**
978
-- Unlock (a portion of) an open file.
979
--
980
-- Parameters:
981
-- # ##fn## : an integer, the handle to the file or device to (partially) lock.
982
-- # ##r## : a sequence, defining a section of the file to be locked, or {} for the whole file (the default).
983
--
984
-- Errors:
985
-- The target file or device must be open.
986
--
987
-- Comments:
988
-- You must have previously locked the
989
-- file using ##lock_file##(). On //WIN32// you can unlock a range of bytes within a
990
-- file by specifying the ##r## as {first_byte, last_byte}. The same range of bytes
991
-- must have been locked by a previous call to [[:lock_file]](). On //Unix// you can
992
-- currently only lock or unlock an entire file. ##r## should be {} when you
993
-- want to unlock an entire file. On //Unix//, ##r## must always be {}, which is the default.
994
--
995
-- You should unlock a file as soon as possible so other processes can use it.
996
--
997
-- Any files that you have locked, will automatically be unlocked when your program
998
-- terminates.
999
--
1000
-- See Also:
1001
-- [[:lock_file]]
1002
10032
1004
-- The byte range can be {} if you want to unlock the whole file.
10052
machine_proc(M_UNLOCK_FILE, {fn, r})
10062
end procedure
1007
1008
--****
1009
-- === File Reading/Writing
1010
1011
--**
1012
-- Read the contents of a file as a sequence of lines.
1013
--
1014
-- Parameters:
1015
-- ##file## : an object, either a file path or the handle to an open file.
1016
-- If this is an empty string, STDIN (the console) is used.
1017
--
1018
-- Returns:
1019
-- A **sequence**, made of lines from the file, as [[:gets]] could read them.
1020
--
1021
-- Comments:
1022
-- If ##file## was a sequence, the file will be closed on completion. Otherwise, it will remain open, but at end of file.
1023
--
1024
-- Example 1:
1025
--
1026
-- data = read_lines("my_file.txt")
1027
-- -- data contains the entire contents of ##my_file.txt##, 1 sequence per line:
1028
-- -- {"Line 1", "Line 2", "Line 3"}
1029
--
1030
--
1031
-- Example 2:
1032
--
1033
-- fh = open("my_file.txt", "r")
1034
-- data = read_lines(fh)
1035
-- close(fh)
1036
--
1037
-- -- data contains the entire contents of ##my_file.txt##, 1 sequence per line:
1038
-- -- {"Line 1", "Line 2", "Line 3"}
1039
--
1040
--
1041
-- See Also:
1042
-- [[:gets]], [[:write_lines]], [[:read_file]]
1043
104411
1045
object fn, ret, y
104611
if sequence(file) then
104710
if length(file) = 0 then
10480
fn = 0
1049
else
105010
fn = open(file, "r")
1051
end if
1052
else
10531
fn = file
1054
end if
105511
if fn < 0 then return -1 end if
1056
10579
ret = {}
10589
while sequence(y) with entry do
105961
if y[$] = '\n' then
106061
y = y[1..$-1]
106161
ifdef UNIX then
106261
if length(y) then
106354
if y[$] = '\r' then
106430
y = y[1..$-1]
1065
end if
1066
end if
1067
end ifdef
1068
end if
106961
ret = append(ret, y)
107061
if fn = 0 then
10710
puts(2, '\n')
1072
end if
1073
entry
107470
y = gets(fn)
107570
end while
1076
10779
if sequence(file) and length(file) != 0 then
10788
close(fn)
1079
end if
1080
10819
return ret
1082
end function
1083
1084
--**
1085
-- Process the contents of a file, one line at a time.
1086
--
1087
-- Parameters:
1088
-- # ##file## : an object. Either a file path or the handle to an open file. An
1089
-- empty string signifies STDIN - the console keyboard.
1090
-- # ##proc## : an integer. The routine_id of a function that will process the line.
1091
-- # ##user_data## : on object. This is passed untouched to ##proc## for each line.
1092
--
1093
-- Returns:
1094
-- An object. If 0 then all the file was processed successfully. Anything else
1095
-- means that something went wrong and this is whatever value was returned by ##proc##.
1096
--
1097
-- Comments:
1098
-- * The function ##proc## must accept three parameters ...
1099
-- ** A sequence: The line to process. It will **not** contain an end-of-line character.
1100
-- ** An integer: The line number.
1101
-- ** An object : This is the ##user_data## that was passed to ##process_lines##.
1102
-- * If ##file## was a sequence, the file will be closed on completion.
1103
-- Otherwise, it will remain open, and be positioned where ever reading stopped.
1104
--
1105
-- Example:
1106
--
1107
-- -- Format each supplied line according to the format pattern supplied as well.
1108
-- function show(sequence aLine, integer line_no, object data)
1109
-- writefln( data[1], {line_no, aLine})
1110
-- if data[2] > 0 and line_no = data[2] then
1111
-- return 1
1112
-- else
1113
-- return 0
1114
-- end if
1115
-- end function
1116
-- -- Show the first 20 lines.
1117
-- process_lines("sample.txt", routine_id("show"), {"[1z:4] : [2]", 20})
1118
--
1119
--
1120
-- See Also:
1121
-- [[:gets]], [[:read_lines]], [[:read_file]]
1122
11231
1124
integer fh
1125
object aLine
1126
object res
11271
integer line_no = 0
1128
11291
res = 0
11301
if sequence(file) then
11311
if length(file) = 0 then
11320
fh = 0
1133
else
11341
fh = open(file, "r")
1135
end if
1136
else
11370
fh = file
1138
end if
11391
if fh < 0 then
11400
return -1
1141
end if
1142
11431
while sequence(aLine) with entry do
11449
line_no += 1
11459
if length(aLine) then
11469
if aLine[$] = '\n' then
11479
aLine = aLine[1 .. $-1]
11489
ifdef UNIX then
11499
if length(aLine) then
11509
if aLine[$] = '\r' then
11519
aLine = aLine[1 .. $-1]
1152
end if
1153
end if
1154
end ifdef
1155
end if
1156
end if
11579
res = call_func(proc, {aLine, line_no, user_data})
11589
if not equal(res, 0) then
11590
exit
1160
end if
1161
1162
entry
116310
aLine = gets(fh)
116410
end while
1165
11661
if sequence(file) and length(file) != 0 then
11671
close(fh)
1168
end if
1169
11701
return res
1171
end function
1172
1173
--**
1174
-- Write a sequence of lines to a file.
1175
--
1176
-- Parameters:
1177
-- # ##file## : an object, either a file path or the handle to an open file.
1178
-- # ##lines## : the sequence of lines to write
1179
--
1180
-- Returns:
1181
-- An **integer**, 1 on success, -1 on failure.
1182
--
1183
-- Errors:
1184
-- If [[:puts]]() cannot write some line of text, a runtime error will occur.
1185
--
1186
-- Comments:
1187
-- If ##file## was a sequence, the file will be closed on completion. Otherwise, it will remain open, but at end of file.
1188
--
1189
-- Whatever integer the lines in ##lines## holds will be truncated to its 8 lowest bits so as to fall in the 0.255 range.
1190
--
1191
-- Example 1:
1192
--
1193
-- if write_lines("data.txt", {"This is important data", "Goodbye"}) != -1 then
1194
-- puts(STDERR, "Failed to write data\n")
1195
-- end if
1196
--
1197
--
1198
-- See Also:
1199
-- [[:read_lines]], [[:write_file]], [[:puts]]
1200
12013
1202
object fn
1203
12043
if sequence(file) then
12052
fn = open(file, "w")
1206
else
12071
fn = file
1208
end if
12093
if fn < 0 then return -1 end if
1210
12113
for i = 1 to length(lines) do
12125
puts(fn, lines[i])
12135
puts(fn, '\n')
12145
end for
1215
12163
if sequence(file) then
12172
close(fn)
1218
end if
1219
12203
return 1
1221
end function
1222
1223
--**
1224
-- Append a sequence of lines to a file.
1225
--
1226
-- Parameters:
1227
-- # ##file## : an object, either a file path or the handle to an open file.
1228
-- # ##lines## : the sequence of lines to write
1229
--
1230
-- Returns:
1231
-- An **integer**, 1 on success, -1 on failure.
1232
--
1233
-- Errors:
1234
-- If [[:puts]]() cannot write some line of text, a runtime error will occur.
1235
--
1236
-- Comments:
1237
-- ##file## is opened, written to and then closed.
1238
--
1239
-- Example 1:
1240
--
1241
-- if append_lines("data.txt", {"This is important data", "Goodbye"}) != -1 then
1242
-- puts(STDERR, "Failed to append data\n")
1243
-- end if
1244
--
1245
--
1246
-- See Also:
1247
-- [[:write_lines]], [[:puts]]
1248
12491
1250
object fn
1251
12521
fn = open(file, "a")
12531
if fn < 0 then return -1 end if
1254
12551
for i = 1 to length(lines) do
12561
puts(fn, lines[i])
12571
puts(fn, '\n')
12581
end for
1259
12601
close(fn)
1261
12621
return 1
1263
end function
1264
1265
public enum
1266101
BINARY_MODE,
1267101
TEXT_MODE,
1268101
UNIX_TEXT,
1269101
DOS_TEXT
1270
1271
--**
1272
-- Read the contents of a file as a single sequence of bytes.
1273
--
1274
-- Parameters:
1275
-- # ##file## : an object, either a file path or the handle to an open file.
1276
-- # ##as_text## : integer, **BINARY_MODE** (the default) assumes //binary mode// that
1277
-- causes every byte to be read in,
1278
-- and **TEXT_MODE** assumes //text mode// that ensures that
1279
-- lines end with just a Ctrl-J (NewLine) character,
1280
-- and the first byte value of 26 (Ctrl-Z) is interpreted as End-Of-File.
1281
--
1282
-- Returns:
1283
-- A **sequence**, holding the entire file.
1284
--
1285
-- Comments
1286
-- * When using BINARY_MODE, each byte in the file is returned as an element in
1287
-- the return sequence.
1288
-- * When not using BINARY_MODE, the file will be interpreted as a text file. This
1289
-- means that all line endings will be transformed to a single 0x0A character and
1290
-- the first 0x1A character (Ctrl-Z) will indicate the end of file (all data after this
1291
-- will not be returned to the caller.)
1292
--
1293
-- Example 1:
1294
--
1295
-- data = read_file("my_file.txt")
1296
-- -- data contains the entire contents of ##my_file.txt##
1297
--
1298
--
1299
-- Example 2:
1300
--
1301
-- fh = open("my_file.txt", "r")
1302
-- data = read_file(fh)
1303
-- close(fh)
1304
--
1305
-- -- data contains the entire contents of ##my_file.txt##
1306
--
1307
--
1308
-- See Also:
1309
-- [[:write_file]], [[:read_lines]]
1310
131121
1312
integer fn
1313
integer len
1314
sequence ret
1315
object temp
1316
atom adr
1317
131821
if sequence(file) then
131919
fn = open(file, "rb")
1320
else
13212
fn = file
1322
end if
132321
if fn < 0 then return -1 end if
1324
132521
temp = seek(fn, -1)
132621
len = where(fn)
132721
temp = seek(fn, 0)
1328
132921
ret = repeat(0, len)
133021
for i = 1 to len do
13311305
ret[i] = getc(fn)
13321305
end for
1333
133421
if sequence(file) then
133519
close(fn)
1336
end if
1337
133821
ifdef WINDOWS then
1339
-- Remove any extra -1 (EOF) characters in case file
1340
-- had been opened in Windows 'text mode'.
1341
for i = len to 1 by -1 do
1342
if ret[i] != -1 then
1343
if i != len then
1344
ret = ret[1 .. i]
1345
end if
1346
exit
1347
end if
1348
end for
1349
end ifdef
1350
135121
if as_text = BINARY_MODE then
135218
return ret
1353
end if
1354
1355
-- Treat as a text file.
13563
fn = find(26, ret) -- Any Ctrl-Z found?
13573
if fn then
1358
-- Ok, so truncate the file data
13591
ret = ret[1 .. fn - 1]
1360
end if
1361
1362
-- Convert Windows endings
13633
ret = replace_all(ret, {13,10}, {10})
13643
if length(ret) > 0 then
13653
if ret[$] != 10 then
13662
ret &= 10
1367
end if
1368
else
13690
ret = {10}
1370
end if
1371
13723
return ret
1373
end function
1374
1375
--**
1376
-- Write a sequence of bytes to a file.
1377
--
1378
-- Parameters:
1379
-- # ##file## : an object, either a file path or the handle to an open file.
1380
-- # ##data## : the sequence of bytes to write
1381
-- # ##as_text## : integer
1382
-- ** **BINARY_MODE** (the default) assumes //binary mode// that
1383
-- causes every byte to be written out as is,
1384
-- ** **TEXT_MODE** assumes //text mode// that causes a NewLine
1385
-- to be written out according to the operating system's
1386
-- end of line convention. In Unix this is Ctrl-J and in
1387
-- Windows this is the pair {Ctrl-L, Ctrl-J}.
1388
-- ** **UNIX_TEXT** ensures that lines are written out with unix style
1389
-- line endings (Ctrl-J).
1390
-- ** **DOS_TEXT** ensures that lines are written out with Windows style
1391
-- line endings {Ctrl-L, Ctrl-J}.
1392
-- Returns:
1393
-- An **integer**, 1 on success, -1 on failure.
1394
--
1395
-- Errors:
1396
-- If [[:puts]] cannot write ##data##, a runtime error will occur.
1397
--
1398
-- Comments:
1399
-- * When ##file## is a file handle, the file is not closed after writing is finished. When ##file## is a
1400
-- file name, it is opened, written to and then closed.
1401
-- * Note that when writing the file in ony of the text modes, the file is truncated
1402
-- at the first Ctrl-Z character in the input data.
1403
--
1404
-- Example 1:
1405
--
1406
-- if write_file("data.txt", "This is important data\nGoodbye") = -1 then
1407
-- puts(STDERR, "Failed to write data\n")
1408
-- end if
1409
--
1410
--
1411
-- See Also:
1412
-- [[:read_file]], [[:write_lines]]
1413
141424
1415
integer fn
1416
atom adr
1417
141824
if as_text != BINARY_MODE then
1419
-- Truncate at first Ctrl-Z
142017
fn = find(26, data)
142117
if fn then
14223
data = data[1 .. fn-1]
1423
end if
1424
-- Ensure last line has a line-end marker.
142517
if length(data) > 0 then
142617
if data[$] != 10 then
142710
data &= 10
1428
end if
1429
else
14300
data = {10}
1431
end if
1432
143317
if as_text = TEXT_MODE then
1434
-- Standardize all line endings
14358
data = replace_all(data, {13,10}, {10})
1436
14379
elsif as_text = UNIX_TEXT then
14383
data = replace_all(data, {13,10}, {10})
1439
14406
elsif as_text = DOS_TEXT then
14416
data = replace_all(data, {13,10}, {10})
14426
data = replace_all(data, {10}, {13,10})
1443
1444
end if
1445
end if
1446
1447
144824
if sequence(file) then
144923
if as_text = TEXT_MODE then
14508
fn = open(file, "w")
1451
else
145215
fn = open(file, "wb")
1453
end if
1454
else
14551
fn = file
1456
end if
145724
if fn < 0 then return -1 end if
1458
145924
puts(fn, data)
1460
146124
if sequence(file) then
146223
close(fn)
1463
end if
1464
146524
return 1
1466
end function
1467
1468
1469
--**
1470
-- Write formatted text to a file..
1471
--
1472
-- Parameters:
1473
-- There are two ways to pass arguments to this function,
1474
-- # Traditional way with first arg being a file handle.
1475
-- ## : integer, The file handle.
1476
-- ## : sequence, The format pattern.
1477
-- ## : object, The data that will be formatted.
1478
-- ## ##data_not_string##: object, If not 0 then the ##data## is not a string.
1479
-- By default this is 0 meaning that ##data## could be a single string.
1480
-- # Alternative way with first argument being the format pattern.
1481
-- ## : sequence, Format pattern.
1482
-- ## : sequence, The data that will be formatted,
1483
-- ## : object, The file to receive the formatted output. Default is
1484
-- to the STDOUT device (console).
1485
-- ## ##data_not_string##: object, If not 0 then the ##data## is not a string.
1486
-- By default this is 0 meaning that ##data## could be a single string.
1487
--
1488
-- Comments:
1489
-- * With the traditional arguments, the first argument must be an integer file handle.
1490
-- * With the alternative arguments, the thrid argument can be a file name string,
1491
-- in which case it is opened for output, written to and then closed.
1492
-- * With the alternative arguments, the third argument can be a two-element sequence
1493
-- containing a file name string and an output type ("a" for append, "w" for write),
1494
-- in which case it is opened accordingly, written to and then closed.
1495
-- * With the alternative arguments, the third argument can a file handle,
1496
-- in which case it is written to only
1497
-- * The format pattern uses the formatting codes defined in [[:text:format]].
1498
-- * When the data to be formatted is a single text string, it does not have to
1499
-- be enclosed in braces,
1500
--
1501
-- Example 1:
1502
--
1503
-- -- To console
1504
-- writef("Today is [4], [u2:3] [3:02], [1:4].", {Year, MonthName, Day, DayName})
1505
-- -- To "sample.txt"
1506
-- writef("Today is [4], [u2:3] [3:02], [1:4].", {Year, MonthName, Day, DayName}, "sample.txt")
1507
-- -- To "sample.dat"
1508
-- integer dat = open("sample.dat", "w")
1509
-- writef("Today is [4], [u2:3] [3:02], [1:4].", {Year, MonthName, Day, DayName}, dat)
1510
-- -- Appended to "sample.log"
1511
-- writef("Today is [4], [u2:3] [3:02], [1:4].", {Year, MonthName, Day, DayName}, {"sample.log", "a"})
1512
-- -- Simple message to console
1513
-- writef("A message")
1514
-- -- Another console message
1515
-- writef(STDERR, "This is a []", "message")
1516
-- -- Outputs two numbers
1517
-- writef(STDERR, "First [], second []", {65, 100},, 1) -- Note that {65, 100} is also "Ad"
1518
--
1519
--
1520
-- See Also:
1521
-- [[:text:format]], [[:writefln]], [[:write_lines]]
1522
15230
15240
integer real_fn = 0
15250
integer close_fn = 0
15260
sequence out_style = "w"
1527
15280
if integer(fm) then
15290
object ts
1530
-- File Handle in first arguement so rotate the arguments.
15310
ts = fm
15320
fm = data
15330
data = fn
15340
fn = ts
1535
end if
1536
15370
if sequence(fn) then
15380
if length(fn) = 2 then
15390
if sequence(fn[1]) then
15400
if equal(fn[2], 'a') then
15410
out_style = "a"
15420
elsif not equal(fn[2], "a") then
15430
out_style = "w"
1544
else
15450
out_style = "a"
1546
end if
15470
fn = fn[1]
1548
end if
1549
end if
15500
real_fn = open(fn, out_style)
1551
15520
if real_fn = -1 then
15530
crash("Unable to write to '%s'", {fn})
1554
end if
15550
close_fn = 1
1556
else
15570
real_fn = fn
1558
end if
1559
15600
if equal(data_not_string, 0) then
15610
if t_display(data) then
15620
data = {data}
1563
end if
1564
end if
15650
puts(real_fn, format(fm, data))
15660
if close_fn then
15670
close(real_fn)
1568
end if
15690
end procedure
1570
1571
--**
1572
-- Write formatted text to a file, ensuring that a new line is also output.
1573
--
1574
-- Parameters:
1575
-- # ##fm## : sequence, Format pattern.
1576
-- # ##data## : sequence, The data that will be formatted,
1577
-- # ##fn## : object, The file to receive the formatted output. Default is
1578
-- to the STDOUT device (console).
1579
-- # ##data_not_string##: object, If not 0 then the ##data## is not a string.
1580
-- By default this is 0 meaning that ##data## could be a single string.
1581
--
1582
-- Comments:
1583
-- * This is the same as [[:writef]], except that it always adds a New Line to
1584
-- the output.
1585
-- * When ##fn## is a file name string, it is opened for output,
1586
-- written to and then closed.
1587
-- * When ##fn## is a two-element sequence containing a file name string and
1588
-- an output type ("a" for append, "w" for write), it is opened accordingly,
1589
-- written to and then closed.
1590
-- * When ##fn## is a file handle, it is written to only
1591
-- * The ##fm## uses the formatting codes defined in [[:text:format]].
1592
--
1593
-- Example 1:
1594
--
1595
-- -- To console
1596
-- writefln("Today is [4], [u2:3] [3:02], [1:4].", {Year, MonthName, Day, DayName})
1597
-- -- To "sample.txt"
1598
-- writefln("Today is [4], [u2:3] [3:02], [1:4].", {Year, MonthName, Day, DayName}, "sample.txt")
1599
-- -- Appended to "sample.log"
1600
-- writefln("Today is [4], [u2:3] [3:02], [1:4].", {Year, MonthName, Day, DayName}, {"sample.log", "a"})
1601
--
1602
--
1603
-- See Also:
1604
-- [[:text:format]], [[:writef]], [[:write_lines]]
16050
16060
if integer(fm) then
16070
writef(data & '\n', fn, fm, data_not_string)
1608
else
16090
writef(fm & '\n', data, fn, data_not_string)
1610
end if
16110
end procedure