diff --git a/common/Makefile.am b/common/Makefile.am
index f84cea17b..678e1a269 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -1,209 +1,211 @@
# Makefile for common gnupg modules
# Copyright (C) 2001, 2003, 2007, 2010 Free Software Foundation, Inc.
#
# This file is part of GnuPG.
#
# GnuPG is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GnuPG 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
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see .
## Process this file with automake to produce Makefile.in
EXTRA_DIST = mkstrtable.awk exaudit.awk exstatus.awk ChangeLog-2011 \
audit-events.h status-codes.h ChangeLog.jnlib \
ChangeLog-2011.include w32info-rc.h.in gnupg.ico
noinst_LIBRARIES = libcommon.a libcommonpth.a libgpgrl.a
if !HAVE_W32CE_SYSTEM
noinst_LIBRARIES += libsimple-pwquery.a
endif
noinst_PROGRAMS = $(module_tests) $(module_maint_tests)
TESTS = $(module_tests)
BUILT_SOURCES = audit-events.h status-codes.h
MAINTAINERCLEANFILES = audit-events.h status-codes.h
AM_CPPFLAGS =
AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(KSBA_CFLAGS)
include $(top_srcdir)/am/cmacros.am
common_sources = \
common-defs.h \
util.h i18n.c i18n.h \
types.h host2net.h dynload.h w32help.h \
mapstrings.c stringhelp.c stringhelp.h \
strlist.c strlist.h \
utf8conv.c utf8conv.h \
argparse.c argparse.h \
logging.c logging.h \
dotlock.c dotlock.h \
mischelp.c mischelp.h \
status.c status.h\
shareddefs.h \
openpgpdefs.h \
gc-opt-flags.h \
keyserver.h \
sexp-parse.h \
tlv.c tlv.h \
init.c init.h \
sexputil.c \
sysutils.c sysutils.h \
homedir.c \
gettime.c gettime.h \
yesno.c \
b64enc.c b64dec.c zb32.c zb32.h \
convert.c \
percent.c \
mbox-util.c mbox-util.h \
miscellaneous.c \
xasprintf.c \
xreadline.c \
membuf.c membuf.h \
iobuf.c iobuf.h \
ttyio.c ttyio.h \
asshelp.c asshelp2.c asshelp.h \
exechelp.h \
signal.c \
audit.c audit.h \
localename.c \
session-env.c session-env.h \
userids.c userids.h \
openpgp-oid.c \
ssh-utils.c ssh-utils.h \
agent-opt.c \
helpfile.c \
- mkdir_p.c mkdir_p.h
+ mkdir_p.c mkdir_p.h \
+ strlist.c strlist.h
if HAVE_W32_SYSTEM
common_sources += w32-reg.c w32-afunix.c w32-afunix.h
endif
# To make the code easier to read we have split home some code into
# separate source files.
if HAVE_W32_SYSTEM
if HAVE_W32CE_SYSTEM
common_sources += exechelp-w32ce.c
else
common_sources += exechelp-w32.c
endif
else
common_sources += exechelp-posix.c
endif
# Sources only useful without NPTH.
without_npth_sources = \
get-passphrase.c get-passphrase.h
libcommon_a_SOURCES = $(common_sources) $(without_npth_sources)
libcommon_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) -DWITHOUT_NPTH=1
libcommonpth_a_SOURCES = $(common_sources)
libcommonpth_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS)
if !HAVE_W32CE_SYSTEM
libsimple_pwquery_a_SOURCES = \
simple-pwquery.c simple-pwquery.h asshelp.c asshelp.h
libsimple_pwquery_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS)
endif
libgpgrl_a_SOURCES = \
gpgrlhelp.c
if MAINTAINER_MODE
# Note: Due to the dependency on Makefile, the file will always be
# rebuilt, so we allow this only in maintainer mode.
# Create the audit-events.h include file from audit.h
# Note: We create the target file in the source directory because it
# is a distributed built source. If we would not do that we may end
# up with two files and then it is not clear which version of the
# files will be picked up.
audit-events.h: Makefile.am mkstrtable.awk exaudit.awk audit.h
$(AWK) -f $(srcdir)/exaudit.awk $(srcdir)/audit.h \
| $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 -v nogettext=1 \
-v namespace=eventstr_ > $(srcdir)/audit-events.h
# Create the status-codes.h include file from status.h
status-codes.h: Makefile.am mkstrtable.awk exstatus.awk status.h
$(AWK) -f $(srcdir)/exstatus.awk $(srcdir)/status.h \
| $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 -v nogettext=1 \
-v namespace=statusstr_ > $(srcdir)/status-codes.h
endif
#
# Module tests
#
module_tests = t-stringhelp t-timestuff \
t-convert t-percent t-gettime t-sysutils t-sexputil \
t-session-env t-openpgp-oid t-ssh-utils \
- t-mapstrings t-zb32 t-mbox-util t-iobuf
+ t-mapstrings t-zb32 t-mbox-util t-iobuf t-strlist
if !HAVE_W32CE_SYSTEM
module_tests += t-exechelp
endif
if HAVE_W32_SYSTEM
module_tests += t-w32-reg
endif
if MAINTAINER_MODE
module_maint_tests = t-helpfile t-b64
else
module_maint_tests =
endif
t_extra_src = t-support.h
t_common_cflags = $(KSBA_CFLAGS) $(LIBGCRYPT_CFLAGS) \
$(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS)
t_common_ldadd = libcommon.a \
$(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
$(LIBINTL) $(LIBICONV)
# Common tests
t_stringhelp_SOURCES = t-stringhelp.c $(t_extra_src)
t_stringhelp_LDADD = $(t_common_ldadd)
t_timestuff_SOURCES = t-timestuff.c $(t_extra_src)
t_timestuff_LDADD = $(t_common_ldadd)
t_convert_LDADD = $(t_common_ldadd)
t_percent_LDADD = $(t_common_ldadd)
t_gettime_LDADD = $(t_common_ldadd)
t_sysutils_LDADD = $(t_common_ldadd)
t_helpfile_LDADD = $(t_common_ldadd)
t_sexputil_LDADD = $(t_common_ldadd)
t_b64_LDADD = $(t_common_ldadd)
t_exechelp_LDADD = $(t_common_ldadd)
t_session_env_LDADD = $(t_common_ldadd)
t_openpgp_oid_LDADD = $(t_common_ldadd)
t_ssh_utils_LDADD = $(t_common_ldadd)
t_mapstrings_LDADD = $(t_common_ldadd)
t_zb32_SOURCES = t-zb32.c $(t_extra_src)
t_zb32_LDADD = $(t_common_ldadd)
t_mbox_util_LDADD = $(t_common_ldadd)
t_iobuf_LDADD = $(t_common_ldadd)
+t_strlist_LDADD = $(t_common_ldadd)
# System specific test
if HAVE_W32_SYSTEM
t_w32_reg_SOURCES = t-w32-reg.c $(t_extra_src)
t_w32_reg_LDADD = $(t_common_ldadd)
endif
# All programs should depend on the created libs.
$(PROGRAMS) : libcommon.a libcommonpth.a
diff --git a/common/strlist.c b/common/strlist.c
index 9bd6195f9..760a46040 100644
--- a/common/strlist.c
+++ b/common/strlist.c
@@ -1,233 +1,252 @@
/* strlist.c - string helpers
* Copyright (C) 1998, 2000, 2001, 2006 Free Software Foundation, Inc.
* Copyright (C) 2015 g10 Code GmbH
*
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify it
* under the terms of either
*
* - the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at
* your option) any later version.
*
* or
*
* - the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* or both in parallel, as here.
*
* GnuPG 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 GNU
* General Public License for more details.
*
* You should have received a copies of the GNU General Public License
* and the GNU Lesser General Public License along with this program;
* if not, see .
*/
#include
#include
#include
#include
#include
#include "util.h"
#include "common-defs.h"
#include "strlist.h"
#include "utf8conv.h"
void
free_strlist( strlist_t sl )
{
strlist_t sl2;
for(; sl; sl = sl2 ) {
sl2 = sl->next;
xfree(sl);
}
}
/* Add STRING to the LIST at the front. This function terminates the
process on memory shortage. */
strlist_t
add_to_strlist( strlist_t *list, const char *string )
{
strlist_t sl;
sl = xmalloc( sizeof *sl + strlen(string));
sl->flags = 0;
strcpy(sl->d, string);
sl->next = *list;
*list = sl;
return sl;
}
/* Add STRING to the LIST at the front. This function returns NULL
and sets ERRNO on memory shortage. */
strlist_t
add_to_strlist_try (strlist_t *list, const char *string)
{
strlist_t sl;
sl = xtrymalloc (sizeof *sl + strlen (string));
if (sl)
{
sl->flags = 0;
strcpy (sl->d, string);
sl->next = *list;
*list = sl;
}
return sl;
}
/* Same as add_to_strlist() but if IS_UTF8 is *not* set, a conversion
to UTF-8 is done. This function terminates the process on memory
shortage. */
strlist_t
add_to_strlist2( strlist_t *list, const char *string, int is_utf8 )
{
strlist_t sl;
if (is_utf8)
sl = add_to_strlist( list, string );
else
{
char *p = native_to_utf8( string );
sl = add_to_strlist( list, p );
xfree ( p );
}
return sl;
}
/* Add STRING to the LIST at the end. This function terminates the
process on memory shortage. */
strlist_t
append_to_strlist( strlist_t *list, const char *string )
{
strlist_t r, sl;
sl = xmalloc( sizeof *sl + strlen(string));
sl->flags = 0;
strcpy(sl->d, string);
sl->next = NULL;
if( !*list )
*list = sl;
else {
for( r = *list; r->next; r = r->next )
;
r->next = sl;
}
return sl;
}
strlist_t
append_to_strlist2( strlist_t *list, const char *string, int is_utf8 )
{
strlist_t sl;
if( is_utf8 )
sl = append_to_strlist( list, string );
else
{
char *p = native_to_utf8 (string);
sl = append_to_strlist( list, p );
xfree( p );
}
return sl;
}
/* Return a copy of LIST. This function terminates the process on
memory shortage.*/
strlist_t
strlist_copy (strlist_t list)
{
strlist_t newlist = NULL, sl, *last;
last = &newlist;
for (; list; list = list->next)
{
sl = xmalloc (sizeof *sl + strlen (list->d));
sl->flags = list->flags;
strcpy(sl->d, list->d);
sl->next = NULL;
*last = sl;
last = &sl;
}
return newlist;
}
strlist_t
strlist_prev( strlist_t head, strlist_t node )
{
strlist_t n;
for(n=NULL; head && head != node; head = head->next )
n = head;
return n;
}
strlist_t
strlist_last( strlist_t node )
{
if( node )
for( ; node->next ; node = node->next )
;
return node;
}
/* Remove the first item from LIST and return its content in an
allocated buffer. This function terminates the process on memory
shortage. */
char *
strlist_pop (strlist_t *list)
{
char *str=NULL;
strlist_t sl=*list;
if(sl)
{
str = xmalloc(strlen(sl->d)+1);
strcpy(str,sl->d);
*list=sl->next;
xfree(sl);
}
return str;
}
/* Return the first element of the string list HAYSTACK whose string
matches NEEDLE. If no elements match, return NULL. */
strlist_t
strlist_find (strlist_t haystack, const char *needle)
{
for (;
haystack;
haystack = haystack->next)
if (strcmp (haystack->d, needle) == 0)
return haystack;
return NULL;
}
int
strlist_length (strlist_t list)
{
int i;
for (i = 0; list; list = list->next)
i ++;
return i;
}
+
+/* Reverse the list *LIST in place. */
+strlist_t
+strlist_rev (strlist_t *list)
+{
+ strlist_t l = *list;
+ strlist_t lrev = NULL;
+
+ while (l)
+ {
+ strlist_t tail = l->next;
+ l->next = lrev;
+ lrev = l;
+ l = tail;
+ }
+
+ *list = lrev;
+ return lrev;
+}
diff --git a/common/strlist.h b/common/strlist.h
index fccce8704..acb92f700 100644
--- a/common/strlist.h
+++ b/common/strlist.h
@@ -1,65 +1,66 @@
/* strlist.h
* Copyright (C) 1998, 2000, 2001, 2006 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify it
* under the terms of either
*
* - the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at
* your option) any later version.
*
* or
*
* - the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* or both in parallel, as here.
*
* GnuPG 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 GNU
* General Public License for more details.
*
* You should have received a copies of the GNU General Public License
* and the GNU Lesser General Public License along with this program;
* if not, see .
*/
#ifndef GNUPG_COMMON_STRLIST_H
#define GNUPG_COMMON_STRLIST_H
struct string_list
{
struct string_list *next;
unsigned int flags;
char d[1];
};
typedef struct string_list *strlist_t;
void free_strlist (strlist_t sl);
strlist_t add_to_strlist (strlist_t *list, const char *string);
strlist_t add_to_strlist_try (strlist_t *list, const char *string);
strlist_t add_to_strlist2( strlist_t *list, const char *string, int is_utf8);
strlist_t append_to_strlist (strlist_t *list, const char *string);
strlist_t append_to_strlist2 (strlist_t *list, const char *string,
int is_utf8);
strlist_t strlist_copy (strlist_t list);
strlist_t strlist_prev (strlist_t head, strlist_t node);
strlist_t strlist_last (strlist_t node);
char * strlist_pop (strlist_t *list);
strlist_t strlist_find (strlist_t haystack, const char *needle);
int strlist_length (strlist_t list);
+strlist_t strlist_rev (strlist_t *haystack);
#define FREE_STRLIST(a) do { free_strlist((a)); (a) = NULL ; } while(0)
#endif /*GNUPG_COMMON_STRLIST_H*/
diff --git a/common/t-strlist.c b/common/t-strlist.c
new file mode 100644
index 000000000..b03390593
--- /dev/null
+++ b/common/t-strlist.c
@@ -0,0 +1,82 @@
+/* t-strlist.c - Regression tests for strist.c
+ * Copyright (C) 2015 g10 Code GmbH
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify it
+ * under the terms of either
+ *
+ * - the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * or
+ *
+ * - the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * or both in parallel, as here.
+ *
+ * GnuPG 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 GNU
+ * General Public License for more details.
+ *
+ * You should have received a copies of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, see .
+ */
+
+#include
+#include
+
+#include "strlist.h"
+
+#include "t-support.h"
+
+static void
+test_strlist_rev (void)
+{
+ strlist_t s = NULL;
+
+ /* Reversing an empty list should yield the empty list. */
+ if (! (strlist_rev (&s) == NULL))
+ fail (1);
+
+ add_to_strlist (&s, "1");
+ add_to_strlist (&s, "2");
+ add_to_strlist (&s, "3");
+
+ if (strcmp (s->d, "3") != 0)
+ fail (2);
+ if (strcmp (s->next->d, "2") != 0)
+ fail (2);
+ if (strcmp (s->next->next->d, "1") != 0)
+ fail (2);
+ if (s->next->next->next)
+ fail (2);
+
+ strlist_rev (&s);
+
+ if (strcmp (s->d, "1") != 0)
+ fail (2);
+ if (strcmp (s->next->d, "2") != 0)
+ fail (2);
+ if (strcmp (s->next->next->d, "3") != 0)
+ fail (2);
+ if (s->next->next->next)
+ fail (2);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ (void)argc;
+ (void)argv;
+
+ test_strlist_rev ();
+
+ return 0;
+}