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