OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [c/] [src/] [libnetworking/] [rtems_webserver/] [misc.c] - Blame information for rev 1779

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
2
 * misc.c -- Miscellaneous routines.
3
 *
4
 * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
5
 *
6
 * See the file "license.txt" for usage and redistribution license requirements
7
 */
8
 
9
/********************************* Includes ***********************************/
10
 
11
#if UEMF
12
        #include        "uemf.h"
13
#else
14
        #include        "basic/basicInternal.h"
15
#endif
16
 
17
/********************************* Defines ************************************/
18
/*
19
 *      Sprintf buffer structure. Make the increment 64 so that
20
 *      a balloc can use a 64 byte block.
21
 */
22
 
23
#define STR_REALLOC             0x1                             /* Reallocate the buffer as required */
24
#define STR_INC                 64                              /* Growth increment */
25
 
26
typedef struct {
27
        char_t  *s;                                                     /* Pointer to buffer */
28
        int             size;                                           /* Current buffer size */
29
        int             max;                                            /* Maximum buffer size */
30
        int             count;                                          /* Buffer count */
31
        int             flags;                                          /* Allocation flags */
32
} strbuf_t;
33
 
34
/*
35
 *      Sprintf formatting flags
36
 */
37
enum flag {
38
        flag_none = 0,
39
        flag_minus = 1,
40
        flag_plus = 2,
41
        flag_space = 4,
42
        flag_hash = 8,
43
        flag_zero = 16,
44
        flag_short = 32,
45
        flag_long = 64
46
};
47
 
48
/************************** Forward Declarations ******************************/
49
 
50
static int      dsnprintf(char_t **s, int size, char_t *fmt, va_list arg,
51
                                int msize);
52
static void     put_char(strbuf_t *buf, char_t c);
53
static void     put_string(strbuf_t *buf, char_t *s, int len,
54
                                int width, int prec, enum flag f);
55
static void     put_ulong(strbuf_t *buf, unsigned long int value, int base,
56
                                int upper, char_t *prefix, int width, int prec, enum flag f);
57
 
58
/************************************ Code ************************************/
59
/*
60
 *      "basename" returns a pointer to the last component of a pathname
61
 *  LINUX and LynxOS have their own basename function
62
 */
63
 
