source: trunk/kStuff/kLdr/kLdrHlp.c@ 3570

Last change on this file since 3570 was 3570, checked in by bird, 18 years ago

Moving kLdr.h.

  • Property svn:keywords set to Id
File size: 6.9 KB
Line 
1/* $Id: kLdrHlp.c 3570 2007-08-31 02:27:16Z bird $ */
2/** @file
3 *
4 * kLdr - The Dynamic Loader, Misc Helper Functions.
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 <k/kLdr.h>
42#include "kLdrHlp.h"
43
44
45/**
46 * Get an environment variable.
47 *
48 * @returns 0 on success.
49 * @returns KLDR_ERR_BUFFER_OVERFLOW on if the buffer is too small.
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.
52 * @param pszVar The variable name.
53 * @param pszVal Where to store the value.
54 * @param cchVal The size of the buffer pointed to by pszVal.
55 */
56int kldrHlpGetEnv(const char *pszVar, char *pszVal, KSIZE cchVal)
57{
58#ifdef __OS2__
59 PSZ pszValue = NULL;
60 int rc;
61
62 *pszVal = '\0';
63 rc = DosScanEnv((PCSZ)pszVar, &pszValue);
64 if (!rc)
65 {
66 KSIZE cch = kLdrHlpStrLen((const char *)pszValue);
67 if (cchVal > cch)
68 kLdrHlpMemCopy(pszVal, pszValue, cch + 1);
69 else
70 rc = KLDR_ERR_BUFFER_OVERFLOW;
71 }
72 else
73 rc = KLDR_ERR_SYMBOL_NOT_FOUND;
74 return rc;
75
76#elif defined(__WIN__)
77 DWORD cch;
78
79 SetLastError(0);
80 cch = GetEnvironmentVariable(pszVar, pszVal, cchVal);
81 if (cch > 0 && cch < cchVal)
82 return 0;
83
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
91#else
92# error "Port me"
93#endif
94}
95
96
97/**
98 * Gets an environment variable and converts it to a KSIZE.
99 *
100 * @returns 0 and *pcb on success.
101 * @returns On failure see kldrHlpGetEnv.
102 * @param pszVar The name of the variable.
103 * @param pcb Where to put the value.
104 */
105int kldrHlpGetEnvUZ(const char *pszVar, KSIZE *pcb)
106{
107 KSIZE cb;
108 unsigned uBase;
109 char szVal[64];
110 KSIZE cchVal = sizeof(szVal);
111 const char *psz;
112 int rc;
113
114 *pcb = 0;
115 rc = kldrHlpGetEnv(pszVar, szVal, cchVal);
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/**
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
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
207/**
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');
220 while (pszNl)
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/**
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{
268 char szLine[16];
269
270 kldrHlpAssertWrite("\n!!!kLdr Assertion Failed!!!\nExpression: ");
271 kldrHlpAssertWrite(pszExpr);
272 kldrHlpAssertWrite("\nAt: ");
273 kldrHlpAssertWrite(pszFile);
274 kldrHlpAssertWrite("(");
275 kldrHlpAssertWrite(kldrHlpInt2Ascii(szLine, sizeof(szLine), iLine, 10));
276 kldrHlpAssertWrite(") ");
277 kldrHlpAssertWrite(pszFunction);
278 kldrHlpAssertWrite("\n");
279}
280
Note: See TracBrowser for help on using the repository browser.