mirror of
git://git.gnupg.org/gnupg.git
synced 2025-05-14 08:13:25 +02:00
Add new function strconcat.
* include/util.h (GNUPG_GCC_A_SENTINEL): New. * util/strgutil.c (do_strconcat, strconcat): New. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
2e7a3ed390
commit
484d073058
@ -28,6 +28,14 @@
|
|||||||
#include "mpi.h"
|
#include "mpi.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
|
||||||
|
/* GCC attributes. */
|
||||||
|
#if __GNUC__ >= 4
|
||||||
|
# define GNUPG_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a)))
|
||||||
|
#else
|
||||||
|
# define GNUPG_GCC_A_SENTINEL(a)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int *argc; /* pointer to argc (value subject to change) */
|
int *argc; /* pointer to argc (value subject to change) */
|
||||||
char ***argv; /* pointer to argv (value subject to change) */
|
char ***argv; /* pointer to argv (value subject to change) */
|
||||||
@ -177,6 +185,8 @@ unsigned int check_trailing_chars( const byte *line, unsigned int len,
|
|||||||
const char *trimchars );
|
const char *trimchars );
|
||||||
unsigned int check_trailing_ws( const byte *line, unsigned int len );
|
unsigned int check_trailing_ws( const byte *line, unsigned int len );
|
||||||
int string_count_chr( const char *string, int c );
|
int string_count_chr( const char *string, int c );
|
||||||
|
int has_invalid_email_chars (const char *s);
|
||||||
|
int is_valid_mailbox (const char *name);
|
||||||
int set_native_charset( const char *newset );
|
int set_native_charset( const char *newset );
|
||||||
const char* get_native_charset(void);
|
const char* get_native_charset(void);
|
||||||
char *native_to_utf8( const char *string );
|
char *native_to_utf8( const char *string );
|
||||||
@ -238,7 +248,7 @@ int write_w32_registry_string(const char *root, const char *dir,
|
|||||||
char *xasprintf (const char *fmt, ...);
|
char *xasprintf (const char *fmt, ...);
|
||||||
char *xtryasprintf (const char *fmt, ...);
|
char *xtryasprintf (const char *fmt, ...);
|
||||||
char *xtryvasprintf (const char *fmt, va_list arg_ptr);
|
char *xtryvasprintf (const char *fmt, va_list arg_ptr);
|
||||||
|
char *strconcat (const char *s1, ...) GNUPG_GCC_A_SENTINEL(0);
|
||||||
|
|
||||||
/*-- pka.c --*/
|
/*-- pka.c --*/
|
||||||
char *get_pka_info (const char *address, unsigned char *fpr);
|
char *get_pka_info (const char *address, unsigned char *fpr);
|
||||||
|
105
util/strgutil.c
105
util/strgutil.c
@ -112,7 +112,7 @@ static int use_iconv = 0;
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
typedef void* iconv_t;
|
typedef void* iconv_t;
|
||||||
#ifndef ICONV_CONST
|
#ifndef ICONV_CONST
|
||||||
#define ICONV_CONST const
|
#define ICONV_CONST const
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
iconv_t (* __stdcall iconv_open) (const char *tocode, const char *fromcode);
|
iconv_t (* __stdcall iconv_open) (const char *tocode, const char *fromcode);
|
||||||
@ -126,25 +126,25 @@ int (* __stdcall iconv_close) (iconv_t cd);
|
|||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static int
|
static int
|
||||||
load_libiconv (void)
|
load_libiconv (void)
|
||||||
{
|
{
|
||||||
static int done;
|
static int done;
|
||||||
|
|
||||||
if (!done)
|
if (!done)
|
||||||
{
|
{
|
||||||
void *handle;
|
void *handle;
|
||||||
|
|
||||||
done = 1; /* Do it right now because we might get called recursivly
|
done = 1; /* Do it right now because we might get called recursivly
|
||||||
through gettext. */
|
through gettext. */
|
||||||
|
|
||||||
handle = dlopen ("iconv.dll", RTLD_LAZY);
|
handle = dlopen ("iconv.dll", RTLD_LAZY);
|
||||||
if (handle)
|
if (handle)
|
||||||
{
|
{
|
||||||
iconv_open = dlsym (handle, "libiconv_open");
|
iconv_open = dlsym (handle, "libiconv_open");
|
||||||
if (iconv_open)
|
if (iconv_open)
|
||||||
iconv = dlsym (handle, "libiconv");
|
iconv = dlsym (handle, "libiconv");
|
||||||
if (iconv)
|
if (iconv)
|
||||||
iconv_close = dlsym (handle, "libiconv_close");
|
iconv_close = dlsym (handle, "libiconv_close");
|
||||||
}
|
}
|
||||||
if (!handle || !iconv_close)
|
if (!handle || !iconv_close)
|
||||||
@ -161,7 +161,7 @@ load_libiconv (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return iconv_open? 0: -1;
|
return iconv_open? 0: -1;
|
||||||
}
|
}
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
|
||||||
@ -625,7 +625,7 @@ set_native_charset( const char *newset )
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (load_libiconv ())
|
if (load_libiconv ())
|
||||||
return G10ERR_GENERAL;
|
return G10ERR_GENERAL;
|
||||||
#endif /*_WIN32*/
|
#endif /*_WIN32*/
|
||||||
|
|
||||||
cd = iconv_open (full_newset, "utf-8");
|
cd = iconv_open (full_newset, "utf-8");
|
||||||
if (cd == (iconv_t)-1) {
|
if (cd == (iconv_t)-1) {
|
||||||
@ -641,7 +641,7 @@ set_native_charset( const char *newset )
|
|||||||
iconv_close (cd);
|
iconv_close (cd);
|
||||||
active_charset_name = full_newset;
|
active_charset_name = full_newset;
|
||||||
no_translation = 0;
|
no_translation = 0;
|
||||||
active_charset = NULL;
|
active_charset = NULL;
|
||||||
use_iconv = 1;
|
use_iconv = 1;
|
||||||
}
|
}
|
||||||
#else /*!USE_GNUPG_ICONV*/
|
#else /*!USE_GNUPG_ICONV*/
|
||||||
@ -680,15 +680,15 @@ native_to_utf8( const char *string )
|
|||||||
char *buffer;
|
char *buffer;
|
||||||
byte *p;
|
byte *p;
|
||||||
size_t length=0;
|
size_t length=0;
|
||||||
|
|
||||||
if (no_translation)
|
if (no_translation)
|
||||||
{ /* Already utf-8 encoded. */
|
{ /* Already utf-8 encoded. */
|
||||||
buffer = xstrdup (string);
|
buffer = xstrdup (string);
|
||||||
}
|
}
|
||||||
else if( !active_charset && !use_iconv) /* Shortcut implementation
|
else if( !active_charset && !use_iconv) /* Shortcut implementation
|
||||||
for Latin-1. */
|
for Latin-1. */
|
||||||
{
|
{
|
||||||
for(s=string; *s; s++ )
|
for(s=string; *s; s++ )
|
||||||
{
|
{
|
||||||
length++;
|
length++;
|
||||||
if( *s & 0x80 )
|
if( *s & 0x80 )
|
||||||
@ -708,13 +708,13 @@ native_to_utf8( const char *string )
|
|||||||
*p = 0;
|
*p = 0;
|
||||||
}
|
}
|
||||||
else /* Need to use a translation table. */
|
else /* Need to use a translation table. */
|
||||||
{
|
{
|
||||||
#ifdef USE_GNUPG_ICONV
|
#ifdef USE_GNUPG_ICONV
|
||||||
iconv_t cd;
|
iconv_t cd;
|
||||||
const char *inptr;
|
const char *inptr;
|
||||||
char *outptr;
|
char *outptr;
|
||||||
size_t inbytes, outbytes;
|
size_t inbytes, outbytes;
|
||||||
|
|
||||||
cd = iconv_open ("utf-8", active_charset_name);
|
cd = iconv_open ("utf-8", active_charset_name);
|
||||||
if (cd == (iconv_t)-1)
|
if (cd == (iconv_t)-1)
|
||||||
{
|
{
|
||||||
@ -722,7 +722,7 @@ native_to_utf8( const char *string )
|
|||||||
return native_to_utf8 (string);
|
return native_to_utf8 (string);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s=string; *s; s++ )
|
for (s=string; *s; s++ )
|
||||||
{
|
{
|
||||||
length++;
|
length++;
|
||||||
if ((*s & 0x80))
|
if ((*s & 0x80))
|
||||||
@ -756,7 +756,7 @@ native_to_utf8( const char *string )
|
|||||||
iconv_close (cd);
|
iconv_close (cd);
|
||||||
|
|
||||||
#else /*!USE_GNUPG_ICONV*/
|
#else /*!USE_GNUPG_ICONV*/
|
||||||
for(s=string; *s; s++ )
|
for(s=string; *s; s++ )
|
||||||
{
|
{
|
||||||
length++;
|
length++;
|
||||||
if( *s & 0x80 )
|
if( *s & 0x80 )
|
||||||
@ -791,7 +791,7 @@ native_to_utf8( const char *string )
|
|||||||
* Convert string, which is in UTF8 to native encoding. illegal
|
* Convert string, which is in UTF8 to native encoding. illegal
|
||||||
* encodings by some "\xnn" and quote all control characters. A
|
* encodings by some "\xnn" and quote all control characters. A
|
||||||
* character with value DELIM will always be quoted, it must be a
|
* character with value DELIM will always be quoted, it must be a
|
||||||
* vanilla ASCII character. A DELIM value of -1 is special: it disables
|
* vanilla ASCII character. A DELIM value of -1 is special: it disables
|
||||||
* all quoting of control characters.
|
* all quoting of control characters.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
@ -826,7 +826,7 @@ utf8_to_native( const char *string, size_t length, int delim )
|
|||||||
}
|
}
|
||||||
if( !nleft ) {
|
if( !nleft ) {
|
||||||
if( !(*s & 0x80) ) { /* plain ascii */
|
if( !(*s & 0x80) ) { /* plain ascii */
|
||||||
if( delim != -1
|
if( delim != -1
|
||||||
&& (*s < 0x20 || *s == 0x7f || *s == delim
|
&& (*s < 0x20 || *s == 0x7f || *s == delim
|
||||||
|| (delim && *s=='\\'))) {
|
|| (delim && *s=='\\'))) {
|
||||||
n++;
|
n++;
|
||||||
@ -993,7 +993,7 @@ utf8_to_native( const char *string, size_t length, int delim )
|
|||||||
const char *inptr;
|
const char *inptr;
|
||||||
char *outbuf, *outptr;
|
char *outbuf, *outptr;
|
||||||
size_t inbytes, outbytes;
|
size_t inbytes, outbytes;
|
||||||
|
|
||||||
*p = 0; /* Terminate the buffer. */
|
*p = 0; /* Terminate the buffer. */
|
||||||
|
|
||||||
cd = iconv_open (active_charset_name, "utf-8");
|
cd = iconv_open (active_charset_name, "utf-8");
|
||||||
@ -1010,13 +1010,13 @@ utf8_to_native( const char *string, size_t length, int delim )
|
|||||||
inbytes = n - 1;;
|
inbytes = n - 1;;
|
||||||
inptr = buffer;
|
inptr = buffer;
|
||||||
outbytes = n * MB_LEN_MAX;
|
outbytes = n * MB_LEN_MAX;
|
||||||
if (outbytes / MB_LEN_MAX != n)
|
if (outbytes / MB_LEN_MAX != n)
|
||||||
BUG (); /* Actually an overflow. */
|
BUG (); /* Actually an overflow. */
|
||||||
outbuf = outptr = xmalloc (outbytes);
|
outbuf = outptr = xmalloc (outbytes);
|
||||||
if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes,
|
if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes,
|
||||||
&outptr, &outbytes) == (size_t)-1) {
|
&outptr, &outbytes) == (size_t)-1) {
|
||||||
static int shown;
|
static int shown;
|
||||||
|
|
||||||
if (!shown)
|
if (!shown)
|
||||||
log_info (_("conversion from `%s' to `%s' failed: %s\n"),
|
log_info (_("conversion from `%s' to `%s' failed: %s\n"),
|
||||||
"utf-8", active_charset_name, strerror (errno));
|
"utf-8", active_charset_name, strerror (errno));
|
||||||
@ -1057,10 +1057,10 @@ char *
|
|||||||
string_to_utf8 (const char *string)
|
string_to_utf8 (const char *string)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
if (!string)
|
if (!string)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Due to a bug in old and not so old PGP versions user IDs have
|
/* Due to a bug in old and not so old PGP versions user IDs have
|
||||||
been copied verbatim into the key. Thus many users with Umlauts
|
been copied verbatim into the key. Thus many users with Umlauts
|
||||||
et al. in their name will see their names garbled. Although this
|
et al. in their name will see their names garbled. Although this
|
||||||
@ -1076,7 +1076,7 @@ string_to_utf8 (const char *string)
|
|||||||
|| ((*s & 0xf8) == 0xf0)
|
|| ((*s & 0xf8) == 0xf0)
|
||||||
|| ((*s & 0xfc) == 0xf8)
|
|| ((*s & 0xfc) == 0xf8)
|
||||||
|| ((*s & 0xfe) == 0xfc)) )
|
|| ((*s & 0xfe) == 0xfc)) )
|
||||||
{
|
{
|
||||||
/* Possible utf-8 character followed by continuation byte.
|
/* Possible utf-8 character followed by continuation byte.
|
||||||
Although this might still be Latin-1 we better assume that it
|
Although this might still be Latin-1 we better assume that it
|
||||||
is valid utf-8. */
|
is valid utf-8. */
|
||||||
@ -1089,7 +1089,7 @@ string_to_utf8 (const char *string)
|
|||||||
|
|
||||||
/* No 0xC3 character in the string; assume that it is Latin-1. */
|
/* No 0xC3 character in the string; assume that it is Latin-1. */
|
||||||
|
|
||||||
for(s=string; *s; s++ )
|
for(s=string; *s; s++ )
|
||||||
{
|
{
|
||||||
length++;
|
length++;
|
||||||
if( *s & 0x80 )
|
if( *s & 0x80 )
|
||||||
@ -1166,6 +1166,59 @@ xtryvasprintf (const char *fmt, va_list arg_ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
do_strconcat (const char *s1, va_list arg_ptr)
|
||||||
|
{
|
||||||
|
const char *argv[48];
|
||||||
|
size_t argc;
|
||||||
|
size_t needed;
|
||||||
|
char *buffer, *p;
|
||||||
|
|
||||||
|
argc = 0;
|
||||||
|
argv[argc++] = s1;
|
||||||
|
needed = strlen (s1);
|
||||||
|
while (((argv[argc] = va_arg (arg_ptr, const char *))))
|
||||||
|
{
|
||||||
|
needed += strlen (argv[argc]);
|
||||||
|
if (argc >= DIM (argv)-1)
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
argc++;
|
||||||
|
}
|
||||||
|
needed++;
|
||||||
|
buffer = xtrymalloc (needed);
|
||||||
|
if (buffer)
|
||||||
|
{
|
||||||
|
for (p = buffer, argc=0; argv[argc]; argc++)
|
||||||
|
p = stpcpy (p, argv[argc]);
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Concatenate the string S1 with all the following strings up to a
|
||||||
|
NULL. Returns a malloced buffer with the new string or NULL on a
|
||||||
|
malloc error or if too many arguments are given. */
|
||||||
|
char *
|
||||||
|
strconcat (const char *s1, ...)
|
||||||
|
{
|
||||||
|
va_list arg_ptr;
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
if (!s1)
|
||||||
|
result = xtrystrdup ("");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
va_start (arg_ptr, s1);
|
||||||
|
result = do_strconcat (s1, arg_ptr);
|
||||||
|
va_end (arg_ptr);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************
|
/****************************************************
|
||||||
******** locale insensitive ctype functions ********
|
******** locale insensitive ctype functions ********
|
||||||
****************************************************/
|
****************************************************/
|
||||||
@ -1258,13 +1311,13 @@ w32_strerror (int w32_errno)
|
|||||||
{
|
{
|
||||||
static char strerr[256];
|
static char strerr[256];
|
||||||
int ec = (int)GetLastError ();
|
int ec = (int)GetLastError ();
|
||||||
|
|
||||||
if (w32_errno == 0)
|
if (w32_errno == 0)
|
||||||
w32_errno = ec;
|
w32_errno = ec;
|
||||||
FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, w32_errno,
|
FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, w32_errno,
|
||||||
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
|
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
strerr, DIM (strerr)-1, NULL);
|
strerr, DIM (strerr)-1, NULL);
|
||||||
return strerr;
|
return strerr;
|
||||||
}
|
}
|
||||||
#endif /*_WIN32*/
|
#endif /*_WIN32*/
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user