64
#if ! LINUX && ! LYNX && ! __rtems__
65
char_t *basename(char_t *name)
66
{
67
        char_t  *cp;
68
 
69
#if NW || WIN
70
        if (((cp = gstrrchr(name, '\\')) == NULL) &&
71
                        ((cp = gstrrchr(name, '/')) == NULL)) {
72
                return name;
73
#else
74
        if ((cp = gstrrchr(name, '/')) == NULL) {
75
                return name;
76
#endif
77
        } else if (*(cp + 1) == '\0' && cp == name) {
78
                return name;
79
        } else if (*(cp + 1) == '\0' && cp != name) {
80
                return T("");
81
        } else {
82
                return ++cp;
83
        }
84
}
85
#endif /* ! LINUX & ! LYNX */
86
 
87
/******************************************************************************/
88
/*
89
 *      Returns a pointer to the directory component of a pathname. bufsize is
90
 *      the size of the buffer in BYTES!
91
 */
92
 
93
char_t *dirname(char_t *buf, char_t *name, int bufsize)
94
{
95
        char_t *cp;
96
        int             len;
97
 
98
        a_assert(name);
99
        a_assert(buf);
100
        a_assert(bufsize > 0);
101
 
102
#if WIN || NW
103
        if ((cp = gstrrchr(name, '/')) == NULL &&
104
                (cp = gstrrchr(name, '\\')) == NULL)
105
#else
106
        if ((cp = gstrrchr(name, '/')) == NULL)
107
#endif
108
        {
109
                gstrcpy(buf, T("."));
110
                return buf;
111
        }
112
 
113
        if ((*(cp + 1) == '\0' && cp == name)) {
114
                gstrncpy(buf, T("."), TSZ(bufsize));
115
                gstrcpy(buf, T("."));
116
                return buf;
117
        }
118
 
119
        len = cp - name;
120
 
121
        if (len < bufsize) {
122
                gstrncpy(buf, name, len);
123
                buf[len] = '\0';
124
        } else {
125
                gstrncpy(buf, name, TSZ(bufsize));
126
                buf[bufsize - 1] = '\0';
127
        }
128
 
129
        return buf;
130
}
131
 
132
 
133
/******************************************************************************/
134
/*
135
 *      sprintf and vsprintf are bad, ok. You can easily clobber memory. Use
136
 *      fmtAlloc and fmtValloc instead! These functions do _not_ support floating
137
 *      point, like %e, %f, %g...
138
 */
139
 
140
int fmtAlloc(char_t **s, int n, char_t *fmt, ...)
141
{
142
        va_list ap;
143
        int             result;
144
 
145
        a_assert(s);
146
        a_assert(fmt);
147
 
148
        *s = NULL;
149
        va_start(ap, fmt);
150
        result = dsnprintf(s, n, fmt, ap, 0);
151
        va_end(ap);
152
        return result;
153
}
154
 
155
/******************************************************************************/
156
/*
157
 *      Support a static buffer version for small buffers only!
158
 */
159
 
160
int fmtStatic(char_t *s, int n, char_t *fmt, ...)
161
{
162
        va_list ap;
163
        int             result;
164
 
165
        a_assert(s);
166
        a_assert(fmt);
167
        a_assert(n <= 256);
168
 
169
        if (n <= 0) {
170
                return -1;
171
        }
172
        va_start(ap, fmt);
173
        result = dsnprintf(&s, n, fmt, ap, 0);
174
        va_end(ap);
175
        return result;
176
}
177
 
178
/******************************************************************************/
179
/*
180
 *      This function appends the formatted string to the supplied string,
181
 *      reallocing if required.
182
 */
183
 
184
int fmtRealloc(char_t **s, int n, int msize, char_t *fmt, ...)
185
{
186
        va_list ap;
187
        int             result;
188
 
189
        a_assert(s);
190
        a_assert(fmt);
191
 
192
        if (msize == -1) {
193
                *s = NULL;
194
        }
195
        va_start(ap, fmt);
196
        result = dsnprintf(s, n, fmt, ap, msize);
197
        va_end(ap);
198
        return result;
199
}
200
 
201
/******************************************************************************/
202
/*
203
 *      A vsprintf replacement.
204
 */
205
 
206
int fmtValloc(char_t **s, int n, char_t *fmt, va_list arg)
207
{
208
        a_assert(s);
209
        a_assert(fmt);
210
 
211
        *s = NULL;
212
        return dsnprintf(s, n, fmt, arg, 0);
213
}
214
 
215
/******************************************************************************/
216
/*
217
 *      Dynamic sprintf implementation. Supports dynamic buffer allocation.
218
 *      This function can be called multiple times to grow an existing allocated
219
 *      buffer. In this case, msize is set to the size of the previously allocated
220
 *      buffer. The buffer will be realloced, as required. If msize is set, we
221
 *      return the size of the allocated buffer for use with the next call. For
222
 *      the first call, msize can be set to -1.
223
 */
224
 
225
static int dsnprintf(char_t **s, int size, char_t *fmt, va_list arg, int msize)
226
{
227
        strbuf_t        buf;
228
        char_t          c;
229
 
230
        a_assert(s);
231
        a_assert(fmt);
232
 
233
        memset(&buf, 0, sizeof(buf));
234
        buf.s = *s;
235
 
236
        if (*s == NULL || msize != 0) {
237
                buf.max = size;
238
                buf.flags |= STR_REALLOC;
239
                if (msize != 0) {
240
                        buf.size = max(msize, 0);
241
                }
242
                if (*s != NULL && msize != 0) {
243
                        buf.count = gstrlen(*s);
244
                }
245
        } else {
246
                buf.size = size;
247
        }
248
 
249
        while ((c = *fmt++) != '\0') {
250
                if (c != '%' || (c = *fmt++) == '%') {
251
                        put_char(&buf, c);
252
                } else {
253
                        enum flag f = flag_none;
254
                        int width = 0;
255
                        int prec = -1;
256
                        for ( ; c != '\0'; c = *fmt++) {
257
                                if (c == '-') {
258
                                        f |= flag_minus;
259
                                } else if (c == '+') {
260
                                        f |= flag_plus;
261
                                } else if (c == ' ') {
262
                                        f |= flag_space;
263
                                } else if (c == '#') {
264
                                        f |= flag_hash;
265
                                } else if (c == '0') {
266
                                        f |= flag_zero;
267
                                } else {
268
                                        break;
269
                                }
270
                        }
271
                        if (c == '*') {
272
                                width = va_arg(arg, int);
273
                                if (width < 0) {
274
                                        f |= flag_minus;
275
                                        width = -width;
276
                                }
277
                                c = *fmt++;
278
                        } else {
279
                                for ( ; gisdigit((int)c); c = *fmt++) {
280
                                        width = width * 10 + (c - '0');
281
                                }
282
                        }
283
                        if (c == '.') {
284
                                f &= ~flag_zero;
285
                                c = *fmt++;
286
                                if (c == '*') {
287
                                        prec = va_arg(arg, int);
288
                                        c = *fmt++;
289
                                } else {
290
                                        for (prec = 0; gisdigit((int)c); c = *fmt++) {
291
                                                prec = prec * 10 + (c - '0');
292
                                        }
293
                                }
294
                        }
295
                        if (c == 'h' || c == 'l') {
296
                                f |= (c == 'h' ? flag_short : flag_long);
297
                                c = *fmt++;
298
                        }
299
                        if (c == 'd' || c == 'i') {
300
                                long int value;
301
                                if (f & flag_short) {
302
                                        value = (short int) va_arg(arg, int);
303
                                } else if (f & flag_long) {
304
                                        value = va_arg(arg, long int);
305
                                } else {
306
                                        value = va_arg(arg, int);
307
                                }
308
                                if (value >= 0) {
309
                                        if (f & flag_plus) {
310
                                                put_ulong(&buf, value, 10, 0, T("+"), width, prec, f);
311
                                        } else if (f & flag_space) {
312
                                                put_ulong(&buf, value, 10, 0, T(" "), width, prec, f);
313
                                        } else {
314
                                                put_ulong(&buf, value, 10, 0, NULL, width, prec, f);
315
                                        }
316
                                } else {
317
                                        put_ulong(&buf, -value, 10, 0, T("-"), width, prec, f);
318
                                }
319
                        } else if (c == 'o' || c == 'u' || c == 'x' || c == 'X') {
320
                                unsigned long int value;
321
                                if (f & flag_short) {
322
                                        value = (unsigned short int) va_arg(arg, unsigned int);
323
                                } else if (f & flag_long) {
324
                                        value = va_arg(arg, unsigned long int);
325
                                } else {
326
                                        value = va_arg(arg, unsigned int);
327
                                }
328
                                if (c == 'o') {
329
                                        if (f & flag_hash && value != 0) {
330
                                                put_ulong(&buf, value, 8, 0, T("0"), width, prec, f);
331
                                        } else {
332
                                                put_ulong(&buf, value, 8, 0, NULL, width, prec, f);
333
                                        }
334
                                } else if (c == 'u') {
335
                                        put_ulong(&buf, value, 10, 0, NULL, width, prec, f);
336
                                } else {
337
                                        if (f & flag_hash && value != 0) {
338
                                                if (c == 'x') {
339
                                                        put_ulong(&buf, value, 16, 0, T("0x"), width,
340
                                                                prec, f);
341
                                                } else {
342
                                                        put_ulong(&buf, value, 16, 1, T("0X"), width,
343
                                                                prec, f);
344
                                                }
345
                                        } else {
346
                                                put_ulong(&buf, value, 16, 0, NULL, width, prec, f);
347
                                        }
348
                                }
349
 
350
                        } else if (c == 'c') {
351
                                char_t value = va_arg(arg, int);
352
                                put_char(&buf, value);
353
 
354
                        } else if (c == 's' || c == 'S') {
355
                                char_t *value = va_arg(arg, char_t *);
356
                                if (value == NULL) {
357
                                        put_string(&buf, T("(null)"), -1, width, prec, f);
358
                                } else if (f & flag_hash) {
359
                                        put_string(&buf,
360
                                                value + 1, (char_t) *value, width, prec, f);
361
                                } else {
362
                                        put_string(&buf, value, -1, width, prec, f);
363
                                }
364
                        } else if (c == 'p') {
365
                                void *value = va_arg(arg, void *);
366
                                put_ulong(&buf,
367
                                        (unsigned long int) value, 16, 0, T("0x"), width, prec, f);
368
                        } else if (c == 'n') {
369
                                if (f & flag_short) {
370
                                        short int *value = va_arg(arg, short int *);
371
                                        *value = buf.count;
372
                                } else if (f & flag_long) {
373
                                        long int *value = va_arg(arg, long int *);
374
                                        *value = buf.count;
375
                                } else {
376
                                        int *value = va_arg(arg, int *);
377
                                        *value = buf.count;
378
                                }
379
                        } else {
380
                                put_char(&buf, c);
381
                        }
382
                }
383
        }
384
        if (buf.s == NULL) {
385
                put_char(&buf, '\0');
386
        }
387
 
388
/*
389
 *      If the user requested a dynamic buffer (*s == NULL), ensure it is returned.
390
 */
391
        if (*s == NULL || msize != 0) {
392
                *s = buf.s;
393
        }
394
 
395
        if (*s != NULL && size > 0) {
396
                if (buf.count < size) {
397
                        (*s)[buf.count] = '\0';
398
                } else {
399
                        (*s)[buf.size - 1] = '\0';
400
                }
401
        }
402
 
403
        if (msize != 0) {
404
                return buf.size;
405
        }
406
        return buf.count;
407
}
408
 
409
/******************************************************************************/
410
/*
411
 *      Add a character to a string buffer
412
 */
413
 
414
static void put_char(strbuf_t *buf, char_t c)
415
{
416
        if (buf->count >= (buf->size - 1)) {
417
                if (! (buf->flags & STR_REALLOC)) {
418
                        return;
419
                }
420
                buf->size += STR_INC;
421
                if (buf->size > buf->max && buf->size > STR_INC) {
422
/*
423
 *                      Caller should increase the size of the calling buffer
424
 */
425
                        buf->size -= STR_INC;
426
                        return;
427
                }
428
                if (buf->s == NULL) {
429
                        buf->s = balloc(B_L, buf->size * sizeof(char_t));
430
                } else {
431
                        buf->s = brealloc(B_L, buf->s, buf->size * sizeof(char_t));
432
                }
433
        }
434
        buf->s[buf->count] = c;
435
        if (c != '\0') {
436
                ++buf->count;
437
        }
438
}
439
 
440
/******************************************************************************/
441
/*
442
 *      Add a string to a string buffer
443
 */
444
 
445
static void put_string(strbuf_t *buf, char_t *s, int len, int width,
446
                int prec, enum flag f)
447
{
448
        int             i;
449
 
450
        if (len < 0) {
451
                len = strnlen(s, prec >= 0 ? prec : ULONG_MAX);
452
        } else if (prec >= 0 && prec < len) {
453
                len = prec;
454
        }
455
        if (width > len && !(f & flag_minus)) {
456
                for (i = len; i < width; ++i) {
457
                        put_char(buf, ' ');
458
                }
459
        }
460
        for (i = 0; i < len; ++i) {
461
                put_char(buf, s[i]);
462
        }
463
        if (width > len && f & flag_minus) {
464
                for (i = len; i < width; ++i) {
465
                        put_char(buf, ' ');
466
                }
467
        }
468
}
469
 
470
/******************************************************************************/
471
/*
472
 *      Add a long to a string buffer
473
 */
474
 
475
static void put_ulong(strbuf_t *buf, unsigned long int value, int base,
476
                int upper, char_t *prefix, int width, int prec, enum flag f)
477
{
478
        unsigned long   x, x2;
479
        int                             len, zeros, i;
480
 
481
        for (len = 1, x = 1; x < ULONG_MAX / base; ++len, x = x2) {
482
                x2 = x * base;
483
                if (x2 > value) {
484
                        break;
485
                }
486
        }
487
        zeros = (prec > len) ? prec - len : 0;
488
        width -= zeros + len;
489
        if (prefix != NULL) {
490
                width -= strnlen(prefix, ULONG_MAX);
491
        }
492
        if (!(f & flag_minus)) {
493
                if (f & flag_zero) {
494
                        for (i = 0; i < width; ++i) {
495
                                put_char(buf, '0');
496
                        }
497
                } else {
498
                        for (i = 0; i < width; ++i) {
499
                                put_char(buf, ' ');
500
                        }
501
                }
502
        }
503
        if (prefix != NULL) {
504
                put_string(buf, prefix, -1, 0, -1, flag_none);
505
        }
506
        for (i = 0; i < zeros; ++i) {
507
                put_char(buf, '0');
508
        }
509
        for ( ; x > 0; x /= base) {
510
                int digit = (value / x) % base;
511
                put_char(buf, (char) ((digit < 10 ? '0' : (upper ? 'A' : 'a') - 10) +
512
                        digit));
513
        }
514
        if (f & flag_minus) {
515
                for (i = 0; i < width; ++i) {
516
                        put_char(buf, ' ');
517
                }
518
        }
519
}
520
 
521
/******************************************************************************/
522
/*
523
 *      Convert an ansi string to a unicode string. On an error, we return the
524
 *      original ansi string which is better than returning NULL. nBytes is the
525
 *      size of the destination buffer (ubuf) in _bytes_.
526
 */
527
 
528
char_t *ascToUni(char_t *ubuf, char *str, int nBytes)
529
{
530
#if UNICODE
531
        if (MultiByteToWideChar(CP_ACP, 0, str, nBytes / sizeof(char_t), ubuf,
532
                        nBytes / sizeof(char_t)) < 0) {
533
                return (char_t*) str;
534
        }
535
#else
536
        memcpy(ubuf, str, nBytes);
537
#endif
538
        return ubuf;
539
}
540
 
541
/******************************************************************************/
542
/*
543
 *      Convert a unicode string to an ansi string. On an error, return the
544
 *      original unicode string which is better than returning NULL.
545
 *      N.B. nBytes is the number of _bytes_ in the destination buffer, buf.
546
 */
547
 
548
char *uniToAsc(char *buf, char_t *ustr, int nBytes)
549
{
550
#if UNICODE
551
        if (WideCharToMultiByte(CP_ACP, 0, ustr, nBytes, buf, nBytes, NULL,
552
                        NULL) < 0) {
553
                return (char*) ustr;
554
        }
555
#else
556
        memcpy(buf, ustr, nBytes);
557
#endif
558
        return (char*) buf;
559
}
560
 
561
/******************************************************************************/
562
/*
563
 *      allocate (balloc) a buffer and do ascii to unicode conversion into it.
564
 *      cp points to the ascii buffer.  alen is the length of the buffer to be
565
 *      converted not including a terminating NULL.  Return a pointer to the
566
 *      unicode buffer which must be bfree'd later.  Return NULL on failure to
567
 *      get buffer.  The buffer returned is NULL terminated.
568
 */
569
 
570
char_t *ballocAscToUni(char *cp, int alen)
571
{
572
        char_t *unip;
573
        int ulen;
574
 
575
        ulen = (alen + 1) * sizeof(char_t);
576
        if ((unip = balloc(B_L, ulen)) == NULL) {
577
                return NULL;
578
        }
579
        ascToUni(unip, cp, ulen);
580
        unip[alen] = 0;
581
        return unip;
582
}
583
 
584
/******************************************************************************/
585
/*
586
 *      allocate (balloc) a buffer and do unicode to ascii conversion into it.
587
 *      unip points to the unicoded string. ulen is the number of characters
588
 *      in the unicode string not including a teminating null.  Return a pointer
589
 *      to the ascii buffer which must be bfree'd later.  Return NULL on failure
590
 *      to get buffer.  The buffer returned is NULL terminated.
591
 */
592
 
593
char *ballocUniToAsc(char_t *unip, int ulen)
594
{
595
        char * cp;
596
 
597
        if ((cp = balloc(B_L, ulen+1)) == NULL) {
598
                return NULL;
599
        }
600
        uniToAsc(cp, unip, ulen);
601
        cp[ulen] = '\0';
602
        return cp;
603
}
604
 
605
/******************************************************************************/
606
/*
607
 *      convert a hex string to an integer. The end of the string or a non-hex
608
 *      character will indicate the end of the hex specification.
609
 */
610
 
611
unsigned int hextoi(char_t *hexstring)
612
{
613
        register char_t                 *h;
614
        register unsigned int   c, v;
615
 
616
        v = 0;
617
        h = hexstring;
618
        if (*h == '0' && (*(h+1) == 'x' || *(h+1) == 'X')) {
619
                h += 2;
620
        }
621
        while ((c = (unsigned int)*h++) != 0) {
622
                if (c >= '0' && c <= '9') {
623
                        c -= '0';
624
                } else if (c >= 'a' && c <= 'f') {
625
                        c = (c - 'a') + 10;
626
                } else if (c >=  'A' && c <= 'F') {
627
                        c = (c - 'A') + 10;
628
                } else {
629
                        break;
630
                }
631
                v = (v * 0x10) + c;
632
        }
633
        return v;
634
}
635
 
636
/******************************************************************************/
637
/*
638
 *      convert a string to an integer. If the string starts with "0x" or "0X"
639
 *      a hexidecimal conversion is done.
640
 */
641
 
642
unsigned int gstrtoi(char_t *s)
643
{
644
        if (*s == '0' && (*(s+1) == 'x' || *(s+1) == 'X')) {
645
                s += 2;
646
                return hextoi(s);
647
        }
648
        return gatoi(s);
649
}
650
 
651
/******************************************************************************/
652
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.