]> git.donarmstrong.com Git - lilypond.git/blob - flower/libc-extension.cc
* scm/lily.scm (PLATFORM): Export.
[lilypond.git] / flower / libc-extension.cc
1 /*
2   libc-extension.cc --  compensate for lacking libc functions.
3
4   source file of the flowerlib
5
6   (c) 1997--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   Jan Nieuwenhuizen <janneke@gnu.org>
8 */
9
10 #include <cmath>
11 #include <cstdio>
12 #include <cstring>
13 #include <cctype>
14
15 #include "libc-extension.hh"
16
17 char *
18 strnlwr (char *start, int n)
19 {
20   char *p = start + n;
21   while (--p >= start)
22     {
23       *p = tolower (*p);    /* a macro on some compilers */
24     }
25   return start;
26 }
27
28 char *
29 strnupr (char *start, int n)
30 {
31   char *p = start + n;
32   while (--p >= start)
33     {
34       *p = toupper (*p);    /* a macro on some compilers */
35     }
36   return start;
37 }
38
39 /*
40   There are some strange problems with round() on early glibcs.
41 */
42 double
43 my_round (double x)
44 {
45   return floor (x -0.5)+ 1.0;
46 }
47
48 #ifndef isinf
49 #if !HAVE_ISINF
50 int
51 isinf (double x)
52 {
53   return x && (x == x/ 2);
54 }
55 #endif
56 #endif
57
58 #if !HAVE_MEMMEM
59
60 /** locate a substring. #memmem# finds the first occurrence of
61     #needle# in #haystack#.  This is not ANSI-C.
62
63     The prototype is not in accordance with the Linux Programmer's
64     Manual v1.15, but it is with /usr/include/string.h   */
65
66 unsigned char *
67 _memmem (unsigned char const *haystack, int haystack_len,
68          unsigned char const *needle, int needle_len)
69 {
70   unsigned char const *end_haystack = haystack + haystack_len - needle_len + 1;
71   unsigned char const *end_needle = needle + needle_len;
72
73   /* Ahhh ... Some minimal lowlevel stuff. This *is* nice; Varation
74      is the spice of life */
75   while (haystack < end_haystack)
76     {
77       unsigned char const *subneedle = needle;
78       unsigned char const *subhaystack = haystack;
79       while (subneedle < end_needle)
80         if (*subneedle++ != *subhaystack++)
81           goto next;
82
83       /* Completed the needle.  Gotcha.  */
84       return (unsigned char *) haystack;
85     next:
86       haystack++;
87     }
88   return 0;
89 }
90
91 void *
92 memmem (void const *haystack, int haystack_len,
93         void const *needle, int needle_len)
94 {
95   unsigned char const *haystack_byte_c = (unsigned char const *)haystack;
96   unsigned char const *needle_byte_c = (unsigned char const *)needle;
97   return _memmem (haystack_byte_c, haystack_len, needle_byte_c, needle_len);
98 }
99
100 #endif
101
102 unsigned char *
103 memrchr (unsigned char const *p, int n, char c)
104 {
105   const unsigned char *q = p + n;
106   while (q > p)
107     {
108       if (*--q == c)
109         return (unsigned char *)q;
110     }
111   return 0;
112 }
113
114 template<class T>
115 inline void
116 my_swap (T &t1, T &t2, T &tmp)
117 {
118   tmp = t1;
119   t1 = t2;
120   t2 = tmp;
121 }
122
123 unsigned char *
124 memrev (unsigned char *byte, int length)
125 {
126   unsigned char tmp_byte;
127   unsigned char *left = byte;
128   unsigned char *right = byte + length;
129
130   while (right > left)
131     my_swap (*right--, *left++, tmp_byte);
132   return byte;
133 }
134
135 #if ! HAVE_SNPRINTF
136 int
137 snprintf (char *str, size_t n, char const *format, ...)
138 {
139   va_list ap;
140   va_start (ap, format);
141   int i = vsprintf (str, format, ap);
142   if (i > 0 && (unsigned) i > n)
143     assert (false);
144   va_end (ap);
145   return i;
146 }
147 #endif
148
149 #if ! HAVE_VSNPRINTF
150 int
151 vsnprintf (char *str, size_t n, char const *format, va_list args)
152 {
153   int i = vsprintf (str, format, args);
154   if (i > 0 && (unsigned) i > n)
155     assert (false);
156   return i;
157 }
158 #endif
159
160 #include <assert.h>
161
162 extern "C" {
163
164 #if ! HAVE_FOPENCOOKIE
165 #if HAVE_FUNOPEN
166
167   FILE *
168   fopencookie (void *cookie, char const *mode, cookie_io_functions_t fun)
169   {
170     (void) mode;
171 #if 0
172     return funopen (cookie, fun.read, fun.write, fun.seek, fun.close);
173 #else
174     return funopen (cookie,
175                     (int (*) (void *, char *, int)) fun.read,
176                     (int (*) (void *, char const *, int)) fun.write,
177                     (fpos_t (*) (void *, fpos_t, int)) fun.seek,
178                     (int (*) (void *)) fun.close);
179 #endif
180   }
181
182 #else /* ! HAVE_FUNOPEN */
183
184 #include <cstdio>
185 #include "memory-stream.hh"
186
187   static bool
188   is_memory_stream (void *foo)
189   {
190     Memory_out_stream *cookie = (Memory_out_stream *) foo;
191     return dynamic_cast<Memory_out_stream *> (cookie);
192   }
193
194   FILE *
195   fopencookie (void *cookie, char const *modes, cookie_io_functions_t io_funcs)
196   {
197     (void) cookie;
198     (void) modes;
199     (void) io_funcs;
200     if (is_memory_stream (cookie))
201       return (FILE *) cookie;
202     assert (false);
203     return 0;
204   }
205
206   int
207   handle_cookie_io_fclose (FILE *file)
208   {
209     if (is_memory_stream (file))
210       return Memory_out_stream::cleaner (file);
211     return fclose (file);
212   }
213
214   int
215   handle_cookie_io_fprintf (FILE *file, char const *format, ...)
216   {
217     va_list ap;
218     va_start (ap, format);
219     if (is_memory_stream (file))
220       {
221         static char buf[65536];
222         int i = vsnprintf (buf, sizeof (buf), format, ap);
223         if (i == -1 || (unsigned) i > sizeof (buf))
224           assert (false);
225         return Memory_out_stream::writer (file, buf, i);
226       }
227     int i = vfprintf (file, format, ap);
228     va_end (ap);
229     return i;
230   }
231
232   int
233   handle_cookie_io_putc (int c, FILE *file)
234   {
235     if (is_memory_stream (file))
236       {
237         char buf[1];
238         buf[0] = (char) c;
239         return Memory_out_stream::writer (file, buf, 1);
240       }
241     return putc (c, file);
242   }
243
244 #endif /* ! HAVE_FUNOPEN */
245 #endif /* ! HAVE_FOPENCOOKIE */
246 } /* extern C */