Changed license terms to the plain LGPL thru-out.
[bpt/guile.git] / libguile / ports.c
1 /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18
19 \f
20 /* Headers. */
21
22 #if HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <errno.h>
28
29 #include "libguile/_scm.h"
30 #include "libguile/eval.h"
31 #include "libguile/objects.h"
32 #include "libguile/smob.h"
33 #include "libguile/chars.h"
34
35 #include "libguile/keywords.h"
36 #include "libguile/root.h"
37 #include "libguile/strings.h"
38
39 #include "libguile/validate.h"
40 #include "libguile/ports.h"
41
42 #ifdef HAVE_STRING_H
43 #include <string.h>
44 #endif
45
46 #ifdef HAVE_MALLOC_H
47 #include <malloc.h>
48 #endif
49
50 #ifdef HAVE_IO_H
51 #include <io.h>
52 #endif
53
54 #ifdef HAVE_UNISTD_H
55 #include <unistd.h>
56 #endif
57
58 #ifdef HAVE_SYS_IOCTL_H
59 #include <sys/ioctl.h>
60 #endif
61
62 #ifdef __MINGW32__
63 #include <fcntl.h>
64 #define ftruncate(fd, size) chsize (fd, size)
65 #endif
66
67 \f
68 /* The port kind table --- a dynamically resized array of port types. */
69
70
71 /* scm_ptobs scm_numptob
72 * implement a dynamicly resized array of ptob records.
73 * Indexes into this table are used when generating type
74 * tags for smobjects (if you know a tag you can get an index and conversely).
75 */
76 scm_t_ptob_descriptor *scm_ptobs;
77 long scm_numptob;
78
79 /* GC marker for a port with stream of SCM type. */
80 SCM
81 scm_markstream (SCM ptr)
82 {
83 int openp;
84 openp = SCM_CELL_WORD_0 (ptr) & SCM_OPN;
85 if (openp)
86 return SCM_PACK (SCM_STREAM (ptr));
87 else
88 return SCM_BOOL_F;
89 }
90
91 /*
92 * We choose to use an interface similar to the smob interface with
93 * fill_input and write as standard fields, passed to the port
94 * type constructor, and optional fields set by setters.
95 */
96
97 static void
98 flush_port_default (SCM port SCM_UNUSED)
99 {
100 }
101
102 static void
103 end_input_default (SCM port SCM_UNUSED, int offset SCM_UNUSED)
104 {
105 }
106
107 static size_t
108 scm_port_free0 (SCM port)
109 {
110 return 0;
111 }
112
113 scm_t_bits
114 scm_make_port_type (char *name,
115 int (*fill_input) (SCM port),
116 void (*write) (SCM port, const void *data, size_t size))
117 {
118 char *tmp;
119 if (255 <= scm_numptob)
120 goto ptoberr;
121 SCM_DEFER_INTS;
122 SCM_SYSCALL (tmp = (char *) realloc ((char *) scm_ptobs,
123 (1 + scm_numptob)
124 * sizeof (scm_t_ptob_descriptor)));
125 if (tmp)
126 {
127 scm_ptobs = (scm_t_ptob_descriptor *) tmp;
128
129 scm_ptobs[scm_numptob].name = name;
130 scm_ptobs[scm_numptob].mark = 0;
131 scm_ptobs[scm_numptob].free = scm_port_free0;
132 scm_ptobs[scm_numptob].print = scm_port_print;
133 scm_ptobs[scm_numptob].equalp = 0;
134 scm_ptobs[scm_numptob].close = 0;
135
136 scm_ptobs[scm_numptob].write = write;
137 scm_ptobs[scm_numptob].flush = flush_port_default;
138
139 scm_ptobs[scm_numptob].end_input = end_input_default;
140 scm_ptobs[scm_numptob].fill_input = fill_input;
141 scm_ptobs[scm_numptob].input_waiting = 0;
142
143 scm_ptobs[scm_numptob].seek = 0;
144 scm_ptobs[scm_numptob].truncate = 0;
145
146 scm_numptob++;
147 }
148 SCM_ALLOW_INTS;
149 if (!tmp)
150 {
151 ptoberr:
152 scm_memory_error ("scm_make_port_type");
153 }
154 /* Make a class object if Goops is present */
155 if (scm_port_class)
156 scm_make_port_classes (scm_numptob - 1, SCM_PTOBNAME (scm_numptob - 1));
157 return scm_tc7_port + (scm_numptob - 1) * 256;
158 }
159
160 void
161 scm_set_port_mark (long tc, SCM (*mark) (SCM))
162 {
163 scm_ptobs[SCM_TC2PTOBNUM (tc)].mark = mark;
164 }
165
166 void
167 scm_set_port_free (long tc, size_t (*free) (SCM))
168 {
169 scm_ptobs[SCM_TC2PTOBNUM (tc)].free = free;
170 }
171
172 void
173 scm_set_port_print (long tc, int (*print) (SCM exp, SCM port,
174 scm_print_state *pstate))
175 {
176 scm_ptobs[SCM_TC2PTOBNUM (tc)].print = print;
177 }
178
179 void
180 scm_set_port_equalp (long tc, SCM (*equalp) (SCM, SCM))
181 {
182 scm_ptobs[SCM_TC2PTOBNUM (tc)].equalp = equalp;
183 }
184
185 void
186 scm_set_port_flush (long tc, void (*flush) (SCM port))
187 {
188 scm_ptobs[SCM_TC2PTOBNUM (tc)].flush = flush;
189 }
190
191 void
192 scm_set_port_end_input (long tc, void (*end_input) (SCM port, int offset))
193 {
194 scm_ptobs[SCM_TC2PTOBNUM (tc)].end_input = end_input;
195 }
196
197 void
198 scm_set_port_close (long tc, int (*close) (SCM))
199 {
200 scm_ptobs[SCM_TC2PTOBNUM (tc)].close = close;
201 }
202
203 void
204 scm_set_port_seek (long tc, off_t (*seek) (SCM port,
205 off_t OFFSET,
206 int WHENCE))
207 {
208 scm_ptobs[SCM_TC2PTOBNUM (tc)].seek = seek;
209 }
210
211 void
212 scm_set_port_truncate (long tc, void (*truncate) (SCM port, off_t length))
213 {
214 scm_ptobs[SCM_TC2PTOBNUM (tc)].truncate = truncate;
215 }
216
217 void
218 scm_set_port_input_waiting (long tc, int (*input_waiting) (SCM))
219 {
220 scm_ptobs[SCM_TC2PTOBNUM (tc)].input_waiting = input_waiting;
221 }
222
223 \f
224
225 SCM_DEFINE (scm_char_ready_p, "char-ready?", 0, 1, 0,
226 (SCM port),
227 "Return @code{#t} if a character is ready on input @var{port}\n"
228 "and return @code{#f} otherwise. If @code{char-ready?} returns\n"
229 "@code{#t} then the next @code{read-char} operation on\n"
230 "@var{port} is guaranteed not to hang. If @var{port} is a file\n"
231 "port at end of file then @code{char-ready?} returns @code{#t}.\n"
232 "@footnote{@code{char-ready?} exists to make it possible for a\n"
233 "program to accept characters from interactive ports without\n"
234 "getting stuck waiting for input. Any input editors associated\n"
235 "with such ports must make sure that characters whose existence\n"
236 "has been asserted by @code{char-ready?} cannot be rubbed out.\n"
237 "If @code{char-ready?} were to return @code{#f} at end of file,\n"
238 "a port at end of file would be indistinguishable from an\n"
239 "interactive port that has no ready characters.}")
240 #define FUNC_NAME s_scm_char_ready_p
241 {
242 scm_t_port *pt;
243
244 if (SCM_UNBNDP (port))
245 port = scm_cur_inp;
246 else
247 SCM_VALIDATE_OPINPORT (1, port);
248
249 pt = SCM_PTAB_ENTRY (port);
250
251 /* if the current read buffer is filled, or the
252 last pushed-back char has been read and the saved buffer is
253 filled, result is true. */
254 if (pt->read_pos < pt->read_end
255 || (pt->read_buf == pt->putback_buf
256 && pt->saved_read_pos < pt->saved_read_end))
257 return SCM_BOOL_T;
258 else
259 {
260 scm_t_ptob_descriptor *ptob = &scm_ptobs[SCM_PTOBNUM (port)];
261
262 if (ptob->input_waiting)
263 return SCM_BOOL(ptob->input_waiting (port));
264 else
265 return SCM_BOOL_T;
266 }
267 }
268 #undef FUNC_NAME
269
270 /* move up to read_len chars from port's putback and/or read buffers
271 into memory starting at dest. returns the number of chars moved. */
272 size_t scm_take_from_input_buffers (SCM port, char *dest, size_t read_len)
273 {
274 scm_t_port *pt = SCM_PTAB_ENTRY (port);
275 size_t chars_read = 0;
276 size_t from_buf = min (pt->read_end - pt->read_pos, read_len);
277
278 if (from_buf > 0)
279 {
280 memcpy (dest, pt->read_pos, from_buf);
281 pt->read_pos += from_buf;
282 chars_read += from_buf;
283 read_len -= from_buf;
284 dest += from_buf;
285 }
286
287 /* if putback was active, try the real input buffer too. */
288 if (pt->read_buf == pt->putback_buf)
289 {
290 from_buf = min (pt->saved_read_end - pt->saved_read_pos, read_len);
291 if (from_buf > 0)
292 {
293 memcpy (dest, pt->saved_read_pos, from_buf);
294 pt->saved_read_pos += from_buf;
295 chars_read += from_buf;
296 }
297 }
298 return chars_read;
299 }
300
301 /* Clear a port's read buffers, returning the contents. */
302 SCM_DEFINE (scm_drain_input, "drain-input", 1, 0, 0,
303 (SCM port),
304 "This procedure clears a port's input buffers, similar\n"
305 "to the way that force-output clears the output buffer. The\n"
306 "contents of the buffers are returned as a single string, e.g.,\n"
307 "\n"
308 "@lisp\n"
309 "(define p (open-input-file ...))\n"
310 "(drain-input p) => empty string, nothing buffered yet.\n"
311 "(unread-char (read-char p) p)\n"
312 "(drain-input p) => initial chars from p, up to the buffer size.\n"
313 "@end lisp\n\n"
314 "Draining the buffers may be useful for cleanly finishing\n"
315 "buffered I/O so that the file descriptor can be used directly\n"
316 "for further input.")
317 #define FUNC_NAME s_scm_drain_input
318 {
319 SCM result;
320 scm_t_port *pt = SCM_PTAB_ENTRY (port);
321 long count;
322
323 SCM_VALIDATE_OPINPORT (1, port);
324
325 count = pt->read_end - pt->read_pos;
326 if (pt->read_buf == pt->putback_buf)
327 count += pt->saved_read_end - pt->saved_read_pos;
328
329 result = scm_allocate_string (count);
330 scm_take_from_input_buffers (port, SCM_STRING_CHARS (result), count);
331
332 return result;
333 }
334 #undef FUNC_NAME
335
336 \f
337 /* Standard ports --- current input, output, error, and more(!). */
338
339 SCM_DEFINE (scm_current_input_port, "current-input-port", 0, 0, 0,
340 (),
341 "Return the current input port. This is the default port used\n"
342 "by many input procedures. Initially, @code{current-input-port}\n"
343 "returns the @dfn{standard input} in Unix and C terminology.")
344 #define FUNC_NAME s_scm_current_input_port
345 {
346 return scm_cur_inp;
347 }
348 #undef FUNC_NAME
349
350 SCM_DEFINE (scm_current_output_port, "current-output-port", 0, 0, 0,
351 (),
352 "Return the current output port. This is the default port used\n"
353 "by many output procedures. Initially,\n"
354 "@code{current-output-port} returns the @dfn{standard output} in\n"
355 "Unix and C terminology.")
356 #define FUNC_NAME s_scm_current_output_port
357 {
358 return scm_cur_outp;
359 }
360 #undef FUNC_NAME
361
362 SCM_DEFINE (scm_current_error_port, "current-error-port", 0, 0, 0,
363 (),
364 "Return the port to which errors and warnings should be sent (the\n"
365 "@dfn{standard error} in Unix and C terminology).")
366 #define FUNC_NAME s_scm_current_error_port
367 {
368 return scm_cur_errp;
369 }
370 #undef FUNC_NAME
371
372 SCM_DEFINE (scm_current_load_port, "current-load-port", 0, 0, 0,
373 (),
374 "Return the current-load-port.\n"
375 "The load port is used internally by @code{primitive-load}.")
376 #define FUNC_NAME s_scm_current_load_port
377 {
378 return scm_cur_loadp;
379 }
380 #undef FUNC_NAME
381
382 SCM_DEFINE (scm_set_current_input_port, "set-current-input-port", 1, 0, 0,
383 (SCM port),
384 "@deffnx {Scheme Procedure} set-current-output-port port\n"
385 "@deffnx {Scheme Procedure} set-current-error-port port\n"
386 "Change the ports returned by @code{current-input-port},\n"
387 "@code{current-output-port} and @code{current-error-port}, respectively,\n"
388 "so that they use the supplied @var{port} for input or output.")
389 #define FUNC_NAME s_scm_set_current_input_port
390 {
391 SCM oinp = scm_cur_inp;
392 SCM_VALIDATE_OPINPORT (1, port);
393 scm_cur_inp = port;
394 return oinp;
395 }
396 #undef FUNC_NAME
397
398
399 SCM_DEFINE (scm_set_current_output_port, "set-current-output-port", 1, 0, 0,
400 (SCM port),
401 "Set the current default output port to @var{port}.")
402 #define FUNC_NAME s_scm_set_current_output_port
403 {
404 SCM ooutp = scm_cur_outp;
405 port = SCM_COERCE_OUTPORT (port);
406 SCM_VALIDATE_OPOUTPORT (1, port);
407 scm_cur_outp = port;
408 return ooutp;
409 }
410 #undef FUNC_NAME
411
412
413 SCM_DEFINE (scm_set_current_error_port, "set-current-error-port", 1, 0, 0,
414 (SCM port),
415 "Set the current default error port to @var{port}.")
416 #define FUNC_NAME s_scm_set_current_error_port
417 {
418 SCM oerrp = scm_cur_errp;
419 port = SCM_COERCE_OUTPORT (port);
420 SCM_VALIDATE_OPOUTPORT (1, port);
421 scm_cur_errp = port;
422 return oerrp;
423 }
424 #undef FUNC_NAME
425
426 \f
427 /* The port table --- an array of pointers to ports. */
428
429 scm_t_port **scm_i_port_table;
430
431 long scm_i_port_table_size = 0; /* Number of ports in scm_i_port_table. */
432 long scm_i_port_table_room = 20; /* Size of the array. */
433
434
435 SCM
436 scm_new_port_table_entry (scm_t_bits tag)
437 #define FUNC_NAME "scm_new_port_table_entry"
438 {
439 /*
440 We initialize the cell to empty, this is in case scm_gc_calloc
441 triggers GC ; we don't want the GC to scan a half-finished Z.
442 */
443
444 SCM z = scm_cons (SCM_EOL, SCM_EOL);
445 scm_t_port *entry = (scm_t_port *) scm_gc_calloc (sizeof (scm_t_port), "port");
446 if (scm_i_port_table_size == scm_i_port_table_room)
447 {
448 /* initial malloc is in gc.c. this doesn't use scm_gc_malloc etc.,
449 since it can never be freed during gc. */
450 void *newt = scm_realloc ((char *) scm_i_port_table,
451 (size_t) (sizeof (scm_t_port *)
452 * scm_i_port_table_room * 2));
453 scm_i_port_table = (scm_t_port **) newt;
454 scm_i_port_table_room *= 2;
455 }
456
457 entry->entry = scm_i_port_table_size;
458
459 entry->file_name = SCM_BOOL_F;
460 entry->rw_active = SCM_PORT_NEITHER;
461
462 scm_i_port_table[scm_i_port_table_size] = entry;
463 scm_i_port_table_size++;
464
465 entry->port = z;
466 SCM_SET_CELL_TYPE(z, tag);
467 SCM_SETPTAB_ENTRY(z, entry);
468
469 return z;
470 }
471 #undef FUNC_NAME
472
473 #if SCM_ENABLE_DEPRECATED==1
474 SCM_API scm_t_port *
475 scm_add_to_port_table (SCM port)
476 {
477 SCM z = scm_new_port_table_entry (scm_tc7_port);
478 scm_t_port * pt = SCM_PTAB_ENTRY(z);
479
480 pt->port = port;
481 SCM_SETCAR(z, SCM_EOL);
482 SCM_SETCDR(z, SCM_EOL);
483 SCM_SETPTAB_ENTRY (port, pt);
484 return pt;
485 }
486 #endif
487
488
489 /* Remove a port from the table and destroy it. */
490 void
491 scm_remove_from_port_table (SCM port)
492 #define FUNC_NAME "scm_remove_from_port_table"
493 {
494 scm_t_port *p = SCM_PTAB_ENTRY (port);
495 long i = p->entry;
496
497 if (i >= scm_i_port_table_size)
498 SCM_MISC_ERROR ("Port not in table: ~S", scm_list_1 (port));
499 if (p->putback_buf)
500 scm_gc_free (p->putback_buf, p->putback_buf_size, "putback buffer");
501 scm_gc_free (p, sizeof (scm_t_port), "port");
502 /* Since we have just freed slot i we can shrink the table by moving
503 the last entry to that slot... */
504 if (i < scm_i_port_table_size - 1)
505 {
506 scm_i_port_table[i] = scm_i_port_table[scm_i_port_table_size - 1];
507 scm_i_port_table[i]->entry = i;
508 }
509 SCM_SETPTAB_ENTRY (port, 0);
510 scm_i_port_table_size--;
511 }
512 #undef FUNC_NAME
513
514
515 #ifdef GUILE_DEBUG
516 /* Functions for debugging. */
517
518 SCM_DEFINE (scm_pt_size, "pt-size", 0, 0, 0,
519 (),
520 "Return the number of ports in the port table. @code{pt-size}\n"
521 "is only included in @code{--enable-guile-debug} builds.")
522 #define FUNC_NAME s_scm_pt_size
523 {
524 return SCM_MAKINUM (scm_i_port_table_size);
525 }
526 #undef FUNC_NAME
527
528 SCM_DEFINE (scm_pt_member, "pt-member", 1, 0, 0,
529 (SCM index),
530 "Return the port at @var{index} in the port table.\n"
531 "@code{pt-member} is only included in\n"
532 "@code{--enable-guile-debug} builds.")
533 #define FUNC_NAME s_scm_pt_member
534 {
535 long i;
536 SCM_VALIDATE_INUM_COPY (1, index, i);
537 if (i < 0 || i >= scm_i_port_table_size)
538 return SCM_BOOL_F;
539 else
540 return scm_i_port_table[i]->port;
541 }
542 #undef FUNC_NAME
543 #endif
544
545 void
546 scm_port_non_buffer (scm_t_port *pt)
547 {
548 pt->read_pos = pt->read_buf = pt->read_end = &pt->shortbuf;
549 pt->write_buf = pt->write_pos = &pt->shortbuf;
550 pt->read_buf_size = pt->write_buf_size = 1;
551 pt->write_end = pt->write_buf + pt->write_buf_size;
552 }
553
554 \f
555 /* Revealed counts --- an oddity inherited from SCSH. */
556
557 /* Find a port in the table and return its revealed count.
558 Also used by the garbage collector.
559 */
560
561 int
562 scm_revealed_count (SCM port)
563 {
564 return SCM_REVEALED(port);
565 }
566
567
568
569 /* Return the revealed count for a port. */
570
571 SCM_DEFINE (scm_port_revealed, "port-revealed", 1, 0, 0,
572 (SCM port),
573 "Return the revealed count for @var{port}.")
574 #define FUNC_NAME s_scm_port_revealed
575 {
576 port = SCM_COERCE_OUTPORT (port);
577 SCM_VALIDATE_OPENPORT (1, port);
578 return SCM_MAKINUM (scm_revealed_count (port));
579 }
580 #undef FUNC_NAME
581
582 /* Set the revealed count for a port. */
583 SCM_DEFINE (scm_set_port_revealed_x, "set-port-revealed!", 2, 0, 0,
584 (SCM port, SCM rcount),
585 "Sets the revealed count for a port to a given value.\n"
586 "The return value is unspecified.")
587 #define FUNC_NAME s_scm_set_port_revealed_x
588 {
589 port = SCM_COERCE_OUTPORT (port);
590 SCM_VALIDATE_OPENPORT (1, port);
591 SCM_VALIDATE_INUM (2, rcount);
592 SCM_REVEALED (port) = SCM_INUM (rcount);
593 return SCM_UNSPECIFIED;
594 }
595 #undef FUNC_NAME
596
597
598 \f
599 /* Retrieving a port's mode. */
600
601 /* Return the flags that characterize a port based on the mode
602 * string used to open a file for that port.
603 *
604 * See PORT FLAGS in scm.h
605 */
606
607 long
608 scm_mode_bits (char *modes)
609 {
610 return (SCM_OPN
611 | (strchr (modes, 'r') || strchr (modes, '+') ? SCM_RDNG : 0)
612 | ( strchr (modes, 'w')
613 || strchr (modes, 'a')
614 || strchr (modes, '+') ? SCM_WRTNG : 0)
615 | (strchr (modes, '0') ? SCM_BUF0 : 0)
616 | (strchr (modes, 'l') ? SCM_BUFLINE : 0));
617 }
618
619
620 /* Return the mode flags from an open port.
621 * Some modes such as "append" are only used when opening
622 * a file and are not returned here. */
623
624 SCM_DEFINE (scm_port_mode, "port-mode", 1, 0, 0,
625 (SCM port),
626 "Return the port modes associated with the open port @var{port}.\n"
627 "These will not necessarily be identical to the modes used when\n"
628 "the port was opened, since modes such as \"append\" which are\n"
629 "used only during port creation are not retained.")
630 #define FUNC_NAME s_scm_port_mode
631 {
632 char modes[4];
633 modes[0] = '\0';
634
635 port = SCM_COERCE_OUTPORT (port);
636 SCM_VALIDATE_OPPORT (1, port);
637 if (SCM_CELL_WORD_0 (port) & SCM_RDNG) {
638 if (SCM_CELL_WORD_0 (port) & SCM_WRTNG)
639 strcpy (modes, "r+");
640 else
641 strcpy (modes, "r");
642 }
643 else if (SCM_CELL_WORD_0 (port) & SCM_WRTNG)
644 strcpy (modes, "w");
645 if (SCM_CELL_WORD_0 (port) & SCM_BUF0)
646 strcat (modes, "0");
647 return scm_mem2string (modes, strlen (modes));
648 }
649 #undef FUNC_NAME
650
651
652 \f
653 /* Closing ports. */
654
655 /* scm_close_port
656 * Call the close operation on a port object.
657 * see also scm_close.
658 */
659 SCM_DEFINE (scm_close_port, "close-port", 1, 0, 0,
660 (SCM port),
661 "Close the specified port object. Return @code{#t} if it\n"
662 "successfully closes a port or @code{#f} if it was already\n"
663 "closed. An exception may be raised if an error occurs, for\n"
664 "example when flushing buffered output. See also @ref{Ports and\n"
665 "File Descriptors, close}, for a procedure which can close file\n"
666 "descriptors.")
667 #define FUNC_NAME s_scm_close_port
668 {
669 size_t i;
670 int rv;
671
672 port = SCM_COERCE_OUTPORT (port);
673
674 SCM_VALIDATE_PORT (1, port);
675 if (SCM_CLOSEDP (port))
676 return SCM_BOOL_F;
677 i = SCM_PTOBNUM (port);
678 if (scm_ptobs[i].close)
679 rv = (scm_ptobs[i].close) (port);
680 else
681 rv = 0;
682 scm_remove_from_port_table (port);
683 SCM_CLR_PORT_OPEN_FLAG (port);
684 return SCM_BOOL (rv >= 0);
685 }
686 #undef FUNC_NAME
687
688 SCM_DEFINE (scm_close_input_port, "close-input-port", 1, 0, 0,
689 (SCM port),
690 "Close the specified input port object. The routine has no effect if\n"
691 "the file has already been closed. An exception may be raised if an\n"
692 "error occurs. The value returned is unspecified.\n\n"
693 "See also @ref{Ports and File Descriptors, close}, for a procedure\n"
694 "which can close file descriptors.")
695 #define FUNC_NAME s_scm_close_input_port
696 {
697 SCM_VALIDATE_INPUT_PORT (1, port);
698 scm_close_port (port);
699 return SCM_UNSPECIFIED;
700 }
701 #undef FUNC_NAME
702
703 SCM_DEFINE (scm_close_output_port, "close-output-port", 1, 0, 0,
704 (SCM port),
705 "Close the specified output port object. The routine has no effect if\n"
706 "the file has already been closed. An exception may be raised if an\n"
707 "error occurs. The value returned is unspecified.\n\n"
708 "See also @ref{Ports and File Descriptors, close}, for a procedure\n"
709 "which can close file descriptors.")
710 #define FUNC_NAME s_scm_close_output_port
711 {
712 port = SCM_COERCE_OUTPORT (port);
713 SCM_VALIDATE_OUTPUT_PORT (1, port);
714 scm_close_port (port);
715 return SCM_UNSPECIFIED;
716 }
717 #undef FUNC_NAME
718
719 SCM_DEFINE (scm_port_for_each, "port-for-each", 1, 0, 0,
720 (SCM proc),
721 "Apply @var{proc} to each port in the Guile port table\n"
722 "in turn. The return value is unspecified. More specifically,\n"
723 "@var{proc} is applied exactly once to every port that exists\n"
724 "in the system at the time @var{port-for-each} is invoked.\n"
725 "Changes to the port table while @var{port-for-each} is running\n"
726 "have no effect as far as @var{port-for-each} is concerned.")
727 #define FUNC_NAME s_scm_port_for_each
728 {
729 long i;
730 SCM ports;
731
732 SCM_VALIDATE_PROC (1, proc);
733
734 /* when pre-emptive multithreading is supported, access to the port
735 table will need to be controlled by a mutex. */
736
737 /* Even without pre-emptive multithreading, running arbitrary code
738 while scanning the port table is unsafe because the port table
739 can change arbitrarily (from a GC, for example). So we build a
740 list in advance while blocking the GC. -mvo */
741
742 SCM_DEFER_INTS;
743 scm_block_gc++;
744 ports = SCM_EOL;
745 for (i = 0; i < scm_i_port_table_size; i++)
746 ports = scm_cons (scm_i_port_table[i]->port, ports);
747 scm_block_gc--;
748 SCM_ALLOW_INTS;
749
750 while (ports != SCM_EOL)
751 {
752 scm_call_1 (proc, SCM_CAR (ports));
753 ports = SCM_CDR (ports);
754 }
755
756 return SCM_UNSPECIFIED;
757 }
758 #undef FUNC_NAME
759
760 \f
761 /* Utter miscellany. Gosh, we should clean this up some time. */
762
763 SCM_DEFINE (scm_input_port_p, "input-port?", 1, 0, 0,
764 (SCM x),
765 "Return @code{#t} if @var{x} is an input port, otherwise return\n"
766 "@code{#f}. Any object satisfying this predicate also satisfies\n"
767 "@code{port?}.")
768 #define FUNC_NAME s_scm_input_port_p
769 {
770 return SCM_BOOL (SCM_INPUT_PORT_P (x));
771 }
772 #undef FUNC_NAME
773
774 SCM_DEFINE (scm_output_port_p, "output-port?", 1, 0, 0,
775 (SCM x),
776 "Return @code{#t} if @var{x} is an output port, otherwise return\n"
777 "@code{#f}. Any object satisfying this predicate also satisfies\n"
778 "@code{port?}.")
779 #define FUNC_NAME s_scm_output_port_p
780 {
781 x = SCM_COERCE_OUTPORT (x);
782 return SCM_BOOL (SCM_OUTPUT_PORT_P (x));
783 }
784 #undef FUNC_NAME
785
786 SCM_DEFINE (scm_port_p, "port?", 1, 0, 0,
787 (SCM x),
788 "Return a boolean indicating whether @var{x} is a port.\n"
789 "Equivalent to @code{(or (input-port? @var{x}) (output-port?\n"
790 "@var{x}))}.")
791 #define FUNC_NAME s_scm_port_p
792 {
793 return SCM_BOOL (SCM_PORTP (x));
794 }
795 #undef FUNC_NAME
796
797 SCM_DEFINE (scm_port_closed_p, "port-closed?", 1, 0, 0,
798 (SCM port),
799 "Return @code{#t} if @var{port} is closed or @code{#f} if it is\n"
800 "open.")
801 #define FUNC_NAME s_scm_port_closed_p
802 {
803 SCM_VALIDATE_PORT (1, port);
804 return SCM_BOOL (!SCM_OPPORTP (port));
805 }
806 #undef FUNC_NAME
807
808 SCM_DEFINE (scm_eof_object_p, "eof-object?", 1, 0, 0,
809 (SCM x),
810 "Return @code{#t} if @var{x} is an end-of-file object; otherwise\n"
811 "return @code{#f}.")
812 #define FUNC_NAME s_scm_eof_object_p
813 {
814 return SCM_BOOL(SCM_EOF_OBJECT_P (x));
815 }
816 #undef FUNC_NAME
817
818 SCM_DEFINE (scm_force_output, "force-output", 0, 1, 0,
819 (SCM port),
820 "Flush the specified output port, or the current output port if @var{port}\n"
821 "is omitted. The current output buffer contents are passed to the\n"
822 "underlying port implementation (e.g., in the case of fports, the\n"
823 "data will be written to the file and the output buffer will be cleared.)\n"
824 "It has no effect on an unbuffered port.\n\n"
825 "The return value is unspecified.")
826 #define FUNC_NAME s_scm_force_output
827 {
828 if (SCM_UNBNDP (port))
829 port = scm_cur_outp;
830 else
831 {
832 port = SCM_COERCE_OUTPORT (port);
833 SCM_VALIDATE_OPOUTPORT (1, port);
834 }
835 scm_flush (port);
836 return SCM_UNSPECIFIED;
837 }
838 #undef FUNC_NAME
839
840 SCM_DEFINE (scm_flush_all_ports, "flush-all-ports", 0, 0, 0,
841 (),
842 "Equivalent to calling @code{force-output} on\n"
843 "all open output ports. The return value is unspecified.")
844 #define FUNC_NAME s_scm_flush_all_ports
845 {
846 size_t i;
847
848 for (i = 0; i < scm_i_port_table_size; i++)
849 {
850 if (SCM_OPOUTPORTP (scm_i_port_table[i]->port))
851 scm_flush (scm_i_port_table[i]->port);
852 }
853 return SCM_UNSPECIFIED;
854 }
855 #undef FUNC_NAME
856
857 SCM_DEFINE (scm_read_char, "read-char", 0, 1, 0,
858 (SCM port),
859 "Return the next character available from @var{port}, updating\n"
860 "@var{port} to point to the following character. If no more\n"
861 "characters are available, the end-of-file object is returned.")
862 #define FUNC_NAME s_scm_read_char
863 {
864 int c;
865 if (SCM_UNBNDP (port))
866 port = scm_cur_inp;
867 SCM_VALIDATE_OPINPORT (1, port);
868 c = scm_getc (port);
869 if (EOF == c)
870 return SCM_EOF_VAL;
871 return SCM_MAKE_CHAR (c);
872 }
873 #undef FUNC_NAME
874
875 /* this should only be called when the read buffer is empty. it
876 tries to refill the read buffer. it returns the first char from
877 the port, which is either EOF or *(pt->read_pos). */
878 int
879 scm_fill_input (SCM port)
880 {
881 scm_t_port *pt = SCM_PTAB_ENTRY (port);
882
883 if (pt->read_buf == pt->putback_buf)
884 {
885 /* finished reading put-back chars. */
886 pt->read_buf = pt->saved_read_buf;
887 pt->read_pos = pt->saved_read_pos;
888 pt->read_end = pt->saved_read_end;
889 pt->read_buf_size = pt->saved_read_buf_size;
890 if (pt->read_pos < pt->read_end)
891 return *(pt->read_pos);
892 }
893 return scm_ptobs[SCM_PTOBNUM (port)].fill_input (port);
894 }
895
896 int
897 scm_getc (SCM port)
898 {
899 int c;
900 scm_t_port *pt = SCM_PTAB_ENTRY (port);
901
902 if (pt->rw_active == SCM_PORT_WRITE)
903 /* may be marginally faster than calling scm_flush. */
904 scm_ptobs[SCM_PTOBNUM (port)].flush (port);
905
906 if (pt->rw_random)
907 pt->rw_active = SCM_PORT_READ;
908
909 if (pt->read_pos >= pt->read_end)
910 {
911 if (scm_fill_input (port) == EOF)
912 return EOF;
913 }
914
915 c = *(pt->read_pos++);
916
917 switch (c)
918 {
919 case '\n':
920 SCM_INCLINE (port);
921 break;
922 case '\t':
923 SCM_TABCOL (port);
924 break;
925 default:
926 SCM_INCCOL (port);
927 break;
928 }
929
930 return c;
931 }
932
933 void
934 scm_putc (char c, SCM port)
935 {
936 scm_lfwrite (&c, 1, port);
937 }
938
939 void
940 scm_puts (const char *s, SCM port)
941 {
942 scm_lfwrite (s, strlen (s), port);
943 }
944
945 /* scm_lfwrite
946 *
947 * This function differs from scm_c_write; it updates port line and
948 * column. */
949
950 void
951 scm_lfwrite (const char *ptr, size_t size, SCM port)
952 {
953 scm_t_port *pt = SCM_PTAB_ENTRY (port);
954 scm_t_ptob_descriptor *ptob = &scm_ptobs[SCM_PTOBNUM (port)];
955
956 if (pt->rw_active == SCM_PORT_READ)
957 scm_end_input (port);
958
959 ptob->write (port, ptr, size);
960
961 for (; size; ptr++, size--) {
962 if (*ptr == '\n') {
963 SCM_INCLINE(port);
964 }
965 else if (*ptr == '\t') {
966 SCM_TABCOL(port);
967 }
968 else {
969 SCM_INCCOL(port);
970 }
971 }
972
973 if (pt->rw_random)
974 pt->rw_active = SCM_PORT_WRITE;
975 }
976
977 /* scm_c_read
978 *
979 * Used by an application to read arbitrary number of bytes from an
980 * SCM port. Same semantics as libc read, except that scm_c_read only
981 * returns less than SIZE bytes if at end-of-file.
982 *
983 * Warning: Doesn't update port line and column counts! */
984
985 size_t
986 scm_c_read (SCM port, void *buffer, size_t size)
987 {
988 scm_t_port *pt = SCM_PTAB_ENTRY (port);
989 size_t n_read = 0, n_available;
990
991 if (pt->rw_active == SCM_PORT_WRITE)
992 scm_ptobs[SCM_PTOBNUM (port)].flush (port);
993
994 if (pt->rw_random)
995 pt->rw_active = SCM_PORT_READ;
996
997 if (SCM_READ_BUFFER_EMPTY_P (pt))
998 {
999 if (scm_fill_input (port) == EOF)
1000 return 0;
1001 }
1002
1003 n_available = pt->read_end - pt->read_pos;
1004
1005 while (n_available < size)
1006 {
1007 memcpy (buffer, pt->read_pos, n_available);
1008 buffer = (char *) buffer + n_available;
1009 pt->read_pos += n_available;
1010 n_read += n_available;
1011
1012 if (SCM_READ_BUFFER_EMPTY_P (pt))
1013 {
1014 if (scm_fill_input (port) == EOF)
1015 return n_read;
1016 }
1017
1018 size -= n_available;
1019 n_available = pt->read_end - pt->read_pos;
1020 }
1021
1022 memcpy (buffer, pt->read_pos, size);
1023 pt->read_pos += size;
1024
1025 return n_read + size;
1026 }
1027
1028 /* scm_c_write
1029 *
1030 * Used by an application to write arbitrary number of bytes to an SCM
1031 * port. Similar semantics as libc write. However, unlike libc
1032 * write, scm_c_write writes the requested number of bytes and has no
1033 * return value.
1034 *
1035 * Warning: Doesn't update port line and column counts!
1036 */
1037
1038 void
1039 scm_c_write (SCM port, const void *ptr, size_t size)
1040 {
1041 scm_t_port *pt = SCM_PTAB_ENTRY (port);
1042 scm_t_ptob_descriptor *ptob = &scm_ptobs[SCM_PTOBNUM (port)];
1043
1044 if (pt->rw_active == SCM_PORT_READ)
1045 scm_end_input (port);
1046
1047 ptob->write (port, ptr, size);
1048
1049 if (pt->rw_random)
1050 pt->rw_active = SCM_PORT_WRITE;
1051 }
1052
1053 void
1054 scm_flush (SCM port)
1055 {
1056 long i = SCM_PTOBNUM (port);
1057 (scm_ptobs[i].flush) (port);
1058 }
1059
1060 void
1061 scm_end_input (SCM port)
1062 {
1063 long offset;
1064 scm_t_port *pt = SCM_PTAB_ENTRY (port);
1065
1066 if (pt->read_buf == pt->putback_buf)
1067 {
1068 offset = pt->read_end - pt->read_pos;
1069 pt->read_buf = pt->saved_read_buf;
1070 pt->read_pos = pt->saved_read_pos;
1071 pt->read_end = pt->saved_read_end;
1072 pt->read_buf_size = pt->saved_read_buf_size;
1073 }
1074 else
1075 offset = 0;
1076
1077 scm_ptobs[SCM_PTOBNUM (port)].end_input (port, offset);
1078 }
1079
1080 \f
1081
1082
1083 void
1084 scm_ungetc (int c, SCM port)
1085 #define FUNC_NAME "scm_ungetc"
1086 {
1087 scm_t_port *pt = SCM_PTAB_ENTRY (port);
1088
1089 if (pt->read_buf == pt->putback_buf)
1090 /* already using the put-back buffer. */
1091 {
1092 /* enlarge putback_buf if necessary. */
1093 if (pt->read_end == pt->read_buf + pt->read_buf_size
1094 && pt->read_buf == pt->read_pos)
1095 {
1096 size_t new_size = pt->read_buf_size * 2;
1097 unsigned char *tmp = (unsigned char *)
1098 scm_gc_realloc (pt->putback_buf, pt->read_buf_size, new_size,
1099 "putback buffer");
1100
1101 pt->read_pos = pt->read_buf = pt->putback_buf = tmp;
1102 pt->read_end = pt->read_buf + pt->read_buf_size;
1103 pt->read_buf_size = pt->putback_buf_size = new_size;
1104 }
1105
1106 /* shift any existing bytes to buffer + 1. */
1107 if (pt->read_pos == pt->read_end)
1108 pt->read_end = pt->read_buf + 1;
1109 else if (pt->read_pos != pt->read_buf + 1)
1110 {
1111 int count = pt->read_end - pt->read_pos;
1112
1113 memmove (pt->read_buf + 1, pt->read_pos, count);
1114 pt->read_end = pt->read_buf + 1 + count;
1115 }
1116
1117 pt->read_pos = pt->read_buf;
1118 }
1119 else
1120 /* switch to the put-back buffer. */
1121 {
1122 if (pt->putback_buf == NULL)
1123 {
1124 pt->putback_buf
1125 = (unsigned char *) scm_gc_malloc (SCM_INITIAL_PUTBACK_BUF_SIZE,
1126 "putback buffer");
1127 pt->putback_buf_size = SCM_INITIAL_PUTBACK_BUF_SIZE;
1128 }
1129
1130 pt->saved_read_buf = pt->read_buf;
1131 pt->saved_read_pos = pt->read_pos;
1132 pt->saved_read_end = pt->read_end;
1133 pt->saved_read_buf_size = pt->read_buf_size;
1134
1135 pt->read_pos = pt->read_buf = pt->putback_buf;
1136 pt->read_end = pt->read_buf + 1;
1137 pt->read_buf_size = pt->putback_buf_size;
1138 }
1139
1140 *pt->read_buf = c;
1141
1142 if (pt->rw_random)
1143 pt->rw_active = SCM_PORT_READ;
1144
1145 if (c == '\n')
1146 {
1147 /* What should col be in this case?
1148 * We'll leave it at -1.
1149 */
1150 SCM_LINUM (port) -= 1;
1151 }
1152 else
1153 SCM_COL(port) -= 1;
1154 }
1155 #undef FUNC_NAME
1156
1157
1158 void
1159 scm_ungets (const char *s, int n, SCM port)
1160 {
1161 /* This is simple minded and inefficient, but unreading strings is
1162 * probably not a common operation, and remember that line and
1163 * column numbers have to be handled...
1164 *
1165 * Please feel free to write an optimized version!
1166 */
1167 while (n--)
1168 scm_ungetc (s[n], port);
1169 }
1170
1171
1172 SCM_DEFINE (scm_peek_char, "peek-char", 0, 1, 0,
1173 (SCM port),
1174 "Return the next character available from @var{port},\n"
1175 "@emph{without} updating @var{port} to point to the following\n"
1176 "character. If no more characters are available, the\n"
1177 "end-of-file object is returned.@footnote{The value returned by\n"
1178 "a call to @code{peek-char} is the same as the value that would\n"
1179 "have been returned by a call to @code{read-char} on the same\n"
1180 "port. The only difference is that the very next call to\n"
1181 "@code{read-char} or @code{peek-char} on that @var{port} will\n"
1182 "return the value returned by the preceding call to\n"
1183 "@code{peek-char}. In particular, a call to @code{peek-char} on\n"
1184 "an interactive port will hang waiting for input whenever a call\n"
1185 "to @code{read-char} would have hung.}")
1186 #define FUNC_NAME s_scm_peek_char
1187 {
1188 int c;
1189 if (SCM_UNBNDP (port))
1190 port = scm_cur_inp;
1191 else
1192 SCM_VALIDATE_OPINPORT (1, port);
1193 c = scm_getc (port);
1194 if (EOF == c)
1195 return SCM_EOF_VAL;
1196 scm_ungetc (c, port);
1197 return SCM_MAKE_CHAR (c);
1198 }
1199 #undef FUNC_NAME
1200
1201 SCM_DEFINE (scm_unread_char, "unread-char", 1, 1, 0,
1202 (SCM cobj, SCM port),
1203 "Place @var{char} in @var{port} so that it will be read by the\n"
1204 "next read operation. If called multiple times, the unread characters\n"
1205 "will be read again in last-in first-out order. If @var{port} is\n"
1206 "not supplied, the current input port is used.")
1207 #define FUNC_NAME s_scm_unread_char
1208 {
1209 int c;
1210
1211 SCM_VALIDATE_CHAR (1, cobj);
1212 if (SCM_UNBNDP (port))
1213 port = scm_cur_inp;
1214 else
1215 SCM_VALIDATE_OPINPORT (2, port);
1216
1217 c = SCM_CHAR (cobj);
1218
1219 scm_ungetc (c, port);
1220 return cobj;
1221 }
1222 #undef FUNC_NAME
1223
1224 SCM_DEFINE (scm_unread_string, "unread-string", 2, 0, 0,
1225 (SCM str, SCM port),
1226 "Place the string @var{str} in @var{port} so that its characters will be\n"
1227 "read in subsequent read operations. If called multiple times, the\n"
1228 "unread characters will be read again in last-in first-out order. If\n"
1229 "@var{port} is not supplied, the current-input-port is used.")
1230 #define FUNC_NAME s_scm_unread_string
1231 {
1232 SCM_VALIDATE_STRING (1, str);
1233 if (SCM_UNBNDP (port))
1234 port = scm_cur_inp;
1235 else
1236 SCM_VALIDATE_OPINPORT (2, port);
1237
1238 scm_ungets (SCM_STRING_CHARS (str), SCM_STRING_LENGTH (str), port);
1239
1240 return str;
1241 }
1242 #undef FUNC_NAME
1243
1244 SCM_DEFINE (scm_seek, "seek", 3, 0, 0,
1245 (SCM fd_port, SCM offset, SCM whence),
1246 "Sets the current position of @var{fd/port} to the integer\n"
1247 "@var{offset}, which is interpreted according to the value of\n"
1248 "@var{whence}.\n"
1249 "\n"
1250 "One of the following variables should be supplied for\n"
1251 "@var{whence}:\n"
1252 "@defvar SEEK_SET\n"
1253 "Seek from the beginning of the file.\n"
1254 "@end defvar\n"
1255 "@defvar SEEK_CUR\n"
1256 "Seek from the current position.\n"
1257 "@end defvar\n"
1258 "@defvar SEEK_END\n"
1259 "Seek from the end of the file.\n"
1260 "@end defvar\n"
1261 "If @var{fd/port} is a file descriptor, the underlying system\n"
1262 "call is @code{lseek}. @var{port} may be a string port.\n"
1263 "\n"
1264 "The value returned is the new position in the file. This means\n"
1265 "that the current position of a port can be obtained using:\n"
1266 "@lisp\n"
1267 "(seek port 0 SEEK_CUR)\n"
1268 "@end lisp")
1269 #define FUNC_NAME s_scm_seek
1270 {
1271 off_t off;
1272 off_t rv;
1273 int how;
1274
1275 fd_port = SCM_COERCE_OUTPORT (fd_port);
1276
1277 off = SCM_NUM2LONG (2, offset);
1278 SCM_VALIDATE_INUM_COPY (3, whence, how);
1279 if (how != SEEK_SET && how != SEEK_CUR && how != SEEK_END)
1280 SCM_OUT_OF_RANGE (3, whence);
1281 if (SCM_OPPORTP (fd_port))
1282 {
1283 scm_t_ptob_descriptor *ptob = scm_ptobs + SCM_PTOBNUM (fd_port);
1284
1285 if (!ptob->seek)
1286 SCM_MISC_ERROR ("port is not seekable",
1287 scm_cons (fd_port, SCM_EOL));
1288 else
1289 rv = ptob->seek (fd_port, off, how);
1290 }
1291 else /* file descriptor?. */
1292 {
1293 SCM_VALIDATE_INUM (1, fd_port);
1294 rv = lseek (SCM_INUM (fd_port), off, how);
1295 if (rv == -1)
1296 SCM_SYSERROR;
1297 }
1298 return scm_long2num (rv);
1299 }
1300 #undef FUNC_NAME
1301
1302 #ifdef __MINGW32__
1303 /* Define this function since it is not supported under Windows. */
1304 static int truncate (char *file, int length)
1305 {
1306 int ret = -1, fdes;
1307 if ((fdes = open (file, O_BINARY | O_WRONLY)) != -1)
1308 {
1309 ret = chsize (fdes, length);
1310 close (fdes);
1311 }
1312 return ret;
1313 }
1314 #endif /* __MINGW32__ */
1315
1316 SCM_DEFINE (scm_truncate_file, "truncate-file", 1, 1, 0,
1317 (SCM object, SCM length),
1318 "Truncates the object referred to by @var{object} to at most\n"
1319 "@var{length} bytes. @var{object} can be a string containing a\n"
1320 "file name or an integer file descriptor or a port.\n"
1321 "@var{length} may be omitted if @var{object} is not a file name,\n"
1322 "in which case the truncation occurs at the current port.\n"
1323 "position. The return value is unspecified.")
1324 #define FUNC_NAME s_scm_truncate_file
1325 {
1326 int rv;
1327 off_t c_length;
1328
1329 /* object can be a port, fdes or filename. */
1330
1331 if (SCM_UNBNDP (length))
1332 {
1333 /* must supply length if object is a filename. */
1334 if (SCM_STRINGP (object))
1335 SCM_MISC_ERROR("must supply length if OBJECT is a filename", SCM_EOL);
1336
1337 length = scm_seek (object, SCM_INUM0, SCM_MAKINUM (SEEK_CUR));
1338 }
1339 c_length = SCM_NUM2LONG (2, length);
1340 if (c_length < 0)
1341 SCM_MISC_ERROR ("negative offset", SCM_EOL);
1342
1343 object = SCM_COERCE_OUTPORT (object);
1344 if (SCM_INUMP (object))
1345 {
1346 SCM_SYSCALL (rv = ftruncate (SCM_INUM (object), c_length));
1347 }
1348 else if (SCM_OPOUTPORTP (object))
1349 {
1350 scm_t_port *pt = SCM_PTAB_ENTRY (object);
1351 scm_t_ptob_descriptor *ptob = scm_ptobs + SCM_PTOBNUM (object);
1352
1353 if (!ptob->truncate)
1354 SCM_MISC_ERROR ("port is not truncatable", SCM_EOL);
1355 if (pt->rw_active == SCM_PORT_READ)
1356 scm_end_input (object);
1357 else if (pt->rw_active == SCM_PORT_WRITE)
1358 ptob->flush (object);
1359
1360 ptob->truncate (object, c_length);
1361 rv = 0;
1362 }
1363 else
1364 {
1365 SCM_VALIDATE_STRING (1, object);
1366 SCM_SYSCALL (rv = truncate (SCM_STRING_CHARS (object), c_length));
1367 }
1368 if (rv == -1)
1369 SCM_SYSERROR;
1370 return SCM_UNSPECIFIED;
1371 }
1372 #undef FUNC_NAME
1373
1374 SCM_DEFINE (scm_port_line, "port-line", 1, 0, 0,
1375 (SCM port),
1376 "Return the current line number for @var{port}.")
1377 #define FUNC_NAME s_scm_port_line
1378 {
1379 port = SCM_COERCE_OUTPORT (port);
1380 SCM_VALIDATE_OPENPORT (1, port);
1381 return SCM_MAKINUM (SCM_LINUM (port));
1382 }
1383 #undef FUNC_NAME
1384
1385 SCM_DEFINE (scm_set_port_line_x, "set-port-line!", 2, 0, 0,
1386 (SCM port, SCM line),
1387 "Set the current line number for @var{port} to @var{line}.")
1388 #define FUNC_NAME s_scm_set_port_line_x
1389 {
1390 port = SCM_COERCE_OUTPORT (port);
1391 SCM_VALIDATE_OPENPORT (1, port);
1392 SCM_VALIDATE_INUM (2, line);
1393 SCM_PTAB_ENTRY (port)->line_number = SCM_INUM (line);
1394 return SCM_UNSPECIFIED;
1395 }
1396 #undef FUNC_NAME
1397
1398 SCM_DEFINE (scm_port_column, "port-column", 1, 0, 0,
1399 (SCM port),
1400 "@deffnx {Scheme Procedure} port-line port\n"
1401 "Return the current column number or line number of @var{port},\n"
1402 "using the current input port if none is specified. If the number is\n"
1403 "unknown, the result is #f. Otherwise, the result is a 0-origin integer\n"
1404 "- i.e. the first character of the first line is line 0, column 0.\n"
1405 "(However, when you display a file position, for example in an error\n"
1406 "message, we recommend you add 1 to get 1-origin integers. This is\n"
1407 "because lines and column numbers traditionally start with 1, and that is\n"
1408 "what non-programmers will find most natural.)")
1409 #define FUNC_NAME s_scm_port_column
1410 {
1411 port = SCM_COERCE_OUTPORT (port);
1412 SCM_VALIDATE_OPENPORT (1, port);
1413 return SCM_MAKINUM (SCM_COL (port));
1414 }
1415 #undef FUNC_NAME
1416
1417 SCM_DEFINE (scm_set_port_column_x, "set-port-column!", 2, 0, 0,
1418 (SCM port, SCM column),
1419 "@deffnx {Scheme Procedure} set-port-line! port line\n"
1420 "Set the current column or line number of @var{port}, using the\n"
1421 "current input port if none is specified.")
1422 #define FUNC_NAME s_scm_set_port_column_x
1423 {
1424 port = SCM_COERCE_OUTPORT (port);
1425 SCM_VALIDATE_OPENPORT (1, port);
1426 SCM_VALIDATE_INUM (2, column);
1427 SCM_PTAB_ENTRY (port)->column_number = SCM_INUM (column);
1428 return SCM_UNSPECIFIED;
1429 }
1430 #undef FUNC_NAME
1431
1432 SCM_DEFINE (scm_port_filename, "port-filename", 1, 0, 0,
1433 (SCM port),
1434 "Return the filename associated with @var{port}. This function returns\n"
1435 "the strings \"standard input\", \"standard output\" and \"standard error\"\n"
1436 "when called on the current input, output and error ports respectively.")
1437 #define FUNC_NAME s_scm_port_filename
1438 {
1439 port = SCM_COERCE_OUTPORT (port);
1440 SCM_VALIDATE_OPENPORT (1, port);
1441 return SCM_FILENAME (port);
1442 }
1443 #undef FUNC_NAME
1444
1445 SCM_DEFINE (scm_set_port_filename_x, "set-port-filename!", 2, 0, 0,
1446 (SCM port, SCM filename),
1447 "Change the filename associated with @var{port}, using the current input\n"
1448 "port if none is specified. Note that this does not change the port's\n"
1449 "source of data, but only the value that is returned by\n"
1450 "@code{port-filename} and reported in diagnostic output.")
1451 #define FUNC_NAME s_scm_set_port_filename_x
1452 {
1453 port = SCM_COERCE_OUTPORT (port);
1454 SCM_VALIDATE_OPENPORT (1, port);
1455 /* We allow the user to set the filename to whatever he likes. */
1456 SCM_SET_FILENAME (port, filename);
1457 return SCM_UNSPECIFIED;
1458 }
1459 #undef FUNC_NAME
1460
1461 #ifndef ttyname
1462 extern char * ttyname();
1463 #endif
1464
1465 void
1466 scm_print_port_mode (SCM exp, SCM port)
1467 {
1468 scm_puts (SCM_CLOSEDP (exp)
1469 ? "closed: "
1470 : (SCM_RDNG & SCM_CELL_WORD_0 (exp)
1471 ? (SCM_WRTNG & SCM_CELL_WORD_0 (exp)
1472 ? "input-output: "
1473 : "input: ")
1474 : (SCM_WRTNG & SCM_CELL_WORD_0 (exp)
1475 ? "output: "
1476 : "bogus: ")),
1477 port);
1478 }
1479
1480 int
1481 scm_port_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED)
1482 {
1483 char *type = SCM_PTOBNAME (SCM_PTOBNUM (exp));
1484 if (!type)
1485 type = "port";
1486 scm_puts ("#<", port);
1487 scm_print_port_mode (exp, port);
1488 scm_puts (type, port);
1489 scm_putc (' ', port);
1490 scm_intprint (SCM_CELL_WORD_1 (exp), 16, port);
1491 scm_putc ('>', port);
1492 return 1;
1493 }
1494
1495 void
1496 scm_ports_prehistory ()
1497 {
1498 scm_numptob = 0;
1499 scm_ptobs = (scm_t_ptob_descriptor *) scm_malloc (sizeof (scm_t_ptob_descriptor));
1500 }
1501
1502 \f
1503
1504 /* Void ports. */
1505
1506 scm_t_bits scm_tc16_void_port = 0;
1507
1508 static int fill_input_void_port (SCM port SCM_UNUSED)
1509 {
1510 return EOF;
1511 }
1512
1513 static void
1514 write_void_port (SCM port SCM_UNUSED,
1515 const void *data SCM_UNUSED,
1516 size_t size SCM_UNUSED)
1517 {
1518 }
1519
1520 SCM
1521 scm_void_port (char *mode_str)
1522 {
1523 SCM_DEFER_INTS;
1524 {
1525 int mode_bits = scm_mode_bits (mode_str);
1526 SCM answer = scm_new_port_table_entry (scm_tc16_void_port);
1527 scm_t_port * pt = SCM_PTAB_ENTRY(answer);
1528
1529 scm_port_non_buffer (pt);
1530
1531 SCM_SETSTREAM (answer, 0);
1532 SCM_SET_CELL_TYPE (answer, scm_tc16_void_port | mode_bits);
1533 SCM_ALLOW_INTS;
1534 return answer;
1535 }
1536 }
1537
1538 SCM_DEFINE (scm_sys_make_void_port, "%make-void-port", 1, 0, 0,
1539 (SCM mode),
1540 "Create and return a new void port. A void port acts like\n"
1541 "@file{/dev/null}. The @var{mode} argument\n"
1542 "specifies the input/output modes for this port: see the\n"
1543 "documentation for @code{open-file} in @ref{File Ports}.")
1544 #define FUNC_NAME s_scm_sys_make_void_port
1545 {
1546 SCM_VALIDATE_STRING (1, mode);
1547 return scm_void_port (SCM_STRING_CHARS (mode));
1548 }
1549 #undef FUNC_NAME
1550
1551 \f
1552 /* Initialization. */
1553
1554 void
1555 scm_init_ports ()
1556 {
1557 /* lseek() symbols. */
1558 scm_c_define ("SEEK_SET", SCM_MAKINUM (SEEK_SET));
1559 scm_c_define ("SEEK_CUR", SCM_MAKINUM (SEEK_CUR));
1560 scm_c_define ("SEEK_END", SCM_MAKINUM (SEEK_END));
1561
1562 scm_tc16_void_port = scm_make_port_type ("void", fill_input_void_port,
1563 write_void_port);
1564 #include "libguile/ports.x"
1565 }
1566
1567 /*
1568 Local Variables:
1569 c-file-style: "gnu"
1570 End:
1571 */