summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/expl3/l3io.dtx
blob: a1223daaa6f98d73f4bcd69be0618ae7fbd96378 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
% \iffalse
%% File: l3io.dtx Copyright (C) 1990-2009 LaTeX3 project
%%
%% It may be distributed and/or modified under the conditions of the
%% LaTeX Project Public License (LPPL), either version 1.3c of this
%% license or (at your option) any later version.  The latest version
%% of this license is in the file
%%
%%    http://www.latex-project.org/lppl.txt
%%
%% This file is part of the ``expl3 bundle'' (The Work in LPPL)
%% and all files in that bundle must be distributed together.
%%
%% The released version of this bundle is available from CTAN.
%%
%% -----------------------------------------------------------------------
%%
%% The development version of the bundle can be found at
%%
%%    http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
%%%%%%%%%%%
%% NOTE: %%
%%%%%%%%%%%
%%
%%   Snapshots taken from the repository represent work in progress and may
%%   not work or may contain conflicting material!  We therefore ask
%%   people _not_ to put them into distributions, archives, etc. without
%%   prior consultation with the LaTeX Project Team.
%%
%% -----------------------------------------------------------------------
%
%<*driver|package>
\RequirePackage{l3names}
%</driver|package>
%\fi
\GetIdInfo$Id: l3io.dtx 1668 2009-11-01 22:13:36Z will $
          {L3 Experimental i/o module}
%\iffalse
%<*driver>
%\fi
\ProvidesFile{\filename.\filenameext}
  [\filedate\space v\fileversion\space\filedescription]
