Revision: 71850
          http://sourceforge.net/p/brlcad/code/71850
Author:   starseeker
Date:     2018-09-26 15:05:11 +0000 (Wed, 26 Sep 2018)
Log Message:
-----------
Whoops, not quite - compiled but left some stuff undefined.  Back out for now

Modified Paths:
--------------
    brlcad/trunk/src/other/libnetpbm/CMakeLists.txt
    brlcad/trunk/src/other/libnetpbm/colorname.c
    brlcad/trunk/src/other/libnetpbm/libpam.c
    brlcad/trunk/src/other/libnetpbm/libpammap.c
    brlcad/trunk/src/other/libnetpbm/libpbmfont.c
    brlcad/trunk/src/other/libnetpbm/libpm.c
    brlcad/trunk/src/other/libnetpbm/libppmfuzzy.c
    brlcad/trunk/src/other/libnetpbm.dist

Added Paths:
-----------
    brlcad/trunk/src/other/libnetpbm/TODO
    brlcad/trunk/src/other/libnetpbm/util/LICENSE_nstring.txt
    brlcad/trunk/src/other/libnetpbm/util/nstring.c
    brlcad/trunk/src/other/libnetpbm/util/nstring.h
    brlcad/trunk/src/other/libnetpbm/util/testnstring.c

Modified: brlcad/trunk/src/other/libnetpbm/CMakeLists.txt
===================================================================
--- brlcad/trunk/src/other/libnetpbm/CMakeLists.txt     2018-09-26 15:01:47 UTC 
(rev 71849)
+++ brlcad/trunk/src/other/libnetpbm/CMakeLists.txt     2018-09-26 15:05:11 UTC 
(rev 71850)
@@ -115,6 +115,7 @@
   libpamn.c
   libpammap.c
   libpamcolor.c
+  util/nstring.c
   )
 
 set(NETPBM_HEADERS
@@ -132,6 +133,7 @@
   ppm.h
   ppmcmap.h
   ppmfloyd.h
+  util/nstring.h
   )
 
 if(NOT DEFINED BUILD_SHARED_LIBS)

Copied: brlcad/trunk/src/other/libnetpbm/TODO (from rev 71848, 
brlcad/trunk/src/other/libnetpbm/TODO)
===================================================================
--- brlcad/trunk/src/other/libnetpbm/TODO                               (rev 0)
+++ brlcad/trunk/src/other/libnetpbm/TODO       2018-09-26 15:05:11 UTC (rev 
71850)
@@ -0,0 +1,2 @@
+See if http://www.jhweiss.de/software/snprintf.html can be used
+to replace nstring.c

Modified: brlcad/trunk/src/other/libnetpbm/colorname.c
===================================================================
--- brlcad/trunk/src/other/libnetpbm/colorname.c        2018-09-26 15:01:47 UTC 
(rev 71849)
+++ brlcad/trunk/src/other/libnetpbm/colorname.c        2018-09-26 15:05:11 UTC 
(rev 71850)
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <errno.h>
 
+#include "nstring.h"
 #include "colorname.h"
 
 static int lineNo;

Modified: brlcad/trunk/src/other/libnetpbm/libpam.c
===================================================================
--- brlcad/trunk/src/other/libnetpbm/libpam.c   2018-09-26 15:01:47 UTC (rev 
71849)
+++ brlcad/trunk/src/other/libnetpbm/libpam.c   2018-09-26 15:05:11 UTC (rev 
71850)
@@ -22,6 +22,7 @@
 
 #include "pm_c_util.h"
 #include "mallocvar.h"
+#include "nstring.h"
 #include "pam.h"
 #include "ppm.h"
 #include "libpbm.h"

Modified: brlcad/trunk/src/other/libnetpbm/libpammap.c
===================================================================
--- brlcad/trunk/src/other/libnetpbm/libpammap.c        2018-09-26 15:01:47 UTC 
(rev 71849)
+++ brlcad/trunk/src/other/libnetpbm/libpammap.c        2018-09-26 15:05:11 UTC 
(rev 71850)
@@ -17,6 +17,7 @@
 
 #include "pm_c_util.h"
 #include "mallocvar.h"
+#include "nstring.h"
 #include "pam.h"
 #include "pammap.h"
 

Modified: brlcad/trunk/src/other/libnetpbm/libpbmfont.c
===================================================================
--- brlcad/trunk/src/other/libnetpbm/libpbmfont.c       2018-09-26 15:01:47 UTC 
(rev 71849)
+++ brlcad/trunk/src/other/libnetpbm/libpbmfont.c       2018-09-26 15:05:11 UTC 
(rev 71850)
@@ -17,6 +17,7 @@
 #include <string.h>
 
 #include "pm_c_util.h"
+#include "nstring.h"
 #include "pbm.h"
 #include "pbmfont.h"
 #include "mallocvar.h"

Modified: brlcad/trunk/src/other/libnetpbm/libpm.c
===================================================================
--- brlcad/trunk/src/other/libnetpbm/libpm.c    2018-09-26 15:01:47 UTC (rev 
71849)
+++ brlcad/trunk/src/other/libnetpbm/libpm.c    2018-09-26 15:05:11 UTC (rev 
71850)
@@ -47,6 +47,8 @@
 #include "pm_c_util.h"
 #include "version.h"
 #include "compile.h"
+#include "nstring.h"
+/*#include "shhopt.h"*/
 #include "mallocvar.h"
 #include "pm.h"
 

Modified: brlcad/trunk/src/other/libnetpbm/libppmfuzzy.c
===================================================================
--- brlcad/trunk/src/other/libnetpbm/libppmfuzzy.c      2018-09-26 15:01:47 UTC 
(rev 71849)
+++ brlcad/trunk/src/other/libnetpbm/libppmfuzzy.c      2018-09-26 15:05:11 UTC 
(rev 71850)
@@ -6,6 +6,7 @@
 =============================================================================*/
 
 #include "pm_c_util.h"
+#include "nstring.h"
 #include "ppm.h"
 
 typedef double fzLog;

Copied: brlcad/trunk/src/other/libnetpbm/util/LICENSE_nstring.txt (from rev 
71848, brlcad/trunk/src/other/libnetpbm/util/LICENSE_nstring.txt)
===================================================================
--- brlcad/trunk/src/other/libnetpbm/util/LICENSE_nstring.txt                   
        (rev 0)
