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.9 2010/02/25 15:31:40 ragge Exp $
31 * Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.
32 * All rights reserved.
34 * This code is derived from software contributed to The NetBSD Foundation
35 * by Klaus Klein and Jason R. Thorpe.
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
46 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
47 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
48 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
49 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
50 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
51 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
52 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
53 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
54 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
56 * POSSIBILITY OF SUCH DAMAGE.
58 * $NetBSD: basename.c,v 1.9 2009/11/24 13:34:20 tnozaki Exp $
62 * Copyright (c) 1987, 1993
63 * The Regents of the University of California. All rights reserved.
65 * Redistribution and use in source and binary forms, with or without
66 * modification, are permitted provided that the following conditions
68 * 1. Redistributions of source code must retain the above copyright
69 * notice, this list of conditions and the following disclaimer.
70 * 2. Redistributions in binary form must reproduce the above copyright
71 * notice, this list of conditions and the following disclaimer in the
72 * documentation and/or other materials provided with the distribution.
73 * 3. Neither the name of the University nor the names of its contributors
74 * may be used to endorse or promote products derived from this software
75 * without specific prior written permission.
77 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
78 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
79 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
80 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
81 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
82 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
83 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
84 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
85 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
86 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
89 * $NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp $
96 #define MKEXT /* XXX */
101 * Appends src to string dst of size siz (unlike strncat, siz is the
102 * full size of dst, not space left). At most siz-1 characters
103 * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
104 * Returns strlen(initial dst) + strlen(src); if retval >= siz,
105 * truncation occurred.
108 strlcat(char *dst
, const char *src
, size_t siz
)
115 /* Find the end of dst and adjust bytes left but don't go past end */
116 while (n
-- != 0 && *d
!= '\0')
122 return(dlen
+ strlen(s
));
132 return(dlen
+ (s
- src
)); /* count does not include NUL */
139 * Copy src to string dst of size siz. At most siz-1 characters
140 * will be copied. Always NUL terminates (unless siz == 0).
141 * Returns strlen(src); if retval >= siz, truncation occurred.
144 strlcpy(char *dst
, const char *src
, size_t siz
)
150 /* Copy as many bytes as will fit */
151 if (n
!= 0 && --n
!= 0) {
153 if ((*d
++ = *s
++) == 0)
158 /* Not enough room in dst, add NUL and traverse rest of src */
161 *d
= '\0'; /* NUL-terminate dst */
166 return(s
- src
- 1); /* count does not include NUL */
174 getopt(int argc
, char **argv
, char *args
)
177 int nlen
= strlen(args
);
181 if (argv
[optind
] && *argv
[optind
] == '-') {
182 cmd
= *(argv
[optind
] + 1);
184 for (n
= 0; n
< nlen
; n
++) {
187 if (args
[n
] == cmd
) {
188 rv
= *(argv
[optind
] + 1);
189 if (args
[n
+1] == ':') {
190 if (*(argv
[optind
] + 2) != '\0') {
191 optarg
= argv
[optind
] + 2;
194 optarg
= argv
[optind
+ 1];
214 #define ISPATHSEPARATOR(x) ((x == '/') || (x == '\\'))
216 #define ISPATHSEPARATOR(x) (x == '/')
219 #ifndef HAVE_BASENAME
221 #define PATH_MAX 5000
227 static char result
[PATH_MAX
];
232 * If `path' is a null pointer or points to an empty string,
233 * return a pointer to the string ".".
235 if ((path
== NULL
) || (*path
== '\0')) {
242 /* Strip trailing slashes, if any. */
243 lastp
= path
+ strlen(path
) - 1;
244 while (lastp
!= path
&& ISPATHSEPARATOR(*lastp
))
247 /* Now find the beginning of this (final) component. */
249 while (p
!= path
&& !ISPATHSEPARATOR(*(p
- 1)))
252 /* ...and copy the result into the result buffer. */
253 len
= (lastp
- p
) + 1 /* last char */;
254 if (len
> (PATH_MAX
- 1))
257 memcpy(result
, p
, len
);
264 #if !defined(HAVE_MKSTEMP) && !defined(WIN32)
271 /* To guarantee multiple calls generate unique names even if
272 the file is not created. 676 different possibilities with 7
273 or more X's, 26 with 6 or less. */
274 static char xtra
[2] = "aa";
279 /* Move to end of path and count trailing X's. */
280 for (trv
= path
; *trv
; ++trv
)
286 /* Use at least one from xtra. Use 2 if more than 6 X's. */
287 if (*(trv
- 1) == 'X')
289 if (xcnt
> 6 && *(trv
- 1) == 'X')
292 /* Set remaining X's to pid digits with 0's to the left. */
293 while (*--trv
== 'X') {
294 *trv
= (pid
% 10) + '0';
298 /* update xtra for next call. */
309 return open(path
, O_CREAT
| O_EXCL
| O_RDWR
, 0600);
319 if (!(x
& 0xffff)) { x
>>= 16; r
+= 16; }
320 if (!(x
& 0xff)) { x
>>= 8; r
+= 8; }
321 if (!(x
& 0xf)) { x
>>= 4; r
+= 4; }
322 if (!(x
& 3)) { x
>>= 2; r
+= 2; }
323 if (!(x
& 1)) { x
>>= 1; r
+= 1; }
330 * Copyright Patrick Powell 1995
331 * This code is based on code written by Patrick Powell (papowell@astart.com)
332 * It may be used for any purpose as long as this notice remains intact
333 * on all source code distributions
336 #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
339 dopr(char *buffer
, size_t maxlen
, const char *format
, va_list args
);
342 fmtstr(char *buffer
, size_t *currlen
, size_t maxlen
, char *value
, int flags
,
346 fmtint(char *buffer
, size_t *currlen
, size_t maxlen
, long value
, int base
,
347 int min
, int max
, int flags
);
350 fmtfp(char *buffer
, size_t *currlen
, size_t maxlen
, long double fvalue
,
351 int min
, int max
, int flags
);
354 dopr_outch(char *buffer
, size_t *currlen
, size_t maxlen
, char c
);
357 * dopr(): poor man's version of doprintf
360 /* format read states */
361 #define DP_S_DEFAULT 0
370 /* format flags - Bits */
371 #define DP_F_MINUS (1 << 0)
372 #define DP_F_PLUS (1 << 1)
373 #define DP_F_SPACE (1 << 2)
374 #define DP_F_NUM (1 << 3)
375 #define DP_F_ZERO (1 << 4)
376 #define DP_F_UP (1 << 5)
377 #define DP_F_UNSIGNED (1 << 6)
379 /* Conversion Flags */
382 #define DP_C_LDOUBLE 3
383 #define DP_C_LONG_LONG 4
385 #define char_to_int(p) (p - '0')
386 #define abs_val(p) (p < 0 ? -p : p)
390 dopr(char *buffer
, size_t maxlen
, const char *format
, va_list args
)
395 int min
= 0, max
= -1, state
= DP_S_DEFAULT
, flags
= 0, cflags
= 0;
400 while (state
!= DP_S_DONE
) {
401 if ((ch
== '\0') || (currlen
>= maxlen
))
409 dopr_outch(buffer
, &currlen
, maxlen
, ch
);
440 if (isdigit((unsigned char)ch
)) {
441 min
= 10 * min
+ char_to_int (ch
);
443 } else if (ch
== '*') {
444 min
= va_arg (args
, int);
458 if (isdigit((unsigned char)ch
)) {
461 max
= 10 * max
+ char_to_int(ch
);
463 } else if (ch
== '*') {
464 max
= va_arg (args
, int);
480 cflags
= DP_C_LONG_LONG
;
485 cflags
= DP_C_LONG_LONG
;
489 cflags
= DP_C_LDOUBLE
;
501 if (cflags
== DP_C_SHORT
)
502 value
= va_arg(args
, int);
503 else if (cflags
== DP_C_LONG
)
504 value
= va_arg(args
, long int);
505 else if (cflags
== DP_C_LONG_LONG
)
506 value
= va_arg (args
, long long);
508 value
= va_arg (args
, int);
509 fmtint(buffer
, &currlen
, maxlen
, value
, 10, min
, max
, flags
);
512 flags
|= DP_F_UNSIGNED
;
513 if (cflags
== DP_C_SHORT
)
514 value
= va_arg(args
, unsigned int);
515 else if (cflags
== DP_C_LONG
)
516 value
= va_arg(args
, unsigned long int);
517 else if (cflags
== DP_C_LONG_LONG
)
518 value
= va_arg(args
, unsigned long long);
520 value
= va_arg(args
, unsigned int);
521 fmtint(buffer
, &currlen
, maxlen
, value
, 8, min
, max
, flags
);
524 flags
|= DP_F_UNSIGNED
;
525 if (cflags
== DP_C_SHORT
)
526 value
= va_arg(args
, unsigned int);
527 else if (cflags
== DP_C_LONG
)
528 value
= va_arg(args
, unsigned long int);
529 else if (cflags
== DP_C_LONG_LONG
)
530 value
= va_arg(args
, unsigned long long);
532 value
= va_arg(args
, unsigned int);
533 fmtint (buffer
, &currlen
, maxlen
, value
, 10, min
, max
, flags
);
538 flags
|= DP_F_UNSIGNED
;
539 if (cflags
== DP_C_SHORT
)
540 value
= va_arg(args
, unsigned int);
541 else if (cflags
== DP_C_LONG
)
542 value
= va_arg(args
, unsigned long int);
543 else if (cflags
== DP_C_LONG_LONG
)
544 value
= va_arg(args
, unsigned long long);
546 value
= va_arg(args
, unsigned int);
547 fmtint(buffer
, &currlen
, maxlen
, value
, 16, min
, max
, flags
);
550 if (cflags
== DP_C_LDOUBLE
)
551 fvalue
= va_arg(args
, long double);
553 fvalue
= va_arg(args
, double);
554 /* um, floating point? */
555 fmtfp(buffer
, &currlen
, maxlen
, fvalue
, min
, max
, flags
);
560 if (cflags
== DP_C_LDOUBLE
)
561 fvalue
= va_arg(args
, long double);
563 fvalue
= va_arg(args
, double);
568 if (cflags
== DP_C_LDOUBLE
)
569 fvalue
= va_arg(args
, long double);
571 fvalue
= va_arg(args
, double);
574 dopr_outch(buffer
, &currlen
, maxlen
, va_arg(args
, int));
577 strvalue
= va_arg(args
, char *);
579 max
= maxlen
; /* ie, no max */
580 fmtstr(buffer
, &currlen
, maxlen
, strvalue
, flags
, min
, max
);
583 strvalue
= va_arg(args
, void *);
584 fmtint(buffer
, &currlen
, maxlen
, (long) strvalue
, 16, min
, max
, flags
);
587 if (cflags
== DP_C_SHORT
) {
589 num
= va_arg(args
, short int *);
591 } else if (cflags
== DP_C_LONG
) {
593 num
= va_arg(args
, long int *);
595 } else if (cflags
== DP_C_LONG_LONG
) {
597 num
= va_arg(args
, long long *);
601 num
= va_arg(args
, int *);
606 dopr_outch(buffer
, &currlen
, maxlen
, ch
);
608 case 'w': /* not supported yet, treat as next char */
611 default: /* Unknown, skip */
615 state
= DP_S_DEFAULT
;
616 flags
= cflags
= min
= 0;
622 break; /* some picky compilers need this */
625 if (currlen
< maxlen
- 1)
626 buffer
[currlen
] = '\0';
628 buffer
[maxlen
- 1] = '\0';
632 fmtstr(char *buffer
, size_t *currlen
, size_t maxlen
,
633 char *value
, int flags
, int min
, int max
)
635 int cnt
= 0, padlen
, strln
; /* amount to pad */
640 for (strln
= 0; value
[strln
]; ++strln
); /* strlen */
641 padlen
= min
- strln
;
644 if (flags
& DP_F_MINUS
)
645 padlen
= -padlen
; /* Left Justify */
647 while ((padlen
> 0) && (cnt
< max
)) {
648 dopr_outch(buffer
, currlen
, maxlen
, ' ');
652 while (*value
&& (cnt
< max
)) {
653 dopr_outch(buffer
, currlen
, maxlen
, *value
++);
656 while ((padlen
< 0) && (cnt
< max
)) {
657 dopr_outch(buffer
, currlen
, maxlen
, ' ');
663 /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
666 fmtint(char *buffer
, size_t *currlen
, size_t maxlen
,
667 long value
, int base
, int min
, int max
, int flags
)
669 unsigned long uvalue
;
671 int signvalue
= 0, place
= 0, caps
= 0;
672 int spadlen
= 0; /* amount to space pad */
673 int zpadlen
= 0; /* amount to zero pad */
675 #define PADMAX(x,y) ((x) > (y) ? (x) : (y))
682 if (!(flags
& DP_F_UNSIGNED
)) {
686 } else if (flags
& DP_F_PLUS
) /* Do a sign (+/i) */
688 else if (flags
& DP_F_SPACE
)
693 caps
= 1; /* Should characters be upper case? */
696 (caps
? "0123456789ABCDEF" : "0123456789abcdef")
697 [uvalue
% (unsigned)base
];
698 uvalue
= (uvalue
/ (unsigned)base
);
699 } while (uvalue
&& (place
< 20));
704 zpadlen
= max
- place
;
705 spadlen
= min
- PADMAX(max
, place
) - (signvalue
? 1 : 0);
710 if (flags
& DP_F_ZERO
) {
711 zpadlen
= PADMAX(zpadlen
, spadlen
);
714 if (flags
& DP_F_MINUS
)
715 spadlen
= -spadlen
; /* Left Justifty */
718 while (spadlen
> 0) {
719 dopr_outch(buffer
, currlen
, maxlen
, ' ');
725 dopr_outch(buffer
, currlen
, maxlen
, signvalue
);
729 while (zpadlen
> 0) {
730 dopr_outch(buffer
, currlen
, maxlen
, '0');
737 dopr_outch(buffer
, currlen
, maxlen
, convert
[--place
]);
739 /* Left Justified spaces */
740 while (spadlen
< 0) {
741 dopr_outch (buffer
, currlen
, maxlen
, ' ');
749 long double result
= 1;
760 round(long double value
)
762 long intpart
= value
;
772 fmtfp(char *buffer
, size_t *currlen
, size_t maxlen
, long double fvalue
,
773 int min
, int max
, int flags
)
775 char iconvert
[20], fconvert
[20];
776 int signvalue
= 0, iplace
= 0, fplace
= 0;
777 int padlen
= 0; /* amount to pad */
778 int zpadlen
= 0, caps
= 0;
779 long intpart
, fracpart
;
783 * AIX manpage says the default is 0, but Solaris says the default
784 * is 6, and sprintf on AIX defaults to 6
789 ufvalue
= abs_val(fvalue
);
793 else if (flags
& DP_F_PLUS
) /* Do a sign (+/i) */
795 else if (flags
& DP_F_SPACE
)
801 * Sorry, we only support 9 digits past the decimal because of our
807 /* We "cheat" by converting the fractional part to integer by
808 * multiplying by a factor of 10
810 fracpart
= round((pow10 (max
)) * (ufvalue
- intpart
));
812 if (fracpart
>= pow10 (max
)) {
814 fracpart
-= pow10 (max
);
817 /* Convert integer part */
820 (caps
? "0123456789ABCDEF" : "0123456789abcdef")
822 intpart
= (intpart
/ 10);
823 } while(intpart
&& (iplace
< 20));
826 iconvert
[iplace
] = 0;
828 /* Convert fractional part */
831 (caps
? "0123456789ABCDEF" : "0123456789abcdef")
833 fracpart
= (fracpart
/ 10);
834 } while(fracpart
&& (fplace
< 20));
837 fconvert
[fplace
] = 0;
839 /* -1 for decimal point, another -1 if we are printing a sign */
840 padlen
= min
- iplace
- max
- 1 - ((signvalue
) ? 1 : 0);
841 zpadlen
= max
- fplace
;
846 if (flags
& DP_F_MINUS
)
847 padlen
= -padlen
; /* Left Justifty */
849 if ((flags
& DP_F_ZERO
) && (padlen
> 0)) {
851 dopr_outch(buffer
, currlen
, maxlen
, signvalue
);
856 dopr_outch(buffer
, currlen
, maxlen
, '0');
861 dopr_outch(buffer
, currlen
, maxlen
, ' ');
865 dopr_outch(buffer
, currlen
, maxlen
, signvalue
);
868 dopr_outch(buffer
, currlen
, maxlen
, iconvert
[--iplace
]);
871 * Decimal point. This should probably use locale to find the
872 * correct char to print out.
874 dopr_outch(buffer
, currlen
, maxlen
, '.');
877 dopr_outch(buffer
, currlen
, maxlen
, fconvert
[--fplace
]);
879 while (zpadlen
> 0) {
880 dopr_outch(buffer
, currlen
, maxlen
, '0');
885 dopr_outch(buffer
, currlen
, maxlen
, ' ');
891 dopr_outch(char *buffer
, size_t *currlen
, size_t maxlen
, char c
)
893 if (*currlen
< maxlen
)
894 buffer
[(*currlen
)++] = c
;
896 #endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
898 #ifndef HAVE_VSNPRINTF
900 vsnprintf(char *str
, size_t count
, const char *fmt
, va_list args
)
903 dopr(str
, count
, fmt
, args
);
907 #endif /* !HAVE_VSNPRINTF */
909 #ifndef HAVE_SNPRINTF
911 snprintf(char *str
,size_t count
,const char *fmt
,...)
916 (void) vsnprintf(str
, count
, fmt
, ap
);
922 #endif /* !HAVE_SNPRINTF */