27
27
% %-----------------------------------------------------------------------------
28
28
-module (io ).
29
29
30
- -export ([format /1 , format /2 , get_line /1 , put_chars /1 , put_chars /2 ]).
30
+ -export ([
31
+ requests /1 ,
32
+ format /1 ,
33
+ format /2 ,
34
+ format /3 ,
35
+ fwrite /1 ,
36
+ fwrite /2 ,
37
+ fwrite /3 ,
38
+ get_line /1 ,
39
+ put_chars /1 ,
40
+ put_chars /2 ,
41
+ scan_erl_exprs /4 ,
42
+ columns /0 ,
43
+ columns /1 ,
44
+ getopts /0 ,
45
+ getopts /1 ,
46
+ printable_range /0
47
+ ]).
48
+
49
+ -export_type ([device / 0 , format / 0 , standard_io / 0 , standard_error / 0 , user / 0 ]).
50
+
51
+ -type format () :: atom () | string () | binary ().
52
+ -type standard_io () :: standard_io .
53
+ -type standard_error () :: standard_error .
54
+ -type user () :: user .
55
+ -type device () :: atom () | pid () | standard_io () | standard_error () | user ().
56
+
57
+ -type getopt () ::
58
+ {echo , boolean ()}
59
+ | {binary , boolean ()}
60
+ | {encoding , unicode }
61
+ | {terminal , boolean ()}
62
+ | {stdin , boolean ()}
63
+ | {stdout , boolean ()}
64
+ | {stderr , boolean ()}.
65
+
66
+ % % @priv
67
+ requests (Requests ) ->
68
+ execute_request (group_leader (), {requests , Requests }).
69
+
70
+ % %-----------------------------------------------------------------------------
71
+ % % @equiv columns(standard_io)
72
+ % % @doc Returns the number of columns for standard I/O.
73
+ % % @end
74
+ % %-----------------------------------------------------------------------------
75
+ -spec columns () -> {ok , pos_integer ()} | {error , enotsup }.
76
+ columns () ->
77
+ columns (standard_io ).
78
+
79
+ % %-----------------------------------------------------------------------------
80
+ % % @param IODevice IO device to get columns of
81
+ % % @doc Returns the number of columns for passed I/O device.
82
+ % % @end
83
+ % %-----------------------------------------------------------------------------
84
+ -spec columns (IODevice :: device ()) -> {ok , pos_integer ()} | {error , enotsup }.
85
+ columns (_IODevice ) ->
86
+ {ok , 80 }.
87
+
88
+ % %-----------------------------------------------------------------------------
89
+ % % @equiv getopts(standard_io)
90
+ % % @doc Get all options for standard I/O
91
+ % % @end
92
+ % %-----------------------------------------------------------------------------
93
+ -spec getopts () -> [getopt ()] | {error , Reason :: any ()}.
94
+ getopts () ->
95
+ getopts (standard_io ).
31
96
32
97
% %-----------------------------------------------------------------------------
33
- % % @doc Equivalent to format(Format, []).
98
+ % % @param IODevice IO device to get options for
99
+ % % @doc Get all options for a given IODevice
34
100
% % @end
35
101
% %-----------------------------------------------------------------------------
36
- -spec format (Format :: string ()) -> string ().
37
- format (Format ) when is_list (Format ) ->
38
- format (Format , []).
102
+ -spec getopts (IODevice :: device ()) -> [getopt ()] | {error , Reason :: any ()}.
103
+ getopts (standard_io ) ->
104
+ [
105
+ {echo , true },
106
+ {binary , false },
107
+ {encoding , unicode },
108
+ {terminal , true },
109
+ {stdout , true },
110
+ {stderr , true },
111
+ {stdin , true }
112
+ ].
113
+
114
+ % %-----------------------------------------------------------------------------
115
+ % % @doc Returns the user-requested range of printable Unicode characters.
116
+ % % Currently always returns `unicode'
117
+ % % @end
118
+ % %-----------------------------------------------------------------------------
119
+ -spec printable_range () -> unicode | latin1 .
120
+ printable_range () ->
121
+ unicode .
122
+
123
+ % % @equiv fwrite(Format)
124
+ -spec format (Format :: format ()) -> ok .
125
+ format (Format ) ->
126
+ fwrite (Format ).
127
+
128
+ % % @equiv fwrite(Format, [])
129
+ -spec fwrite (Format :: format ()) -> ok .
130
+ fwrite (Format ) ->
131
+ fwrite (Format , []).
132
+
133
+ % % @equiv fwrite(Format, Data)
134
+ -spec format (Format :: format (), Data :: [term ()]) -> ok .
135
+ format (Format , Data ) ->
136
+ fwrite (Format , Data ).
137
+
138
+ % % @equiv fwrite(standard_io, Format, Data)
139
+ -spec fwrite (Format :: format (), Data :: [term ()]) -> ok .
140
+ fwrite (Format , Data ) ->
141
+ fwrite (standard_io , Format , Data ).
142
+
143
+ % % @equiv fwrite(IODevice, Format, Data)
144
+ -spec format (IODevice :: device (), Format :: format (), Data :: [term ()]) -> ok .
145
+ format (IODevice , Format , Data ) ->
146
+ fwrite (IODevice , Format , Data ).
39
147
40
148
% %-----------------------------------------------------------------------------
41
149
% % @param Format format string
42
- % % @param Args format argument
43
- % % @returns string
44
- % % @doc Format string and data to console.
150
+ % % @param Data format arguments
151
+ % % @param IODevice device to write to
152
+ % % @returns ok
153
+ % % @doc Format string and data to IO device.
45
154
% % See io_lib:format/2 for information about
46
155
% % formatting capabilities.
47
156
% % @end
48
157
% %-----------------------------------------------------------------------------
49
- -spec format ( Format :: string (), Args :: list ()) -> string ().
50
- format ( Format , Args ) when is_list (Format ) andalso is_list (Args ) ->
158
+ -spec fwrite ( IODevice :: device (), Format :: string (), Args :: list ()) -> string ().
159
+ fwrite ( IODevice , Format , Args ) when is_list (Format ) andalso is_list (Args ) ->
51
160
Msg =
52
161
try
53
162
io_lib :format (Format , Args )
54
163
catch
55
164
_ :_ ->
56
165
io_lib :format (" Bad format! Format: ~p Args: ~p~n " , [Format , Args ])
57
166
end ,
58
- put_chars (Msg ).
167
+ put_chars (IODevice , Msg ).
168
+
169
+ % %-----------------------------------------------------------------------------
170
+ % % @param IODevice device to read from
171
+ % % @param Prompt prompt to print
172
+ % % @param StartLocation start location for reading
173
+ % % @param Options options for tokenizing
174
+ % % @returns read tokens or an error
175
+ % % @doc Reads data from IODevice with a given prompt
176
+ % % @end
177
+ % %-----------------------------------------------------------------------------
178
+ -spec scan_erl_exprs (IODevice :: device (), Prompt :: atom () | unicode :chardata (), any (), any ()) ->
179
+ {ok , Tokens :: any (), EndLocation :: any ()}
180
+ | {eof , EndLocation :: any ()}
181
+ | eof
182
+ | {error , any ()}.
183
+ scan_erl_exprs (IODevice , Prompt , StartLocation , Options ) when is_pid (IODevice ) ->
184
+ execute_request (
185
+ IODevice , {get_until , unicode , Prompt , erl_scan , tokens , [StartLocation , Options ]}
186
+ ).
59
187
60
188
% %-----------------------------------------------------------------------------
61
189
% % @param Prompt prompt for user input
@@ -78,33 +206,48 @@ get_line(Prompt) ->
78
206
end .
79
207
80
208
% %-----------------------------------------------------------------------------
209
+ % % @equiv put_chars(standard_io, Chars)
81
210
% % @param Chars character(s) to write to console
82
211
% % @returns ok
83
212
% % @doc Writes the given character(s) to the console.
84
213
% % @end
85
214
% %-----------------------------------------------------------------------------
86
215
-spec put_chars (Chars :: list () | binary ()) -> ok .
87
216
put_chars (Chars ) ->
88
- Self = self (),
89
- case erlang :group_leader () of
90
- Self ->
91
- console :print (Chars );
92
- Leader ->
93
- Ref = make_ref (),
94
- Leader ! {io_request , self (), Ref , {put_chars , unicode , Chars }},
95
- receive
96
- {io_reply , Ref , Line } -> Line
97
- end
98
- end .
217
+ put_chars (standard_io , Chars ).
99
218
100
219
% %-----------------------------------------------------------------------------
101
- % % @param Chars character(s) to write to console
220
+ % % @param Device device to send characters to
221
+ % % @param Chars character(s) to write to device
102
222
% % @returns ok
103
- % % @doc Writes the given character(s) to the console .
223
+ % % @doc Writes the given character(s) to the given device .
104
224
% % @end
105
225
% %-----------------------------------------------------------------------------
106
- -spec put_chars (Device :: any (), Chars :: list () | binary ()) -> ok .
226
+ -spec put_chars (Device :: device (), Chars :: list () | binary ()) -> ok .
227
+ put_chars (standard_io , Chars ) ->
228
+ Self = self (),
229
+ case erlang :group_leader () of
230
+ Self ->
231
+ console :print (Chars );
232
+ Leader ->
233
+ execute_request (Leader , {put_chars , unicode , Chars })
234
+ end ;
107
235
put_chars (standard_error , Chars ) ->
108
- put_chars (Chars );
109
- put_chars (standard_output , Chars ) ->
110
- put_chars (Chars ).
236
+ put_chars (standard_io , Chars ).
237
+
238
+ % % @priv
239
+ convert_request ({requests , Requests }) ->
240
+ {requests , [convert_request (Request ) || Request <- Requests ]};
241
+ convert_request (nl ) ->
242
+ {put_chars , unicode , " \n " };
243
+ convert_request (Other ) ->
244
+ Other .
245
+
246
+ % % @priv
247
+ execute_request (Device , Request ) when is_pid (Device ) ->
248
+ Converted = convert_request (Request ),
249
+ Ref = make_ref (),
250
+ Device ! {io_request , self (), Ref , Converted },
251
+ receive
252
+ {io_reply , Ref , Result } -> Result
253
+ end .
0 commit comments