+++ brlcad/trunk/src/other/libnetpbm/util/LICENSE_nstring.txt   2018-09-26 
15:05:11 UTC (rev 71850)
@@ -0,0 +1,121 @@
+The Frontier Artistic License Version 1.0
+Derived from the Artistic License at OpenSource.org.
+Submitted to OpenSource.org for Open Source Initiative certification.
+   
+Preamble
+
+The intent of this document is to state the conditions under which a
+Package may be copied, such that the Copyright Holder maintains some
+semblance of artistic control over the development of the package,
+while giving the users of the package the right to use and distribute
+the Package in a more-or-less customary fashion, plus the right to
+make reasonable modifications.
+   
+Definitions
+
+  "Package" refers to the script, suite, file, or collection of
+  scripts, suites, and/or files distributed by the Copyright Holder,
+  and to derivatives of that Package created through textual modification.
+
+  "Standard Version" refers to such a Package if it has not been
+  modified, or has been modified in accordance with the wishes of
+  the Copyright Holder.
+
+  "Copyright Holder" is whoever is named in the copyright statement
+  or statements for the package.
+
+  "You" is you, if you're thinking about copying or distributing
+  this Package.
+
+  "Reasonable copying fee" is whatever you can justify on the basis
+  of media cost, duplication charges, time of people involved, and
+  so on. (You will not be required to justify it to the Copyright
+  Holder, but only to the computing community at large as a market
+  that must bear the fee.)
+
+  "Freely Available" means that no fee is charged for the item
+  itself, though there may be fees involved in handling the item.
+  It also means that recipients of the item may redistribute it under
+  the same conditions they received it.
+       
+
+Terms
+
+1. You may make and give away verbatim copies of the source form of
+the Standard Version of this Package without restriction, provided
+that you duplicate all of the original copyright notices and
+associated disclaimers.
+   
+2. You may apply bug fixes, portability fixes, and other modifications
+derived from the Public Domain or from the Copyright Holder. A Package
+modified in such a way shall still be considered the Standard Version.
+   
+3. You may otherwise modify your copy of this Package in any way,
+provided that you insert a prominent notice in each changed script,
+suite, or file stating how and when you changed that script, suite,
+or file, and provided that you do at least ONE of the following:
+   
+  a) Use the modified Package only within your corporation or
+  organization, or retain the modified Package solely for personal use.
+     
+  b) Place your modifications in the Public Domain or otherwise make
+  them Freely Available, such as by posting said modifications to Usenet
+  or an equivalent medium, or placing the modifications on a major archive
+  site such as ftp.uu.net, or by allowing the Copyright Holder to include
+  your modifications in the Standard Version of the Package.
+     
+  c) Rename any non-standard executables so the names do not conflict
+  with standard executables, which must also be provided, and provide
+  a separate manual page (or equivalent) for each non-standard executable
+  that clearly documents how it differs from the Standard Version.
+     
+  d) Make other distribution arrangements with the Copyright Holder.
+     
+4. You may distribute the programs of this Package in object code or
+executable form, provided that you do at least ONE of the following:
+   
+  a) Distribute a Standard Version of the executables and library
+  files, together with instructions (in the manual page or
+  equivalent) on where to get the Standard Version.
+     
+  b) Accompany the distribution with the machine-readable source of
+  the Package with your modifications.
+     
+  c) Accompany any non-standard executables with their corresponding
+  Standard Version executables, give the non-standard executables
+  non-standard names, and clearly document the differences in manual
+  pages (or equivalent), together with instructions on where to get
+  the Standard Version.
+     
+  d) Make other distribution arrangements with the Copyright Holder.
+     
+5. You may charge a reasonable copying fee for any distribution of
+this Package. You may charge any fee you choose for support of this
+Package. You may not charge a fee for this Package itself. However,
+you may distribute this Package in aggregate with other (possibly
+commercial) programs as part of a larger (possibly commercial)
+software distribution provided that you do not advertise this Package
+as a product of your own.
+   
+6. The scripts and library files supplied as input to or produced as
+output from the programs of this Package do not automatically fall
+under the copyright of this Package, but belong to whomever generated
+them, and may be sold commercially, and may be aggregated with this
+Package.
+   
+7. Scripts, suites, or programs supplied by you that depend on or
+otherwise make use of this Package shall not be considered part of
+this Package.
+   
+8. The name of the Copyright Holder may not be used to endorse or
+promote products derived from this software without specific prior
+written permission.
+   
+9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+   
+                        The End
+
+
+http://www.spinwardstars.com/frontier/fal.html

