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