Merge remote-tracking branch 'origin/stable-2.0'
[bpt/guile.git] / libguile / inline.h
CommitLineData
16ea9620
MV
1/* classes: h_files */
2
3#ifndef SCM_INLINE_H
4#define SCM_INLINE_H
5
452c5ad9
LC
6/* Copyright (C) 2001, 2002, 2003, 2004, 2006, 2008, 2009, 2010,
7 * 2011 Free Software Foundation, Inc.
16ea9620 8 *
73be1d9e 9 * This library is free software; you can redistribute it and/or
53befeb7
NJ
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 3 of
12 * the License, or (at your option) any later version.
16ea9620 13 *
53befeb7
NJ
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
16ea9620 18 *
73be1d9e
MV
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
53befeb7
NJ
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * 02110-1301 USA
73be1d9e 23 */
16ea9620
MV
24
25/* This file is for inline functions. On platforms that don't support
4cf77f09
AW
26 inlining functions, they are turned into ordinary functions. On
27 platforms that do support inline functions, the definitions are still
28 compiled into the library, once, in inline.c. */
16ea9620 29
1e71eafb 30#include <stdio.h>
f5c2af4b
LC
31#include <string.h>
32
33#include "libguile/__scm.h"
1e71eafb 34
16ea9620
MV
35#include "libguile/pairs.h"
36#include "libguile/gc.h"
9bc4701c 37#include "libguile/threads.h"
2a610be5 38#include "libguile/array-handle.h"
f5c2af4b 39#include "libguile/ports.h"
2a610be5 40#include "libguile/numbers.h"
f5c2af4b 41#include "libguile/error.h"
16ea9620 42
c8a1bdc4 43
4cf77f09
AW
44SCM_INLINE SCM scm_array_handle_ref (scm_t_array_handle *h, ssize_t pos);
45SCM_INLINE void scm_array_handle_set (scm_t_array_handle *h, ssize_t pos, SCM val);
60e7529a 46
4cf77f09
AW
47SCM_INLINE int scm_is_pair (SCM x);
48SCM_INLINE int scm_is_string (SCM x);
f5c2af4b 49
4cf77f09
AW
50SCM_INLINE int scm_get_byte_or_eof (SCM port);
51SCM_INLINE int scm_peek_byte_or_eof (SCM port);
52SCM_INLINE void scm_putc (char c, SCM port);
53SCM_INLINE void scm_puts (const char *str_data, SCM port);
3f520967 54
60e7529a 55
ff670362
AW
56SCM_INLINE SCM scm_cell (scm_t_bits car, scm_t_bits cdr);
57SCM_INLINE SCM scm_double_cell (scm_t_bits car, scm_t_bits cbr,
58 scm_t_bits ccr, scm_t_bits cdr);
59SCM_INLINE SCM scm_words (scm_t_bits car, scm_t_uint16 n_words);
6253f3f1 60
ff670362
AW
61#if SCM_CAN_INLINE || defined SCM_INLINE_C_IMPLEMENTING_INLINES
62/* Either inlining, or being included from inline.c. */
6253f3f1 63
4cf77f09 64SCM_INLINE_IMPLEMENTATION SCM
9598a406
MV
65scm_array_handle_ref (scm_t_array_handle *h, ssize_t p)
66{
6d7c4402 67 if (SCM_UNLIKELY (p < 0 && ((size_t)-p) > h->base))
2a610be5
AW
68 /* catch overflow */
69 scm_out_of_range (NULL, scm_from_ssize_t (p));
70 /* perhaps should catch overflow here too */
71 return h->impl->vref (h, h->base + p);
9598a406 72}
eab1b259 73
4cf77f09 74SCM_INLINE_IMPLEMENTATION void
9598a406
MV
75scm_array_handle_set (scm_t_array_handle *h, ssize_t p, SCM v)
76{
3245c0fb 77 if (SCM_UNLIKELY (p < 0 && ((size_t)-p) > h->base))
2a610be5
AW
78 /* catch overflow */
79 scm_out_of_range (NULL, scm_from_ssize_t (p));
80 /* perhaps should catch overflow here too */
81 h->impl->vset (h, h->base + p, v);
9598a406 82}
eab1b259 83
4cf77f09 84SCM_INLINE_IMPLEMENTATION int
d5ad4aa6
MV
85scm_is_pair (SCM x)
86{
23f2b9a3
KR
87 /* The following "workaround_for_gcc_295" avoids bad code generated by
88 i386 gcc 2.95.4 (the Debian packaged 2.95.4-24 at least).
89
90 Under the default -O2 the inlined SCM_I_CONSP test gets "optimized" so
91 the fetch of the tag word from x is done before confirming it's a
92 non-immediate (SCM_NIMP). Needless to say that bombs badly if x is a
93 immediate. This was seen to afflict scm_srfi1_split_at and something
94 deep in the bowels of ceval(). In both cases segvs resulted from
95 deferencing a random immediate value. srfi-1.test exposes the problem
96 through a short list, the immediate being SCM_EOL in that case.
97 Something in syntax.test exposed the ceval() problem.
98
99 Just "volatile SCM workaround_for_gcc_295 = lst" is enough to avoid the
100 problem, without even using that variable. The "w=w" is just to
101 prevent a warning about it being unused.
102 */
103#if defined (__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ == 95
104 volatile SCM workaround_for_gcc_295 = x;
105 workaround_for_gcc_295 = workaround_for_gcc_295;
106#endif
107
d5ad4aa6
MV
108 return SCM_I_CONSP (x);
109}
110
4cf77f09 111SCM_INLINE_IMPLEMENTATION int
183f7849
LC
112scm_is_string (SCM x)
113{
114 return SCM_NIMP (x) && (SCM_TYP7 (x) == scm_tc7_string);
115}
f5c2af4b
LC
116
117/* Port I/O. */
118
4cf77f09 119SCM_INLINE_IMPLEMENTATION int
889975e5 120scm_get_byte_or_eof (SCM port)
f5c2af4b
LC
121{
122 int c;
123 scm_t_port *pt = SCM_PTAB_ENTRY (port);
124
125 if (pt->rw_active == SCM_PORT_WRITE)
126 /* may be marginally faster than calling scm_flush. */
127 scm_ptobs[SCM_PTOBNUM (port)].flush (port);
128
129 if (pt->rw_random)
130 pt->rw_active = SCM_PORT_READ;
131
132 if (pt->read_pos >= pt->read_end)
133 {
452c5ad9 134 if (SCM_UNLIKELY (scm_fill_input (port) == EOF))
f5c2af4b
LC
135 return EOF;
136 }
137
138 c = *(pt->read_pos++);
139
f5c2af4b
LC
140 return c;
141}
142
452c5ad9 143/* Like `scm_get_byte_or_eof' but does not change PORT's `read_pos'. */
4cf77f09 144SCM_INLINE_IMPLEMENTATION int
452c5ad9
LC
145scm_peek_byte_or_eof (SCM port)
146{
147 int c;
148 scm_t_port *pt = SCM_PTAB_ENTRY (port);
149
150 if (pt->rw_active == SCM_PORT_WRITE)
151 /* may be marginally faster than calling scm_flush. */
152 scm_ptobs[SCM_PTOBNUM (port)].flush (port);
153
154 if (pt->rw_random)
155 pt->rw_active = SCM_PORT_READ;
156
157 if (pt->read_pos >= pt->read_end)
158 {
159 if (SCM_UNLIKELY (scm_fill_input (port) == EOF))
160 return EOF;
161 }
162
163 c = *pt->read_pos;
164
165 return c;
166}
167
4cf77f09 168SCM_INLINE_IMPLEMENTATION void
f5c2af4b
LC
169scm_putc (char c, SCM port)
170{
171 SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
172 scm_lfwrite (&c, 1, port);
173}
174
4cf77f09 175SCM_INLINE_IMPLEMENTATION void
f5c2af4b
LC
176scm_puts (const char *s, SCM port)
177{
178 SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
179 scm_lfwrite (s, strlen (s), port);
180}
181
182
16ea9620 183#endif
16ea9620 184#endif