source: trunk/kLdr/kLdrHlp.c@ 3003

Last change on this file since 3003 was 2944, checked in by bird, 19 years ago

split up kLdrHlp.c and kLdr.c to make it more flexible (like using the module interpreters without the dynamic loader bit and similar).

  • Property svn:keywords set to Id
File size: 6.9 KB
RevLine 
[2826]1/* $Id: kLdrHlp.c 2944 2007-01-13 15:55:40Z bird $ */
[2825]2/** @file
3 *
[2944]4 * kLdr - The Dynamic Loader, Misc Helper Functions.
[2825]5 *
6 * Copyright (c) 2006 knut st. osmundsen <bird-kbuild-src@anduin.net>
7 *
8 *
9 * This file is part of kLdr.
10 *
11 * kLdr is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * kLdr is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with kLdr; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#ifdef __OS2__
32# define INCL_BASE
33# define INCL_ERRORS
34# include <os2.h>
35#elif defined(__WIN__)
36# include <Windows.h>
37#else
38# error "port me"
39#endif
40
41#include <kLdr.h>
42#include "kLdrHlp.h"
43
44
45/**
46 * Get an environment variable.
47 *
[2867]48 * @returns 0 on success.
[2869]49 * @returns KLDR_ERR_BUFFER_OVERFLOW on if the buffer is too small.
[2867]50 * @returns KLDR_ERR_SYMBOL_NOT_FOUND if not found. (Yeah, abusing the status code, but it's only internally...)
51 * @returns OS specfic status code on other error.
[2825]52 * @param pszVar The variable name.
[2867]53 * @param pszVal Where to store the value.
54 * @param cchVal The size of the buffer pointed to by pszVal.
[2825]55 */
[2867]56int kldrHlpGetEnv(const char *pszVar, char *pszVal, size_t cchVal)
[2825]57{
58#ifdef __OS2__
59 PSZ pszValue = NULL;
[2867]60 int rc;
61
62 *pszVal = '\0';
63 rc = DosScanEnv((PCSZ)pszVar, &pszValue);
[2825]64 if (!rc)
65 {
[2883]66 size_t cch = kLdrHlpStrLen((const char *)pszValue);
[2867]67 if (cchVal > cch)
68 kLdrHlpMemCopy(pszVal, pszValue, cch + 1);
69 else
70 rc = KLDR_ERR_BUFFER_OVERFLOW;
[2825]71 }
72 else
[2867]73 rc = KLDR_ERR_SYMBOL_NOT_FOUND;
[2825]74 return rc;
75
76#elif defined(__WIN__)
77 DWORD cch;
[2867]78
[2825]79 SetLastError(0);
[2867]80 cch = GetEnvironmentVariable(pszVar, pszVal, cchVal);
[2869]81 if (cch > 0 && cch < cchVal)
[2825]82 return 0;
83
[2867]84 *pszVal = '\0';
85 if (cch >= cchVal)
86 return KLDR_ERR_BUFFER_OVERFLOW;
87 if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
88 return KLDR_ERR_SYMBOL_NOT_FOUND;
89 return GetLastError();
90
[2825]91#else
92# error "Port me"
93#endif
94}
95
96
97/**
[2846]98 * Gets an environment variable and converts it to a size_t.
99 *
100 * @returns 0 and *pcb on success.
[2867]101 * @returns On failure see kldrHlpGetEnv.
[2846]102 * @param pszVar The name of the variable.
103 * @param pcb Where to put the value.
104 */
105int kldrHlpGetEnvUZ(const char *pszVar, size_t *pcb)
106{
107 size_t cb;
108 unsigned uBase;
109 char szVal[64];
110 size_t cchVal = sizeof(szVal);
111 const char *psz;
112 int rc;
113
114 *pcb = 0;
[2867]115 rc = kldrHlpGetEnv(pszVar, szVal, cchVal);
[2846]116 if (rc)
117 return rc;
118
119 /* figure out the base. */
120 uBase = 10;
121 psz = szVal;
122 if ( *psz == '0'
123 && (psz[1] == 'x' || psz[1] == 'X'))
124 {
125 uBase = 16;
126 psz += 2;
127 }
128
129 /* convert it up to the first unknown char. */
130 cb = 0;
131 for(;;)
132 {
133 const char ch = *psz;
134 unsigned uDigit;
135 if (!ch)
136 break;
137 else if (ch >= '0' && ch <= '9')
138 uDigit = ch - '0';
139 else if (ch >= 'a' && ch <= 'z')
140 uDigit = ch - 'a' + 10;
141 else if (ch >= 'A' && ch <= 'Z')
142 uDigit = ch - 'A' + 10;
143 else
144 break;
145 if (uDigit >= uBase)
146 break;
147
148 /* add the digit */
149 cb *= uBase;
150 cb += uDigit;
151
152 psz++;
153 }
154
155 /* check for unit */
156 if (*psz == 'm' || *psz == 'M')
157 cb *= 1024*1024;
158 else if (*psz == 'k' ||*psz == 'K')
159 cb *= 1024;
160 else if (*psz == 'g' || *psz == 'G')
161 cb *= 1024*1024*1024;
162
163 *pcb = cb;
164 return 0;
165}
166
167
168/**
[2825]169 * Terminate the process.
170 *
171 * @param rc The exit status.
172 */
173void kldrHlpExit(int rc)
174{
175 for (;;)
176 {
177#ifdef __OS2__
178 DosExit(EXIT_PROCESS, rc);
179
180#elif defined(__WIN__)
181 TerminateProcess(GetCurrentProcess(), rc);
182
183#else
184# error "Port me"
185#endif
186 kldrHlpAssert(!"Impossible");
187 }
188}
189
[2830]190
191/**
192 * Sleep for a number of milliseconds.
193 * @param cMillies Number of milliseconds to sleep.
194 */
195void kldrHlpSleep(unsigned cMillies)
196{
197#ifdef __OS2__
198 DosSleep(cMillies);
199#elif defined(__WIN__)
200 Sleep(cMillies);
201#else
202 usleep(cMillies * 1000);
203#endif
204}
205
206
[2836]207/**
[2832]208 * Writes a assert string with unix lineendings.
209 *
210 * @param pszMsg The string.
211 */
212static void kldrHlpAssertWrite(const char *pszMsg)
213{
214#if defined(__OS2__) || defined(__WIN__)
215 /*
216 * Line by line.
217 */
218 ULONG cbWritten;
219 const char *pszNl = kLdrHlpStrChr(pszMsg, '\n');
[2842]220 while (pszNl)
[2832]221 {
222 cbWritten = pszNl - pszMsg;
223
224#ifdef __OS2__
225 if (cbWritten)
226 DosWrite((HFILE)2, pszMsg, cbWritten, &cbWritten);
227 DosWrite((HFILE)2, "\r\n", 2, &cbWritten);
228#else /* __WIN32__ */
229 if (cbWritten)
230 WriteFile((HANDLE)STD_ERROR_HANDLE, pszMsg, cbWritten, &cbWritten, NULL);
231 WriteFile((HANDLE)STD_ERROR_HANDLE, "\r\n", 2, &cbWritten, NULL);
232#endif
233
234 /* next */
235 pszMsg = pszNl + 1;
236 pszNl = kLdrHlpStrChr(pszMsg, '\n');
237 }
238
239 /*
240 * Remaining incomplete line.
241 */
242 if (*pszMsg)
243 {
244 cbWritten = kLdrHlpStrLen(pszMsg);
245#ifdef __OS2__
246 DosWrite((HFILE)2, pszMsg, cbWritten, &cbWritten);
247#else /* __WIN32__ */
248 WriteFile((HANDLE)STD_ERROR_HANDLE, pszMsg, cbWritten, &cbWritten, NULL);
249#endif
250 }
251
252#else
253# error "port me"
254#endif
255}
256
257
258/**
[2825]259 * Internal worker for the kLdrHlpAssert() macro.
260 *
261 * @param pszExpr The assert expression.
262 * @param pszFile The filename.
263 * @param iLine The line number.
264 * @param pszFunction The function name.
265 */
266void kldrHlpAssertMsg(const char *pszExpr, const char *pszFile, unsigned iLine, const char *pszFunction)
267{
[2832]268 char szLine[16];
[2825]269
[2832]270 kldrHlpAssertWrite("\n!!!kLdr Assertion Failed!!!\nExpression: ");
271 kldrHlpAssertWrite(pszExpr);
272 kldrHlpAssertWrite("\nAt: ");
273 kldrHlpAssertWrite(pszFile);
274 kldrHlpAssertWrite("(");
[2836]275 kldrHlpAssertWrite(kldrHlpInt2Ascii(szLine, sizeof(szLine), iLine, 10));
[2832]276 kldrHlpAssertWrite(") ");
277 kldrHlpAssertWrite(pszFunction);
278 kldrHlpAssertWrite("\n");
279}
[2825]280
Note: See TracBrowser for help on using the repository browser.