%\iffalse
\documentclass[full]{l3doc}
\begin{document}
\DocInput{l3io.dtx}
\end{document}
%</driver>
% \fi
%
% \title{The \textsf{l3io} package\thanks{This file
%         has version number \fileversion, last
%         revised \filedate.}\\
% Low-level file i/o}
% \author{\Team}
% \date{\filedate}
% \maketitle
%
% \begin{documentation}
%
% \TeX{} is capable of reading from and writing up to 16 individual
% streams. These i/o operations are accessable in \LaTeX3 with functions
% from the "\io.."  modules. In most cases it will be
% sufficiant for the programmer to use the functions provided by the
% auxiliary file module, but here are the necessary functions for
% manipulating private streams.
%
% Sometimes it is not known beforehand how much text is going to be
% written with a single call. As a result some internal \TeX{} buffer
% may overflow. To avoid this kind of problem, \LaTeX3 maintains beside
% direct write operations like "\iow_now:Nx" also so called ``long''
% writes where the output is broken into individual lines on every blank
% in the text to be written. The resulting files are difficult to read
% for humans but since they usually serve only as internal storage this
% poses no problem.
%
% Beside the functions that immediately act (e.g., "\iow_now:Nx",
% etc.) we also have deferred operations that are saved away until the
% next page is finished. This allow to expand the <tokens> at the right
% time to get correct page numbers etc.
%
% \section{Functions for output streams}
%
% \begin{function}{ \iow_new:N |
%                   \iow_new:c }
% \begin{syntax}
%   "\iow_new:N" <stream>
% \end{syntax}
% Defines <stream> to be a new identifer denoting an output stream for
% use in subsequent functions.
% \begin{texnote}
% "\iow_new:N" corresponds to the plain \TeX{} \tn{newwrite}
% allocation routine.
% \end{texnote}
% \end{function}
%
% \begin{function}{ \iow_open:Nn |
%                   \iow_open:cn }
% \begin{syntax}
%   "\iow_open:Nn" <stream> \Arg{file name}
% \end{syntax}
% Opens output stream <stream> to write to <file name>. The output
% stream is immediately available for use. If the <stream> was already
% used as an output stream to some other file, this file gets closed
% first.\footnote{This is a precaution since on some OS it is possible
% to open the same file for output more than once which then results in
% some internal errors at the end of the run.} Also, all output streams
% still open at the end of the \TeX{} run will be automatically closed.
% \end{function}
%
% \begin{function}{ \iow_close:N }
% \begin{syntax}
%   "\iow_open:Nn" <stream>
% \end{syntax}
% Closes output stream <stream>.
% \end{function}
%
% \subsection{Immediate writing}
%
% \begin{function}{ \iow_now:Nx |
%                   \iow_now:Nn }
% \begin{syntax}
%  "\iow_now:Nx" <stream> \Arg{tokens}
% \end{syntax}
% "\iow_now:Nx" immediately writes the expansion of <tokens> to the
% output stream <stream>. If <stream> is not open output goes to the
% terminal. The variant "\iow_now:Nn" writes out <tokens> without any
% further expansion.
% \begin{texnote}
% These are the equivalent of \TeX's "\immediate\write" with and without
% expansion control.
% \end{texnote}
% \end{function}
%
% \begin{function}{ \iow_log:n  | \iow_log:x  |
%                   \iow_term:x | \iow_term:n }
% \begin{syntax}
%  "\iow_log:x" \Arg{tokens}
% \end{syntax}
% These functions write to the log file (also known as the transcript file) or
% to the terminal respectively. They are equivalent to "\iow_now:Nx" where
% <stream> is the transcript file ("\c_iow_log_stream") or the terminal
% ("\c_iow_term_stream").
% \end{function}
%
% \begin{function}{ \iow_now_buffer_safe:Nn |
%                   \iow_now_buffer_safe:Nx }
% \begin{syntax}
%  "\iow_now_buffer_safe:Nn" <stream> \Arg{tokens}
% \end{syntax}
% Like "\iow_now:Nx" but splits <tokens> at every blank into separate
% lines. When potentially (very) long token lists are being written, this
% avoids the problem of
% buffer overflow when reading back the file.
% \end{function}
%
% \begin{function}{ \iow_now_when_avail:Nn |
%                   \iow_now_when_avail:cn }
% \begin{syntax}
%  "\iow_now_when_avail:Nn" <stream> \Arg{tokens}
% \end{syntax}
% This special function first checks if the <stream> is open for writing.
% If not it does nothing otherwise it behaves like "\iow_now:Nn".
% \end{function}
%
% \subsection{Deferred writing}
%
% \begin{function}{ \iow_shipout:Nn | \iow_shipout:Nx }
% \begin{syntax}
%   "\iow_shipout_x:Nn"  <stream> \Arg{tokens}
% \end{syntax}
% These functions write <tokens> to the specified <stream>, but unlike with
% "\iow_now:Nn" which write the material immediately, "\iow_shipout:Nn" waits
% until the processing of the current page has finished.
% \end{function}
%
% \begin{function}{ \iow_shipout_x:Nn | \iow_shipout_x:Nx }
% \begin{syntax}
%   "\iow_shipout_x:Nn"  <stream> \Arg{tokens}
% \end{syntax}
% More useful than the "\iow_shipout:Nn" functions, these functions also write
% <tokens> to <stream> at the end of the processing of the current page;
% however, before <tokens> are written they are subjected to a further
% "x" expansion stage.
%
% This is useful for writing messages that depend
% on counters (such as the page number) that are not known until the page has
% been completed.
%
% "\iow_shipout_x:Nn" always needs "{}" around the second argument.
% \begin{texnote}
% "\iow_shipout_x:Nn" is equivalent to \TeX's \tn{write}.
% \end{texnote}
% \end{function}
%
% \subsection{Special characters for writing}
%
% \begin{function}{\iow_newline:}
% \begin{syntax}
%   "\iow_newline:"
% \end{syntax}
% Function that produces a new line when used within the <token list>
% that gets written some output stream in non-verbatim mode.
% \end{function}
%
% \begin{function}{\iow_space:}
% \begin{syntax}
%   "\iow_space:"
% \end{syntax}
% Function that produces a space when used within the <token list>
% that gets written to some output stream in an expanding mode.
% \end{function}
%
% \begin{function}{\iow_char:N}
% \begin{syntax}
%   "\iow_space:N" "\"<char>
%   "\iow_space:N" "\%"
% \end{syntax}
% Inserts <char> into the output stream. Useful when trying to write difficult
% characters such as "%", "{", "}", etc., in messages.
% \end{function}
%
% \section{Functions for input streams}
%
% \begin{function}{\ior_new:N}
% \begin{syntax}
%   "\ior_new:N" <stream>
% \end{syntax}
% This function defines <stream> to be a new input stream constant.
% \begin{texnote}
% This is the new name and new implementation for plain \TeX's
% \tn{newread}.
% \end{texnote}
% \end{function}
%
% \begin{function}{\ior_open:Nn}
% \begin{syntax}
%   "\ior_open:Nn" <stream> \Arg{file name}
% \end{syntax}
% This function opens <stream> as an input stream for the external file
% <file name>. If <file name> doesn't exist or is an empty file the
% stream is considered to be fully read, a condition which can be tested
% with "\ior_if_eof:NTF" etc. If <stream> was already used to read from some
% other file this file will be closed first. The input stream is ready
% for immediate use.
% \end{function}
%
% \begin{function}{\ior_close:N}
% \begin{syntax}
%   "\ior_close:N" <stream>
% \end{syntax}
% This function closes the read stream <stream>.
% \begin{texnote}
% This is a new name for \tn{closein} but it is considered bad practice
% to make use of this knowledge :-)
% \end{texnote}
% \end{function}
%
% \begin{function}{ \ior_if_eof_p:N / (EXP) | \ior_if_eof:N / (TF)(EXP) }
% \begin{syntax}
%   "\ior_if_eof:NTF" <stream> \Arg{true code} \Arg{false code}
% \end{syntax}
% Conditional that tests if some input stream is fully read. The
% condition is also true if the input stream is not open.
% \end{function}
%
% \begin{function}{\if_eof:w}
% \begin{syntax}
%   "\if_eof:w" <stream> <true code> "\else:" <false code> "\fi:"
% \end{syntax}
% \begin{texnote}
% This is the primitive \tn{ifeof} but we allow only a <stream> and not
% a plain number after it.
% \end{texnote}
% \end{function}
%
% \begin{function}{ \ior_to:NN  |
%                   \ior_gto:NN }
% \begin{syntax}
%   "\ior_to:NN" <stream> <tl var.>
% \end{syntax}
% Functions that reads one or more lines (until an equal number of left
% and right braces are found) from the input stream <stream> and places
% the result locally or globally into the token list variable.
% If <stream> is not open, input is requested from the terminal.
% \end{function}
%
% \section{Constants}
%
% \begin{variable}{\c_iow_comment_char |
%                  \c_iow_lbrace_char  |
%                  \c_iow_rbrace_char}
% Constants that can be used to represent comment character, left and
% right brace in token lists that should be written to a file.
% \end{variable}
%
% \begin{variable}{ \c_iow_term_stream | \c_ior_term_stream }
% Input or output stream denoting the terminal. If used as an input
% stream the user is prompted with the name of the token list variable
% (that is used
% in the call "\ior_to:NN" or "\ior_gto:NN") followed by an equal sign.
% If you don't want an automatic prompt of this sort ``misuse''
% "\c_iow_log_stream" as an input stream.
% \end{variable}
%
% \begin{variable}{ \c_iow_log_stream | \c_ior_log_stream }
% Output stream that writes only to the transcript file (e.g., the
% ".log" file on most systems). You may ``misuse'' this stream as an
% input stream. In this case it acts as a terminal stream without user
% prompting.
% \end{variable}
%
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3io} implementation}
%
%    We start by ensuring that the required packages are loaded.
%    \begin{macrocode}
%<*package>
\ProvidesExplPackage
  {\filename}{\filedate}{\fileversion}{\filedescription}
