OSSP CVS Repository

ossp - Check-in [4318]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 4318
Date: 2004-Jan-13 20:43:14 (local)
2004-Jan-13 19:43:14 (UTC)
User:rse
Branch:
Comment: 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.
Tickets:
Inspections:
Files:
ossp-pkg/uuid/ChangeLog      1.7 -> 1.8     10 inserted, 0 deleted
ossp-pkg/uuid/Makefile.in      1.11 -> 1.12     1 inserted, 1 deleted
ossp-pkg/uuid/TODO      1.6 -> 1.7     1 inserted, 1 deleted
ossp-pkg/uuid/uuid.ac      1.5 -> 1.6     1 inserted, 0 deleted
ossp-pkg/uuid/uuid.c      1.22 -> 1.23     127 inserted, 6 deleted
ossp-pkg/uuid/uuid_bm.h      added-> 1.1
ossp-pkg/uuid/uuid_cli.c      1.8 -> 1.9     14 inserted, 2 deleted
ossp-pkg/uuid/uuid_cli.pod      1.5 -> 1.6     7 inserted, 0 deleted
ossp-pkg/uuid/uuid_str.c      added-> 1.1
ossp-pkg/uuid/uuid_str.h      added-> 1.1

ossp-pkg/uuid/ChangeLog 1.7 -> 1.8

--- 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]
 


ossp-pkg/uuid/Makefile.in 1.11 -> 1.12

--- 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


ossp-pkg/uuid/TODO 1.6 -> 1.7

--- 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


ossp-pkg/uuid/uuid.ac 1.5 -> 1.6

--- 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)


ossp-pkg/uuid/uuid.c 1.22 -> 1.23

--- 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;
 }
 


ossp-pkg/uuid/uuid_bm.h -> 1.1

*** /dev/null    Mon Apr 29 20:37:11 2024
--- -    Mon Apr 29 20:42:42 2024
***************
*** 0 ****
--- 1,80 ----
+ /*
+ **  OSSP uuid - Universally Unique Identifier
+ **  Copyright (c) 2004 Ralf S. Engelschall <rse@engelschall.com>
+ **  Copyright (c) 2004 The OSSP Project <http://www.ossp.org/>
+ **
+ **  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__ */
+ 


ossp-pkg/uuid/uuid_cli.c 1.8 -> 1.9

--- 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 */


ossp-pkg/uuid/uuid_cli.pod 1.5 -> 1.6

--- 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<uuid>
 [B<-v> I<version>]
+[B<-m>]
 [B<-n> I<count>]
 [B<-1>]
 [B<-r>]
@@ -84,6 +85,12 @@
 namespace UUIDs (currently known are "C<DNS>", "C<URL>", "C<OID>", and
 "C<X500>"). The I<name> 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<count>
 
 Generate I<count> UUIDs instead of just a single one (the default).


ossp-pkg/uuid/uuid_str.c -> 1.1

*** /dev/null    Mon Apr 29 20:37:11 2024
--- -    Mon Apr 29 20:42:42 2024
***************
*** 0 ****
--- 1,752 ----
+ /*
+ **  OSSP uuid - Universally Unique Identifier
+ **  Copyright (c) 2004 Ralf S. Engelschall <rse@engelschall.com>
+ **  Copyright (c) 2004 The OSSP Project <http://www.ossp.org/>
+ **
+ **  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 <papowell@astart.com>
+  * 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 <papowell@astart.com>      (1995)
+  * o Brandon Long <blong@fiction.net>          (1996, for Mutt)
+  * o Thomas Roessler <roessler@guug.de>        (1998, for Mutt)
+  * o Michael Elkins <me@cs.hmc.edu>            (1998, for Mutt)
+  * o Andrew Tridgell <tridge@samba.org>        (1998, for Samba)
+  * o Luke Mewburn <lukem@netbsd.org>           (1999, for LukemFTP)
+  * o Ralf S. Engelschall <rse@engelschall.com> (1999, for OSSP)
+  */
+ 
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <string.h>
+ #include <ctype.h>
+ 
+ #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 = "<NULL>";
+     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;
+ }
+ 


ossp-pkg/uuid/uuid_str.h -> 1.1

*** /dev/null    Mon Apr 29 20:37:11 2024
--- -    Mon Apr 29 20:42:42 2024
***************
*** 0 ****
--- 1,63 ----
+ /*
+ **  OSSP uuid - Universally Unique Identifier
+ **  Copyright (c) 2004 Ralf S. Engelschall <rse@engelschall.com>
+ **  Copyright (c) 2004 The OSSP Project <http://www.ossp.org/>
+ **
+ **  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 <stdarg.h>
+ #include <string.h>
+ 
+ #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__ */
+ 

CVSTrac 2.0.1