Copied: brlcad/trunk/src/other/libnetpbm/util/nstring.c (from rev 71848, 
brlcad/trunk/src/other/libnetpbm/util/nstring.c)
===================================================================
--- brlcad/trunk/src/other/libnetpbm/util/nstring.c                             
(rev 0)
+++ brlcad/trunk/src/other/libnetpbm/util/nstring.c     2018-09-26 15:05:11 UTC 
(rev 71850)
@@ -0,0 +1,906 @@
+/*
+ * snprintf.c - a portable implementation of snprintf
+ *
+
+   THIS MODULE WAS ADAPTED FOR NETPBM BY BRYAN HENDERSON ON 2002.03.24.
+   Bryan got the base from 
+   http://www.ijs.si/software/snprintf/snprintf-2.2.tar.gz, but made
+   a lot of changes and additions.
+
+ * AUTHOR
+ *   Mark Martinec <mark.marti...@ijs.si>, April 1999.
+ *
+ *   Copyright 1999, Mark Martinec. All rights reserved.
+ *
+ * TERMS AND CONDITIONS
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the "Frontier Artistic License" which comes
+ *   with this Kit.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty
+ *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *   See the Frontier Artistic License for more details.
+ *
+ *   You should have received a copy of the Frontier Artistic License
+ *   with this Kit in the file named LICENSE.txt .
+ *   If not, I'll be glad to provide one.
+ *
+ * FEATURES
+ * - careful adherence to specs regarding flags, field width and precision;
+ * - good performance for large string handling (large format, large
+ *   argument or large paddings). Performance is similar to system's sprintf
+ *   and in several cases significantly better (make sure you compile with
+ *   optimizations turned on, tell the compiler the code is strict ANSI
+ *   if necessary to give it more freedom for optimizations);
+ * - return value semantics per ISO/IEC 9899:1999 ("ISO C99");
+ * - written in standard ISO/ANSI C - requires an ANSI C compiler.
+ *
+ * IMPLEMENTED CONVERSION SPECIFIERS AND DATA TYPES
+ *
+ * This snprintf implements only the following conversion specifiers:
+ * s, c, d, u, o, x, X, p  (and synonyms: i, D, U, O - see below)
+ * with flags: '-', '+', ' ', '0' and '#'.
+ * An asterisk is acceptable for field width as well as precision.
+ *
+ * Length modifiers 'h' (short int), 'l' (long int),
+ * and 'll' (long long int) are implemented.
+ *
+ * Conversion of numeric data (conversion specifiers d, u, o, x, X, p)
+ * with length modifiers (none or h, l, ll) is left to the system routine
+ * sprintf, but all handling of flags, field width and precision as well as
+ * c and s conversions is done very carefully by this portable routine.
+ * If a string precision (truncation) is specified (e.g. %.8s) it is
+ * guaranteed the string beyond the specified precision will not be referenced.
+ *
+ * Length modifiers h, l and ll are ignored for c and s conversions (you
+ * can't use data types wint_t and wchar_t).
+ *
+ * The following common synonyms for conversion characters are acceptable:
+ *   - i is a synonym for d
+ *   - D is a synonym for ld, explicit length modifiers are ignored
+ *   - U is a synonym for lu, explicit length modifiers are ignored
+ *   - O is a synonym for lo, explicit length modifiers are ignored
+ * The D, O and U conversion characters are nonstandard, they are accepted
+ * for backward compatibility only, and should not be used for new code.
+ *
+ * The following is specifically NOT implemented:
+ *   - flag ' (thousands' grouping character) is recognized but ignored
+ *   - numeric conversion specifiers: f, e, E, g, G and synonym F,
+ *     as well as the new a and A conversion specifiers
+ *   - length modifier 'L' (long double) and 'q' (quad - use 'll' instead)
+ *   - wide character/string conversions: lc, ls, and nonstandard
+ *     synonyms C and S
+ *   - writeback of converted string length: conversion character n
+ *   - the n$ specification for direct reference to n-th argument
+ *   - locales
+ *
+ * It is permitted for str_m to be zero, and it is permitted to specify NULL
+ * pointer for resulting string argument if str_m is zero (as per ISO C99).
+ *
+ * The return value is the number of characters which would be generated
+ * for the given input, excluding the trailing null. If this value
+ * is greater or equal to str_m, not all characters from the result
+ * have been stored in str, output bytes beyond the (str_m-1) -th character
+ * are discarded. If str_m is greater than zero it is guaranteed
+ * the resulting string will be null-terminated.
+ *
+ * NOTE that this matches the ISO C99, OpenBSD, and GNU C library 2.1,
+ * but is different from some older and vendor implementations,
+ * and is also different from XPG, XSH5, SUSv2 specifications.
+ * For historical discussion on changes in the semantics and standards
+ * of snprintf see printf(3) man page in the Linux programmers manual.
+ *
+ * Routines asprintf and vasprintf return a pointer (in the ptr argument)
+ * to a buffer sufficiently large to hold the resulting string. This pointer
+ * should be passed to free(3) to release the allocated storage when it is
+ * no longer needed. If sufficient space cannot be allocated, these functions
+ * will return -1 and set ptr to be a NULL pointer. These two routines are a
+ * GNU C library extensions (glibc).
+ *
+ * Routines asnprintf and vasnprintf are similar to asprintf and vasprintf,
+ * yet, like snprintf and vsnprintf counterparts, will write at most str_m-1
+ * characters into the allocated output string, the last character in the
+ * allocated buffer then gets the terminating null. If the formatted string
+ * length (the return value) is greater than or equal to the str_m argument,
+ * the resulting string was truncated and some of the formatted characters
+ * were discarded. These routines present a handy way to limit the amount
+ * of allocated memory to some sane value.
+ *
+ * AVAILABILITY
+ *   http://www.ijs.si/software/snprintf/
+ *
+ */
+
+
+#define PORTABLE_SNPRINTF_VERSION_MAJOR 2
+#define PORTABLE_SNPRINTF_VERSION_MINOR 2
+
+#include <sys/types.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "pm.h"
+#include "pm_c_util.h"
+
+#include "nstring.h"
+
+#ifdef isdigit
+#undef isdigit
+#endif
+#define isdigit(c) ((c) >= '0' && (c) <= '9')
+
+/* For copying strings longer or equal to 'breakeven_point'
+ * it is more efficient to call memcpy() than to do it inline.
+ * The value depends mostly on the processor architecture,
+ * but also on the compiler and its optimization capabilities.
+ * The value is not critical, some small value greater than zero
+ * will be just fine if you don't care to squeeze every drop
+ * of performance out of the code.
+ *
+ * Small values favor memcpy, large values favor inline code.
+ */
+#if defined(__alpha__) || defined(__alpha)
+#  define breakeven_point   2  /* AXP (DEC Alpha)     - gcc or cc or egcs */
+#endif
+#if defined(__i386__)  || defined(__i386)
+#  define breakeven_point  12  /* Intel Pentium/Linux - gcc 2.96 */
+#endif
+#if defined(__hppa)
+#  define breakeven_point  10  /* HP-PA               - gcc */
+#endif
+#if defined(__sparc__) || defined(__sparc)
+#  define breakeven_point  33  /* Sun Sparc 5         - gcc 2.8.1 */
+#endif
+
+/* some other values of possible interest: */
+/* #define breakeven_point  8 */  /* VAX 4000          - vaxc */
+/* #define breakeven_point 19 */  /* VAX 4000          - gcc 2.7.0 */
+
+#ifndef breakeven_point
+#  define breakeven_point   6  /* some reasonable one-size-fits-all value */
+#endif
+
+#define fast_memcpy(d,s,n) \
+  { register size_t nn = (size_t)(n); \
+    if (nn >= breakeven_point) memcpy((d), (s), nn); \
+    else if (nn > 0) { /* proc call overhead is worth only for large strings*/\
+      register char *dd; register const char *ss; \
+      for (ss=(s), dd=(d); nn>0; nn--) *dd++ = *ss++; } }
+
+#define fast_memset(d,c,n) \
+  { register size_t nn = (size_t)(n); \
+    if (nn >= breakeven_point) memset((d), (int)(c), nn); \
+    else if (nn > 0) { /* proc call overhead is worth only for large strings*/\
+      register char *dd; register const int cc=(int)(c); \
+      for (dd=(d); nn>0; nn--) *dd++ = cc; } }
+
+/* declarations */
+
+static char credits[] = "\n\
+@(#)snprintf.c, v2.2: Mark Martinec, <mark.marti...@ijs.si>\n\
+@(#)snprintf.c, v2.2: Copyright 1999, Mark Martinec. Frontier Artistic License 
applies.\n\
+@(#)snprintf.c, v2.2: http://www.ijs.si/software/snprintf/\n";;
+
+
+
+void
+vsnprintfN(char *       const str,
+           size_t       const str_m,
+           const char * const fmt,
+           va_list            ap,
+           size_t *     const sizeP) {
+
+    size_t str_l = 0;
+    const char *p = fmt;
+
+    /* In contrast with POSIX, the ISO C99 now says that str can be
+       NULL and str_m can be 0.  This is more useful than the old:
+       if (str_m < 1) return -1;
+    */
+
+    if (!p) p = "";
+    while (*p) {
+        if (*p != '%') {
+            /* if (str_l < str_m) str[str_l++] = *p++; -- this would
+               be sufficient but the following code achieves better
+               performance for cases * where format string is long and
+               contains few conversions
+            */
+            const char *q = strchr(p + 1,'%');
+            size_t n = !q ? strlen(p) : (q - p);
+            if (str_l < str_m) {
+                size_t avail = str_m - str_l;
+                fast_memcpy(str + str_l, p, (n > avail ? avail : n));
+            }
+            p += n; str_l += n;
+        } else {
+            const char *starting_p;
+            size_t min_field_width = 0, precision = 0;
+            int zero_padding = 0, precision_specified = 0, justify_left = 0;
+            int alternate_form = 0, force_sign = 0;
+            int space_for_positive = 1;
+                /* If both the ' ' and '+' flags appear,
+                   the ' ' flag should be ignored.
+                */
+            char length_modifier = '\0';  /* allowed values: \0, h, l, L */
+            char tmp[32];
+                /* temporary buffer for simple numeric->string conversion */
+
+            const char *str_arg;
+                /* string address in case of string argument */
+            size_t str_arg_l;
+                /* natural field width of arg without padding and sign */
+            unsigned char uchar_arg;
+                /* unsigned char argument value - only defined for c
+                   conversion.  N.B. standard explicitly states the char
+                   argument for the c conversion is unsigned.
+                */
+
+            size_t number_of_zeros_to_pad = 0;
+                /* number of zeros to be inserted for numeric
+                   conversions as required by the precision or minimal
+                   field width
+                */
+
+            size_t zero_padding_insertion_ind = 0;
+                /* index into tmp where zero padding is to be inserted */
+
+            char fmt_spec = '\0';
+                /* current conversion specifier character */
+
+            str_arg = credits;
+                /* just to make compiler happy (defined but not used) */
+            str_arg = NULL;
+            starting_p = p;
+            ++p;  /* skip '%' */
+
+            /* parse flags */
+            while (*p == '0' || *p == '-' || *p == '+' ||
+                   *p == ' ' || *p == '#' || *p == '\'') {
+                switch (*p) {
+                case '0': zero_padding = 1; break;
+                case '-': justify_left = 1; break;
+                case '+': force_sign = 1; space_for_positive = 0; break;
+                case ' ': force_sign = 1; break;
+                    /* If both the ' ' and '+' flags appear, the ' '
+                       flag should be ignored
+                    */
+                case '#': alternate_form = 1; break;
+                case '\'': break;
+                }
+                ++p;
+            }
+            /* If the '0' and '-' flags both appear, the '0' flag
+               should be ignored.
+            */
+
+            /* parse field width */
+            if (*p == '*') {
+                int j;
+                p++; j = va_arg(ap, int);
+                if (j >= 0) min_field_width = j;
+                else { min_field_width = -j; justify_left = 1; }
+            } else if (isdigit((int)(*p))) {
+                /* size_t could be wider than unsigned int; make sure
+                   we treat argument like common implementations do
+                */
+                unsigned int uj = *p++ - '0';
+                while (isdigit((int)(*p)))
+                    uj = 10*uj + (unsigned int)(*p++ - '0');
+                min_field_width = uj;
+            }
+            /* parse precision */
+            if (*p == '.') {
+                p++; precision_specified = 1;
+                if (*p == '*') {
+                    int j = va_arg(ap, int);
+                    p++;
+                    if (j >= 0) precision = j;
+                    else {
+                        precision_specified = 0; precision = 0;
+                        /* NOTE: Solaris 2.6 man page claims that in
+                           this case the precision should be set to 0.
+                           Digital Unix 4.0, HPUX 10 and BSD man page
+                           claim that this case should be treated as
+                           unspecified precision, which is what we do
+                           here.
+                        */
+                    }
+                } else if (isdigit((int)(*p))) {
+                    /* size_t could be wider than unsigned int; make
+                       sure we treat argument like common
+                       implementations do
+                    */
+                    unsigned int uj = *p++ - '0';
+                    while (isdigit((int)(*p)))
+                        uj = 10*uj + (unsigned int)(*p++ - '0');
+                    precision = uj;
+                }
+            }
+            /* parse 'h', 'l' and 'll' length modifiers */
+            if (*p == 'h' || *p == 'l') {
+                length_modifier = *p; p++;
+                if (length_modifier == 'l' && *p == 'l') {
+                    /* double l = long long */
+                    length_modifier = 'l';  /* treat it as a single 'l' */
+                    p++;
+                }
+            }
+            fmt_spec = *p;
+
+            /* common synonyms: */
+            switch (fmt_spec) {
+            case 'i': fmt_spec = 'd'; break;
+            case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;
+            case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;
+            case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;
+            default: break;
+            }
+            /* get parameter value, do initial processing */
+            switch (fmt_spec) {
+            case '%':
+                /* % behaves similar to 's' regarding flags and field widths */
+            case 'c':
+                /* c behaves similar to 's' regarding flags and field widths */
+            case 's':
+                /* wint_t and wchar_t not handled */
+                length_modifier = '\0';
+                /* the result of zero padding flag with non-numeric
+                    conversion specifier is undefined. Solaris and
+                    HPUX 10 does zero padding in this case, Digital
+                    Unix and Linux does not.
+                */
+
+                zero_padding = 0;
+                    /* turn zero padding off for string conversions */
+                str_arg_l = 1;
+                switch (fmt_spec) {
+                case '%':
+                    str_arg = p; break;
+                case 'c': {
+                    int j = va_arg(ap, int);
+                    uchar_arg = (unsigned char) j;
+                        /* standard demands unsigned char */
+                    str_arg = (const char *) &uchar_arg;
+                    break;
+                }
+                case 's':
+                    str_arg = va_arg(ap, const char *);
+                    if (!str_arg)
+                        /* make sure not to address string beyond the
+                           specified precision !!!
+                        */
+                        str_arg_l = 0;
+                    else if (!precision_specified)
+                        /* truncate string if necessary as requested by
+                           precision 
+                        */
+                        str_arg_l = strlen(str_arg);
+                    else if (precision == 0)
+                        str_arg_l = 0;
+                    else {
+                        /* memchr on HP does not like n > 2^31  !!! */
+                        const char * q =
+                            memchr(str_arg, '\0',
+                                   precision <= 0x7fffffff ?
+                                   precision : 0x7fffffff);
+                        str_arg_l = !q ? precision : (q-str_arg);
+                    }
+                    break;
+                default: break;
+                }
+                break;
+            case 'd': case 'u': case 'o': case 'x': case 'X': case 'p': {
+                /* NOTE: the u, o, x, X and p conversion specifiers imply
+                   the value is unsigned;  d implies a signed value
+                */
+                int arg_sign = 0;
+                /* 0  if numeric argument is zero (or if pointer is NULL
+                      for 'p'),
+                   +1 if greater than zero (or nonzero for unsigned arguments),
+                   -1 if negative (unsigned argument is never negative)
+                */
+
+                int int_arg = 0;
+                unsigned int uint_arg = 0;
+                   /* defined only for length modifier h, or for no
+                      length modifiers
+                   */
+
+                long int long_arg = 0;  unsigned long int ulong_arg = 0;
+                /* only defined for length modifier l */
+
+                void *ptr_arg = NULL;
+                /* pointer argument value -only defined for p conversion */
+
+                if (fmt_spec == 'p') {
+                    /* HPUX 10: An l, h, ll or L before any other
+                        conversion character (other than d, i, u, o,
+                        x, or X) is ignored.
+
+                      Digital Unix: not specified, but seems to behave
+                      as HPUX does.
+
+                      Solaris: If an h, l, or L appears before any
+                      other conversion specifier (other than d, i, u,
+                      o, x, or X), the behavior is
+                      undefined. (Actually %hp converts only 16-bits
+                      of address and %llp treats address as 64-bit
+                      data which is incompatible with (void *)
+                      argument on a 32-bit system). 
+                    */
+
+                    length_modifier = '\0';
+                    ptr_arg = va_arg(ap, void *);
+                    if (ptr_arg != NULL) arg_sign = 1;
+                } else if (fmt_spec == 'd') {  /* signed */
+                    switch (length_modifier) {
+                    case '\0':
+                    case 'h':
+                        /* It is non-portable to specify a second
+                           argument of char or short to va_arg,
+                           because arguments seen by the called
+                           function are not char or short.  C converts
+                           char and short arguments to int before
+                           passing them to a function.
+                        */
+                        int_arg = va_arg(ap, int);
+                        if      (int_arg > 0) arg_sign =  1;
+                        else if (int_arg < 0) arg_sign = -1;
+                        break;
+                    case 'l':
+                        long_arg = va_arg(ap, long int);
+                        if      (long_arg > 0) arg_sign =  1;
+                        else if (long_arg < 0) arg_sign = -1;
+                        break;
+                    }
+                } else {  /* unsigned */
+                    switch (length_modifier) {
+                    case '\0':
+                    case 'h':
+                        uint_arg = va_arg(ap, unsigned int);
+                        if (uint_arg)
+                            arg_sign = 1;
+                        break;
+                    case 'l':
+                        ulong_arg = va_arg(ap, unsigned long int);
+                        if (ulong_arg)
+                            arg_sign = 1;
+                        break;
+                    }
+                }
+                str_arg = tmp; str_arg_l = 0;
+                /* NOTE: For d, i, u, o, x, and X conversions, if
+                   precision is specified, the '0' flag should be
+                   ignored. This is so with Solaris 2.6, Digital UNIX
+                   4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with
+                   Perl.
+                */
+                if (precision_specified)
+                    zero_padding = 0;
+                if (fmt_spec == 'd') {
+                    if (force_sign && arg_sign >= 0)
+                        tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
+                    /* leave negative numbers for sprintf to handle,
+                       to avoid handling tricky cases like (short
+                       int)(-32768)
+                    */
+                } else if (alternate_form) {
+                    if (arg_sign != 0 && (fmt_spec == 'x' ||
+                                          fmt_spec == 'X')) {
+                        tmp[str_arg_l++] = '0';
+                        tmp[str_arg_l++] = fmt_spec;
+                    }
+                    /* alternate form should have no effect for p
+                       conversion, but ...
+                    */
+                }
+                zero_padding_insertion_ind = str_arg_l;
+                if (!precision_specified)
+                    precision = 1;   /* default precision is 1 */
+                if (precision == 0 && arg_sign == 0) {
+                    /* converted to null string */
+                    /* When zero value is formatted with an explicit
+                       precision 0, the resulting formatted string is
+                       empty (d, i, u, o, x, X, p).
+                    */
+                } else {
+                    char f[5]; int f_l = 0;
+                    f[f_l++] = '%';
+                        /* construct a simple format string for sprintf */
+                    if (!length_modifier) { }
+                    else if (length_modifier=='2') {
+                        f[f_l++] = 'l'; f[f_l++] = 'l';
+                    }
+                    else
+                        f[f_l++] = length_modifier;
+                    f[f_l++] = fmt_spec; f[f_l++] = '\0';
+                    if (fmt_spec == 'p')
+                        str_arg_l += sprintf(tmp+str_arg_l, f, ptr_arg);
+                    else if (fmt_spec == 'd') {  /* signed */
+                        switch (length_modifier) {
+                        case '\0':
+                        case 'h':
+                            str_arg_l+=sprintf(tmp+str_arg_l, f, int_arg);
+                            break;
+                        case 'l':
+                            str_arg_l+=sprintf(tmp+str_arg_l, f, long_arg);
+                            break;
+                        }
+                    } else {  /* unsigned */
+                        switch (length_modifier) {
+                        case '\0':
+                        case 'h':
+                            str_arg_l += sprintf(tmp+str_arg_l, f, uint_arg);
+                            break;
+                        case 'l':
+                            str_arg_l += sprintf(tmp+str_arg_l, f, ulong_arg);
+                            break;
+                        }
+                    }
+                    /* include the optional minus sign and possible "0x"
+                       in the region before the zero padding insertion point
+                    */
+                    if (zero_padding_insertion_ind < str_arg_l &&
+                        tmp[zero_padding_insertion_ind] == '-') {
+                        zero_padding_insertion_ind++;
+                    }
+                    if (zero_padding_insertion_ind+1 < str_arg_l &&
+                        tmp[zero_padding_insertion_ind]   == '0' &&
+                        (tmp[zero_padding_insertion_ind+1] == 'x' ||
+                         tmp[zero_padding_insertion_ind+1] == 'X') ) {
+                        zero_padding_insertion_ind += 2;
+                    }
+                }
+                {
+                    size_t num_of_digits =
+                        str_arg_l - zero_padding_insertion_ind;
+                    if (alternate_form && fmt_spec == 'o'
+                        /* unless zero is already the first character */
+                        && !(zero_padding_insertion_ind < str_arg_l
+                             && tmp[zero_padding_insertion_ind] == '0')) {
+                        /* assure leading zero for alternate-form
+                           octal numbers 
+                        */
+                        if (!precision_specified ||
+                            precision < num_of_digits+1) {
+                            /* precision is increased to force the
+                               first character to be zero, except if a
+                               zero value is formatted with an
+                               explicit precision of zero
+                            */
+                            precision = num_of_digits+1;
+                            precision_specified = 1;
+                        }
+                    }
+                    /* zero padding to specified precision? */
+                    if (num_of_digits < precision) 
+                        number_of_zeros_to_pad = precision - num_of_digits;
+                }
+                /* zero padding to specified minimal field width? */
+                if (!justify_left && zero_padding) {
+                    int n =
+                        min_field_width - (str_arg_l+number_of_zeros_to_pad);
+                    if (n > 0) number_of_zeros_to_pad += n;
+                }
+            } break;
+            default:
+                /* unrecognized conversion specifier, keep format
+                   string as-is
+                */
+                zero_padding = 0;
+                    /* turn zero padding off for non-numeric convers. */
+                /* reset flags */
+                justify_left = 1;
+                min_field_width = 0;
+                /* discard the unrecognized conversion, just keep the
+                   unrecognized conversion character
+                */
+                str_arg = p;
+                str_arg_l = 0;
+                if (*p)
+                    /* include invalid conversion specifier unchanged
+                       if not at end-of-string
+                    */
+                    ++str_arg_l;
+                break;
+            }
+            if (*p)
+                p++;  /* step over the just processed conversion specifier */
+            /* insert padding to the left as requested by
+               min_field_width; this does not include the zero padding
+               in case of numerical conversions
+            */
+
+            if (!justify_left) {
+                /* left padding with blank or zero */
+                int n = min_field_width - (str_arg_l+number_of_zeros_to_pad);
+                if (n > 0) {
+                    if (str_l < str_m) {
+                        size_t avail = str_m-str_l;
+                        fast_memset(str+str_l, (zero_padding ? '0' : ' '),
+                                    (n > avail ? avail : n));
+                    }
+                    str_l += n;
+                }
+            }
+            /* zero padding as requested by the precision or by the
+               minimal field width for numeric conversions required?
+            */
+            if (number_of_zeros_to_pad <= 0) {
+                /* will not copy first part of numeric right now,
+                   force it to be copied later in its entirety
+                */
+                zero_padding_insertion_ind = 0;
+            } else {
+                /* insert first part of numerics (sign or '0x') before
+                   zero padding
+                */
+                int n = zero_padding_insertion_ind;
+                if (n > 0) {
+                    if (str_l < str_m) {
+                        size_t avail = str_m-str_l;
+                        fast_memcpy(str+str_l, str_arg, (n>avail?avail:n));
+                    }
+                    str_l += n;
+                }
+                /* insert zero padding as requested by the precision
+                   or min field width
+                */
+                n = number_of_zeros_to_pad;
+                if (n > 0) {
+                    if (str_l < str_m) {
+                        size_t avail = str_m - str_l;
+                        fast_memset(str + str_l, '0', (n > avail ? avail : n));
+                    }
+                    str_l += n;
+                }
+            }
+            /* insert formatted string (or as-is conversion specifier
+               for unknown conversions)
+            */
+            {
+                int n = str_arg_l - zero_padding_insertion_ind;
+                if (n > 0) {
+                    if (str_l < str_m) {
+                        size_t avail = str_m-str_l;
+                        fast_memcpy(str + str_l,
+                                    str_arg + zero_padding_insertion_ind,
+                                    (n > avail ? avail : n));
+                    }
+                    str_l += n;
+                }
+            }
+            /* insert right padding */
+            if (justify_left) {
+                /* right blank padding to the field width */
+                int n = min_field_width - (str_arg_l+number_of_zeros_to_pad);
+                if (n > 0) {
+                    if (str_l < str_m) {
+                        size_t avail = str_m-str_l;
+                        fast_memset(str+str_l, ' ', (n>avail?avail:n));
+                    }
+                    str_l += n;
+                }
+            }
+        }
+    }
+    if (str_m > 0) {
+        /* make sure the string is null-terminated even at the expense
+           of overwriting the last character (shouldn't happen, but
+           just in case)
+        */
+        str[str_l <= str_m-1 ? str_l : str_m-1] = '\0';
+    }
+    *sizeP = str_l;
+}
+
+
+
+int
+snprintfN(char *       const dest,
+          size_t       const str_m,
+          const char * const fmt,
+          ...) {
+
+    size_t size;
+    va_list ap;
+
+    va_start(ap, fmt);
+    
+    vsnprintfN(dest, str_m, fmt, ap, &size);
+
+    va_end(ap);
+
+    assert(size <= INT_MAX);
+
+    return size;
+}
+
+
+
+/* When a function that is supposed to return a malloc'ed string cannot
+   get the memory for it, it should return 'strsol'.  That has a much
+   better effect on the caller, if the caller doesn't explicitly allow for
+   the out of memory case, than returning NULL.  Note that it is very
+   rare for the system not to have enough memory to return a small string,
+   so it's OK to have somewhat nonsensical behavior when it happens.  We
+   just don't want catastrophic behavior.
+
+   'strsol' is an external symbol, so if Caller wants to detect the
+   out-of-memory failure, he certainly can.
+*/
+const char * const strsol = "NO MEMORY TO CREATE STRING!";
+
+
+
+/* We would like to have vasprintfN(), but it is difficult because you
+   can't run through a va_list twice, which we would want to do: once
+   to measure the length; once actually to build the string.  On some
+   machines, you can simply make two copies of the va_list variable in
+   normal C fashion, but on others you need va_copy, which is a
+   relatively recent invention.  In particular, the simple va_list copy
+   failed on an AMD64 Gcc Linux system in March 2006.
+*/
+
+void PM_GNU_PRINTF_ATTR(2,3)
+asprintfN(const char ** const resultP,
+          const char *  const fmt, 
+          ...) {
+
+    va_list varargs;
+    
+    size_t dryRunLen;
+    
+    va_start(varargs, fmt);
+    
+    vsnprintfN(NULL, 0, fmt, varargs, &dryRunLen);
+
+    va_end(varargs);
+
+    if (dryRunLen + 1 < dryRunLen)
+        /* arithmetic overflow */
+        *resultP = strsol;
+    else {
+        size_t const allocSize = dryRunLen + 1;
+        char * result;
+        result = malloc(allocSize);
+        if (result == NULL)
+            *resultP = strsol;
+        else {
+            va_list varargs;
+            size_t realLen;
+
+            va_start(varargs, fmt);
+
+            vsnprintfN(result, allocSize, fmt, varargs, &realLen);
+                
+            assert(realLen == dryRunLen);
+            va_end(varargs);
+
+            *resultP = result;
+        }
+    }
+}
+
+
+
+void
+strfree(const char * const string) {
+
+    if (string != strsol)
+        free((void *) string);
+}
+
+
+
+const char *
+strsepN(char ** const stringP, const char * const delim) {
+    const char * retval;   
+
+    if (stringP == NULL || *stringP == NULL)
+        retval = NULL;
+    else {
+        char * p;
+
+        retval = *stringP;
+
+        for (p = *stringP; *p && strchr(delim, *p) == NULL; ++p);
+ 
+        if (*p) {
+            /* We hit a delimiter, not end-of-string.  So null out the 
+               delimiter and advance user's pointer to the next token
+            */
+            *p++ = '\0';
+            *stringP = p;
+        } else {
+            /* We ran out of string.  So the end-of-string delimiter is 
+               already there, and we set the user's pointer to NULL to 
+               indicate there are no more tokens.
+            */
+            *stringP = NULL;
+        }
+    }
+    return retval;
+}
+
+
+
+int
+stripeq(const char * const comparand,
+        const char * const comparator) {
+/*----------------------------------------------------------------------------
+  Compare two strings, ignoring leading and trailing white space.
+
+  Return 1 (true) if the strings are identical; 0 (false) otherwise.
+-----------------------------------------------------------------------------*/
+    char *p, *q, *px, *qx;
+    char equal;
+  
+    /* Make p and q point to the first non-blank character in each string.
+     If there are no non-blank characters, make them point to the terminating
+     NULL.
+     */
+
+    p = (char *) comparand;
+    while (ISSPACE(*p)) p++;
+    q = (char *) comparator;
+    while (ISSPACE(*q)) q++;
+
+    /* Make px and qx point to the last non-blank character in each string.
+       If there are no nonblank characters (which implies the string is
+       null), make them point to the terminating NULL.
+    */
+
+    if (*p == '\0') px = p;
+    else {
+        px = p + strlen(p) - 1;
+        while (ISSPACE(*px)) px--;
+    }
+
+    if (*q == '\0') qx = q;
+    else {
+        qx = q + strlen(q) - 1;
+        while (ISSPACE(*qx)) qx--;
+    }
+
+    equal = 1;   /* initial assumption */
+  
+    /* If the stripped strings aren't the same length, 
+       we know they aren't equal 
+     */
+    if (px - p != qx - q) equal = 0;
+
+    else
+    while (p <= px) {
+        if (*p != *q) equal = 0;
+        p++; q++;
+    }
+    return equal;
+}
+
+
+
+const char *
+memmemN(const char * const haystack,
+        size_t       const haystacklen,
+        const char * const needle,
+        size_t       const needlelen) {
+
+    /* This does the same as the function of the same name in the GNU
+       C library
+    */
+    const char * p;
+
+    for (p = haystack; p <= haystack + haystacklen - needlelen; ++p)
+        if (MEMEQ(p, needle, needlelen))
+            return p;
+
+    return NULL;
+}

Copied: brlcad/trunk/src/other/libnetpbm/util/nstring.h (from rev 71848, 
brlcad/trunk/src/other/libnetpbm/util/nstring.h)
===================================================================
--- brlcad/trunk/src/other/libnetpbm/util/nstring.h                             
(rev 0)
+++ brlcad/trunk/src/other/libnetpbm/util/nstring.h     2018-09-26 15:05:11 UTC 
(rev 71850)
@@ -0,0 +1,157 @@
+#ifndef _NSTRING_H
+#define _NSTRING_H
+
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "pm.h"  /* For PM_GNU_PRINTF_ATTR, __inline__ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if 0
+} /* to fake out automatic code indenters */
+#endif
+
+/* Here is are string functions that respect the size of the array
+   into which you are copying -- E.g. STRSCPY truncates the source string as
+   required so that it fits, with the terminating null, in the destination
+   array.
+*/
+#define STRSCPY(A,B) \
+       (strncpy((A), (B), sizeof(A)), *((A)+sizeof(A)-1) = '\0')
+#define STRSCMP(A,B) \
+       (strncmp((A), (B), sizeof(A)))
+#define STRSCAT(A,B) \
+    (strncpy(A+strlen(A), B, sizeof(A)-strlen(A)), *((A)+sizeof(A)-1) = '\0')
+
+#define STREQ(A, B) \
+    (strcmp((A), (B)) == 0)
+#define STRNEQ(A, B, C) \
+    (strncmp((A), (B), (C)) == 0)
+#define STRCASEEQ(A, B) \
+    (strcasecmp((A), (B)) == 0)
+#define STRNCASEEQ(A, B, C) \
+    (strncasecmp((A), (B), (C)) == 0)
+#define STRSEQ(A, B) \
+       (strncmp((A), (B), sizeof(A)) == 0)
+
+#define MEMEQ(A, B, C) \
+    (memcmp((A), (B), (C)) == 0)
+#define MEMSZERO(A) \
+    bzero((A), sizeof(A))
+
+
+static __inline__ int
+streq(const char * const comparand,
+      const char * const comparator) {
+
+    return strcmp(comparand, comparator) == 0;
+}
+
+
+
+/* The standard C library routines isdigit(), for some weird 
+   historical reason, does not take a character (type 'char') as its
+   argument.  Instead it takes an integer.  When the integer is a whole
+   number, it represents a character in the obvious way using the local
+   character set encoding.  When the integer is negative, the results
+   are undefined.
+
+   Passing a character to isdigit(), which expects an integer, results in
+   isdigit() sometimes getting a negative number.
+
+   On some systems, when the integer is negative, it represents exactly
+   the character you want it to anyway (e.g. -1 is the character that is
+   encoded 0xFF).  But on others, it does not.
+
+   (The same is true of other routines like isdigit()).
+
+   Therefore, we have the substitutes for isdigit() etc. that take an
+   actual character (type 'char') as an argument.
+*/
+
+#define ISALNUM(C) (isalnum((unsigned char)(C)))
+#define ISALPHA(C) (isalpha((unsigned char)(C)))
+#define ISCNTRL(C) (iscntrl((unsigned char)(C)))
+#define ISDIGIT(C) (isdigit((unsigned char)(C)))
+#define ISGRAPH(C) (isgraph((unsigned char)(C)))
+#define ISLOWER(C) (islower((unsigned char)(C)))
+#define ISPRINT(C) (isprint((unsigned char)(C)))
+#define ISPUNCT(C) (ispunct((unsigned char)(C)))
+#define ISSPACE(C) (isspace((unsigned char)(C)))
+#define ISUPPER(C) (isupper((unsigned char)(C)))
+#define ISXDIGIT(C) (isxdigit((unsigned char)(C)))
+#define TOUPPER(C) ((char)toupper((unsigned char)(C)))
+
+
+/* These are all private versions of commonly available standard C
+   library subroutines whose names are the same except with the N at
+   the end.  Because not all standard C libraries have them all,
+   Netpbm must include them in its own libraries, and because some
+   standard C libraries have some of them, Netpbm must use different
+   names for them.
+   
+   The GNU C library has all of them.  All but the oldest standard C libraries
+   have snprintf().
+
+   There are slight differences between the asprintf() family and that
+   found in other libraries:
+
+     - There is no return value.
+
+     - The returned string is a const char * instead of a char *.  The
+       const is more correct.
+
+     - If the function can't get the memory, it returns 'strsol',
+       which is a string that is in static memory that contains text
+       indicating an out of memory failure has occurred, intead of
+       NULL.  This makes it much easier for programs to ignore this
+       possibility.
+
+   strfree() is strictly a Netpbm invention, to allow proper type checking
+   when freeing storage allocated by the Netpbm asprintfN().
+*/
+
+extern const char * const strsol;
+
+int
+snprintfN(char *       const dest,
+          size_t       const str_m,
+          const char * const fmt,
+          ...) PM_GNU_PRINTF_ATTR(3,4);
+
+void
+vsnprintfN(char *       const str,
+           size_t       const str_m,
+           const char * const fmt,
+           va_list            ap,
+           size_t *     const sizeP);
+
+void
+asprintfN(const char ** const resultP,
+          const char *  const fmt,
+          ...) PM_GNU_PRINTF_ATTR(2,3);
+
+void 
+strfree(const char * const string);
+
+const char *
+strsepN(char ** const stringP, const char * const delim);
+
+int
+stripeq(const char * const comparand,
+        const char * const comparator);
+
+const char *
+memmemN(const char * const haystack,
+        size_t       const haystacklen,
+        const char * const needle,
+        size_t       const needlelen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

Copied: brlcad/trunk/src/other/libnetpbm/util/testnstring.c (from rev 71848, 
brlcad/trunk/src/other/libnetpbm/util/testnstring.c)
===================================================================
--- brlcad/trunk/src/other/libnetpbm/util/testnstring.c                         
(rev 0)
+++ brlcad/trunk/src/other/libnetpbm/util/testnstring.c 2018-09-26 15:05:11 UTC 
(rev 71850)
@@ -0,0 +1,30 @@
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "nstring.h"
+
+#define true (1)
+#define false (0)
+
+int
+main(int argc, char **argv) {
+
+    char snprintfNResult[80];
+    const char * asprintfNResult; 
+
+    printf("Hello world.\n");
+
+    snprintfN(snprintfNResult, 19, "snprintfN test truncated");
+
+    printf("snprintfN result='%s'\n", snprintfNResult);
+
+    asprintfN(&asprintfNResult, "asprintf'ed string %d %u %s", 
+              5, 89, "substring");
+
+    printf("asprintfN result='%s'\n", asprintfNResult);
+
+    strfree(asprintfNResult);
+    return 0;
+}

Modified: brlcad/trunk/src/other/libnetpbm.dist
===================================================================
--- brlcad/trunk/src/other/libnetpbm.dist       2018-09-26 15:01:47 UTC (rev 
71849)
+++ brlcad/trunk/src/other/libnetpbm.dist       2018-09-26 15:05:11 UTC (rev 
71850)
@@ -1,6 +1,7 @@
 set(libnetpbm_ignore_files
 CMakeLists.txt
 README
+TODO
 bitio.c
 bitio.h
 colorname.c
@@ -63,7 +64,11 @@
 util/bitreverse.h
 util/intcode.h
 util/mallocvar.h
+util/nstring.c
+util/nstring.h
+util/LICENSE_nstring.txt
 util/pm_c_util.h
 util/ppmdcfont.c
+util/testnstring.c
 version.h.in
 )

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
BRL-CAD Source Commits mailing list
brlcad-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to