\package_check_loaded_expl:
%</package>
%<*initex|package>
%    \end{macrocode}
%
% This section is primarily concerned with input and output streams.
% The naming conventions for i/o streams is |ior| (for read) and |iow|
% (for write) as module names. e.g.\ |\c_ior_test_stream| is an input stream
% variable called `test'.
%
% \subsection{Output streams}
%
% \begin{macro}{\iow_new:N,\iow_new:c}
%    Allocation of new output streams is done by these functions.
%    As we currently do not distribute a new allocation module we nick
%    the |\newwrite| function.
%    \begin{macrocode}
%<*initex>
\alloc_setup_type:nnn {iow} \c_zero \c_sixteen
\cs_new_nopar:Npn \iow_new:N #1 {\alloc_reg:NnNN g {iow} \tex_chardef:D #1}
%</initex>
%<*package>
\cs_set_eq:NN \iow_new:N \newwrite
%</package>
\cs_generate_variant:Nn \iow_new:N {c}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\iow_open:Nn,\iow_open:cn}
%    To open streams for reading or writing the following two functions
%    are provided. The streams are opened immediately.
%
%    From some bad experiences on the mainframe, I learned that it is
%    better to force the close before opening a dataset for writing.
%    We have to check whether this is also necessary in case of
%    |\tex_openin:D|.
%    \begin{macrocode}
\cs_new_nopar:Npn \iow_open:Nn #1#2 {
  \iow_close:N #1
  \tex_immediate:D \tex_openout:D #1#2 \scan_stop:
}
\cs_generate_variant:Nn \iow_open:Nn {c}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\iow_close:N}
%    Since we close output streams prior to opening, a separate closing
%    operation is probably not necessary. But here it is, just in
%    case\ldots. Actually you will need this if you intend to write
%    and then read in the same pass from a stream.
%    \begin{macrocode}
\cs_new_nopar:Npn \iow_close:N { \tex_immediate:D \tex_closeout:D }
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\c_iow_term_stream,\c_ior_term_stream}
% \begin{macro}{\c_iow_log_stream,\c_ior_log_stream}
%    Here we allocate two output streams for writing to the transcript
%    file only (|\c_iow_log_stream|) and to both the terminal and transcript
%    file (|\c_iow_term_stream|). Both can be used to read from and have
%    equivalent "\c_ior" versions.
%    \begin{macrocode}
\cs_new_eq:NN \c_iow_term_stream \c_sixteen
\cs_new_eq:NN \c_ior_term_stream \c_sixteen
\cs_new_eq:NN \c_iow_log_stream \c_minus_one
\cs_new_eq:NN \c_ior_log_stream \c_minus_one
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \paragraph{Immediate writing}
%
% \begin{macro}{\iow_now:Nx}
%    An abbreviation for an often used operation, which immediately
%    writes its second argument expanded to the output stream.
%    \begin{macrocode}
\cs_new_nopar:Npn \iow_now:Nx { \tex_immediate:D \iow_shipout_x:Nn }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\iow_now:Nn}
%    This routine writes the second argument onto the output
%    stream without expansion. If this stream isn't open, the output goes to
%    the terminal instead.
%    If the first argument is no output stream at all, we get an
%    internal error.
%    \begin{macrocode}
\cs_new_nopar:Npn \iow_now:Nn #1#2 {
  \iow_now:Nx #1 { \exp_not:n {#2} }
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\iow_log:n,\iow_log:x,\iow_term:n,\iow_term:x}
%    Now we redefine two functions for which we needed a definition
%    very early on.
%    \begin{macrocode}
\cs_set_nopar:Npn \iow_log:x  { \iow_now:Nx \c_iow_log_stream  }
\cs_new_nopar:Npn \iow_log:n  { \iow_now:Nn \c_iow_log_stream  }
\cs_set_nopar:Npn \iow_term:x { \iow_now:Nx \c_iow_term_stream }
\cs_new_nopar:Npn \iow_term:n { \iow_now:Nn \c_iow_term_stream }
%    \end{macrocode}
%    "\iow_term:x" isn't exactly equivalent to the old |\typeout| since
%    we need to control expansion in the function we provide for the user.
%  \end{macro}
%
%
% \begin{macro}{\iow_now_when_avail:Nn,\iow_now_when_avail:cn}
%    |\iow_now_when_avail:Nn | \m{stream} \m{code}.  This routine writes
%    its second argument unexpanded to the stream given by the first
%    argument, provided that this stream was opened for writing. Note,
%    that |#| characters get doubled within \m{code}.
%
%    In this routine we have to check whether or not the output stream
%    that was requested is defined at all.
%    So we check if the name is still free.
%
%    \begin{macrocode}
\cs_new_nopar:Npn \iow_now_when_avail:Nn #1 {
  \cs_if_free:NTF #1 {\use_none:n} {\iow_now:Nn #1}
}
\cs_generate_variant:Nn \iow_now_when_avail:Nn {c}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\iow_now_buffer_safe:Nn,\iow_now_buffer_safe:Nx}
% \begin{macro}[aux]{\iow_now_buffer_safe_expanded_aux:w}
%    Another type of writing onto an output stream is used for
%    potentially long token sequences. We break the output lines at
%    every blank in the second argument. This avoids the problem of
%    buffer overflow when reading back, or badly broken lines on
%    systems with limited file records.  The only thing we have to
%    take care of, is the danger of two blanks in succession since
%    these get converted into a |\par| when we read the stuff back.
%    But this can happen only if things like
%    two spaces find their way into the second argument.
%    Usually, multiple spaces are removed by \TeX's scanner.
%    \begin{macrocode}
\cs_new_nopar:Npn \iow_now_buffer_safe_aux:w #1#2#3 {
  \group_begin: \tex_newlinechar:D`\ #1#2{#3} \group_end:
}
\cs_new_nopar:Npn \iow_now_buffer_safe:Nx {
  \iow_now_buffer_safe_aux:w \iow_now:Nx
}
\cs_new_nopar:Npn \iow_now_buffer_safe:Nn {
  \iow_now_buffer_safe_aux:w \iow_now:Nn
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \paragraph{Deferred writing}
%
% \begin{macro}{\iow_shipout_x:Nn,\iow_shipout_x:Nx}
% First the easy part, this is the primitive.
%    \begin{macrocode}
\cs_set_eq:NN \iow_shipout_x:Nn \tex_write:D
\cs_generate_variant:Nn \iow_shipout_x:Nn {Nx}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\iow_shipout:Nn,\iow_shipout:Nx}
% With \eTeX\ available deferred writing is easy.
%    \begin{macrocode}
\cs_new_nopar:Npn \iow_shipout:Nn #1#2{
  \iow_shipout_x:Nn #1 { \exp_not:n {#2} }
}
\cs_generate_variant:Nn \iow_shipout:Nn {Nx}
%    \end{macrocode}
% \end{macro}
%
% `Buffer safe' forms of these functions are not possible since the deferred
% writing will restore the value of |\tex_newlinechar:D| before it will have
% a chance to act. But on the other hand it is nevertheless possible
% to make all deferred writes long by setting the |\tex_newlinechar:D|
% inside the output routine just before the |\tex_shipout:D|. The only
% disadvantage of this method is the fact that messages to the
% terminal during this time will also then break at spaces. But we
% should consider this.
%
% \paragraph{Special characters for writing}
%
% \begin{macro}{\iow_newline:}
%    Global variable holding the character that forces a new line when
%    something is written to an output stream.
%    \begin{macrocode}
\cs_new_nopar:Npn \iow_newline: {^^J}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\iow_space:}
%    Global variable holding the character that inserts a space char when
%    writing to an output stream.
%    \begin{macrocode}
\cs_new_nopar:Npn \iow_space: {~}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\iow_char:N}
% Function to write any escaped char to an output stream.
%    \begin{macrocode}
\cs_new:Npn \iow_char:N #1 { \cs_to_str:N #1 }
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\c_iow_comment_char}
% \begin{macro}{\c_iow_lbrace_char}
% \begin{macro}{\c_iow_rbrace_char}
% TODO: remove these in favour of "\iow_char:N" (Will, Apr 2009)
%
%   We also need to be able to write braces and the comment character.  We
%   achieve this by defining global constants to expand into a version of
%   these characters with |\tex_catcode:D|${}=12$.
%    \begin{macrocode}
\tl_new:Nx \c_iow_comment_char {\cs_to_str:N\%}
%    \end{macrocode}
%    To avoid another allocation function which is probably only
%    necessary here we use the |\cs_set_nopar:Npx| command directly.
%    \begin{macrocode}
\tl_new:Nx \c_iow_lbrace_char{\cs_to_str:N\{}
\tl_new:Nx \c_iow_rbrace_char{\cs_to_str:N\}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \subsection{Input streams}
%
% \begin{macro}{\ior_new:N}
%    Allocation of new input streams is done by this function.
%    As we currently do not distribute a new allocation module we nick
%    the |\newwread| function.
%    \begin{macrocode}
%<*initex>
\alloc_setup_type:nnn {ior} \c_zero \c_sixteen
\cs_new_nopar:Npn \ior_new:N #1 {\alloc_reg:NnNN g {ior} \tex_chardef:D #1}
%</initex>
%<package>\cs_set_eq:NN \ior_new:N \newread
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ior_open:Nn}
% \begin{macro}{\ior_close:N}
%    Processing of input-streams (via |\tex_openin:D| and |closein|) is
%    always `immediate' as far as \TeX{} is concerned. An extra
%    |\tex_immediate:D| is silently ignored.
%    \begin{macrocode}
\cs_set_eq:NN \ior_close:N \tex_closein:D
\cs_new_nopar:Npn \ior_open:Nn #1#2 {
  \ior_close:N #1 \scan_stop:
  \tex_openin:D #1#2 \scan_stop:
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\if_eof:w}
%    \begin{macrocode}
\cs_new_eq:NN \if_eof:w \tex_ifeof:D
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\ior_if_eof_p:N}
% \begin{macro}[TF]{\ior_if_eof:N}
%    |\ior_if_eof:NTF | \m{stream} \m{true case} \m{false case}.  To
%    test if some particular input stream is exhausted the following
%    conditional is provided:
%    \begin{macrocode}
\prg_new_conditional:Nnn \ior_if_eof:N {p,TF,T,F} {
  \tex_ifeof:D #1 \prg_return_true: \else: \prg_return_false: \fi:
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%
% \begin{macro}{\ior_to:NN}
% \begin{macro}{\ior_gto:NN}
%    And here we read from files.
%    \begin{macrocode}
\cs_new_nopar:Npn \ior_to:NN #1#2 {
  \tex_read:D #1 to #2
%<check>  \chk_local_or_pref_global:N #2
}
\cs_new_nopar:Npn \ior_gto:NN {
%<+check>  \pref_global_chk:
%<-check>  \pref_global:D
  \ior_to:NN
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%    \begin{macrocode}
%</initex|package>
%    \end{macrocode}
%
%    Show token usage:
%    \begin{macrocode}
%<*showmemory>
\showMemUsage
%</showmemory>
%    \end{macrocode}
%
% \end{implementation}
% \PrintIndex
%
% \endinput