Watt-32 tcp/ip  2.2 dev-rel.10
strings.c
Go to the documentation of this file.
1 
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <ctype.h>
9 
10 #include "wattcp.h"
11 #include "misc.h"
12 #include "strings.h"
13 
14 /*
15  * This file contains some gross hacks. Take great care !
16  */
17 #include "nochkstk.h"
18 
19 #ifdef __WATCOMC__
20  extern void _outchar (char c);
21  #pragma aux _outchar = \
22  "mov ah, 2" \
23  "int 21h" \
24  parm [dl] \
25  modify [ax];
26 #endif
27 
28 /*
29  * Print a single character to stdout.
30  */
31 static int W32_CALL outch (char chr)
32 {
33  if (chr == (char)0x1A) /* EOF (^Z) causes trouble to stdout */
34  return (0);
35 
36 #if defined(WIN32)
37  if (stdout_hnd != INVALID_HANDLE_VALUE)
38  {
39  DWORD written = 0UL;
40 
41  WriteConsoleA (stdout_hnd, &chr, 1, &written, NULL);
42  return (int) written;
43  }
44 
45 #elif !(DOSX)
46  /* Qemm doesn't like INT 21 without a valid ES reg. intdos() sets up that.
47  */
48  {
49  union REGS r;
50  r.h.ah = 2;
51  r.h.dl = chr;
52  intdos (&r, &r);
53  }
54 
55 #elif (DOSX & POWERPAK)
56  {
57  union REGS r;
58  r.h.ah = 2;
59  r.h.dl = chr;
60  int386 (0x21, &r, &r);
61  }
62 
63 #elif defined(__BORLANDC__) /* avoid spawning tasm.exe */
64  _ES = _DS;
65  _DL = chr;
66  _AL = 2;
67  geninterrupt (0x21);
68 
69 #elif defined(_MSC_VER) || defined(__DMC__)
70  asm mov dl, chr
71  asm mov ah, 2
72  asm int 21h
73 
74 #elif defined(__CCDL__)
75  asm mov dl, [chr]
76  asm mov ah, 2
77  asm int 0x21
78 
79 #elif defined(__WATCOMC__)
80  _outchar (chr);
81 
82 #elif defined(__HIGHC__) /* outch() must not be optimised! */
83  _inline (0x8A,0x55,0x08); /* mov dl,[ebp+8] */
84  _inline (0xB4,0x02); /* mov ah,2 */
85  _inline (0xCD,0x21); /* int 21h */
86 
87 #elif defined(__GNUC__)
88  __asm__ __volatile__
89  ("movb %b0, %%dl\n\t"
90  "movb $2, %%ah\n\t"
91  "int $0x21\n\t"
92  :
93  : "r" (chr)
94  : "%eax", "%edx" );
95 
96 #else
97  #error Tell me how to do this
98 #endif
99 
100  return (1);
101 }
102 
103 int (W32_CALL *_outch)(char c) = outch;
104 
105 /*---------------------------------------------------*/
106 
107 #if defined(USE_DEBUG)
108  int (MS_CDECL *_printf) (const char*, ...) = printf;
109 #else
110  static int MS_CDECL empty_printf (const char *fmt, ...)
111  {
112  outsnl ("`(*_printf)()' called outside `USE_DEBUG'");
113  ARGSUSED (fmt);
114  return (0);
115  }
116  int (MS_CDECL *_printf) (const char*, ...) = empty_printf;
117 #endif
118 
119 /*---------------------------------------------------*/
120 
121 void W32_CALL outs (const char *s)
122 {
123  while (_outch && s && *s)
124  {
125  if (*s == '\n')
126  (*_outch) ('\r');
127  (*_outch) (*s++);
128  }
129 }
130 
131 void W32_CALL outsnl (const char *s)
132 {
133  outs (s);
134  outs ("\n");
135 }
136 
137 void W32_CALL outsn (const char *s, int n)
138 {
139  while (_outch && *s != '\0' && n-- >= 0)
140  {
141  if (*s == '\n')
142  (*_outch) ('\r');
143  (*_outch) (*s++);
144  }
145 }
146 
147 void W32_CALL outhex (char c)
148 {
149  char lo, hi;
150 
151  if (!_outch)
152  return;
153 
154  hi = (c & 0xF0) >> 4;
155  lo = c & 15;
156 
157  if (hi > 9)
158  (*_outch) ((char)(hi-10+'A'));
159  else (*_outch) ((char)(hi+'0'));
160 
161  if (lo > 9)
162  (*_outch) ((char)(lo-10+'A'));
163  else (*_outch) ((char)(lo+'0'));
164 }
165 
166 void W32_CALL outhexes (const char *s, int n)
167 {
168  while (_outch && n-- > 0)
169  {
170  outhex (*s++);
171  (*_outch) (' ');
172  }
173 }
174 
180 char * W32_CALL rip (char *s)
181 {
182  char *p;
183 
184  if ((p = strrchr(s,'\n')) != NULL) *p = '\0';
185  if ((p = strrchr(s,'\r')) != NULL) *p = '\0';
186  return (s);
187 }
188 
194 BYTE atox (const char *hex)
195 {
196  unsigned hi = toupper ((int)hex[2]);
197  unsigned lo = toupper ((int)hex[3]);
198 
199  hi -= isdigit (hi) ? '0' : 'A'-10;
200  lo -= isdigit (lo) ? '0' : 'A'-10;
201  return (BYTE) ((hi << 4) + lo);
202 }
203 
207 char *strreplace (int ch1, int ch2, char *str)
208 {
209  char *s;
210 
211  WATT_ASSERT (str != NULL);
212 
213  s = str;
214  while (*s)
215  {
216  if (*s == ch1)
217  *s = ch2;
218  s++;
219  }
220  return (str);
221 }
222 
226 char *_strlcpy (char *dst, const char *src, size_t len)
227 {
228  WATT_ASSERT (src != NULL);
229  WATT_ASSERT (dst != NULL);
230  WATT_ASSERT (len > 0);
231 
232  if (strlen(src) < len)
233  return strcpy (dst, src);
234 
235  memcpy (dst, src, len);
236  dst [len-1] = '\0';
237  return (dst);
238 }
239 
243 char *strltrim (const char *s)
244 {
245  WATT_ASSERT (s != NULL);
246 
247  while (s[0] && s[1] && isspace((int)s[0]))
248  s++;
249  return (char*)s;
250 }
251 
255 char *strrtrim (char *s)
256 {
257  size_t n;
258 
259  WATT_ASSERT (s != NULL);
260 
261  n = strlen (s);
262  while (n)
263  {
264  if (!isspace((int)s[--n]))
265  break;
266  s[n] = '\0';
267  }
268  return (s);
269 }
270 
277 size_t strntrimcpy (char *dst, const char *src, size_t n)
278 {
279  size_t len;
280  const char *s;
281 
282  WATT_ASSERT (src != NULL);
283  WATT_ASSERT (dst != NULL);
284 
285  len = 0;
286  s = src;
287 
288  if (n && s[0])
289  {
290  while (isspace((int)*s))
291  ++s;
292  len = strlen (s);
293  if (len)
294  {
295  const char *e = &s[len-1];
296  while (isspace((int)*e))
297  {
298  --e;
299  --len;
300  }
301  if (len > n)
302  len = n;
303  strncpy (dst, s, len);
304  }
305  }
306  if (len < n)
307  dst[len] = '\0';
308  return (len);
309 }
310 
311 /*
312  * A strtok_r() function taken from libcurl:
313  *
314  * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
315  */
316 char *strtok_r (char *ptr, const char *sep, char **end)
317 {
318  if (!ptr)
319  {
320  /* we got NULL input so then we get our last position instead */
321  ptr = *end;
322  }
323 
324  /* pass all letters that are including in the separator string */
325  while (*ptr && strchr(sep, *ptr))
326  ++ptr;
327 
328  if (*ptr)
329  {
330  /* so this is where the next piece of string starts */
331  char *start = ptr;
332 
333  /* set the end pointer to the first byte after the start */
334  *end = start + 1;
335 
336  /* scan through the string to find where it ends, it ends on a
337  * null byte or a character that exists in the separator string.
338  */
339  while (**end && !strchr(sep, **end))
340  ++*end;
341 
342  if (**end)
343  {
344  /* the end is not a null byte */
345  **end = '\0'; /* zero terminate it! */
346  ++*end; /* advance the last pointer to beyond the null byte */
347  }
348  return (start); /* return the position where the string starts */
349  }
350  /* we ended up on a null byte, there are no more strings to find! */
351  return (NULL);
352 }
353 
354 #ifdef NOT_USED
355 int isstring (const char *str, size_t len)
356 {
357  if (strlen(str) > len-1)
358  return (0);
359 
360  while (*str)
361  {
362  if (!isprint(*str++))
363  {
364  str--;
365  if (!isspace(*str++))
366  return (0);
367  }
368  }
369  return (1);
370 }
371 #endif
char * strreplace(int ch1, int ch2, char *str)
Replace 'ch1' to 'ch2' in string 'str'.
Definition: strings.c:207
char * strltrim(const char *s)
Return pointer to first non-blank (space/tab) in a string.
Definition: strings.c:243
size_t strntrimcpy(char *dst, const char *src, size_t n)
Copy a string, stripping leading and trailing blanks (space/tab).
Definition: strings.c:277
Core definitions.
char * _strlcpy(char *dst, const char *src, size_t len)
Similar to strncpy(), but always returns 'dst' with 0-termination.
Definition: strings.c:226
char * strrtrim(char *s)
Trim trailing blanks (space/tab) from a string.
Definition: strings.c:255
BYTE atox(const char *hex)
Convert hexstring "0x??" to hex.
Definition: strings.c:194
Definition: ah.h:48
char *W32_CALL rip(char *s)
Removes end-of-line termination from a string.
Definition: strings.c:180