Index: ossp-pkg/uuid/ChangeLog RCS File: /v/ossp/cvs/ossp-pkg/uuid/Attic/ChangeLog,v rcsdiff -q -kk '-r1.7' '-r1.8' -u '/v/ossp/cvs/ossp-pkg/uuid/Attic/ChangeLog,v' 2>/dev/null --- ChangeLog 2004/01/13 10:02:26 1.7 +++ ChangeLog 2004/01/13 19:43:14 1.8 @@ -13,6 +13,16 @@ Changes between 0.9.0 and 0.9.1 (11-Jan-2004 to xx-Jan-2004) + o Implement uuid_dump() and corresponding uuid CLI "-d" + option for dumping a given UUID into clear text. For convinience + reasons add uuid_bm.h (bit mask API) and uuid_str (string + formatting API) sub-modules. + [Ralf S. Engelschall] + + o Add "-m" option to CLI for allowing to generate v1 UUIDs + with random multi-cast addresses (API UUID_MCASTRND option). + [Ralf S. Engelschall] + o Disable the C++ and F77 checks in GNU libtool. [Ralf S. Engelschall] Index: ossp-pkg/uuid/Makefile.in RCS File: /v/ossp/cvs/ossp-pkg/uuid/Attic/Makefile.in,v rcsdiff -q -kk '-r1.11' '-r1.12' -u '/v/ossp/cvs/ossp-pkg/uuid/Attic/Makefile.in,v' 2>/dev/null --- Makefile.in 2004/01/13 09:26:46 1.11 +++ Makefile.in 2004/01/13 19:43:14 1.12 @@ -51,7 +51,7 @@ POD2MAN = pod2man LIB_NAME = libuuid.la -LIB_OBJS = uuid.lo uuid_md5.lo uuid_prng.lo uuid_mac.lo uuid_ui64.lo +LIB_OBJS = uuid.lo uuid_md5.lo uuid_prng.lo uuid_mac.lo uuid_ui64.lo uuid_str.lo PRG_NAME = uuid PRG_OBJS = uuid_cli.o Index: ossp-pkg/uuid/TODO RCS File: /v/ossp/cvs/ossp-pkg/uuid/Attic/TODO,v rcsdiff -q -kk '-r1.6' '-r1.7' -u '/v/ossp/cvs/ossp-pkg/uuid/Attic/TODO,v' 2>/dev/null --- TODO 2004/01/11 18:26:56 1.6 +++ TODO 2004/01/13 19:43:14 1.7 @@ -1,6 +1,6 @@ - more platform support in uuid_mac.c?! -- implement uuid -d (uuid_dump): dumping/decoding - global locking according to standard? - persistent/non-volatile state writing? - additional C API for DCE 1.1 compatibility - additional Perl API for covering Perl language +- use uuid_bm.h stuff throughout code Index: ossp-pkg/uuid/uuid.ac RCS File: /v/ossp/cvs/ossp-pkg/uuid/Attic/uuid.ac,v rcsdiff -q -kk '-r1.5' '-r1.6' -u '/v/ossp/cvs/ossp-pkg/uuid/Attic/uuid.ac,v' 2>/dev/null --- uuid.ac 2004/01/11 08:27:18 1.5 +++ uuid.ac 2004/01/13 19:43:14 1.6 @@ -86,6 +86,7 @@ AC_CHECK_FUNCS(getifaddrs nanosleep) dnl # check size of built-in types + AC_CHECK_TYPES([long long, long double]) AC_CHECK_SIZEOF(char, 1) AC_CHECK_SIZEOF(unsigned char, 1) AC_CHECK_SIZEOF(short, 2) Index: ossp-pkg/uuid/uuid.c RCS File: /v/ossp/cvs/ossp-pkg/uuid/Attic/uuid.c,v rcsdiff -q -kk '-r1.22' '-r1.23' -u '/v/ossp/cvs/ossp-pkg/uuid/Attic/uuid.c,v' 2>/dev/null --- uuid.c 2004/01/11 12:14:19 1.22 +++ uuid.c 2004/01/13 19:43:14 1.23 @@ -45,6 +45,8 @@ #include "uuid_prng.h" #include "uuid_mac.h" #include "uuid_ui64.h" +#include "uuid_str.h" +#include "uuid_bm.h" /* determine types of 8-bit size */ #if SIZEOF_CHAR == 1 @@ -478,6 +480,11 @@ (which in our case is 1us (= 1000ns) because we use gettimeofday(2) */ #define UUIDS_PER_TICK 10 +/* time offset between UUID and Unix Epoch time according to standards. + (UUID UTC base time is October 15, 1582 + Unix UTC base time is January 1, 1970) */ +#define UUID_TIMEOFFSET "01B21DD213814000" + /* INTERNAL: generate UUID version 1: time, clock and node based */ static uuid_rc_t uuid_generate_v1(uuid_t *uuid, unsigned int mode, va_list ap) { @@ -536,11 +543,8 @@ t = ui64_addn(t, time_now.tv_usec, NULL); t = ui64_muln(t, 10, NULL); - /* adjust for offset between UUID and Unix Epoch time through adding - the magic offset 01B21DD213814000 from draft-leach-uuids-guids-01. - (UUID UTC base time is October 15, 1582 - Unix UTC base time is January 1, 1970) */ - offset = ui64_s2i("01B21DD213814000", NULL, 16); + /* adjust for offset between UUID and Unix Epoch time */ + offset = ui64_s2i(UUID_TIMEOFFSET, NULL, 16); t = ui64_add(t, offset, NULL); /* compensate for low resolution system clock by adding @@ -732,13 +736,130 @@ return rc; } +/* decoding tables */ +static struct { + uuid_uint8_t num; + const char *desc; +} uuid_dectab_variant[] = { + { BM_OCTET(0,0,0,0,0,0,0,0), "reserved (NCS backward compatible)" }, + { BM_OCTET(1,0,0,0,0,0,0,0), "DCE 1.1, ISO/IEC 11578:1996" }, + { BM_OCTET(1,1,0,0,0,0,0,0), "reserved (Microsoft GUID)" }, + { BM_OCTET(1,1,1,0,0,0,0,0), "reserved (future use)" } +}; +static struct { + int num; + const char *desc; +} uuid_dectab_version[] = { + { 1, "time and node based" }, + { 3, "name based" }, + { 4, "random data based" } +}; + /* dump UUID object as descriptive text */ uuid_rc_t uuid_dump(uuid_t *uuid, char **str) { + const char *version; + const char *variant; + uint8_t tmp8; + uint16_t tmp16; + uint32_t tmp32; + char string[UUID_LEN_STR+1]; + char *s; + int i; + ui64_t t; + ui64_t offset; + int t_nsec; + int t_usec; + time_t t_sec; + char buf[19+1]; /* YYYY-MM-DD HH:MM:SS */ + struct tm *tm; + /* sanity check argument(s) */ if (uuid == NULL || str == NULL) return UUID_RC_ARG; - /* FIXME */ + + /* initialize output buffer */ + *str = NULL; + + /* decode into string representation */ + s = string; + uuid_format(uuid, &s); + str_rsprintf(str, "UUID: %s\n", s); + + /* decode UUID variant */ + variant = "unknown"; + tmp8 = uuid->obj.clock_seq_hi_and_reserved; + for (i = 7; i >= 0; i--) { + if ((tmp8 & BM_BIT(i,1)) == 0) { + tmp8 &= ~BM_MASK(i,0); + break; + } + } + for (i = 0; i < sizeof(uuid_dectab_variant)/sizeof(uuid_dectab_variant[0]); i++) { + if (uuid_dectab_variant[i].num == tmp8) { + variant = uuid_dectab_variant[i].desc; + break; + } + } + str_rsprintf(str, "variant: %s\n", variant); + + /* decode UUID version */ + version = "unknown"; + tmp16 = (BM_SHR(uuid->obj.time_hi_and_version, 12) & 0x000f); + for (i = 0; i < sizeof(uuid_dectab_version)/sizeof(uuid_dectab_version[0]); i++) { + if (uuid_dectab_version[i].num == (int)tmp16) { + version = uuid_dectab_version[i].desc; + break; + } + } + str_rsprintf(str, "version: %d (%s)\n", (int)tmp16, version); + + /* we currently support DCE 1.1 variants of version 1/3/4 only */ + if (!( tmp8 == BM_OCTET(1,0,0,0,0,0,0,0) + && (tmp16 == 1 || tmp16 == 3 || tmp16 == 4))) + return UUID_RC_OK; + + /* decode more */ + if (tmp16 == 1) { + /* decode version 1 */ + + /* decode system time */ + t = ui64_rol(ui64_n2i((unsigned long)(uuid->obj.time_hi_and_version & 0x0fff)), 48, NULL), + t = ui64_or(t, ui64_rol(ui64_n2i((unsigned long)(uuid->obj.time_mid)), 32, NULL)); + t = ui64_or(t, ui64_n2i((unsigned long)(uuid->obj.time_low))); + offset = ui64_s2i(UUID_TIMEOFFSET, NULL, 16); + t = ui64_sub(t, offset, NULL); + t = ui64_divn(t, 10, &t_nsec); + t = ui64_divn(t, 1000000, &t_usec); + t_sec = (time_t)ui64_i2n(t); + tm = gmtime(&t_sec); + strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm); + str_rsprintf(str, "content: time: %s.%06d.%d UTC\n", buf, t_usec, t_nsec); + + /* decode clock sequence */ + tmp32 = ((uuid->obj.clock_seq_hi_and_reserved & ~((0x03) << 6)) << 8) + + uuid->obj.clock_seq_low; + str_rsprintf(str, " clock: %ld (usually random)\n", (unsigned long)tmp32); + + /* decode node MAC address */ + str_rsprintf(str, " node: %02x:%02x:%02x:%02x:%02x:%02x (%s)\n", + (unsigned int)uuid->obj.node[0], + (unsigned int)uuid->obj.node[1], + (unsigned int)uuid->obj.node[2], + (unsigned int)uuid->obj.node[3], + (unsigned int)uuid->obj.node[4], + (unsigned int)uuid->obj.node[5], + (uuid->obj.node[0] & 0x80 ? "random multicast" : "real unicast")); + } + else if (tmp16 == 3) { + /* decode version 3 */ + str_rsprintf(str, "content: [not decipherable]\n"); + } + else if (tmp16 == 4) { + /* decode version 4 */ + str_rsprintf(str, "content: [no semantics]\n"); + } + return UUID_RC_OK; } Index: ossp-pkg/uuid/uuid_bm.h RCS File: /v/ossp/cvs/ossp-pkg/uuid/Attic/uuid_bm.h,v co -q -kk -p'1.1' '/v/ossp/cvs/ossp-pkg/uuid/Attic/uuid_bm.h,v' | diff -u /dev/null - -L'ossp-pkg/uuid/uuid_bm.h' 2>/dev/null --- ossp-pkg/uuid/uuid_bm.h +++ - 2024-05-16 15:46:01.360385681 +0200 @@ -0,0 +1,80 @@ +/* +** OSSP uuid - Universally Unique Identifier +** Copyright (c) 2004 Ralf S. Engelschall +** Copyright (c) 2004 The OSSP Project +** +** This file is part of OSSP uuid, a library for the generation +** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ +** +** Permission to use, copy, modify, and distribute this software for +** any purpose with or without fee is hereby granted, provided that +** the above copyright notice and this permission notice appear in all +** copies. +** +** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED +** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +** +** uuid_bm.c: bitmask API implementation +*/ + +#ifndef __UUID_BM_H__ +#define __UUID_BM_H__ + +/* + * Bitmask Calculation Macros + * (Notice: bit positions are counted n...0, i.e. lowest bit is position 0) + */ + +/* generate a bitmask consisting of 1 bits from (and including) + bit position `l' (left) to (and including) bit position `r' */ +#define BM_MASK(l,r) \ + (((1<<((l)-(r)+1))-1)<<(r)) + +/* extract a value v from a word w at position `l' to `r' and return value */ +#define BM_GET(w,l,r) \ + (((w)>>(r))&BM_MASK((l)-(r),0)) + +/* insert a value v into a word w at position `l' to `r' and return word */ +#define BM_SET(w,l,r,v) \ + ((w)|(((v)&BM_MASK((l)-(r),0))<<(r))) + +/* generate a single bit `b' (0 or 1) at bit position `n' */ +#define BM_BIT(n,b) \ + ((b)<<(n)) + +/* generate a quad word octet of bits (a half byte, i.e. bit positions 3 to 0) */ +#define BM_QUAD(b3,b2,b1,b0) \ + (BM_BIT(3,(b3))|BM_BIT(2,(b2))|BM_BIT(1,(b1))|BM_BIT(0,(b0))) + +/* generate an octet word of bits (a byte, i.e. bit positions 7 to 0) */ +#define BM_OCTET(b7,b6,b5,b4,b3,b2,b1,b0) \ + ((BM_QUAD(b7,b6,b5,b4)<<4)|BM_QUAD(b3,b2,b1,b0)) + +/* generate the value 2^n */ +#define BM_POW2(n) \ + BM_BIT(1,n) + +/* shift word w k bits to the left or to the right */ +#define BM_SHL(w,k) \ + ((w)<<(k)) +#define BM_SHR(w,k) \ + ((w)>>(k)) + +/* rotate word w (of bits n..0) k bits to the left or to the right */ +#define BM_ROL(w,n,k) \ + (BM_SHL((w),(k))&BM_MASK(n,0))|BM_SHR(((w)&BM_MASK(n,0)),(n)-(k)) +#define BM_ROR(w,n,k) \ + (BM_SHR(((w)&BM_MASK(n,0)),(k)))|BM_SHL(((w),(n)-(k))&BM_MASK(n,0)) + +#endif /* __UUID_BM_H__ */ + Index: ossp-pkg/uuid/uuid_cli.c RCS File: /v/ossp/cvs/ossp-pkg/uuid/Attic/uuid_cli.c,v rcsdiff -q -kk '-r1.8' '-r1.9' -u '/v/ossp/cvs/ossp-pkg/uuid/Attic/uuid_cli.c,v' 2>/dev/null --- uuid_cli.c 2004/01/13 09:29:48 1.8 +++ uuid_cli.c 2004/01/13 19:43:14 1.9 @@ -91,7 +91,7 @@ raw = 0; /* default is ASCII output */ decode = 0; /* default is to encode */ version = UUID_VERSION1; - while ((ch = getopt(argc, argv, "1n:rdo:v:")) != -1) { + while ((ch = getopt(argc, argv, "1n:rdmo:v:")) != -1) { switch (ch) { case '1': iterate = 1; @@ -115,6 +115,9 @@ if ((fp = fopen(optarg, "w")) == NULL) error(1, "fopen: %s", strerror(errno)); break; + case 'm': + version |= UUID_MCASTRND; + break; case 'v': i = strtol(optarg, &p, 10); if (*p != '\0') @@ -141,7 +144,16 @@ /* decoding */ if (argc != 1) usage("invalid number of arguments"); - /* FIXME */ + if ((rc = uuid_create(&uuid)) != UUID_RC_OK) + error(1, "uuid_create: %s", uuid_error(rc)); + if ((rc = uuid_parse(uuid, argv[0])) != UUID_RC_OK) + error(1, "uuid_parse: %s", uuid_error(rc)); + if ((rc = uuid_dump(uuid, &cp)) != UUID_RC_OK) + error(1, "uuid_dump: %s", uuid_error(rc)); + fprintf(stdout, "%s", cp); + free(cp); + if ((rc = uuid_destroy(uuid)) != UUID_RC_OK) + error(1, "uuid_destroy: %s", uuid_error(rc)); } else { /* encoding */ Index: ossp-pkg/uuid/uuid_cli.pod RCS File: /v/ossp/cvs/ossp-pkg/uuid/Attic/uuid_cli.pod,v rcsdiff -q -kk '-r1.5' '-r1.6' -u '/v/ossp/cvs/ossp-pkg/uuid/Attic/uuid_cli.pod,v' 2>/dev/null --- uuid_cli.pod 2004/01/13 09:20:03 1.5 +++ uuid_cli.pod 2004/01/13 19:43:15 1.6 @@ -37,6 +37,7 @@ B [B<-v> I] +[B<-m>] [B<-n> I] [B<-1>] [B<-r>] @@ -84,6 +85,12 @@ namespace UUIDs (currently known are "C", "C", "C", and "C"). The I is a string of arbitrary length. +=item B<-m> + +Forces the use of a random multi-cast MAC address when generating +version 1 UUIDs. By default the real physical MAC address of the system +is used. + =item B<-n> I Generate I UUIDs instead of just a single one (the default). Index: ossp-pkg/uuid/uuid_str.c RCS File: /v/ossp/cvs/ossp-pkg/uuid/Attic/uuid_str.c,v co -q -kk -p'1.1' '/v/ossp/cvs/ossp-pkg/uuid/Attic/uuid_str.c,v' | diff -u /dev/null - -L'ossp-pkg/uuid/uuid_str.c' 2>/dev/null --- ossp-pkg/uuid/uuid_str.c +++ - 2024-05-16 15:46:01.372086773 +0200 @@ -0,0 +1,752 @@ +/* +** OSSP uuid - Universally Unique Identifier +** Copyright (c) 2004 Ralf S. Engelschall +** Copyright (c) 2004 The OSSP Project +** +** This file is part of OSSP uuid, a library for the generation +** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ +** +** Permission to use, copy, modify, and distribute this software for +** any purpose with or without fee is hereby granted, provided that +** the above copyright notice and this permission notice appear in all +** copies. +** +** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED +** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +** +** uuid_str.c: string formatting functions +*/ + +/* + * Copyright Patrick Powell 1995 + * This code is based on code written by Patrick Powell + * It may be used for any purpose as long as this notice remains intact + * on all source code distributions. + */ + +/* + * This code contains numerious changes and enhancements which were + * made by lots of contributors over the last years to Patrick Powell's + * original code: + * + * o Patrick Powell (1995) + * o Brandon Long (1996, for Mutt) + * o Thomas Roessler (1998, for Mutt) + * o Michael Elkins (1998, for Mutt) + * o Andrew Tridgell (1998, for Samba) + * o Luke Mewburn (1999, for LukemFTP) + * o Ralf S. Engelschall (1999, for OSSP) + */ + +#include +#include +#include +#include + +#include "config.h" +#include "uuid_str.h" + +#if HAVE_LONG_LONG +#define LLONG long long +#else +#define LLONG long +#endif + +#if HAVE_LONG_DOUBLE +#define LDOUBLE long double +#else +#define LDOUBLE double +#endif + +static void fmtstr (char *, size_t *, size_t, char *, int, int, int); +static void fmtint (char *, size_t *, size_t, LLONG, int, int, int, int); +static void fmtfp (char *, size_t *, size_t, LDOUBLE, int, int, int); +static void dopr_outch (char *, size_t *, size_t, int); + +/* format read states */ +#define DP_S_DEFAULT 0 +#define DP_S_FLAGS 1 +#define DP_S_MIN 2 +#define DP_S_DOT 3 +#define DP_S_MAX 4 +#define DP_S_MOD 5 +#define DP_S_CONV 6 +#define DP_S_DONE 7 + +/* format flags - Bits */ +#define DP_F_MINUS (1 << 0) +#define DP_F_PLUS (1 << 1) +#define DP_F_SPACE (1 << 2) +#define DP_F_NUM (1 << 3) +#define DP_F_ZERO (1 << 4) +#define DP_F_UP (1 << 5) +#define DP_F_UNSIGNED (1 << 6) + +/* conversion flags */ +#define DP_C_SHORT 1 +#define DP_C_LONG 2 +#define DP_C_LDOUBLE 3 +#define DP_C_LLONG 4 + +/* some handy macros */ +#define char_to_int(p) (p - '0') +#define MAX(p,q) ((p >= q) ? p : q) +#define NUL '\0' + +static void +dopr( + char *buffer, + size_t maxlen, + size_t *retlen, + const char *format, + va_list args) +{ + char ch; + LLONG value; + LDOUBLE fvalue; + char *strvalue; + int min; + int max; + int state; + int flags; + int cflags; + size_t currlen; + + state = DP_S_DEFAULT; + flags = currlen = cflags = min = 0; + max = -1; + ch = *format++; + + if (buffer == NULL) + maxlen = 999999; + + while (state != DP_S_DONE) { + if ((ch == NUL) || (currlen >= maxlen)) + state = DP_S_DONE; + + switch (state) { + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + dopr_outch(buffer, &currlen, maxlen, ch); + ch = *format++; + break; + case DP_S_FLAGS: + switch (ch) { + case '-': + flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + flags |= DP_F_ZERO; + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) { + min = 10 * min + char_to_int(ch); + ch = *format++; + } else if (ch == '*') { + min = va_arg(args, int); + ch = *format++; + state = DP_S_DOT; + } else + state = DP_S_DOT; + break; + case DP_S_DOT: + if (ch == '.') { + state = DP_S_MAX; + ch = *format++; + } else + state = DP_S_MOD; + break; + case DP_S_MAX: + if (isdigit((unsigned char)ch)) { + if (max < 0) + max = 0; + max = 10 * max + char_to_int(ch); + ch = *format++; + } else if (ch == '*') { + max = va_arg(args, int); + ch = *format++; + state = DP_S_MOD; + } else + state = DP_S_MOD; + break; + case DP_S_MOD: + switch (ch) { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'l': + if (*format == 'l') { + cflags = DP_C_LLONG; + format++; + } else + cflags = DP_C_LONG; + ch = *format++; + break; + case 'q': + cflags = DP_C_LLONG; + ch = *format++; + break; + case 'L': + cflags = DP_C_LDOUBLE; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) { + case 'd': + case 'i': + switch (cflags) { + case DP_C_SHORT: + value = (short int)va_arg(args, int); + break; + case DP_C_LONG: + value = va_arg(args, long int); + break; + case DP_C_LLONG: + value = va_arg(args, LLONG); + break; + default: + value = va_arg(args, int); + break; + } + fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'X': + flags |= DP_F_UP; + /* FALLTHROUGH */ + case 'x': + case 'o': + case 'u': + flags |= DP_F_UNSIGNED; + switch (cflags) { + case DP_C_SHORT: + value = (unsigned short int)va_arg(args, unsigned int); + break; + case DP_C_LONG: + value = (LLONG)va_arg(args, unsigned long int); + break; + case DP_C_LLONG: + value = va_arg(args, unsigned LLONG); + break; + default: + value = (LLONG)va_arg(args, unsigned int); + break; + } + fmtint(buffer, &currlen, maxlen, value, + ch == 'o' ? 8 : (ch == 'u' ? 10 : 16), + min, max, flags); + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags); + break; + case 'E': + flags |= DP_F_UP; + case 'e': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + break; + case 'G': + flags |= DP_F_UP; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + break; + case 'c': + dopr_outch(buffer, &currlen, maxlen, va_arg(args, int)); + break; + case 's': + strvalue = va_arg(args, char *); + if (max < 0) + max = maxlen; + fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max); + break; + case 'p': + value = (long)va_arg(args, void *); + fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags); + break; + case 'n': /* XXX */ + if (cflags == DP_C_SHORT) { + short int *num; + num = va_arg(args, short int *); + *num = currlen; + } else if (cflags == DP_C_LONG) { /* XXX */ + long int *num; + num = va_arg(args, long int *); + *num = (long int) currlen; + } else if (cflags == DP_C_LLONG) { /* XXX */ + LLONG *num; + num = va_arg(args, LLONG *); + *num = (LLONG) currlen; + } else { + int *num; + num = va_arg(args, int *); + *num = currlen; + } + break; + case '%': + dopr_outch(buffer, &currlen, maxlen, ch); + break; + case 'w': + /* not supported yet, treat as next char */ + ch = *format++; + break; + default: + /* unknown, skip */ + break; + } + ch = *format++; + state = DP_S_DEFAULT; + flags = cflags = min = 0; + max = -1; + break; + case DP_S_DONE: + break; + default: + break; + } + } + if (currlen >= maxlen - 1) + currlen = maxlen - 1; + if (buffer != NULL) + buffer[currlen] = NUL; + *retlen = currlen; + return; +} + +static void +fmtstr( + char *buffer, + size_t *currlen, + size_t maxlen, + char *value, + int flags, + int min, + int max) +{ + int padlen, strln; + int cnt = 0; + + if (value == NULL) + value = ""; + for (strln = 0; value[strln] != '\0'; strln++) + ; + padlen = min - strln; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; + + while ((padlen > 0) && (cnt < max)) { + dopr_outch(buffer, currlen, maxlen, ' '); + --padlen; + ++cnt; + } + while (*value && (cnt < max)) { + dopr_outch(buffer, currlen, maxlen, *value++); + ++cnt; + } + while ((padlen < 0) && (cnt < max)) { + dopr_outch(buffer, currlen, maxlen, ' '); + ++padlen; + ++cnt; + } +} + +static void +fmtint( + char *buffer, + size_t *currlen, + size_t maxlen, + LLONG value, + int base, + int min, + int max, + int flags) +{ + int signvalue = 0; + unsigned LLONG uvalue; + char convert[20]; + int place = 0; + int spadlen = 0; + int zpadlen = 0; + int caps = 0; + + if (max < 0) + max = 0; + uvalue = value; + if (!(flags & DP_F_UNSIGNED)) { + if (value < 0) { + signvalue = '-'; + uvalue = -value; + } else if (flags & DP_F_PLUS) + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + } + if (flags & DP_F_UP) + caps = 1; + do { + convert[place++] = + (caps ? "0123456789ABCDEF" : "0123456789abcdef") + [uvalue % (unsigned) base]; + uvalue = (uvalue / (unsigned) base); + } while (uvalue && (place < 20)); + if (place == 20) + place--; + convert[place] = 0; + + zpadlen = max - place; + spadlen = min - MAX(max, place) - (signvalue ? 1 : 0); + if (zpadlen < 0) + zpadlen = 0; + if (spadlen < 0) + spadlen = 0; + if (flags & DP_F_ZERO) { + zpadlen = MAX(zpadlen, spadlen); + spadlen = 0; + } + if (flags & DP_F_MINUS) + spadlen = -spadlen; + + /* spaces */ + while (spadlen > 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + --spadlen; + } + + /* sign */ + if (signvalue) + dopr_outch(buffer, currlen, maxlen, signvalue); + + /* zeros */ + if (zpadlen > 0) { + while (zpadlen > 0) { + dopr_outch(buffer, currlen, maxlen, '0'); + --zpadlen; + } + } + /* digits */ + while (place > 0) + dopr_outch(buffer, currlen, maxlen, convert[--place]); + + /* left justified spaces */ + while (spadlen < 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + ++spadlen; + } + return; +} + +static LDOUBLE +abs_val(LDOUBLE value) +{ + LDOUBLE result = value; + if (value < 0) + result = -value; + return result; +} + +static LDOUBLE +pow10(int exponent) +{ + LDOUBLE result = 1; + while (exponent > 0) { + result *= 10; + exponent--; + } + return result; +} + +static long +round(LDOUBLE value) +{ + long intpart; + intpart = (long) value; + value = value - intpart; + if (value >= 0.5) + intpart++; + return intpart; +} + +static void +fmtfp( + char *buffer, + size_t *currlen, + size_t maxlen, + LDOUBLE fvalue, + int min, + int max, + int flags) +{ + int signvalue = 0; + LDOUBLE ufvalue; + char iconvert[20]; + char fconvert[20]; + int iplace = 0; + int fplace = 0; + int padlen = 0; + int zpadlen = 0; + int caps = 0; + long intpart; + long fracpart; + + if (max < 0) + max = 6; + ufvalue = abs_val(fvalue); + if (fvalue < 0) + signvalue = '-'; + else if (flags & DP_F_PLUS) + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + + intpart = (long)ufvalue; + + /* sorry, we only support 9 digits past the decimal because of our + conversion method */ + if (max > 9) + max = 9; + + /* we "cheat" by converting the fractional part to integer by + multiplying by a factor of 10 */ + fracpart = round((pow10(max)) * (ufvalue - intpart)); + + if (fracpart >= pow10(max)) { + intpart++; + fracpart -= pow10(max); + } + + /* convert integer part */ + do { + iconvert[iplace++] = + (caps ? "0123456789ABCDEF" + : "0123456789abcdef")[intpart % 10]; + intpart = (intpart / 10); + } while (intpart && (iplace < 20)); + if (iplace == 20) + iplace--; + iconvert[iplace] = 0; + + /* convert fractional part */ + do { + fconvert[fplace++] = + (caps ? "0123456789ABCDEF" + : "0123456789abcdef")[fracpart % 10]; + fracpart = (fracpart / 10); + } while (fracpart && (fplace < 20)); + if (fplace == 20) + fplace--; + fconvert[fplace] = 0; + + /* -1 for decimal point, another -1 if we are printing a sign */ + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + zpadlen = max - fplace; + if (zpadlen < 0) + zpadlen = 0; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; + + if ((flags & DP_F_ZERO) && (padlen > 0)) { + if (signvalue) { + dopr_outch(buffer, currlen, maxlen, signvalue); + --padlen; + signvalue = 0; + } + while (padlen > 0) { + dopr_outch(buffer, currlen, maxlen, '0'); + --padlen; + } + } + while (padlen > 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + --padlen; + } + if (signvalue) + dopr_outch(buffer, currlen, maxlen, signvalue); + + while (iplace > 0) + dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]); + + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + if (max > 0) { + dopr_outch(buffer, currlen, maxlen, '.'); + + while (fplace > 0) + dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]); + } + while (zpadlen > 0) { + dopr_outch(buffer, currlen, maxlen, '0'); + --zpadlen; + } + + while (padlen < 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + ++padlen; + } + return; +} + +static void +dopr_outch( + char *buffer, + size_t *currlen, + size_t maxlen, + int c) +{ + if (*currlen < maxlen) { + if (buffer != NULL) + buffer[(*currlen)] = (char)c; + (*currlen)++; + } + return; +} + +int +str_vsnprintf( + char *str, + size_t count, + const char *fmt, + va_list args) +{ + size_t retlen; + + if (str != NULL) + str[0] = NUL; + dopr(str, count, &retlen, fmt, args); + return retlen; +} + +int +str_snprintf( + char *str, + size_t count, + const char *fmt, + ...) +{ + va_list ap; + int rv; + + va_start(ap, fmt); + rv = str_vsnprintf(str, count, fmt, ap); + va_end(ap); + return rv; +} + +char * +str_vasprintf( + const char *fmt, + va_list ap) +{ + char *rv; + int n; + + n = str_vsnprintf(NULL, -1, fmt, ap); + if ((rv = (char *)malloc(n+1)) == NULL) + return NULL; + str_vsnprintf(rv, n+1, fmt, ap); + return rv; +} + +char * +str_asprintf( + const char *fmt, + ...) +{ + va_list ap; + char *rv; + + va_start(ap, fmt); + rv = str_vasprintf(fmt, ap); + va_end(ap); + return rv; +} + +int +str_vrsprintf( + char **str, + const char *fmt, + va_list ap) +{ + int rv; + size_t n; + + if (str == NULL) + return -1; + if (*str == NULL) { + *str = str_vasprintf(fmt, ap); + rv = strlen(*str); + } + else { + n = strlen(*str); + rv = str_vsnprintf(NULL, -1, fmt, ap); + if ((*str = (char *)realloc(*str, n+rv+1)) == NULL) + return -1; + str_vsnprintf((*str)+n, rv+1, fmt, ap); + } + return rv; +} + +int +str_rsprintf( + char **str, + const char *fmt, + ...) +{ + va_list ap; + int rv; + + va_start(ap, fmt); + rv = str_vrsprintf(str, fmt, ap); + va_end(ap); + return rv; +} + Index: ossp-pkg/uuid/uuid_str.h RCS File: /v/ossp/cvs/ossp-pkg/uuid/Attic/uuid_str.h,v co -q -kk -p'1.1' '/v/ossp/cvs/ossp-pkg/uuid/Attic/uuid_str.h,v' | diff -u /dev/null - -L'ossp-pkg/uuid/uuid_str.h' 2>/dev/null --- ossp-pkg/uuid/uuid_str.h +++ - 2024-05-16 15:46:01.375056086 +0200 @@ -0,0 +1,63 @@ +/* +** OSSP uuid - Universally Unique Identifier +** Copyright (c) 2004 Ralf S. Engelschall +** Copyright (c) 2004 The OSSP Project +** +** This file is part of OSSP uuid, a library for the generation +** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ +** +** Permission to use, copy, modify, and distribute this software for +** any purpose with or without fee is hereby granted, provided that +** the above copyright notice and this permission notice appear in all +** copies. +** +** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED +** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +** +** uuid_str.h: string formatting functions +*/ + +#ifndef __UUID_STR_H__ +#define __UUID_STR_H__ + +#include +#include + +#define STR_PREFIX uuid_ + +/* embedding support */ +#ifdef STR_PREFIX +#if defined(__STDC__) || defined(__cplusplus) +#define __STR_CONCAT(x,y) x ## y +#define STR_CONCAT(x,y) __STR_CONCAT(x,y) +#else +#define __STR_CONCAT(x) x +#define STR_CONCAT(x,y) __STR_CONCAT(x)y +#endif +#define str_vsnprintf STR_CONCAT(STR_PREFIX,str_vsnprintf) +#define str_snprintf STR_CONCAT(STR_PREFIX,str_snprintf) +#define str_vrsprintf STR_CONCAT(STR_PREFIX,str_vrsprintf) +#define str_rsprintf STR_CONCAT(STR_PREFIX,str_rsprintf) +#define str_vasprintf STR_CONCAT(STR_PREFIX,str_vasprintf) +#define str_asprintf STR_CONCAT(STR_PREFIX,str_asprintf) +#endif + +extern int str_vsnprintf (char *, size_t, const char *, va_list); +extern int str_snprintf (char *, size_t, const char *, ...); +extern int str_vrsprintf (char **, const char *, va_list); +extern int str_rsprintf (char **, const char *, ...); +extern char *str_vasprintf ( const char *, va_list); +extern char *str_asprintf ( const char *, ...); + +#endif /* __UUID_STR_H__ */ +