1b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/*
2b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
3b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
4b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Licensed under the Apache License, Version 2.0 (the "License");
5b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * you may not use this file except in compliance with the License.
6b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * You may obtain a copy of the License at
7b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
8b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *     http://www.apache.org/licenses/LICENSE-2.0
9b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
10b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Unless required by applicable law or agreed to in writing, software
11b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * distributed under the License is distributed on an "AS IS" BASIS,
12b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * See the License for the specific language governing permissions and
14b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * limitations under the License.
15b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
16b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
17b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @file picopal.c
18b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
19b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * pico platform abstraction layer
20b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
21b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
22b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * All rights reserved.
23b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
24b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * History:
25b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * - 2009-04-20 -- initial version
26b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
27b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
28b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
29b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* GCC does not supporte #pragma message */
30b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if !defined(__GNUC__)
31b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PRAGMA_MESSAGE
32b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
33b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
34b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(PRAGMA_MESSAGE) && defined(PICO_PLATFORM)
35b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#pragma message("PICO_PLATFORM       : is defined externally")
36b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
37b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
38b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(PRAGMA_MESSAGE) && defined(_WIN32)
39b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#pragma message("_WIN32              : is defined")
40b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
41b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
42b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(PRAGMA_MESSAGE) && defined(__APPLE__)
43b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#pragma message("__APPLE__           : is defined")
44b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
45b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
46b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(PRAGMA_MESSAGE) && defined(__MACH__)
47b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#pragma message("__MACH__            : is defined")
48b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
49b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
50b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(PRAGMA_MESSAGE) && defined(macintosh)
51b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#pragma message("macintosh           : is defined")
52b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
53b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
54b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(PRAGMA_MESSAGE) && defined(linux)
55b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#pragma message("linux               : is defined")
56b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
57b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(PRAGMA_MESSAGE) && defined(__linux__)
58b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#pragma message("__linux__           : is defined")
59b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
60b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(PRAGMA_MESSAGE) && defined(__linux)
61b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#pragma message("__linux             : is defined")
62b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
63b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
64b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
65b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <stdlib.h>
66b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <string.h>
67b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <stdio.h>
68b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <stdarg.h>
69b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
70b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picodefs.h"
71b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picopal.h"
72b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
73b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus
74b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern "C" {
75b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
76b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if 0
77b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
78b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
79b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
80b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if PICO_PLATFORM == PICO_Windows
81b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* use high-resolution timer functions on Windows platform */
82b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define USE_CLOCK 0
83b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#else
84b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* use clock() function instead of high-resolution timer on
85b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   non-Windows platforms */
86b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define USE_CLOCK 1
87b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
88b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
89b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <time.h>
90b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if PICO_PLATFORM == PICO_Windows
91b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <windows.h>
92b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
93b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
94b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(PRAGMA_MESSAGE)
95b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#pragma message("PICO_PLATFORM       : " PICO_PLATFORM_STRING)
96b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
97b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
98b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
99b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_int32 picopal_atoi(const picopal_char *s) {
100b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  return (picopal_int32)atoi((const char *)s);
101b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
102b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
103b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_int32 picopal_strcmp(const picopal_char *a, const picopal_char *b) {
104b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  return (picopal_int32)strcmp((const char *)a, (const char *)b);
105b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
106b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
107b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_int32 picopal_strncmp(const picopal_char *a, const picopal_char *b, picopal_objsize_t siz) {
108b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  return (picopal_int32)strncmp((const char *)a, (const char *)b, (size_t) siz);
109b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
110b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
111b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_objsize_t picopal_strlen(const picopal_char *s) {
112b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  return (picopal_objsize_t)strlen((const char *)s);
113b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
114b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
115b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_char *picopal_strchr(const picopal_char *s, picopal_char c) {
116b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  return (picopal_char *)strchr((const char *)s, (int)c);
117b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
118b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
119b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_char *picopal_strstr(const picopal_char *s, const picopal_char *substr) {
120b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  return (picopal_char *)strstr((const char *)s, (const char *)substr);
121b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
122b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
123b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_char *picopal_strcpy(picopal_char *d, const picopal_char *s) {
124b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  return (picopal_char *)strcpy((char *)d, (const char *)s);
125b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
126b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
127b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_char *picopal_strcat(picopal_char *dest, const picopal_char *src) {
128b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  return (picopal_char *)strcat((char *)dest, (const char *)src);
129b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
130b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
131b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
132b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* copy src into dst, but make sure that dst is not accessed beyond its size 'siz' and is allways NULLC-terminated.
133b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * 'siz' is the number of bytes of the destination, including one byte for NULLC!
134b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * returns the full length of the input string, not including termination NULLC (strlen(src)).
135b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * the copy is successfull without truncation if picopal_strlcpy(dst,src,siz) < siz */
136b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_objsize_t picopal_strlcpy(picopal_char *dst, const picopal_char *src, picopal_objsize_t siz)
137b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
138b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picopal_char *d = dst;
139b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        const picopal_char *s = src;
140b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picopal_objsize_t n = siz;
141b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
142b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* Copy as many bytes as will fit */
143b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (n != 0) {
144b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                while (--n != 0) {
145b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        if ((*(d++) = *(s++)) == NULLC) {
146b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                break;
147b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        }
148b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
149b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
150b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
151b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* Not enough room in dst, add NULLC and traverse rest of src */
152b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (n == 0) {
153b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (siz != 0) {
154b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        *d = NULLC;                /* NULLC-terminate dst */
155b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
156b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                while (*(s++)) {}
157b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        ;
158b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
159b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
160b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return(s - src - 1);        /* count does not include NULLC */
161b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
162b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
163b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
164b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_int16 picopal_sprintf(picopal_char * dst, const picopal_char *fmt, ...)
165b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
166b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_int16 i;
167b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    va_list args;
168b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
169b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    va_start(args, (char *)fmt);
170b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    i = (picopal_int16)vsprintf((char *) dst, (const char *)fmt, args);
171b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    va_end(args);
172b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return i;
173b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
174b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
175b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
176b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_objsize_t picopal_vslprintf(picopal_char * dst, picopal_objsize_t siz, const picopal_char *fmt, va_list args) {
177b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_char buf[21];
178b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_char *d = dst;
179b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    const picopal_char *f = fmt;
180b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_char * b;
181b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_objsize_t len, nnew, n = siz;
182b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_int32 ival;
183b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_char cval;
184b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_objsize_t i = 0;
185b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
186b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (!f) {
187b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        f = (picopal_char *) "";
188b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
189b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while (*f) {
190b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (*f == '%') {
191b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            switch (*(++f)) {
192b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                case 'i':
193b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    f++;
194b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    ival = va_arg(args,int);
195b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    picopal_sprintf(buf,(picopal_char *)"%i",ival);
196b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    b = buf;
197b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    break;
198b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                case 'c':
199b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    f++;
200b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cval = va_arg(args,int);
201b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    picopal_sprintf(buf,(picopal_char *)"%c",cval);
202b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    b = buf;
203b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    break;
204b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                case 's':
205b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    f++;
206b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    b = (picopal_char *) va_arg(args, char*);
207b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    break;
208b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                default:
209b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    if (n > 0) {
210b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        (*d++) = '%';
211b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        n--;
212b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    }
213b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    i++;
214b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    b = NULL;
215b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    break;
216b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
217b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (b) {
218b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                len = picopal_strlcpy(d,b,n); /* n1 is the actual length of sval */
219b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                i += len;
220b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                nnew = (n > len) ? n-len : 0; /* nnew is the new value of n */
221b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                d += (n - nnew);
222b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                n = nnew;
223b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
224b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
225b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (n) {
226b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                (*d++) = (*f);
227b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                n--;
228b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
229b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            i++;
230b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            f++;
231b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
232b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
233b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
234b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return i;
235b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
236b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
237b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_objsize_t picopal_slprintf(picopal_char * dst, picopal_objsize_t siz, const picopal_char *fmt, /*args*/ ...) {
238b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_objsize_t i;
239b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    va_list args;
240b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
241b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    va_start(args, (char *)fmt);
242b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    i = picopal_vslprintf(dst, siz, fmt, args);
243b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    va_end(args);
244b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return i;
245b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
246b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
247b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
248b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
249b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* copies 'length' bytes from 'src' to 'dest'. (regions may be overlapping) no error checks! */
250b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid * picopal_mem_copy(const void * src, void * dst, picopal_objsize_t length)
251b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
252b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return memmove(dst, src, (size_t) length);
253b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
254b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
255b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* sets 'length' bytes starting at dest[0] to 'byte_val' */
256b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid * picopal_mem_set(void * dest, picopal_uint8 byte_val, picopal_objsize_t length)
257b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
258b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return memset(dest, (int) byte_val, (size_t) length);
259b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
260b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
261b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *************************************************/
262b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* fixed-point math                                */
263b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *************************************************/
264b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
265b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *************************************************/
266b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* transcendent math                                */
267b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *************************************************/
268b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
269b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
270b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_double picopal_cos(const picopal_double cos_arg)
271b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
272b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picopal_double) cos((double)cos_arg);
273b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
274b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_double picopal_sin(const picopal_double sin_arg)
275b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
276b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picopal_double) sin((double) sin_arg);
277b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
278b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_double picopal_fabs(const picopal_double fabs_arg)
279b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
280b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picopal_double) fabs((double) fabs_arg);
281b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
282b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
283b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
284b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *************************************************/
285b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* file access                                     */
286b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *************************************************/
287b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOPAL_EOL '\n'
288b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
289b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_char picopal_eol(void)
290b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
291b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICOPAL_EOL;
292b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
293b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
294b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* 'fopen' opens the file with name 'filename'. Depending on
295b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   'mode' :
296b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen      'PICOPAL_TEXT_READ'    : Opens an existing text file for reading.
297b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                      The file is positioned at the beginning of the file.
298b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen      'PICOPAL_TEXT_WRITE'   : Opens and truncates an existing file or creates a new
299b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                      text file for writing. The file is positioned at the
300b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                      beginning.
301b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen      'PICOPAL_BIN_READ'  : Opens an existing binary file for reading.
302b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                      The file is positioned at the beginning of the file.
303b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen      'PICOPAL_BIN_WRITE' : Opens and truncates an existing file or creates a new
304b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                      binary file for writing. The file is positioned at the
305b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                      beginning.
306b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    If the opening of the file is successful a file pointer is given
307b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    back. Otherwise a NIL-File is given back.
308b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/
309b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_File picopal_fopen (picopal_char filename[], picopal_access_mode mode)
310b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
311b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_File res;
312b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
313b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     switch (mode) {
314b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     case PICOPAL_TEXT_READ :
315b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         res = (picopal_File) fopen((char *)filename, (char *)"r");
316b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         break;
317b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     case PICOPAL_TEXT_WRITE :
318b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         res = (picopal_File) fopen((char *)filename, (char *)"w");
319b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         break;
320b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     case PICOPAL_BINARY_READ :
321b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         res = (picopal_File) fopen((char *)filename, (char *)"rb");
322b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         break;
323b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     case PICOPAL_BINARY_WRITE :
324b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         res = (picopal_File) fopen((char *)filename, (char *)"wb");
325b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         break;
326b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     default :
327b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         res = (picopal_File) NULL;
328b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     }
329b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     return res;
330b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
331b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
332b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
333b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
334b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_File picopal_get_fnil (void)
335b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
336b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picopal_File) NULL;
337b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
338b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
339b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
340b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_int8 picopal_is_fnil (picopal_File f)
341b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
342b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (NULL == f);
343b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
344b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
345b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picopal_fflush (picopal_File f)
346b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
347b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (0 == fflush((FILE *)f)) ? PICO_OK : PICO_EOF;
348b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
349b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
350b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
351b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picopal_fclose (picopal_File f)
352b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
353b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (0 == fclose((FILE *)f)) ? PICO_OK : PICO_EOF;
354b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
355b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
356b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
357b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
358b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_uint32 picopal_flength (picopal_File stream)
359b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
360b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    fpos_t fpos;
361b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_int32 len;
362b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
363b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    fgetpos((FILE *)stream,&fpos);
364b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_fseek(stream,0,SEEK_END);
365b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    len = ftell((FILE *)stream);
366b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    fsetpos((FILE *)stream,&fpos);
367b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    clearerr((FILE *)stream);
368b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return len;
369b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
370b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
371b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
372b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_uint8 picopal_feof (picopal_File stream)
373b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
374b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (0 != feof((FILE *)stream));
375b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
376b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
377b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
378b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picopal_fseek (picopal_File f, picopal_uint32 offset, picopal_int8 seekmode)
379b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
380b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (0 == fseek((FILE *)f, offset, seekmode)) ? PICO_OK : PICO_EOF;
381b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
382b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
383b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picopal_fget_char (picopal_File f, picopal_char * ch)
384b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
385b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_int16 res;
386b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
387b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    res = fgetc((FILE *)f);
388b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (res >= 0) {
389b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen      *ch = (picopal_char) res;
390b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
391b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    else {
392b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen      *ch = '\0';
393b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
394b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (res >= 0) ? PICO_OK : PICO_EOF;
395b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
396b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
397b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_objsize_t picopal_fread_bytes (picopal_File f, void * ptr, picopal_objsize_t objsize, picopal_uint32 nobj)
398b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
399b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picopal_objsize_t) fread(ptr, objsize, nobj, (FILE *)f);
400b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
401b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
402b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_objsize_t picopal_fwrite_bytes (picopal_File f, void * ptr, picopal_objsize_t objsize, picopal_uint32 nobj){    return (picopal_objsize_t) fwrite(ptr, objsize, nobj, (FILE *)f);}
403b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *************************************************/
404b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* functions for debugging/testing purposes only   */
405b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *************************************************/
406b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
407b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid *picopal_mpr_alloc(picopal_objsize_t size)
408b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
409b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if PICO_PLATFORM == PICO_Windows
410b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
411b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#else
412b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* not yet implemented for other platforms;  corresponding
413b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       function on UNIX systems is pvalloc */
414b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return NULL;
415b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
416b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    size = size;        /* avoid warning "var not used in this function"*/
417b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
418b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
419b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
420b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picopal_mpr_free(void **p)
421b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
422b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if PICO_PLATFORM == PICO_Windows
423b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    VirtualFree(*p, 0, MEM_RELEASE);
424b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#else
425b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* not yet implemented for other platforms */
426b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
427b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *p = NULL;
428b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
429b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
430b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picopal_mpr_protect(void *addr, picopal_objsize_t len, picopal_int16 prot)
431b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
432b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    pico_status_t status = PICO_OK;
433b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
434b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if PICO_PLATFORM == PICO_Windows
435b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    DWORD dwNewProtect, dwOldProtect;
436b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    dwNewProtect = PICOPAL_PROT_NONE;
437b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (prot & PICOPAL_PROT_READ) {
438b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (prot & PICOPAL_PROT_WRITE) {
439b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            dwNewProtect = PAGE_READWRITE;
440b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
441b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            dwNewProtect = PAGE_READONLY;
442b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
443b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else if (prot & PICOPAL_PROT_WRITE) {
444b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* under Windows write-only is not possible */
445b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        dwNewProtect = PAGE_READWRITE;
446b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
447b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (!VirtualProtect(addr, len, dwNewProtect, &dwOldProtect)) {
448b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        status = PICO_ERR_OTHER;
449b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
450b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#else
451b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* not yet implemented for other platforms */
452b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    addr = addr;        /* avoid warning "var not used in this function"*/
453b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    len = len;            /* avoid warning "var not used in this function"*/
454b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    prot = prot;        /* avoid warning "var not used in this function"*/
455b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
456b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
457b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return status;
458b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
459b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/*
460b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *  Reference:
461b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * A Fast, Compact Approximation of the Exponential Function by Nicol N. Schraudolph in Neural Computation, 11,853-862 (1999)
462b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * See also: http://www-h.eng.cam.ac.uk/help/tpl/programs/Matlab/mex.html
463b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
464b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
465b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_double picopal_quick_exp(const picopal_double y) {
466b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    union {
467b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picopal_double d;
468b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen          struct {
469b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            #if PICO_ENDIANNESS == ENDIANNESS_LITTLE /* little endian */
470b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen              picopal_int32 j,i;
471b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            #else
472b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen              picopal_int32 i,j;
473b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            #endif
474b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen          } n;
475b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
476b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } _eco;
477b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    _eco.n.i = (picopal_int32)(1512775.3951951856938297995605697f * y) + 1072632447;
478b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return _eco.d;
479b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
480b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
481b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
482b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *************************************************/
483b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* timer                                           */
484b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *************************************************/
485b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
486b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if IMPLEMENT_TIMER
487b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
488b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define USEC_PER_SEC 1000000
489b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
490b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef clock_t picopal_clock_t;
491b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
492b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
493b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if USE_CLOCK
494b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_clock_t startTime;
495b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#else
496b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenint timerInit = 0;
497b190149a69b110e6719ce0a41877a683f8db7ae7Charles ChenLARGE_INTEGER startTime;
498b190149a69b110e6719ce0a41877a683f8db7ae7Charles ChenLARGE_INTEGER timerFreq;
499b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
500b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
501b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
502b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicopal_clock_t picopal_clock(void)
503b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
504b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picopal_clock_t)clock();
505b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
506b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
507b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif /* IMPLEMENT_TIMER */
508b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
509b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picopal_get_timer(picopal_uint32 * sec, picopal_uint32 * usec)
510b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
511b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if IMPLEMENT_TIMER
512b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if USE_CLOCK
513b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_clock_t dt;
514b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    dt = picopal_clock() - startTime;
515b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *sec = dt / CLOCKS_PER_SEC;
516b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *usec = USEC_PER_SEC * (dt % CLOCKS_PER_SEC) / CLOCKS_PER_SEC;
517b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#else
518b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    LARGE_INTEGER now;
519b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (!timerInit) {
520b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen      QueryPerformanceFrequency(&timerFreq);
521b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen      timerInit = 1;
522b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
523b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (QueryPerformanceCounter(&now) && 0) {
524b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/*
525b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        LONGLONG dt, tf;
526b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        dt = now.QuadPart - GLOB(startTime).QuadPart;
527b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        tf = GLOB(timerFreq).QuadPart;
528b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *sec = (unsigned int) (dt / tf);
529b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *usec = (unsigned int) (USEC_PER_SEC * (dt % tf) / tf);
530b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/
531b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        double dt, tf;
532b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        dt = (double)(now.QuadPart - startTime.QuadPart);
533b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        tf = (double)(timerFreq.QuadPart);
534b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *sec = (unsigned int) (dt /tf);
535b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *usec = (unsigned int) ((double)USEC_PER_SEC * (dt / tf)) % USEC_PER_SEC;
536b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
537b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* high freq counter not supported by system */
538b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        DWORD dt;
539b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        dt = GetTickCount() - startTime.LowPart;
540b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *sec = dt / 1000;
541b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *usec = 1000 * (dt % 1000);
542b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
543b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif /* USE_CLOCK */
544b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#else
545b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *sec = 0;
546b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *usec = 0;
547b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif /* IMPLEMENT_TIMER */
548b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
549b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
550b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus
551b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
552b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
553b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
554b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* End picopal.c */
555