ports.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412
  1. /* Copyright (C) 1995,1996,1997,1998,1999, 2000, 2002 Free Software Foundation, Inc.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2, or (at your option)
  6. * any later version.
  7. *
  8. * This program 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
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; see the file COPYING. If not, write to
  15. * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  16. * Boston, MA 02111-1307 USA
  17. *
  18. * As a special exception, the Free Software Foundation gives permission
  19. * for additional uses of the text contained in its release of GUILE.
  20. *
  21. * The exception is that, if you link the GUILE library with other files
  22. * to produce an executable, this does not by itself cause the
  23. * resulting executable to be covered by the GNU General Public License.
  24. * Your use of that executable is in no way restricted on account of
  25. * linking the GUILE library code into it.
  26. *
  27. * This exception does not however invalidate any other reasons why
  28. * the executable file might be covered by the GNU General Public License.
  29. *
  30. * This exception applies only to the code released by the
  31. * Free Software Foundation under the name GUILE. If you copy
  32. * code from other Free Software Foundation releases into a copy of
  33. * GUILE, as the General Public License permits, the exception does
  34. * not apply to the code that you add in this way. To avoid misleading
  35. * anyone as to the status of such modified files, you must delete
  36. * this exception notice from them.
  37. *
  38. * If you write modifications of your own for GUILE, it is your choice
  39. * whether to permit this exception to apply to your modifications.
  40. * If you do not wish that, delete this exception notice. */
  41. /* Headers. */
  42. #include <stdio.h>
  43. #include "libguile/_scm.h"
  44. #include "libguile/objects.h"
  45. #include "libguile/smob.h"
  46. #include "libguile/chars.h"
  47. #include "libguile/keywords.h"
  48. #include "libguile/root.h"
  49. #include "libguile/strings.h"
  50. #include "libguile/validate.h"
  51. #include "libguile/ports.h"
  52. #ifdef HAVE_STRING_H
  53. #include <string.h>
  54. #endif
  55. #ifdef HAVE_MALLOC_H
  56. #include <malloc.h>
  57. #endif
  58. #ifdef HAVE_UNISTD_H
  59. #include <unistd.h>
  60. #endif
  61. #ifdef HAVE_SYS_IOCTL_H
  62. #include <sys/ioctl.h>
  63. #endif
  64. /* The port kind table --- a dynamically resized array of port types. */
  65. /* scm_ptobs scm_numptob
  66. * implement a dynamicly resized array of ptob records.
  67. * Indexes into this table are used when generating type
  68. * tags for smobjects (if you know a tag you can get an index and conversely).
  69. */
  70. scm_ptob_descriptor *scm_ptobs;
  71. int scm_numptob;
  72. /* GC marker for a port with stream of SCM type. */
  73. SCM
  74. scm_markstream (SCM ptr)
  75. {
  76. int openp;
  77. openp = SCM_CELL_WORD_0 (ptr) & SCM_OPN;
  78. if (openp)
  79. return SCM_PACK (SCM_STREAM (ptr));
  80. else
  81. return SCM_BOOL_F;
  82. }
  83. /*
  84. * We choose to use an interface similar to the smob interface with
  85. * fill_input and write as standard fields, passed to the port
  86. * type constructor, and optional fields set by setters.
  87. */
  88. static void
  89. flush_port_default (SCM port)
  90. {
  91. }
  92. static void
  93. end_input_default (SCM port, int offset)
  94. {
  95. }
  96. long
  97. scm_make_port_type (char *name,
  98. int (*fill_input) (SCM port),
  99. void (*write) (SCM port, const void *data, size_t size))
  100. {
  101. char *tmp;
  102. if (255 <= scm_numptob)
  103. goto ptoberr;
  104. SCM_DEFER_INTS;
  105. SCM_SYSCALL (tmp = (char *) realloc ((char *) scm_ptobs,
  106. (1 + scm_numptob)
  107. * sizeof (scm_ptob_descriptor)));
  108. if (tmp)
  109. {
  110. scm_ptobs = (scm_ptob_descriptor *) tmp;
  111. scm_ptobs[scm_numptob].name = name;
  112. scm_ptobs[scm_numptob].mark = 0;
  113. scm_ptobs[scm_numptob].free = scm_free0;
  114. scm_ptobs[scm_numptob].print = scm_port_print;
  115. scm_ptobs[scm_numptob].equalp = 0;
  116. scm_ptobs[scm_numptob].close = 0;
  117. scm_ptobs[scm_numptob].write = write;
  118. scm_ptobs[scm_numptob].flush = flush_port_default;
  119. scm_ptobs[scm_numptob].end_input = end_input_default;
  120. scm_ptobs[scm_numptob].fill_input = fill_input;
  121. scm_ptobs[scm_numptob].input_waiting = 0;
  122. scm_ptobs[scm_numptob].seek = 0;
  123. scm_ptobs[scm_numptob].truncate = 0;
  124. scm_numptob++;
  125. }
  126. SCM_ALLOW_INTS;
  127. if (!tmp)
  128. ptoberr:scm_wta (SCM_MAKINUM ((long) scm_numptob),
  129. (char *) SCM_NALLOC, "scm_make_port_type");
  130. /* Make a class object if Goops is present */
  131. if (scm_port_class)
  132. scm_make_port_classes (scm_numptob - 1, SCM_PTOBNAME (scm_numptob - 1));
  133. return scm_tc7_port + (scm_numptob - 1) * 256;
  134. }
  135. void
  136. scm_set_port_mark (long tc, SCM (*mark) (SCM))
  137. {
  138. scm_ptobs[SCM_TC2PTOBNUM (tc)].mark = mark;
  139. }
  140. void
  141. scm_set_port_free (long tc, scm_sizet (*free) (SCM))
  142. {
  143. scm_ptobs[SCM_TC2PTOBNUM (tc)].free = free;
  144. }
  145. void
  146. scm_set_port_print (long tc, int (*print) (SCM exp, SCM port,
  147. scm_print_state *pstate))
  148. {
  149. scm_ptobs[SCM_TC2PTOBNUM (tc)].print = print;
  150. }
  151. void
  152. scm_set_port_equalp (long tc, SCM (*equalp) (SCM, SCM))
  153. {
  154. scm_ptobs[SCM_TC2PTOBNUM (tc)].equalp = equalp;
  155. }
  156. void
  157. scm_set_port_flush (long tc, void (*flush) (SCM port))
  158. {
  159. scm_ptobs[SCM_TC2PTOBNUM (tc)].flush = flush;
  160. }
  161. void
  162. scm_set_port_end_input (long tc, void (*end_input) (SCM port, int offset))
  163. {
  164. scm_ptobs[SCM_TC2PTOBNUM (tc)].end_input = end_input;
  165. }
  166. void
  167. scm_set_port_close (long tc, int (*close) (SCM))
  168. {
  169. scm_ptobs[SCM_TC2PTOBNUM (tc)].close = close;
  170. }
  171. void
  172. scm_set_port_seek (long tc, off_t (*seek) (SCM port,
  173. off_t OFFSET,
  174. int WHENCE))
  175. {
  176. scm_ptobs[SCM_TC2PTOBNUM (tc)].seek = seek;
  177. }
  178. void
  179. scm_set_port_truncate (long tc, void (*truncate) (SCM port, off_t length))
  180. {
  181. scm_ptobs[SCM_TC2PTOBNUM (tc)].truncate = truncate;
  182. }
  183. void
  184. scm_set_port_input_waiting (long tc, int (*input_waiting) (SCM))
  185. {
  186. scm_ptobs[SCM_TC2PTOBNUM (tc)].input_waiting = input_waiting;
  187. }
  188. SCM_DEFINE (scm_char_ready_p, "char-ready?", 0, 1, 0,
  189. (SCM port),
  190. "Returns @code{#t} if a character is ready on input @var{port} and\n"
  191. "returns @code{#f} otherwise. If @code{char-ready?} returns @code{#t}\n"
  192. "then the next @code{read-char} operation on @var{port} is\n"
  193. "guaranteed not to hang. If @var{port} is a file port at end of\n"
  194. "file then @code{char-ready?} returns @code{#t}.\n"
  195. "@footnote{@code{char-ready?} exists to make it possible for a\n"
  196. "program to accept characters from interactive ports without getting\n"
  197. "stuck waiting for input. Any input editors associated with such ports\n"
  198. "must make sure that characters whose existence has been asserted by\n"
  199. "@code{char-ready?} cannot be rubbed out. If @code{char-ready?} were to\n"
  200. "return @code{#f} at end of file, a port at end of file would be\n"
  201. "indistinguishable from an interactive port that has no ready\n"
  202. "characters.}")
  203. #define FUNC_NAME s_scm_char_ready_p
  204. {
  205. scm_port *pt;
  206. if (SCM_UNBNDP (port))
  207. port = scm_cur_inp;
  208. else
  209. SCM_VALIDATE_OPINPORT (1,port);
  210. pt = SCM_PTAB_ENTRY (port);
  211. /* if the current read buffer is filled, or the
  212. last pushed-back char has been read and the saved buffer is
  213. filled, result is true. */
  214. if (pt->read_pos < pt->read_end
  215. || (pt->read_buf == pt->putback_buf
  216. && pt->saved_read_pos < pt->saved_read_end))
  217. return SCM_BOOL_T;
  218. else
  219. {
  220. scm_ptob_descriptor *ptob = &scm_ptobs[SCM_PTOBNUM (port)];
  221. if (ptob->input_waiting)
  222. return SCM_BOOL(ptob->input_waiting (port));
  223. else
  224. return SCM_BOOL_T;
  225. }
  226. }
  227. #undef FUNC_NAME
  228. /* Clear a port's read buffers, returning the contents. */
  229. SCM_DEFINE (scm_drain_input, "drain-input", 1, 0, 0,
  230. (SCM port),
  231. "Drains @var{PORT}'s read buffers (including any pushed-back characters)\n"
  232. "and returns the contents as a single string.")
  233. #define FUNC_NAME s_scm_drain_input
  234. {
  235. SCM result;
  236. scm_port *pt = SCM_PTAB_ENTRY (port);
  237. int count;
  238. char *dst;
  239. SCM_VALIDATE_OPINPORT (1,port);
  240. count = pt->read_end - pt->read_pos;
  241. if (pt->read_buf == pt->putback_buf)
  242. count += pt->saved_read_end - pt->saved_read_pos;
  243. result = scm_makstr (count, 0);
  244. dst = SCM_CHARS (result);
  245. while (pt->read_pos < pt->read_end)
  246. *dst++ = *(pt->read_pos++);
  247. if (pt->read_buf == pt->putback_buf)
  248. {
  249. while (pt->saved_read_pos < pt->saved_read_end)
  250. *dst++ = *(pt->saved_read_pos++);
  251. }
  252. return result;
  253. }
  254. #undef FUNC_NAME
  255. /* Standard ports --- current input, output, error, and more(!). */
  256. SCM_DEFINE (scm_current_input_port, "current-input-port", 0, 0, 0,
  257. (),
  258. "Returns the current input port. This is the default port used by many\n"
  259. "input procedures. Initially, @code{current-input-port} returns the\n"
  260. "value of @code{???}.")
  261. #define FUNC_NAME s_scm_current_input_port
  262. {
  263. return scm_cur_inp;
  264. }
  265. #undef FUNC_NAME
  266. SCM_DEFINE (scm_current_output_port, "current-output-port", 0, 0, 0,
  267. (),
  268. "Returns the current output port. This is the default port used by many\n"
  269. "output procedures. Initially, @code{current-output-port} returns the\n"
  270. "value of @code{???}.")
  271. #define FUNC_NAME s_scm_current_output_port
  272. {
  273. return scm_cur_outp;
  274. }
  275. #undef FUNC_NAME
  276. SCM_DEFINE (scm_current_error_port, "current-error-port", 0, 0, 0,
  277. (),
  278. "Return the port to which errors and warnings should be sent (the\n"
  279. "@dfn{standard error} in Unix and C terminology).")
  280. #define FUNC_NAME s_scm_current_error_port
  281. {
  282. return scm_cur_errp;
  283. }
  284. #undef FUNC_NAME
  285. SCM_DEFINE (scm_current_load_port, "current-load-port", 0, 0, 0,
  286. (),
  287. "Return the current-load-port.\n"
  288. "The load port is used internally by `primitive-load'.")
  289. #define FUNC_NAME s_scm_current_load_port
  290. {
  291. return scm_cur_loadp;
  292. }
  293. #undef FUNC_NAME
  294. SCM_DEFINE (scm_set_current_input_port, "set-current-input-port", 1, 0, 0,
  295. (SCM port),
  296. "@deffnx primitive set-current-output-port port\n"
  297. "@deffnx primitive set-current-error-port port\n"
  298. "Change the ports returned by @code{current-input-port},\n"
  299. "@code{current-output-port} and @code{current-error-port}, respectively,\n"
  300. "so that they use the supplied @var{port} for input or output.")
  301. #define FUNC_NAME s_scm_set_current_input_port
  302. {
  303. SCM oinp = scm_cur_inp;
  304. SCM_VALIDATE_OPINPORT (1,port);
  305. scm_cur_inp = port;
  306. return oinp;
  307. }
  308. #undef FUNC_NAME
  309. SCM_DEFINE (scm_set_current_output_port, "set-current-output-port", 1, 0, 0,
  310. (SCM port),
  311. "Set the current default output port to PORT.")
  312. #define FUNC_NAME s_scm_set_current_output_port
  313. {
  314. SCM ooutp = scm_cur_outp;
  315. port = SCM_COERCE_OUTPORT (port);
  316. SCM_VALIDATE_OPOUTPORT (1,port);
  317. scm_cur_outp = port;
  318. return ooutp;
  319. }
  320. #undef FUNC_NAME
  321. SCM_DEFINE (scm_set_current_error_port, "set-current-error-port", 1, 0, 0,
  322. (SCM port),
  323. "Set the current default error port to PORT.")
  324. #define FUNC_NAME s_scm_set_current_error_port
  325. {
  326. SCM oerrp = scm_cur_errp;
  327. port = SCM_COERCE_OUTPORT (port);
  328. SCM_VALIDATE_OPOUTPORT (1,port);
  329. scm_cur_errp = port;
  330. return oerrp;
  331. }
  332. #undef FUNC_NAME
  333. /* The port table --- an array of pointers to ports. */
  334. scm_port **scm_port_table;
  335. int scm_port_table_size = 0; /* Number of ports in scm_port_table. */
  336. int scm_port_table_room = 20; /* Size of the array. */
  337. /* Add a port to the table. */
  338. scm_port *
  339. scm_add_to_port_table (SCM port)
  340. {
  341. scm_port *entry;
  342. if (scm_port_table_size == scm_port_table_room)
  343. {
  344. void *newt = realloc ((char *) scm_port_table,
  345. (scm_sizet) (sizeof (scm_port *)
  346. * scm_port_table_room * 2));
  347. if (newt == NULL)
  348. scm_memory_error ("scm_add_to_port_table");
  349. scm_port_table = (scm_port **) newt;
  350. scm_port_table_room *= 2;
  351. }
  352. entry = (scm_port *) malloc (sizeof (scm_port));
  353. if (entry == NULL)
  354. scm_memory_error ("scm_add_to_port_table");
  355. entry->port = port;
  356. entry->entry = scm_port_table_size;
  357. entry->revealed = 0;
  358. entry->stream = 0;
  359. entry->file_name = SCM_BOOL_F;
  360. entry->line_number = 0;
  361. entry->column_number = 0;
  362. entry->putback_buf = 0;
  363. entry->putback_buf_size = 0;
  364. entry->rw_active = SCM_PORT_NEITHER;
  365. entry->rw_random = 0;
  366. scm_port_table[scm_port_table_size] = entry;
  367. scm_port_table_size++;
  368. return entry;
  369. }
  370. /* Remove a port from the table and destroy it. */
  371. void
  372. scm_remove_from_port_table (SCM port)
  373. {
  374. scm_port *p = SCM_PTAB_ENTRY (port);
  375. int i = p->entry;
  376. if (i >= scm_port_table_size)
  377. scm_wta (port, "Port not in table", "scm_remove_from_port_table");
  378. if (p->putback_buf)
  379. free (p->putback_buf);
  380. free (p);
  381. /* Since we have just freed slot i we can shrink the table by moving
  382. the last entry to that slot... */
  383. if (i < scm_port_table_size - 1)
  384. {
  385. scm_port_table[i] = scm_port_table[scm_port_table_size - 1];
  386. scm_port_table[i]->entry = i;
  387. }
  388. SCM_SETPTAB_ENTRY (port, 0);
  389. scm_port_table_size--;
  390. }
  391. #ifdef GUILE_DEBUG
  392. /* Functions for debugging. */
  393. SCM_DEFINE (scm_pt_size, "pt-size", 0, 0, 0,
  394. (),
  395. "Returns the number of ports in the port table.\n"
  396. "`pt-size' is only included in GUILE_DEBUG builds.")
  397. #define FUNC_NAME s_scm_pt_size
  398. {
  399. return SCM_MAKINUM (scm_port_table_size);
  400. }
  401. #undef FUNC_NAME
  402. SCM_DEFINE (scm_pt_member, "pt-member", 1, 0, 0,
  403. (SCM index),
  404. "Returns the port at INDEX in the port table.\n"
  405. "`pt-member' is only included in GUILE_DEBUG builds.")
  406. #define FUNC_NAME s_scm_pt_member
  407. {
  408. int i;
  409. SCM_VALIDATE_INUM_COPY (1,index,i);
  410. if (i < 0 || i >= scm_port_table_size)
  411. return SCM_BOOL_F;
  412. else
  413. return scm_port_table[i]->port;
  414. }
  415. #undef FUNC_NAME
  416. #endif
  417. void
  418. scm_port_non_buffer (scm_port *pt)
  419. {
  420. pt->read_pos = pt->read_buf = pt->read_end = &pt->shortbuf;
  421. pt->write_buf = pt->write_pos = &pt->shortbuf;
  422. pt->read_buf_size = pt->write_buf_size = 1;
  423. pt->write_end = pt->write_buf + pt->write_buf_size;
  424. }
  425. /* Revealed counts --- an oddity inherited from SCSH. */
  426. /* Find a port in the table and return its revealed count.
  427. Also used by the garbage collector.
  428. */
  429. int
  430. scm_revealed_count (SCM port)
  431. {
  432. return SCM_REVEALED(port);
  433. }
  434. /* Return the revealed count for a port. */
  435. SCM_DEFINE (scm_port_revealed, "port-revealed", 1, 0, 0,
  436. (SCM port),
  437. "Returns the revealed count for @var{port}.")
  438. #define FUNC_NAME s_scm_port_revealed
  439. {
  440. port = SCM_COERCE_OUTPORT (port);
  441. SCM_VALIDATE_PORT (1,port);
  442. return SCM_MAKINUM (scm_revealed_count (port));
  443. }
  444. #undef FUNC_NAME
  445. /* Set the revealed count for a port. */
  446. SCM_DEFINE (scm_set_port_revealed_x, "set-port-revealed!", 2, 0, 0,
  447. (SCM port, SCM rcount),
  448. "Sets the revealed count for a port to a given value.\n"
  449. "The return value is unspecified.")
  450. #define FUNC_NAME s_scm_set_port_revealed_x
  451. {
  452. port = SCM_COERCE_OUTPORT (port);
  453. SCM_VALIDATE_PORT (1,port);
  454. SCM_VALIDATE_INUM (2,rcount);
  455. SCM_REVEALED (port) = SCM_INUM (rcount);
  456. return SCM_UNSPECIFIED;
  457. }
  458. #undef FUNC_NAME
  459. /* Retrieving a port's mode. */
  460. /* Return the flags that characterize a port based on the mode
  461. * string used to open a file for that port.
  462. *
  463. * See PORT FLAGS in scm.h
  464. */
  465. long
  466. scm_mode_bits (char *modes)
  467. {
  468. return (SCM_OPN
  469. | (strchr (modes, 'r') || strchr (modes, '+') ? SCM_RDNG : 0)
  470. | ( strchr (modes, 'w')
  471. || strchr (modes, 'a')
  472. || strchr (modes, '+') ? SCM_WRTNG : 0)
  473. | (strchr (modes, '0') ? SCM_BUF0 : 0)
  474. | (strchr (modes, 'l') ? SCM_BUFLINE : 0));
  475. }
  476. /* Return the mode flags from an open port.
  477. * Some modes such as "append" are only used when opening
  478. * a file and are not returned here. */
  479. SCM_DEFINE (scm_port_mode, "port-mode", 1, 0, 0,
  480. (SCM port),
  481. "Returns the port modes associated with the open port @var{port}. These\n"
  482. "will not necessarily be identical to the modes used when the port was\n"
  483. "opened, since modes such as \"append\" which are used only during\n"
  484. "port creation are not retained.")
  485. #define FUNC_NAME s_scm_port_mode
  486. {
  487. char modes[3];
  488. modes[0] = '\0';
  489. port = SCM_COERCE_OUTPORT (port);
  490. SCM_VALIDATE_OPPORT (1,port);
  491. if (SCM_CELL_WORD_0 (port) & SCM_RDNG) {
  492. if (SCM_CELL_WORD_0 (port) & SCM_WRTNG)
  493. strcpy (modes, "r+");
  494. else
  495. strcpy (modes, "r");
  496. }
  497. else if (SCM_CELL_WORD_0 (port) & SCM_WRTNG)
  498. strcpy (modes, "w");
  499. if (SCM_CELL_WORD_0 (port) & SCM_BUF0)
  500. strcat (modes, "0");
  501. return scm_makfromstr (modes, strlen (modes), 0);
  502. }
  503. #undef FUNC_NAME
  504. /* Closing ports. */
  505. /* scm_close_port
  506. * Call the close operation on a port object.
  507. * see also scm_close.
  508. */
  509. SCM_DEFINE (scm_close_port, "close-port", 1, 0, 0,
  510. (SCM port),
  511. "Close the specified port object. Returns @code{#t} if it successfully\n"
  512. "closes a port or @code{#f} if it was already\n"
  513. "closed. An exception may be raised if an error occurs, for example\n"
  514. "when flushing buffered output.\n"
  515. "See also @ref{Ports and File Descriptors, close}, for a procedure\n"
  516. "which can close file descriptors.")
  517. #define FUNC_NAME s_scm_close_port
  518. {
  519. scm_sizet i;
  520. int rv;
  521. port = SCM_COERCE_OUTPORT (port);
  522. SCM_VALIDATE_PORT (1, port);
  523. if (SCM_CLOSEDP (port))
  524. return SCM_BOOL_F;
  525. i = SCM_PTOBNUM (port);
  526. if (scm_ptobs[i].close)
  527. rv = (scm_ptobs[i].close) (port);
  528. else
  529. rv = 0;
  530. scm_remove_from_port_table (port);
  531. SCM_SETAND_CAR (port, ~SCM_OPN);
  532. return SCM_NEGATE_BOOL (rv < 0);
  533. }
  534. #undef FUNC_NAME
  535. SCM_DEFINE (scm_close_input_port, "close-input-port", 1, 0, 0,
  536. (SCM port),
  537. "Close the specified input port object. The routine has no effect if\n"
  538. "the file has already been closed. An exception may be raised if an\n"
  539. "error occurs. The value returned is unspecified.\n\n"
  540. "See also @ref{Ports and File Descriptors, close}, for a procedure\n"
  541. "which can close file descriptors.")
  542. #define FUNC_NAME s_scm_close_input_port
  543. {
  544. SCM_VALIDATE_INPUT_PORT (1, port);
  545. scm_close_port (port);
  546. return SCM_UNSPECIFIED;
  547. }
  548. #undef FUNC_NAME
  549. SCM_DEFINE (scm_close_output_port, "close-output-port", 1, 0, 0,
  550. (SCM port),
  551. "Close the specified output port object. The routine has no effect if\n"
  552. "the file has already been closed. An exception may be raised if an\n"
  553. "error occurs. The value returned is unspecified.\n\n"
  554. "See also @ref{Ports and File Descriptors, close}, for a procedure\n"
  555. "which can close file descriptors.")
  556. #define FUNC_NAME s_scm_close_output_port
  557. {
  558. port = SCM_COERCE_OUTPORT (port);
  559. SCM_VALIDATE_OUTPUT_PORT (1, port);
  560. scm_close_port (port);
  561. return SCM_UNSPECIFIED;
  562. }
  563. #undef FUNC_NAME
  564. SCM_DEFINE (scm_close_all_ports_except, "close-all-ports-except", 0, 0, 1,
  565. (SCM ports),
  566. "Close all open file ports used by the interpreter\n"
  567. "except for those supplied as arguments. This procedure\n"
  568. "is intended to be used before an exec call to close file descriptors\n"
  569. "which are not needed in the new process.")
  570. #define FUNC_NAME s_scm_close_all_ports_except
  571. {
  572. int i = 0;
  573. SCM_VALIDATE_REST_ARGUMENT (ports);
  574. while (i < scm_port_table_size)
  575. {
  576. SCM thisport = scm_port_table[i]->port;
  577. int found = 0;
  578. SCM ports_ptr = ports;
  579. while (SCM_NNULLP (ports_ptr))
  580. {
  581. SCM port = SCM_COERCE_OUTPORT (SCM_CAR (ports_ptr));
  582. if (i == 0)
  583. SCM_VALIDATE_OPPORT (SCM_ARG1,port);
  584. if (SCM_EQ_P (port, thisport))
  585. found = 1;
  586. ports_ptr = SCM_CDR (ports_ptr);
  587. }
  588. if (found)
  589. i++;
  590. else
  591. /* i is not to be incremented here. */
  592. scm_close_port (thisport);
  593. }
  594. return SCM_UNSPECIFIED;
  595. }
  596. #undef FUNC_NAME
  597. /* Utter miscellany. Gosh, we should clean this up some time. */
  598. SCM_DEFINE (scm_input_port_p, "input-port?", 1, 0, 0,
  599. (SCM x),
  600. "Returns @code{#t} if @var{x} is an input port, otherwise returns\n"
  601. "@code{#f}. Any object satisfying this predicate also satisfies\n"
  602. "@code{port?}.")
  603. #define FUNC_NAME s_scm_input_port_p
  604. {
  605. if (SCM_IMP (x))
  606. return SCM_BOOL_F;
  607. return SCM_BOOL(SCM_INPUT_PORT_P (x));
  608. }
  609. #undef FUNC_NAME
  610. SCM_DEFINE (scm_output_port_p, "output-port?", 1, 0, 0,
  611. (SCM x),
  612. "Returns @code{#t} if @var{x} is an output port, otherwise returns\n"
  613. "@code{#f}. Any object satisfying this predicate also satisfies\n"
  614. "@code{port?}.")
  615. #define FUNC_NAME s_scm_output_port_p
  616. {
  617. if (SCM_IMP (x))
  618. return SCM_BOOL_F;
  619. if (SCM_PORT_WITH_PS_P (x))
  620. x = SCM_PORT_WITH_PS_PORT (x);
  621. return SCM_BOOL(SCM_OUTPUT_PORT_P (x));
  622. }
  623. #undef FUNC_NAME
  624. SCM_DEFINE (scm_port_closed_p, "port-closed?", 1, 0, 0,
  625. (SCM port),
  626. "Returns @code{#t} if @var{port} is closed or @code{#f} if it is open.")
  627. #define FUNC_NAME s_scm_port_closed_p
  628. {
  629. SCM_VALIDATE_PORT (1,port);
  630. return SCM_NEGATE_BOOL(SCM_OPPORTP (port));
  631. }
  632. #undef FUNC_NAME
  633. SCM_DEFINE (scm_eof_object_p, "eof-object?", 1, 0, 0,
  634. (SCM x),
  635. "Returns @code{#t} if @var{x} is an end-of-file object; otherwise\n"
  636. "returns @code{#f}.")
  637. #define FUNC_NAME s_scm_eof_object_p
  638. {
  639. return SCM_BOOL(SCM_EOF_OBJECT_P (x));
  640. }
  641. #undef FUNC_NAME
  642. SCM_DEFINE (scm_force_output, "force-output", 0, 1, 0,
  643. (SCM port),
  644. "Flush the specified output port, or the current output port if @var{port}\n"
  645. "is omitted. The current output buffer contents are passed to the \n"
  646. "underlying port implementation (e.g., in the case of fports, the\n"
  647. "data will be written to the file and the output buffer will be cleared.)\n"
  648. "It has no effect on an unbuffered port.\n\n"
  649. "The return value is unspecified.")
  650. #define FUNC_NAME s_scm_force_output
  651. {
  652. if (SCM_UNBNDP (port))
  653. port = scm_cur_outp;
  654. else
  655. {
  656. port = SCM_COERCE_OUTPORT (port);
  657. SCM_VALIDATE_OPOUTPORT (1,port);
  658. }
  659. scm_flush (port);
  660. return SCM_UNSPECIFIED;
  661. }
  662. #undef FUNC_NAME
  663. SCM_DEFINE (scm_flush_all_ports, "flush-all-ports", 0, 0, 0,
  664. (),
  665. "Equivalent to calling @code{force-output} on\n"
  666. "all open output ports. The return value is unspecified.")
  667. #define FUNC_NAME s_scm_flush_all_ports
  668. {
  669. int i;
  670. for (i = 0; i < scm_port_table_size; i++)
  671. {
  672. if (SCM_OPOUTPORTP (scm_port_table[i]->port))
  673. scm_flush (scm_port_table[i]->port);
  674. }
  675. return SCM_UNSPECIFIED;
  676. }
  677. #undef FUNC_NAME
  678. SCM_DEFINE (scm_read_char, "read-char", 0, 1, 0,
  679. (SCM port),
  680. "Returns the next character available from @var{port}, updating\n"
  681. "@var{port} to point to the following character. If no more\n"
  682. "characters are available, an end-of-file object is returned.")
  683. #define FUNC_NAME s_scm_read_char
  684. {
  685. int c;
  686. if (SCM_UNBNDP (port))
  687. port = scm_cur_inp;
  688. SCM_VALIDATE_OPINPORT (1,port);
  689. c = scm_getc (port);
  690. if (EOF == c)
  691. return SCM_EOF_VAL;
  692. return SCM_MAKE_CHAR (c);
  693. }
  694. #undef FUNC_NAME
  695. /* this should only be called when the read buffer is empty. it
  696. tries to refill the read buffer. it returns the first char from
  697. the port, which is either EOF or *(pt->read_pos). */
  698. int
  699. scm_fill_input (SCM port)
  700. {
  701. scm_port *pt = SCM_PTAB_ENTRY (port);
  702. if (pt->read_buf == pt->putback_buf)
  703. {
  704. /* finished reading put-back chars. */
  705. pt->read_buf = pt->saved_read_buf;
  706. pt->read_pos = pt->saved_read_pos;
  707. pt->read_end = pt->saved_read_end;
  708. pt->read_buf_size = pt->saved_read_buf_size;
  709. if (pt->read_pos < pt->read_end)
  710. return *(pt->read_pos);
  711. }
  712. return scm_ptobs[SCM_PTOBNUM (port)].fill_input (port);
  713. }
  714. int
  715. scm_getc (SCM port)
  716. {
  717. int c;
  718. scm_port *pt = SCM_PTAB_ENTRY (port);
  719. if (pt->rw_active == SCM_PORT_WRITE)
  720. {
  721. /* may be marginally faster than calling scm_flush. */
  722. scm_ptobs[SCM_PTOBNUM (port)].flush (port);
  723. }
  724. if (pt->rw_random)
  725. pt->rw_active = SCM_PORT_READ;
  726. if (pt->read_pos >= pt->read_end)
  727. {
  728. if (scm_fill_input (port) == EOF)
  729. return EOF;
  730. }
  731. c = *(pt->read_pos++);
  732. if (c == '\n')
  733. {
  734. SCM_INCLINE (port);
  735. }
  736. else if (c == '\t')
  737. {
  738. SCM_TABCOL (port);
  739. }
  740. else
  741. {
  742. SCM_INCCOL (port);
  743. }
  744. return c;
  745. }
  746. void
  747. scm_putc (char c, SCM port)
  748. {
  749. scm_lfwrite (&c, 1, port);
  750. }
  751. void
  752. scm_puts (const char *s, SCM port)
  753. {
  754. scm_lfwrite (s, strlen (s), port);
  755. }
  756. void
  757. scm_lfwrite (const char *ptr, scm_sizet size, SCM port)
  758. {
  759. scm_port *pt = SCM_PTAB_ENTRY (port);
  760. scm_ptob_descriptor *ptob = &scm_ptobs[SCM_PTOBNUM (port)];
  761. if (pt->rw_active == SCM_PORT_READ)
  762. scm_end_input (port);
  763. ptob->write (port, ptr, size);
  764. if (pt->rw_random)
  765. pt->rw_active = SCM_PORT_WRITE;
  766. }
  767. void
  768. scm_flush (SCM port)
  769. {
  770. scm_sizet i = SCM_PTOBNUM (port);
  771. (scm_ptobs[i].flush) (port);
  772. }
  773. void
  774. scm_end_input (SCM port)
  775. {
  776. int offset;
  777. scm_port *pt = SCM_PTAB_ENTRY (port);
  778. if (pt->read_buf == pt->putback_buf)
  779. {
  780. offset = pt->read_end - pt->read_pos;
  781. pt->read_buf = pt->saved_read_buf;
  782. pt->read_pos = pt->saved_read_pos;
  783. pt->read_end = pt->saved_read_end;
  784. pt->read_buf_size = pt->saved_read_buf_size;
  785. }
  786. else
  787. offset = 0;
  788. scm_ptobs[SCM_PTOBNUM (port)].end_input (port, offset);
  789. }
  790. void
  791. scm_ungetc (int c, SCM port)
  792. {
  793. scm_port *pt = SCM_PTAB_ENTRY (port);
  794. if (pt->read_buf == pt->putback_buf)
  795. /* already using the put-back buffer. */
  796. {
  797. /* enlarge putback_buf if necessary. */
  798. if (pt->read_end == pt->read_buf + pt->read_buf_size
  799. && pt->read_buf == pt->read_pos)
  800. {
  801. int new_size = pt->read_buf_size * 2;
  802. unsigned char *tmp =
  803. (unsigned char *) realloc (pt->putback_buf, new_size);
  804. if (tmp == NULL)
  805. scm_memory_error ("scm_ungetc");
  806. pt->read_pos = pt->read_buf = pt->putback_buf = tmp;
  807. pt->read_end = pt->read_buf + pt->read_buf_size;
  808. pt->read_buf_size = pt->putback_buf_size = new_size;
  809. }
  810. /* shift any existing bytes to buffer + 1. */
  811. if (pt->read_pos == pt->read_end)
  812. pt->read_end = pt->read_buf + 1;
  813. else if (pt->read_pos != pt->read_buf + 1)
  814. {
  815. int count = pt->read_end - pt->read_pos;
  816. memmove (pt->read_buf + 1, pt->read_pos, count);
  817. pt->read_end = pt->read_buf + 1 + count;
  818. }
  819. pt->read_pos = pt->read_buf;
  820. }
  821. else
  822. /* switch to the put-back buffer. */
  823. {
  824. if (pt->putback_buf == NULL)
  825. {
  826. pt->putback_buf
  827. = (unsigned char *) malloc (SCM_INITIAL_PUTBACK_BUF_SIZE);
  828. if (pt->putback_buf == NULL)
  829. scm_memory_error ("scm_ungetc");
  830. pt->putback_buf_size = SCM_INITIAL_PUTBACK_BUF_SIZE;
  831. }
  832. pt->saved_read_buf = pt->read_buf;
  833. pt->saved_read_pos = pt->read_pos;
  834. pt->saved_read_end = pt->read_end;
  835. pt->saved_read_buf_size = pt->read_buf_size;
  836. pt->read_pos = pt->read_buf = pt->putback_buf;
  837. pt->read_end = pt->read_buf + 1;
  838. pt->read_buf_size = pt->putback_buf_size;
  839. }
  840. *pt->read_buf = c;
  841. if (pt->rw_random)
  842. pt->rw_active = SCM_PORT_READ;
  843. if (c == '\n')
  844. {
  845. /* What should col be in this case?
  846. * We'll leave it at -1.
  847. */
  848. SCM_LINUM (port) -= 1;
  849. }
  850. else
  851. SCM_COL(port) -= 1;
  852. }
  853. void
  854. scm_ungets (const char *s, int n, SCM port)
  855. {
  856. /* This is simple minded and inefficient, but unreading strings is
  857. * probably not a common operation, and remember that line and
  858. * column numbers have to be handled...
  859. *
  860. * Please feel free to write an optimized version!
  861. */
  862. while (n--)
  863. scm_ungetc (s[n], port);
  864. }
  865. SCM_DEFINE (scm_peek_char, "peek-char", 0, 1, 0,
  866. (SCM port),
  867. "Returns the next character available from @var{port},\n"
  868. "@emph{without} updating @var{port} to point to the following\n"
  869. "character. If no more characters are available, an end-of-file object\n"
  870. "is returned.@footnote{The value returned by a call to @code{peek-char}\n"
  871. "is the same as the value that would have been returned by a call to\n"
  872. "@code{read-char} on the same port. The only difference is that the very\n"
  873. "next call to @code{read-char} or @code{peek-char} on that\n"
  874. "@var{port} will return the value returned by the preceding call to\n"
  875. "@code{peek-char}. In particular, a call to @code{peek-char} on an\n"
  876. "interactive port will hang waiting for input whenever a call to\n"
  877. "@code{read-char} would have hung.}")
  878. #define FUNC_NAME s_scm_peek_char
  879. {
  880. int c;
  881. if (SCM_UNBNDP (port))
  882. port = scm_cur_inp;
  883. else
  884. SCM_VALIDATE_OPINPORT (1,port);
  885. c = scm_getc (port);
  886. if (EOF == c)
  887. return SCM_EOF_VAL;
  888. scm_ungetc (c, port);
  889. return SCM_MAKE_CHAR (c);
  890. }
  891. #undef FUNC_NAME
  892. SCM_DEFINE (scm_unread_char, "unread-char", 2, 0, 0,
  893. (SCM cobj, SCM port),
  894. "Place @var{char} in @var{port} so that it will be read by the\n"
  895. "next read operation. If called multiple times, the unread characters\n"
  896. "will be read again in last-in first-out order. If @var{port} is\n"
  897. "not supplied, the current input port is used.")
  898. #define FUNC_NAME s_scm_unread_char
  899. {
  900. int c;
  901. SCM_VALIDATE_CHAR (1,cobj);
  902. if (SCM_UNBNDP (port))
  903. port = scm_cur_inp;
  904. else
  905. SCM_VALIDATE_OPINPORT (2,port);
  906. c = SCM_CHAR (cobj);
  907. scm_ungetc (c, port);
  908. return cobj;
  909. }
  910. #undef FUNC_NAME
  911. SCM_DEFINE (scm_unread_string, "unread-string", 2, 0, 0,
  912. (SCM str, SCM port),
  913. "Place the string @var{str} in @var{port} so that its characters will be\n"
  914. "read in subsequent read operations. If called multiple times, the\n"
  915. "unread characters will be read again in last-in first-out order. If\n"
  916. "@var{port} is not supplied, the current-input-port is used.")
  917. #define FUNC_NAME s_scm_unread_string
  918. {
  919. SCM_VALIDATE_STRING (1,str);
  920. if (SCM_UNBNDP (port))
  921. port = scm_cur_inp;
  922. else
  923. SCM_VALIDATE_OPINPORT (2,port);
  924. scm_ungets (SCM_ROCHARS (str), SCM_LENGTH (str), port);
  925. return str;
  926. }
  927. #undef FUNC_NAME
  928. SCM_DEFINE (scm_seek, "seek", 3, 0, 0,
  929. (SCM object, SCM offset, SCM whence),
  930. "Sets the current position of @var{fd/port} to the integer @var{offset},\n"
  931. "which is interpreted according to the value of @var{whence}.\n\n"
  932. "One of the following variables should be supplied\n"
  933. "for @var{whence}:\n"
  934. "@defvar SEEK_SET\n"
  935. "Seek from the beginning of the file.\n"
  936. "@end defvar\n"
  937. "@defvar SEEK_CUR\n"
  938. "Seek from the current position.\n"
  939. "@end defvar\n"
  940. "@defvar SEEK_END\n"
  941. "Seek from the end of the file.\n"
  942. "@end defvar\n\n"
  943. "If @var{fd/port} is a file descriptor, the underlying system call is\n"
  944. "@code{lseek}. @var{port} may be a string port.\n\n"
  945. "The value returned is the new position in the file. This means that\n"
  946. "the current position of a port can be obtained using:\n"
  947. "@smalllisp\n"
  948. "(seek port 0 SEEK_CUR)\n"
  949. "@end smalllisp")
  950. #define FUNC_NAME s_scm_seek
  951. {
  952. off_t off;
  953. off_t rv;
  954. int how;
  955. object = SCM_COERCE_OUTPORT (object);
  956. off = SCM_NUM2LONG (2,offset);
  957. SCM_VALIDATE_INUM_COPY (3,whence,how);
  958. if (how != SEEK_SET && how != SEEK_CUR && how != SEEK_END)
  959. SCM_OUT_OF_RANGE (3, whence);
  960. if (SCM_OPPORTP (object))
  961. {
  962. scm_ptob_descriptor *ptob = scm_ptobs + SCM_PTOBNUM (object);
  963. if (!ptob->seek)
  964. SCM_MISC_ERROR ("port is not seekable",
  965. scm_cons (object, SCM_EOL));
  966. else
  967. rv = ptob->seek (object, off, how);
  968. }
  969. else /* file descriptor?. */
  970. {
  971. SCM_VALIDATE_INUM (1,object);
  972. rv = lseek (SCM_INUM (object), off, how);
  973. if (rv == -1)
  974. SCM_SYSERROR;
  975. }
  976. return scm_long2num (rv);
  977. }
  978. #undef FUNC_NAME
  979. SCM_DEFINE (scm_truncate_file, "truncate-file", 1, 1, 0,
  980. (SCM object, SCM length),
  981. "Truncates the object referred to by @var{obj} to at most @var{size} bytes.\n"
  982. "@var{obj} can be a string containing a file name or an integer file\n"
  983. "descriptor or a port. @var{size} may be omitted if @var{obj} is not\n"
  984. "a file name, in which case the truncation occurs at the current port.\n"
  985. "position.\n\n"
  986. "The return value is unspecified.")
  987. #define FUNC_NAME s_scm_truncate_file
  988. {
  989. int rv;
  990. off_t c_length;
  991. /* object can be a port, fdes or filename. */
  992. if (SCM_UNBNDP (length))
  993. {
  994. /* must supply length if object is a filename. */
  995. if (SCM_ROSTRINGP (object))
  996. SCM_MISC_ERROR("must supply length if OBJECT is a filename",SCM_EOL);
  997. length = scm_seek (object, SCM_INUM0, SCM_MAKINUM (SEEK_CUR));
  998. }
  999. c_length = SCM_NUM2LONG (2,length);
  1000. if (c_length < 0)
  1001. SCM_MISC_ERROR ("negative offset", SCM_EOL);
  1002. object = SCM_COERCE_OUTPORT (object);
  1003. if (SCM_INUMP (object))
  1004. {
  1005. SCM_SYSCALL (rv = ftruncate (SCM_INUM (object), c_length));
  1006. }
  1007. else if (SCM_OPOUTPORTP (object))
  1008. {
  1009. scm_port *pt = SCM_PTAB_ENTRY (object);
  1010. scm_ptob_descriptor *ptob = scm_ptobs + SCM_PTOBNUM (object);
  1011. if (!ptob->truncate)
  1012. SCM_MISC_ERROR ("port is not truncatable", SCM_EOL);
  1013. if (pt->rw_active == SCM_PORT_READ)
  1014. scm_end_input (object);
  1015. else if (pt->rw_active == SCM_PORT_WRITE)
  1016. ptob->flush (object);
  1017. ptob->truncate (object, c_length);
  1018. rv = 0;
  1019. }
  1020. else
  1021. {
  1022. SCM_VALIDATE_ROSTRING (1,object);
  1023. SCM_COERCE_SUBSTR (object);
  1024. SCM_SYSCALL (rv = truncate (SCM_ROCHARS (object), c_length));
  1025. }
  1026. if (rv == -1)
  1027. SCM_SYSERROR;
  1028. return SCM_UNSPECIFIED;
  1029. }
  1030. #undef FUNC_NAME
  1031. SCM_DEFINE (scm_port_line, "port-line", 1, 0, 0,
  1032. (SCM port),
  1033. "Return the current line number for PORT.")
  1034. #define FUNC_NAME s_scm_port_line
  1035. {
  1036. port = SCM_COERCE_OUTPORT (port);
  1037. SCM_VALIDATE_OPENPORT (1,port);
  1038. return SCM_MAKINUM (SCM_LINUM (port));
  1039. }
  1040. #undef FUNC_NAME
  1041. SCM_DEFINE (scm_set_port_line_x, "set-port-line!", 2, 0, 0,
  1042. (SCM port, SCM line),
  1043. "Set the current line number for PORT to LINE.")
  1044. #define FUNC_NAME s_scm_set_port_line_x
  1045. {
  1046. port = SCM_COERCE_OUTPORT (port);
  1047. SCM_VALIDATE_OPENPORT (1,port);
  1048. SCM_VALIDATE_INUM (2,line);
  1049. SCM_PTAB_ENTRY (port)->line_number = SCM_INUM (line);
  1050. return SCM_UNSPECIFIED;
  1051. }
  1052. #undef FUNC_NAME
  1053. SCM_DEFINE (scm_port_column, "port-column", 1, 0, 0,
  1054. (SCM port),
  1055. "@deffnx primitive port-line [input-port]\n"
  1056. "Return the current column number or line number of @var{input-port},\n"
  1057. "using the current input port if none is specified. If the number is\n"
  1058. "unknown, the result is #f. Otherwise, the result is a 0-origin integer\n"
  1059. "- i.e. the first character of the first line is line 0, column 0.\n"
  1060. "(However, when you display a file position, for example in an error\n"
  1061. "message, we recommand you add 1 to get 1-origin integers. This is\n"
  1062. "because lines and column numbers traditionally start with 1, and that is\n"
  1063. "what non-programmers will find most natural.)")
  1064. #define FUNC_NAME s_scm_port_column
  1065. {
  1066. port = SCM_COERCE_OUTPORT (port);
  1067. SCM_VALIDATE_OPENPORT (1,port);
  1068. return SCM_MAKINUM (SCM_COL (port));
  1069. }
  1070. #undef FUNC_NAME
  1071. SCM_DEFINE (scm_set_port_column_x, "set-port-column!", 2, 0, 0,
  1072. (SCM port, SCM column),
  1073. "@deffnx primitive set-port-column! [input-port] column\n"
  1074. "Set the current column or line number of @var{input-port}, using the\n"
  1075. "current input port if none is specified.")
  1076. #define FUNC_NAME s_scm_set_port_column_x
  1077. {
  1078. port = SCM_COERCE_OUTPORT (port);
  1079. SCM_VALIDATE_OPENPORT (1,port);
  1080. SCM_VALIDATE_INUM (2,column);
  1081. SCM_PTAB_ENTRY (port)->column_number = SCM_INUM (column);
  1082. return SCM_UNSPECIFIED;
  1083. }
  1084. #undef FUNC_NAME
  1085. SCM_DEFINE (scm_port_filename, "port-filename", 1, 0, 0,
  1086. (SCM port),
  1087. "Return the filename associated with @var{port}. This function returns\n"
  1088. "the strings \"standard input\", \"standard output\" and \"standard error\""
  1089. "when called on the current input, output and error ports respectively.")
  1090. #define FUNC_NAME s_scm_port_filename
  1091. {
  1092. port = SCM_COERCE_OUTPORT (port);
  1093. SCM_VALIDATE_OPENPORT (1,port);
  1094. return SCM_PTAB_ENTRY (port)->file_name;
  1095. }
  1096. #undef FUNC_NAME
  1097. SCM_DEFINE (scm_set_port_filename_x, "set-port-filename!", 2, 0, 0,
  1098. (SCM port, SCM filename),
  1099. "Change the filename associated with @var{port}, using the current input\n"
  1100. "port if none is specified. Note that this does not change the port's\n"
  1101. "source of data, but only the value that is returned by\n"
  1102. "@code{port-filename} and reported in diagnostic output.")
  1103. #define FUNC_NAME s_scm_set_port_filename_x
  1104. {
  1105. port = SCM_COERCE_OUTPORT (port);
  1106. SCM_VALIDATE_OPENPORT (1,port);
  1107. /* We allow the user to set the filename to whatever he likes. */
  1108. return SCM_PTAB_ENTRY (port)->file_name = filename;
  1109. }
  1110. #undef FUNC_NAME
  1111. #ifndef ttyname
  1112. extern char * ttyname();
  1113. #endif
  1114. void
  1115. scm_print_port_mode (SCM exp, SCM port)
  1116. {
  1117. scm_puts (SCM_CLOSEDP (exp)
  1118. ? "closed: "
  1119. : (SCM_RDNG & SCM_CELL_WORD_0 (exp)
  1120. ? (SCM_WRTNG & SCM_CELL_WORD_0 (exp)
  1121. ? "input-output: "
  1122. : "input: ")
  1123. : (SCM_WRTNG & SCM_CELL_WORD_0 (exp)
  1124. ? "output: "
  1125. : "bogus: ")),
  1126. port);
  1127. }
  1128. int
  1129. scm_port_print (SCM exp, SCM port, scm_print_state *pstate)
  1130. {
  1131. char *type = SCM_PTOBNAME (SCM_PTOBNUM (exp));
  1132. if (!type)
  1133. type = "port";
  1134. scm_puts ("#<", port);
  1135. scm_print_port_mode (exp, port);
  1136. scm_puts (type, port);
  1137. scm_putc (' ', port);
  1138. scm_intprint (SCM_CELL_WORD_1 (exp), 16, port);
  1139. scm_putc ('>', port);
  1140. return 1;
  1141. }
  1142. extern void scm_make_fptob ();
  1143. extern void scm_make_stptob ();
  1144. extern void scm_make_sfptob ();
  1145. void
  1146. scm_ports_prehistory ()
  1147. {
  1148. scm_numptob = 0;
  1149. scm_ptobs = (scm_ptob_descriptor *) malloc (sizeof (scm_ptob_descriptor));
  1150. /* WARNING: These scm_newptob calls must be done in this order.
  1151. * They must agree with the port declarations in tags.h.
  1152. */
  1153. /* scm_tc16_fport = */ scm_make_fptob ();
  1154. /* scm_tc16_pipe was here */ scm_make_fptob (); /* dummy. */
  1155. /* scm_tc16_strport = */ scm_make_stptob ();
  1156. /* scm_tc16_sfport = */ scm_make_sfptob ();
  1157. }
  1158. /* Void ports. */
  1159. long scm_tc16_void_port = 0;
  1160. static int fill_input_void_port (SCM port)
  1161. {
  1162. return EOF;
  1163. }
  1164. static void
  1165. write_void_port (SCM port, const void *data, size_t size)
  1166. {
  1167. }
  1168. SCM
  1169. scm_void_port (char *mode_str)
  1170. {
  1171. int mode_bits;
  1172. SCM answer;
  1173. scm_port * pt;
  1174. SCM_NEWCELL (answer);
  1175. SCM_DEFER_INTS;
  1176. mode_bits = scm_mode_bits (mode_str);
  1177. pt = scm_add_to_port_table (answer);
  1178. scm_port_non_buffer (pt);
  1179. SCM_SETPTAB_ENTRY (answer, pt);
  1180. SCM_SETSTREAM (answer, 0);
  1181. SCM_SET_CELL_TYPE (answer, scm_tc16_void_port | mode_bits);
  1182. SCM_ALLOW_INTS;
  1183. return answer;
  1184. }
  1185. SCM_DEFINE (scm_sys_make_void_port, "%make-void-port", 1, 0, 0,
  1186. (SCM mode),
  1187. "Create and return a new void port. A void port acts like\n"
  1188. "/dev/null. The @var{mode} argument\n"
  1189. "specifies the input/output modes for this port: see the\n"
  1190. "documentation for @code{open-file} in @ref{File Ports}.")
  1191. #define FUNC_NAME s_scm_sys_make_void_port
  1192. {
  1193. SCM_VALIDATE_ROSTRING (1,mode);
  1194. SCM_COERCE_SUBSTR (mode);
  1195. return scm_void_port (SCM_ROCHARS (mode));
  1196. }
  1197. #undef FUNC_NAME
  1198. /* Initialization. */
  1199. void
  1200. scm_init_ports ()
  1201. {
  1202. /* lseek() symbols. */
  1203. scm_sysintern ("SEEK_SET", SCM_MAKINUM (SEEK_SET));
  1204. scm_sysintern ("SEEK_CUR", SCM_MAKINUM (SEEK_CUR));
  1205. scm_sysintern ("SEEK_END", SCM_MAKINUM (SEEK_END));
  1206. scm_tc16_void_port = scm_make_port_type ("void", fill_input_void_port,
  1207. write_void_port);
  1208. #include "libguile/ports.x"
  1209. }
  1210. /*
  1211. Local Variables:
  1212. c-file-style: "gnu"
  1213. End:
  1214. */