7f250d15ff98fe8a325e25e3da481520f55aeb68
2 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
19 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * $Id: compat.c,v 1.1.1.1 2008/08/24 05:33:08 gmcgarry Exp $
29 * Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.
30 * All rights reserved.
32 * This code is derived from software contributed to The NetBSD Foundation
33 * by Klaus Klein and Jason R. Thorpe.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * 3. All advertising materials mentioning features or use of this software
44 * must display the following acknowledgement:
45 * This product includes software developed by the NetBSD
46 * Foundation, Inc. and its contributors.
47 * 4. Neither the name of The NetBSD Foundation nor the names of its
48 * contributors may be used to endorse or promote products derived
49 * from this software without specific prior written permission.
51 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
52 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
53 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
54 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
55 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
56 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
57 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
58 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
59 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
61 * POSSIBILITY OF SUCH DAMAGE.
63 * $NetBSD: compat.c,v 1.1.1.1 2008/08/24 05:33:08 gmcgarry Exp $
65 * Copyright (c) 1987, 1993
66 * The Regents of the University of California. All rights reserved.
68 * Redistribution and use in source and binary forms, with or without
69 * modification, are permitted provided that the following conditions
71 * 1. Redistributions of source code must retain the above copyright
72 * notice, this list of conditions and the following disclaimer.
73 * 2. Redistributions in binary form must reproduce the above copyright
74 * notice, this list of conditions and the following disclaimer in the
75 * documentation and/or other materials provided with the distribution.
76 * 3. Neither the name of the University nor the names of its contributors
77 * may be used to endorse or promote products derived from this software
78 * without specific prior written permission.
80 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
81 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
82 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
83 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
84 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
85 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
86 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
87 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
88 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
89 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
92 * $NetBSD: compat.c,v 1.1.1.1 2008/08/24 05:33:08 gmcgarry Exp $
94 #include <LibConfig.h>
102 getopt(int argc
, char **argv
, char *args
)
105 size_t nlen
= strlen(args
);
109 if (argv
[optind
] && *argv
[optind
] == '-') {
110 cmd
= *(argv
[optind
] + 1);
112 for (n
= 0; n
< nlen
; n
++) {
115 if (args
[n
] == cmd
) {
116 rv
= *(argv
[optind
] + 1);
117 if (args
[n
+1] == ':') {
118 if (*(argv
[optind
] + 2) != '\0') {
119 optarg
= argv
[optind
] + 2;
122 optarg
= argv
[optind
+ 1];
142 #define ISPATHSEPARATOR(x) ((x == '/') || (x == '\\'))
144 #define ISPATHSEPARATOR(x) (x == '/')
147 #ifndef HAVE_BASENAME
149 #define PATH_MAX 5000
155 static char singledot
[] = ".";
156 static char result
[PATH_MAX
];
161 * If `path' is a null pointer or points to an empty string,
162 * return a pointer to the string ".".
164 if ((path
== NULL
) || (*path
== '\0'))
167 /* Strip trailing slashes, if any. */
168 lastp
= path
+ strlen(path
) - 1;
169 while (lastp
!= path
&& ISPATHSEPARATOR(*lastp
))
172 /* Now find the beginning of this (final) component. */
174 while (p
!= path
&& !ISPATHSEPARATOR(*(p
- 1)))
177 /* ...and copy the result into the result buffer. */
178 len
= (lastp
- p
) + 1 /* last char */;
179 if (len
> (PATH_MAX
- 1))
182 memcpy(result
, p
, len
);
189 #if !defined(HAVE_MKSTEMP) && !defined(WIN32)
196 /* To guarantee multiple calls generate unique names even if
197 the file is not created. 676 different possibilities with 7
198 or more X's, 26 with 6 or less. */
199 static char xtra
[2] = "aa";
204 /* Move to end of path and count trailing X's. */
205 for (trv
= path
; *trv
; ++trv
)
211 /* Use at least one from xtra. Use 2 if more than 6 X's. */
212 if (*(trv
- 1) == 'X')
214 if (xcnt
> 6 && *(trv
- 1) == 'X')
217 /* Set remaining X's to pid digits with 0's to the left. */
218 while (*--trv
== 'X') {
219 *trv
= (pid
% 10) + '0';
223 /* update xtra for next call. */
234 return open(path
, O_CREAT
| O_EXCL
| O_RDWR
, 0600);
244 if (!(x
& 0xffff)) { x
>>= 16; r
+= 16; }
245 if (!(x
& 0xff)) { x
>>= 8; r
+= 8; }
246 if (!(x
& 0xf)) { x
>>= 4; r
+= 4; }
247 if (!(x
& 3)) { x
>>= 2; r
+= 2; }
248 if (!(x
& 1)) { x
>>= 1; r
+= 1; }
255 * Copyright Patrick Powell 1995
256 * This code is based on code written by Patrick Powell (papowell@astart.com)
257 * It may be used for any purpose as long as this notice remains intact
258 * on all source code distributions
261 #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
264 dopr(char *buffer
, size_t maxlen
, const char *format
, va_list args
);
267 fmtstr(char *buffer
, size_t *currlen
, size_t maxlen
, char *value
, int flags
,
271 fmtint(char *buffer
, size_t *currlen
, size_t maxlen
, long value
, int base
,
272 int min
, int max
, int flags
);
275 fmtfp(char *buffer
, size_t *currlen
, size_t maxlen
, long double fvalue
,
276 int min
, int max
, int flags
);
279 dopr_outch(char *buffer
, size_t *currlen
, size_t maxlen
, char c
);
282 * dopr(): poor man's version of doprintf
285 /* format read states */
286 #define DP_S_DEFAULT 0
295 /* format flags - Bits */
296 #define DP_F_MINUS (1 << 0)
297 #define DP_F_PLUS (1 << 1)
298 #define DP_F_SPACE (1 << 2)
299 #define DP_F_NUM (1 << 3)
300 #define DP_F_ZERO (1 << 4)
301 #define DP_F_UP (1 << 5)
302 #define DP_F_UNSIGNED (1 << 6)
304 /* Conversion Flags */
307 #define DP_C_LDOUBLE 3
308 #define DP_C_LONG_LONG 4
310 #define char_to_int(p) (p - '0')
311 #define abs_val(p) (p < 0 ? -p : p)
315 dopr(char *buffer
, size_t maxlen
, const char *format
, va_list args
)
320 int min
= 0, max
= -1, state
= DP_S_DEFAULT
, flags
= 0, cflags
= 0;
325 while (state
!= DP_S_DONE
) {
326 if ((ch
== '\0') || (currlen
>= maxlen
))
334 dopr_outch(buffer
, &currlen
, maxlen
, ch
);
365 if (isdigit((unsigned char)ch
)) {
366 min
= 10 * min
+ char_to_int (ch
);
368 } else if (ch
== '*') {
369 min
= va_arg (args
, int);
383 if (isdigit((unsigned char)ch
)) {
386 max
= 10 * max
+ char_to_int(ch
);
388 } else if (ch
== '*') {
389 max
= va_arg (args
, int);
405 cflags
= DP_C_LONG_LONG
;
410 cflags
= DP_C_LONG_LONG
;
414 cflags
= DP_C_LDOUBLE
;
426 if (cflags
== DP_C_SHORT
)
427 value
= va_arg(args
, int);
428 else if (cflags
== DP_C_LONG
)
429 value
= va_arg(args
, long int);
430 else if (cflags
== DP_C_LONG_LONG
)
431 value
= va_arg (args
, long long);
433 value
= va_arg (args
, int);
434 fmtint(buffer
, &currlen
, maxlen
, value
, 10, min
, max
, flags
);
437 flags
|= DP_F_UNSIGNED
;
438 if (cflags
== DP_C_SHORT
)
439 value
= va_arg(args
, unsigned int);
440 else if (cflags
== DP_C_LONG
)
441 value
= va_arg(args
, unsigned long int);
442 else if (cflags
== DP_C_LONG_LONG
)
443 value
= va_arg(args
, unsigned long long);
445 value
= va_arg(args
, unsigned int);
446 fmtint(buffer
, &currlen
, maxlen
, value
, 8, min
, max
, flags
);
449 flags
|= DP_F_UNSIGNED
;
450 if (cflags
== DP_C_SHORT
)
451 value
= va_arg(args
, unsigned int);
452 else if (cflags
== DP_C_LONG
)
453 value
= va_arg(args
, unsigned long int);
454 else if (cflags
== DP_C_LONG_LONG
)
455 value
= va_arg(args
, unsigned long long);
457 value
= va_arg(args
, unsigned int);
458 fmtint (buffer
, &currlen
, maxlen
, value
, 10, min
, max
, flags
);
463 flags
|= DP_F_UNSIGNED
;
464 if (cflags
== DP_C_SHORT
)
465 value
= va_arg(args
, unsigned int);
466 else if (cflags
== DP_C_LONG
)
467 value
= va_arg(args
, unsigned long int);
468 else if (cflags
== DP_C_LONG_LONG
)
469 value
= va_arg(args
, unsigned long long);
471 value
= va_arg(args
, unsigned int);
472 fmtint(buffer
, &currlen
, maxlen
, value
, 16, min
, max
, flags
);
475 if (cflags
== DP_C_LDOUBLE
)
476 fvalue
= va_arg(args
, long double);
478 fvalue
= va_arg(args
, double);
479 /* um, floating point? */
480 fmtfp(buffer
, &currlen
, maxlen
, fvalue
, min
, max
, flags
);
485 if (cflags
== DP_C_LDOUBLE
)
486 fvalue
= va_arg(args
, long double);
488 fvalue
= va_arg(args
, double);
493 if (cflags
== DP_C_LDOUBLE
)
494 fvalue
= va_arg(args
, long double);
496 fvalue
= va_arg(args
, double);
499 dopr_outch(buffer
, &currlen
, maxlen
, va_arg(args
, int));
502 strvalue
= va_arg(args
, char *);
504 max
= maxlen
; /* ie, no max */
505 fmtstr(buffer
, &currlen
, maxlen
, strvalue
, flags
, min
, max
);
508 strvalue
= va_arg(args
, void *);
509 fmtint(buffer
, &currlen
, maxlen
, (long) strvalue
, 16, min
, max
, flags
);
512 if (cflags
== DP_C_SHORT
) {
514 num
= va_arg(args
, short int *);
516 } else if (cflags
== DP_C_LONG
) {
518 num
= va_arg(args
, long int *);
520 } else if (cflags
== DP_C_LONG_LONG
) {
522 num
= va_arg(args
, long long *);
526 num
= va_arg(args
, int *);
531 dopr_outch(buffer
, &currlen
, maxlen
, ch
);
533 case 'w': /* not supported yet, treat as next char */
536 default: /* Unknown, skip */
540 state
= DP_S_DEFAULT
;
541 flags
= cflags
= min
= 0;
547 break; /* some picky compilers need this */
550 if (currlen
< maxlen
- 1)
551 buffer
[currlen
] = '\0';
553 buffer
[maxlen
- 1] = '\0';
557 fmtstr(char *buffer
, size_t *currlen
, size_t maxlen
,
558 char *value
, int flags
, int min
, int max
)
560 int cnt
= 0, padlen
, strln
; /* amount to pad */
565 for (strln
= 0; value
[strln
]; ++strln
); /* strlen */
566 padlen
= min
- strln
;
569 if (flags
& DP_F_MINUS
)
570 padlen
= -padlen
; /* Left Justify */
572 while ((padlen
> 0) && (cnt
< max
)) {
573 dopr_outch(buffer
, currlen
, maxlen
, ' ');
577 while (*value
&& (cnt
< max
)) {
578 dopr_outch(buffer
, currlen
, maxlen
, *value
++);
581 while ((padlen
< 0) && (cnt
< max
)) {
582 dopr_outch(buffer
, currlen
, maxlen
, ' ');
588 /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
591 fmtint(char *buffer
, size_t *currlen
, size_t maxlen
,
592 long value
, int base
, int min
, int max
, int flags
)
594 unsigned long uvalue
;
596 int signvalue
= 0, place
= 0, caps
= 0;
597 int spadlen
= 0; /* amount to space pad */
598 int zpadlen
= 0; /* amount to zero pad */
600 #define PADMAX(x,y) ((x) > (y) ? (x) : (y))
607 if (!(flags
& DP_F_UNSIGNED
)) {
611 } else if (flags
& DP_F_PLUS
) /* Do a sign (+/i) */
613 else if (flags
& DP_F_SPACE
)
618 caps
= 1; /* Should characters be upper case? */
621 (caps
? "0123456789ABCDEF" : "0123456789abcdef")
622 [uvalue
% (unsigned)base
];
623 uvalue
= (uvalue
/ (unsigned)base
);
624 } while (uvalue
&& (place
< 20));
629 zpadlen
= max
- place
;
630 spadlen
= min
- PADMAX(max
, place
) - (signvalue
? 1 : 0);
635 if (flags
& DP_F_ZERO
) {
636 zpadlen
= PADMAX(zpadlen
, spadlen
);
639 if (flags
& DP_F_MINUS
)
640 spadlen
= -spadlen
; /* Left Justifty */
643 while (spadlen
> 0) {
644 dopr_outch(buffer
, currlen
, maxlen
, ' ');
650 dopr_outch(buffer
, currlen
, maxlen
, signvalue
);
654 while (zpadlen
> 0) {
655 dopr_outch(buffer
, currlen
, maxlen
, '0');
662 dopr_outch(buffer
, currlen
, maxlen
, convert
[--place
]);
664 /* Left Justified spaces */
665 while (spadlen
< 0) {
666 dopr_outch (buffer
, currlen
, maxlen
, ' ');
674 long double result
= 1;
685 round(long double value
)
687 long intpart
= value
;
697 fmtfp(char *buffer
, size_t *currlen
, size_t maxlen
, long double fvalue
,
698 int min
, int max
, int flags
)
700 char iconvert
[20], fconvert
[20];
701 int signvalue
= 0, iplace
= 0, fplace
= 0;
702 int padlen
= 0; /* amount to pad */
703 int zpadlen
= 0, caps
= 0;
704 long intpart
, fracpart
;
708 * AIX manpage says the default is 0, but Solaris says the default
709 * is 6, and sprintf on AIX defaults to 6
714 ufvalue
= abs_val(fvalue
);
718 else if (flags
& DP_F_PLUS
) /* Do a sign (+/i) */
720 else if (flags
& DP_F_SPACE
)
726 * Sorry, we only support 9 digits past the decimal because of our
732 /* We "cheat" by converting the fractional part to integer by
733 * multiplying by a factor of 10
735 fracpart
= round((pow10 (max
)) * (ufvalue
- intpart
));
737 if (fracpart
>= pow10 (max
)) {
739 fracpart
-= pow10 (max
);
742 /* Convert integer part */
745 (caps
? "0123456789ABCDEF" : "0123456789abcdef")
747 intpart
= (intpart
/ 10);
748 } while(intpart
&& (iplace
< 20));
751 iconvert
[iplace
] = 0;
753 /* Convert fractional part */
756 (caps
? "0123456789ABCDEF" : "0123456789abcdef")
758 fracpart
= (fracpart
/ 10);
759 } while(fracpart
&& (fplace
< 20));
762 fconvert
[fplace
] = 0;
764 /* -1 for decimal point, another -1 if we are printing a sign */
765 padlen
= min
- iplace
- max
- 1 - ((signvalue
) ? 1 : 0);
766 zpadlen
= max
- fplace
;
771 if (flags
& DP_F_MINUS
)
772 padlen
= -padlen
; /* Left Justifty */
774 if ((flags
& DP_F_ZERO
) && (padlen
> 0)) {
776 dopr_outch(buffer
, currlen
, maxlen
, signvalue
);
781 dopr_outch(buffer
, currlen
, maxlen
, '0');
786 dopr_outch(buffer
, currlen
, maxlen
, ' ');
790 dopr_outch(buffer
, currlen
, maxlen
, signvalue
);
793 dopr_outch(buffer
, currlen
, maxlen
, iconvert
[--iplace
]);
796 * Decimal point. This should probably use locale to find the
797 * correct char to print out.
799 dopr_outch(buffer
, currlen
, maxlen
, '.');
802 dopr_outch(buffer
, currlen
, maxlen
, fconvert
[--fplace
]);
804 while (zpadlen
> 0) {
805 dopr_outch(buffer
, currlen
, maxlen
, '0');
810 dopr_outch(buffer
, currlen
, maxlen
, ' ');
816 dopr_outch(char *buffer
, size_t *currlen
, size_t maxlen
, char c
)
818 if (*currlen
< maxlen
)
819 buffer
[(*currlen
)++] = c
;
821 #endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
823 #ifndef HAVE_VSNPRINTF
825 vsnprintf(char *str
, size_t count
, const char *fmt
, va_list args
)
828 dopr(str
, count
, fmt
, args
);
832 #endif /* !HAVE_VSNPRINTF */
834 #ifndef HAVE_SNPRINTF
836 snprintf(char *str
,size_t count
,const char *fmt
,...)
841 (void) vsnprintf(str
, count
, fmt
, ap
);
847 #endif /* !HAVE_SNPRINTF */