From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Paul Eggert Newsgroups: gmane.emacs.devel Subject: Re: Using stpcpy Date: Thu, 25 Dec 2014 04:25:38 -0800 Organization: UCLA Computer Science Department Message-ID: <549C0242.3010402@cs.ucla.edu> References: <549849A7.3070208@yandex.ru> <54991006.8030208@cs.ucla.edu> <54994677.9080608@yandex.ru> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------070702040902030504060003" X-Trace: ger.gmane.org 1419510379 23831 80.91.229.3 (25 Dec 2014 12:26:19 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 25 Dec 2014 12:26:19 +0000 (UTC) Cc: Emacs development discussions To: Dmitry Antipov Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Dec 25 13:26:13 2014 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Y47Ua-0004He-TR for ged-emacs-devel@m.gmane.org; Thu, 25 Dec 2014 13:26:13 +0100 Original-Received: from localhost ([::1]:50714 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y47Ua-0006oL-8W for ged-emacs-devel@m.gmane.org; Thu, 25 Dec 2014 07:26:12 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:35547) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y47UI-0006oA-6D for emacs-devel@gnu.org; Thu, 25 Dec 2014 07:25:58 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Y47UE-0003CH-LX for emacs-devel@gnu.org; Thu, 25 Dec 2014 07:25:54 -0500 Original-Received: from smtp.cs.ucla.edu ([131.179.128.62]:60405) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y47UE-0003AF-2t for emacs-devel@gnu.org; Thu, 25 Dec 2014 07:25:50 -0500 Original-Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 2D4B1A6000C; Thu, 25 Dec 2014 04:25:42 -0800 (PST) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Original-Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Ae5WT44lQi6B; Thu, 25 Dec 2014 04:25:38 -0800 (PST) Original-Received: from [192.168.1.9] (pool-71-177-17-123.lsanca.dsl-w.verizon.net [71.177.17.123]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 5244FA60008; Thu, 25 Dec 2014 04:25:38 -0800 (PST) User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.3.0 In-Reply-To: <54994677.9080608@yandex.ru> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 131.179.128.62 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:180653 Archived-At: This is a multi-part message in MIME format. --------------070702040902030504060003 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Dmitry Antipov wrote: > (because lispstpcpy can use known length of a Lisp_String and so call memcpy, > which should be faster than strcpy). Thanks for reviewing. Also, we should fix the strcat uses in lib-src and lwlib. Attached is a revised patch that should address all this. --------------070702040902030504060003 Content-Type: text/x-diff; name="0001-Prefer-stpcpy-to-strcat.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-Prefer-stpcpy-to-strcat.patch" =46rom 5609af083525dae86339be5c8548679363b1ed90 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 25 Dec 2014 04:19:17 -0800 Subject: [PATCH] Prefer stpcpy to strcat * admin/merge-gnulib (GNULIB_MODULES): Add stpcpy. * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * lib/stpcpy.c, m4/stpcpy.m4: New files, from gnulib. * lib-src/ebrowse.c (sym_scope_1, operator_name, open_file): * lib-src/emacsclient.c (get_server_config, set_local_socket) (start_daemon_and_retry_set_socket): * lib-src/etags.c (main, C_entries, relative_filename): * lib-src/pop.c (sendline): * lib-src/update-game-score.c (main): * lwlib/xlwmenu.c (resource_widget_value): * src/callproc.c (child_setup): * src/dbusbind.c (xd_signature_cat): * src/doc.c (get_doc_string, Fsnarf_documentation): * src/editfns.c (Fuser_full_name): * src/frame.c (xrdb_get_resource): * src/gtkutil.c (xg_get_file_with_chooser): * src/tparam.c (tparam1): * src/xfns.c (xic_create_fontsetname): * src/xrdb.c (gethomedir, get_user_db, get_environ_db): * src/xsmfns.c (smc_save_yourself_CB): Rewrite to avoid the need for strcat, typically by using stpcpy and/or liststpcpy. strcat tends to be part of O(N**2) algorithms. * src/doc.c (sibling_etc): * src/xrdb.c (xdefaults): Now a top-level static constant. --- ChangeLog | 29 +++++++++++++++++++++++++++ admin/merge-gnulib | 2 +- lib-src/ebrowse.c | 29 +++++++++++++++------------ lib-src/emacsclient.c | 35 +++++++++++++++----------------- lib-src/etags.c | 33 +++++++++++++++--------------- lib-src/pop.c | 3 +-- lib-src/update-game-score.c | 12 +++++------ lib/gnulib.mk | 11 +++++++++- lib/stpcpy.c | 49 +++++++++++++++++++++++++++++++++++++++= ++++++ lwlib/xlwmenu.c | 7 +++---- m4/gnulib-comp.m4 | 9 +++++++++ m4/stpcpy.m4 | 25 +++++++++++++++++++++++ src/callproc.c | 7 ++----- src/dbusbind.c | 2 +- src/doc.c | 33 +++++++++++------------------- src/editfns.c | 5 ++--- src/frame.c | 20 +++++++++--------- src/gtkutil.c | 6 +++--- src/tparam.c | 4 ++-- src/xfns.c | 34 +++++++++++++++---------------- src/xrdb.c | 44 ++++++++++++++++++---------------------= - src/xsmfns.c | 6 ++---- 22 files changed, 252 insertions(+), 153 deletions(-) create mode 100644 lib/stpcpy.c create mode 100644 m4/stpcpy.m4 diff --git a/ChangeLog b/ChangeLog index 425984a..6ec465d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2014-12-25 Paul Eggert + + Prefer stpcpy to strcat + * admin/merge-gnulib (GNULIB_MODULES): Add stpcpy. + * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. + * lib/stpcpy.c, m4/stpcpy.m4: New files, from gnulib. + * lib-src/ebrowse.c (sym_scope_1, operator_name, open_file): + * lib-src/emacsclient.c (get_server_config, set_local_socket) + (start_daemon_and_retry_set_socket): + * lib-src/etags.c (main, C_entries, relative_filename): + * lib-src/pop.c (sendline): + * lib-src/update-game-score.c (main): + * lwlib/xlwmenu.c (resource_widget_value): + * src/callproc.c (child_setup): + * src/dbusbind.c (xd_signature_cat): + * src/doc.c (get_doc_string, Fsnarf_documentation): + * src/editfns.c (Fuser_full_name): + * src/frame.c (xrdb_get_resource): + * src/gtkutil.c (xg_get_file_with_chooser): + * src/tparam.c (tparam1): + * src/xfns.c (xic_create_fontsetname): + * src/xrdb.c (gethomedir, get_user_db, get_environ_db): + * src/xsmfns.c (smc_save_yourself_CB): + Rewrite to avoid the need for strcat, typically by using stpcpy + and/or liststpcpy. strcat tends to be part of O(N**2) algorithms. + * src/doc.c (sibling_etc): + * src/xrdb.c (xdefaults): + Now a top-level static constant. + 2014-12-24 Stephen Leake =20 * CONTRIBUTE: Move user-level information to doc/emacs/trouble.texi. diff --git a/admin/merge-gnulib b/admin/merge-gnulib index 64514f7..84c6ebf 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib @@ -36,7 +36,7 @@ GNULIB_MODULES=3D' manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qacl readlink readlinkat sig2str socklen stat-time stdalign stddef stdio - strftime strtoimax strtoumax symlink sys_stat + stpcpy strftime strtoimax strtoumax symlink sys_stat sys_time time time_r timer-time timespec-add timespec-sub unsetenv update-copyright utimens vla warnings diff --git a/lib-src/ebrowse.c b/lib-src/ebrowse.c index 29a88e8..b743159 100644 --- a/lib-src/ebrowse.c +++ b/lib-src/ebrowse.c @@ -1150,19 +1150,19 @@ sym_scope_1 (struct sym *p) if (*scope_buffer) { ensure_scope_buffer_room (3); - strcat (scope_buffer, "::"); + strcpy (scope_buffer + scope_buffer_len, "::"); scope_buffer_len +=3D 2; } =20 len =3D strlen (p->name); ensure_scope_buffer_room (len + 1); - strcat (scope_buffer, p->name); + strcpy (scope_buffer + scope_buffer_len, p->name); scope_buffer_len +=3D len; =20 if (HAS_FLAG (p->flags, F_TEMPLATE)) { ensure_scope_buffer_room (3); - strcat (scope_buffer, "<>"); + strcpy (scope_buffer + scope_buffer_len, "<>"); scope_buffer_len +=3D 2; } =20 @@ -2797,24 +2797,25 @@ operator_name (int *sc) s =3D token_string (LA1); MATCH (); =20 - len =3D strlen (s) + 10; + ptrdiff_t slen =3D strlen (s); + len =3D slen + 10; if (len > id_size) { size_t new_size =3D max (len, 2 * id_size); id =3D (char *) xrealloc (id, new_size); id_size =3D new_size; } - strcpy (id, s); + char *z =3D stpcpy (id, s); =20 /* Vector new or delete? */ if (LOOKING_AT ('[')) { - strcat (id, "["); + z =3D stpcpy (z, "["); MATCH (); =20 if (LOOKING_AT (']')) { - strcat (id, "]"); + strcpy (z, "]"); MATCH (); } } @@ -2830,7 +2831,7 @@ operator_name (int *sc) id =3D (char *) xrealloc (id, new_size); id_size =3D new_size; } - strcpy (id, "operator"); + char *z =3D stpcpy (id, "operator"); =20 /* Beware access declarations of the form "X::f;" Beware of `operator () ()'. Yet another difficulty is found in @@ -2842,14 +2843,16 @@ operator_name (int *sc) len +=3D strlen (s) + 2; if (len > id_size) { + ptrdiff_t idlen =3D z - id; size_t new_size =3D max (len, 2 * id_size); id =3D (char *) xrealloc (id, new_size); id_size =3D new_size; + z =3D id + idlen; } =20 if (*s !=3D ')' && *s !=3D ']') - strcat (id, " "); - strcat (id, s); + *z++ =3D ' '; + z =3D stpcpy (z, s); MATCH (); =20 /* If this is a simple operator like `+', stop now. */ @@ -3462,9 +3465,9 @@ open_file (char *file) buffer =3D (char *) xrealloc (buffer, buffer_size); } =20 - strcpy (buffer, path->path); - strcat (buffer, "/"); - strcat (buffer, file); + char *z =3D stpcpy (buffer, path->path); + *z++ =3D '/'; + strcpy (z, file); fp =3D fopen (buffer, "r"); } =20 diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index ddc1b6d..cfc321a 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c @@ -905,9 +905,9 @@ get_server_config (const char *config_file, struct so= ckaddr_in *server, { char *path =3D xmalloc (strlen (home) + strlen (config_file) + EXTRA_SPACE); - strcpy (path, home); - strcat (path, "/.emacs.d/server/"); - strcat (path, config_file); + char *z =3D stpcpy (path, home); + z =3D stpcpy (z, "/.emacs.d/server/"); + strcpy (z, config_file); config =3D fopen (path, "rb"); free (path); } @@ -916,9 +916,9 @@ get_server_config (const char *config_file, struct so= ckaddr_in *server, { char *path =3D xmalloc (strlen (home) + strlen (config_file) + EXTRA_SPACE); - strcpy (path, home); - strcat (path, "/.emacs.d/server/"); - strcat (path, config_file); + char *z =3D stpcpy (path, home); + z =3D stpcpy (z, "/.emacs.d/server/"); + strcpy (z, config_file); config =3D fopen (path, "rb"); free (path); } @@ -1193,7 +1193,6 @@ set_local_socket (const char *local_socket_name) { /* socket_name is a file name component. */ long uid =3D geteuid (); - ptrdiff_t tmpdirlen; use_tmpdir =3D 1; tmpdir =3D egetenv ("TMPDIR"); if (!tmpdir) @@ -1212,12 +1211,11 @@ set_local_socket (const char *local_socket_name) #endif tmpdir =3D "/tmp"; } - tmpdirlen =3D strlen (tmpdir); socket_name_storage =3D - xmalloc (tmpdirlen + strlen (server_name) + EXTRA_SPACE); - strcpy (socket_name_storage, tmpdir); - sprintf (socket_name_storage + tmpdirlen, "/emacs%ld/", uid); - strcat (socket_name_storage + tmpdirlen, server_name); + xmalloc (strlen (tmpdir) + strlen (server_name) + EXTRA_SPACE); + char *z =3D stpcpy (socket_name_storage, tmpdir); + z +=3D sprintf (z, "/emacs%ld/", uid); + strcpy (z, server_name); local_socket_name =3D socket_name_storage; } =20 @@ -1253,12 +1251,12 @@ set_local_socket (const char *local_socket_name) { /* We're running under su, apparently. */ long uid =3D pw->pw_uid; - ptrdiff_t tmpdirlen =3D strlen (tmpdir); char *user_socket_name - =3D xmalloc (tmpdirlen + strlen (server_name) + EXTRA_SPACE); - strcpy (user_socket_name, tmpdir); - sprintf (user_socket_name + tmpdirlen, "/emacs%ld/", uid); - strcat (user_socket_name + tmpdirlen, server_name); + =3D xmalloc (strlen (tmpdir) + strlen (server_name) + + EXTRA_SPACE); + char *z =3D stpcpy (user_socket_name, tmpdir); + z +=3D sprintf (z, "/emacs%ld/", uid); + strcpy (z, server_name); =20 if (strlen (user_socket_name) < sizeof (server.sun_path)) strcpy (server.sun_path, user_socket_name); @@ -1507,8 +1505,7 @@ start_daemon_and_retry_set_socket (void) const char *deq =3D "--daemon=3D"; char *daemon_arg =3D xmalloc (strlen (deq) + strlen (socket_name) + 1); - strcpy (daemon_arg, deq); - strcat (daemon_arg, socket_name); + strcpy (stpcpy (daemon_arg, deq), socket_name); d_argv[1] =3D daemon_arg; } execvp ("emacs", d_argv); diff --git a/lib-src/etags.c b/lib-src/etags.c index 6639ac4..78b3fed 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c @@ -1277,13 +1277,13 @@ main (int argc, char **argv) default: continue; /* the for loop */ } - strcpy (cmd, "mv "); - strcat (cmd, tagfile); - strcat (cmd, " OTAGS;fgrep -v '\t"); - strcat (cmd, argbuffer[i].what); - strcat (cmd, "\t' OTAGS >"); - strcat (cmd, tagfile); - strcat (cmd, ";rm OTAGS"); + char *z =3D stpcpy (cmd, "mv "); + z =3D stpcpy (z, tagfile); + z =3D stpcpy (z, " OTAGS;fgrep -v '\t"); + z =3D stpcpy (z, argbuffer[i].what); + z =3D stpcpy (z, "\t' OTAGS >"); + z =3D stpcpy (z, tagfile); + strcpy (z, ";rm OTAGS"); if (system (cmd) !=3D EXIT_SUCCESS) fatal ("failed to execute shell command", (char *)NULL); } @@ -1307,10 +1307,10 @@ main (int argc, char **argv) /* Maybe these should be used: setenv ("LC_COLLATE", "C", 1); setenv ("LC_ALL", "C", 1); */ - strcpy (cmd, "sort -u -o "); - strcat (cmd, tagfile); - strcat (cmd, " "); - strcat (cmd, tagfile); + char *z =3D stpcpy (cmd, "sort -u -o "); + z =3D stpcpy (z, tagfile); + *z++ =3D ' '; + strcpy (z, tagfile); exit (system (cmd)); } return EXIT_SUCCESS; @@ -3427,8 +3427,9 @@ C_entries (int c_ext, FILE *inf) case omethodtag: case omethodparm: objdef =3D omethodcolon; - linebuffer_setlen (&token_name, token_name.len + 1); - strcat (token_name.buffer, ":"); + int toklen =3D token_name.len; + linebuffer_setlen (&token_name, toklen + 1); + strcpy (token_name.buffer + toklen, ":"); break; } if (structdef =3D=3D stagseen) @@ -6362,12 +6363,12 @@ relative_filename (char *file, char *dir) while ((dp =3D strchr (dp + 1, '/')) !=3D NULL) i +=3D 1; res =3D xnew (3*i + strlen (fp + 1) + 1, char); - res[0] =3D '\0'; + char *z =3D res; while (i-- > 0) - strcat (res, "../"); + z =3D stpcpy (z, "../"); =20 /* Add the file name relative to the common root of file and dir. */ - strcat (res, fp + 1); + strcpy (z, fp + 1); free (afn); =20 return res; diff --git a/lib-src/pop.c b/lib-src/pop.c index ffe16c5..7001150 100644 --- a/lib-src/pop.c +++ b/lib-src/pop.c @@ -1397,8 +1397,7 @@ sendline (popserver server, const char *line) over a few dozen messages, and is a big chunk of the time we spend fetching mail from a server close by. */ buf =3D alloca (strlen (line) + 3); - strcpy (buf, line); - strcat (buf, "\r\n"); + strcpy (stpcpy (buf, line), "\r\n"); ret =3D fullwrite (server->file, buf, strlen (buf)); =20 if (ret < 0) diff --git a/lib-src/update-game-score.c b/lib-src/update-game-score.c index 7a64cd0..b311001 100644 --- a/lib-src/update-game-score.c +++ b/lib-src/update-game-score.c @@ -221,9 +221,9 @@ main (int argc, char **argv) if (!scorefile) lose_syserr ("Couldn't allocate score file"); =20 - strcpy (scorefile, prefix); - strcat (scorefile, "/"); - strcat (scorefile, argv[optind]); + char *z =3D stpcpy (scorefile, prefix); + *z++ =3D '/'; + strcpy (z, argv[optind]); =20 newscore.score =3D normalize_integer (argv[optind + 1]); if (! newscore.score) @@ -430,8 +430,7 @@ write_scores (const char *filename, const struct scor= e_entry *scores, char *tempfile =3D malloc (strlen (filename) + strlen (".tempXXXXXX") = + 1); if (!tempfile) return -1; - strcpy (tempfile, filename); - strcat (tempfile, ".tempXXXXXX"); + strcpy (stpcpy (tempfile, filename), ".tempXXXXXX"); fd =3D mkostemp (tempfile, 0); if (fd < 0) return -1; @@ -462,8 +461,7 @@ lock_file (const char *filename, void **state) char *lockpath =3D malloc (strlen (filename) + strlen (lockext) + 60);= if (!lockpath) return -1; - strcpy (lockpath, filename); - strcat (lockpath, lockext); + strcpy (stpcpy (lockpath, filename), lockext); *state =3D lockpath; =20 while ((fd =3D open (lockpath, O_CREAT | O_EXCL, 0600)) < 0) diff --git a/lib/gnulib.mk b/lib/gnulib.mk index 740ebb1..27a5964 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk @@ -21,7 +21,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=3D. --lib=3Dlibgnu --source-b= ase=3Dlib --m4-base=3Dm4 --doc-base=3Ddoc --tests-base=3Dtests --aux-dir=3D= build-aux --avoid=3Dclose --avoid=3Ddup --avoid=3Dfchdir --avoid=3Dfstat = --avoid=3Dmalloc-posix --avoid=3Dmsvc-inval --avoid=3Dmsvc-nothrow --avoi= d=3Dopen --avoid=3Dopenat-die --avoid=3Dopendir --avoid=3Draise --avoid=3D= save-cwd --avoid=3Dselect --avoid=3Dsigprocmask --avoid=3Dstdarg --avoid=3D= stdbool --avoid=3Dthreadlib --makefile-name=3Dgnulib.mk --conditional-dep= endencies --no-libtool --macro-prefix=3Dgl --no-vc-files alloca-opt binar= y-io byteswap c-ctype c-strcase careadlinkat close-stream count-one-bits = count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 d= toastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasyn= c fdopendir filemode fstatat fsync getloadavg getopt-gnu gettime gettimeo= fday intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 = pselect pthread_sigmask putenv qacl readlink readlinkat sig2str socklen s= tat-time stdalign stddef stdio strftime strtoimax strtoumax symlink sys_s= tat sys_time time time_r timer-time timespec-add timespec-sub unsetenv up= date-copyright utimens vla warnings +# Reproduce by: gnulib-tool --import --dir=3D. --lib=3Dlibgnu --source-b= ase=3Dlib --m4-base=3Dm4 --doc-base=3Ddoc --tests-base=3Dtests --aux-dir=3D= build-aux --avoid=3Dclose --avoid=3Ddup --avoid=3Dfchdir --avoid=3Dfstat = --avoid=3Dmalloc-posix --avoid=3Dmsvc-inval --avoid=3Dmsvc-nothrow --avoi= d=3Dopen --avoid=3Dopenat-die --avoid=3Dopendir --avoid=3Draise --avoid=3D= save-cwd --avoid=3Dselect --avoid=3Dsigprocmask --avoid=3Dstdarg --avoid=3D= stdbool --avoid=3Dthreadlib --makefile-name=3Dgnulib.mk --conditional-dep= endencies --no-libtool --macro-prefix=3Dgl --no-vc-files alloca-opt binar= y-io byteswap c-ctype c-strcase careadlinkat close-stream count-one-bits = count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 d= toastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasyn= c fdopendir filemode fstatat fsync getloadavg getopt-gnu gettime gettimeo= fday intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 = pselect pthread_sigmask putenv qacl readlink readlinkat sig2str socklen s= tat-time stdalign stddef stdio stpcpy strftime strtoimax strtoumax symlin= k sys_stat sys_time time time_r timer-time timespec-add timespec-sub unse= tenv update-copyright utimens vla warnings =20 =20 MOSTLYCLEANFILES +=3D core *.stackdump @@ -1214,6 +1214,15 @@ EXTRA_DIST +=3D stdlib.in.h =20 ## end gnulib module stdlib =20 +## begin gnulib module stpcpy + + +EXTRA_DIST +=3D stpcpy.c + +EXTRA_libgnu_a_SOURCES +=3D stpcpy.c + +## end gnulib module stpcpy + ## begin gnulib module strftime =20 libgnu_a_SOURCES +=3D strftime.c diff --git a/lib/stpcpy.c b/lib/stpcpy.c new file mode 100644 index 0000000..880a706 --- /dev/null +++ b/lib/stpcpy.c @@ -0,0 +1,49 @@ +/* stpcpy.c -- copy a string and return pointer to end of new string + Copyright (C) 1992, 1995, 1997-1998, 2006, 2009-2014 Free Software + Foundation, Inc. + + NOTE: The canonical source of this file is maintained with the GNU C = Library. + Bugs can be reported to bug-glibc@prep.ai.mit.edu. + + This program 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 any + later version. + + 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 + 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 .= */ + +#include + +#include + +#undef __stpcpy +#ifdef _LIBC +# undef stpcpy +#endif + +#ifndef weak_alias +# define __stpcpy stpcpy +#endif + +/* Copy SRC to DEST, returning the address of the terminating '\0' in DE= ST. */ +char * +__stpcpy (char *dest, const char *src) +{ + register char *d =3D dest; + register const char *s =3D src; + + do + *d++ =3D *s; + while (*s++ !=3D '\0'); + + return d - 1; +} +#ifdef weak_alias +weak_alias (__stpcpy, stpcpy) +#endif diff --git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c index 6f4db56..2d2d409 100644 --- a/lwlib/xlwmenu.c +++ b/lwlib/xlwmenu.c @@ -439,10 +439,9 @@ resource_widget_value (XlwMenuWidget mw, widget_valu= e *val) int complete_length =3D strlen (resourced_name) + strlen (val->value) + 2; complete_name =3D XtMalloc (complete_length); - *complete_name =3D 0; - strcat (complete_name, resourced_name); - strcat (complete_name, " "); - strcat (complete_name, val->value); + char *z =3D stpcpy (complete_name, resourced_name); + *z++ =3D ' '; + strcpy (z, val->value); } =20 val->toolkit_data =3D complete_name; diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 39ec8ae..49fdf5e 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -123,6 +123,7 @@ AC_DEFUN([gl_EARLY], # Code from module stdint: # Code from module stdio: # Code from module stdlib: + # Code from module stpcpy: # Code from module strftime: # Code from module string: # Code from module strtoimax: @@ -341,6 +342,12 @@ AC_DEFUN([gl_INIT], gl_STDINT_H gl_STDIO_H gl_STDLIB_H + gl_FUNC_STPCPY + if test $HAVE_STPCPY =3D 0; then + AC_LIBOBJ([stpcpy]) + gl_PREREQ_STPCPY + fi + gl_STRING_MODULE_INDICATOR([stpcpy]) gl_FUNC_GNU_STRFTIME gl_HEADER_STRING_H gl_FUNC_STRTOIMAX @@ -889,6 +896,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/stdint.in.h lib/stdio.in.h lib/stdlib.in.h + lib/stpcpy.c lib/strftime.c lib/strftime.h lib/string.in.h @@ -995,6 +1003,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/stdint.m4 m4/stdio_h.m4 m4/stdlib_h.m4 + m4/stpcpy.m4 m4/strftime.m4 m4/string_h.m4 m4/strtoimax.m4 diff --git a/m4/stpcpy.m4 b/m4/stpcpy.m4 new file mode 100644 index 0000000..966ba95 --- /dev/null +++ b/m4/stpcpy.m4 @@ -0,0 +1,25 @@ +# stpcpy.m4 serial 8 +dnl Copyright (C) 2002, 2007, 2009-2014 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_STPCPY], +[ + dnl Persuade glibc to declare stpcpy(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + dnl The stpcpy() declaration in lib/string.in.h uses 'restrict'. + AC_REQUIRE([AC_C_RESTRICT]) + + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + AC_CHECK_FUNCS([stpcpy]) + if test $ac_cv_func_stpcpy =3D no; then + HAVE_STPCPY=3D0 + fi +]) + +# Prerequisites of lib/stpcpy.c. +AC_DEFUN([gl_PREREQ_STPCPY], [ + : +]) diff --git a/src/callproc.c b/src/callproc.c index a677334..f40ed32 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -1315,13 +1315,10 @@ child_setup (int in, int out, int err, char **new= _argv, bool set_pgrp, =20 if (STRINGP (display)) { - char *vdata; - if (MAX_ALLOCA - sizeof "DISPLAY=3D" < SBYTES (display)) exec_failed (new_argv[0], ENOMEM); - vdata =3D alloca (sizeof "DISPLAY=3D" + SBYTES (display)); - strcpy (vdata, "DISPLAY=3D"); - strcat (vdata, SSDATA (display)); + char *vdata =3D alloca (sizeof "DISPLAY=3D" + SBYTES (display)); + lispstpcpy (stpcpy (vdata, "DISPLAY=3D"), display); new_env =3D add_env (env, new_env, vdata); } =20 diff --git a/src/dbusbind.c b/src/dbusbind.c index 4852739..983b05c 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c @@ -357,7 +357,7 @@ xd_signature_cat (char *signature, char const *x) ptrdiff_t xlen =3D strlen (x); if (DBUS_MAXIMUM_SIGNATURE_LENGTH - xlen <=3D siglen) string_overflow (); - strcat (signature, x); + strcpy (signature + siglen, x); } =20 /* Compute SIGNATURE of OBJECT. It must have a form that it can be diff --git a/src/doc.c b/src/doc.c index 1b87c23..1d9c330 100644 --- a/src/doc.c +++ b/src/doc.c @@ -42,6 +42,8 @@ static ptrdiff_t get_doc_string_buffer_size; =20 static unsigned char *read_bytecode_pointer; =20 +static char const sibling_etc[] =3D "../etc/"; + /* `readchar' in lread.c calls back here to fetch the next byte. If UNREADFLAG is 1, we unread a byte. */ =20 @@ -80,7 +82,6 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool= definition) { char *from, *to, *name, *p, *p1; int fd; - ptrdiff_t minsize; int offset; EMACS_INT position; Lisp_Object file, tem, pos; @@ -113,21 +114,14 @@ get_doc_string (Lisp_Object filepos, bool unibyte, = bool definition) =20 tem =3D Ffile_name_absolute_p (file); file =3D ENCODE_FILE (file); - if (NILP (tem)) - { - Lisp_Object docdir =3D ENCODE_FILE (Vdoc_directory); - minsize =3D SCHARS (docdir); - /* sizeof ("../etc/") =3D=3D 8 */ - if (minsize < 8) - minsize =3D 8; - name =3D SAFE_ALLOCA (minsize + SCHARS (file) + 8); - char *z =3D lispstpcpy (name, docdir); - strcpy (z, SSDATA (file)); - } - else - { - name =3D SSDATA (file); - } + Lisp_Object docdir + =3D NILP (tem) ? ENCODE_FILE (Vdoc_directory) : empty_unibyte_string= ; + ptrdiff_t docdir_sizemax =3D SBYTES (docdir) + 1; +#ifndef CANNOT_DUMP + docdir_sizemax =3D max (docdir_sizemax, sizeof sibling_etc); +#endif + name =3D SAFE_ALLOCA (docdir_sizemax + SBYTES (file)); + lispstpcpy (lispstpcpy (name, docdir), file); =20 fd =3D emacs_open (name, O_RDONLY, 0); if (fd < 0) @@ -137,8 +131,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bo= ol definition) { /* Preparing to dump; DOC file is probably not installed. So check in ../etc. */ - strcpy (name, "../etc/"); - strcat (name, SSDATA (file)); + lispstpcpy (stpcpy (name, sibling_etc), file); =20 fd =3D emacs_open (name, O_RDONLY, 0); } @@ -580,7 +573,6 @@ the same file name is found in the `doc-directory'. = */) (0) #endif /* CANNOT_DUMP */ { - static char const sibling_etc[] =3D "../etc/"; dirname =3D sibling_etc; dirlen =3D sizeof sibling_etc - 1; } @@ -594,8 +586,7 @@ the same file name is found in the `doc-directory'. = */) count =3D SPECPDL_INDEX (); USE_SAFE_ALLOCA; name =3D SAFE_ALLOCA (dirlen + SBYTES (filename) + 1); - strcpy (name, dirname); - strcat (name, SSDATA (filename)); /*** Add this line ***/ + lispstpcpy (stpcpy (name, dirname), filename); /*** Add this line ***= / =20 /* Vbuild_files is nil when temacs is run, and non-nil after that. */= if (NILP (Vbuild_files)) diff --git a/src/editfns.c b/src/editfns.c index 0a07886..430c4c9 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -1350,10 +1350,9 @@ name, or nil if there is no such user. */) USE_SAFE_ALLOCA; char *r =3D SAFE_ALLOCA (strlen (p) + SBYTES (login) + 1); memcpy (r, p, q - p); - r[q - p] =3D 0; - strcat (r, SSDATA (login)); + char *s =3D lispstpcpy (&r[q - p], login); r[q - p] =3D upcase ((unsigned char) r[q - p]); - strcat (r, q + 1); + strcpy (s, q + 1); full =3D build_string (r); SAFE_FREE (); } diff --git a/src/frame.c b/src/frame.c index 3127366..2ad1c1b5 100644 --- a/src/frame.c +++ b/src/frame.c @@ -4076,23 +4076,23 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object a= ttribute, Lisp_Object class, Li =20 /* Start with emacs.FRAMENAME for the name (the specific one) and with `Emacs' for the class key (the general one). */ - lispstpcpy (name_key, Vx_resource_name); - lispstpcpy (class_key, Vx_resource_class); + char *nz =3D lispstpcpy (name_key, Vx_resource_name); + char *cz =3D lispstpcpy (class_key, Vx_resource_class); =20 - strcat (class_key, "."); - strcat (class_key, SSDATA (class)); + *cz++ =3D '.'; + cz =3D lispstpcpy (cz, class); =20 if (!NILP (component)) { - strcat (class_key, "."); - strcat (class_key, SSDATA (subclass)); + *cz++ =3D '.'; + lispstpcpy (cz, subclass); =20 - strcat (name_key, "."); - strcat (name_key, SSDATA (component)); + *nz++ =3D '.'; + nz =3D lispstpcpy (nz, component); } =20 - strcat (name_key, "."); - strcat (name_key, SSDATA (attribute)); + *nz++ =3D '.'; + lispstpcpy (nz, attribute); =20 char *value =3D x_get_string_resource (rdb, name_key, class_key); SAFE_FREE(); diff --git a/src/gtkutil.c b/src/gtkutil.c index 9465d54..f61cbc2 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -1839,12 +1839,12 @@ xg_get_file_with_chooser (struct frame *f, =20 if (x_gtk_file_dialog_help_text) { - msgbuf[0] =3D '\0'; + char *z =3D msgbuf; /* Gtk+ 2.10 has the file name text entry box integrated in the di= alog. Show the C-l help text only for versions < 2.10. */ if (gtk_check_version (2, 10, 0) && action !=3D GTK_FILE_CHOOSER_A= CTION_SAVE) - strcat (msgbuf, "\nType C-l to display a file name text entry bo= x.\n"); - strcat (msgbuf, "\nIf you don't like this file selector, use the "= + z =3D stpcpy (z, "\nType C-l to display a file name text entry b= ox.\n"); + strcpy (z, "\nIf you don't like this file selector, use the " "corresponding\nkey binding or customize " "use-file-dialog to turn it off."); =20 diff --git a/src/tparam.c b/src/tparam.c index e02cea3..b0cd004 100644 --- a/src/tparam.c +++ b/src/tparam.c @@ -255,9 +255,9 @@ tparam1 (const char *string, char *outstring, int len= , } *op =3D 0; while (doup-- > 0) - strcat (op, up); + op =3D stpcpy (op, up); while (doleft-- > 0) - strcat (op, left); + op =3D stpcpy (op, left); return outstring; } =0C diff --git a/src/xfns.c b/src/xfns.c index 1b17311..ba2601d 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -1710,13 +1710,14 @@ xic_create_fontsetname (const char *base_fontname= , int motif) { const char *sep =3D motif ? ";" : ","; char *fontsetname; + char *z; =20 /* Make a fontset name from the base font name. */ if (xic_default_fontset =3D=3D base_fontname) { /* There is no base font name, use the default. */ fontsetname =3D xmalloc (strlen (base_fontname) + 2); - strcpy (fontsetname, base_fontname); + z =3D stpcpy (fontsetname, base_fontname); } else { @@ -1737,9 +1738,9 @@ xic_create_fontsetname (const char *base_fontname, = int motif) Use the specified font plus the default. */ fontsetname =3D xmalloc (strlen (base_fontname) + strlen (xic_default_fontset) + 3); - strcpy (fontsetname, base_fontname); - strcat (fontsetname, sep); - strcat (fontsetname, xic_default_fontset); + z =3D stpcpy (fontsetname, base_fontname); + z =3D stpcpy (z, sep); + z =3D stpcpy (z, xic_default_fontset); } else { @@ -1800,27 +1801,26 @@ xic_create_fontsetname (const char *base_fontname= , int motif) /* Build the font spec that matches all. */ len =3D p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies)= + 1; font_all =3D alloca (len); - strcpy (font_all, allfamilies); - strcat (font_all, all); - memcpy (font_all + strlen (all) + strlen (allfamilies), p2, p - p2); - strcpy (font_all + strlen (all) + strlen (allfamilies) + (p - p2), - allcs); + z =3D stpcpy (font_all, allfamilies); + z =3D stpcpy (z, all); + memcpy (z, p2, p - p2); + strcpy (z + (p - p2), allcs); =20 /* Build the actual font set name. */ len =3D strlen (base_fontname) + strlen (font_allcs) + strlen (font_allfamilies) + strlen (font_all) + 5; fontsetname =3D xmalloc (len); - strcpy (fontsetname, base_fontname); - strcat (fontsetname, sep); - strcat (fontsetname, font_allcs); - strcat (fontsetname, sep); - strcat (fontsetname, font_allfamilies); - strcat (fontsetname, sep); - strcat (fontsetname, font_all); + z =3D stpcpy (fontsetname, base_fontname); + z =3D stpcpy (z, sep); + z =3D stpcpy (z, font_allcs); + z =3D stpcpy (z, sep); + z =3D stpcpy (z, font_allfamilies); + z =3D stpcpy (z, sep); + z =3D stpcpy (z, font_all); } } if (motif) - return strcat (fontsetname, ":"); + strcpy (z, ":"); return fontsetname; } #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */ diff --git a/src/xrdb.c b/src/xrdb.c index 32ad3c7..e21206d 100644 --- a/src/xrdb.c +++ b/src/xrdb.c @@ -232,9 +232,10 @@ gethomedir (void) if (ptr =3D=3D NULL) return xstrdup ("/"); =20 - copy =3D xmalloc (strlen (ptr) + 2); - strcpy (copy, ptr); - return strcat (copy, "/"); + ptrdiff_t len =3D strlen (ptr); + copy =3D xmalloc (len + 2); + strcpy (copy + len, "/"); + return memcpy (copy, ptr, len); } =20 =20 @@ -334,6 +335,7 @@ get_user_app (const char *class) return db; } =20 +static char const xdefaults[] =3D ".Xdefaults"; =20 static XrmDatabase get_user_db (Display *display) @@ -351,16 +353,12 @@ get_user_db (Display *display) db =3D XrmGetStringDatabase (xdefs); else { - char *home; - char *xdefault; - - home =3D gethomedir (); - xdefault =3D xmalloc (strlen (home) + sizeof ".Xdefaults"); - strcpy (xdefault, home); - strcat (xdefault, ".Xdefaults"); - db =3D XrmGetFileDatabase (xdefault); - xfree (home); - xfree (xdefault); + char *home =3D gethomedir (); + ptrdiff_t homelen =3D strlen (home); + char *filename =3D xrealloc (home, homelen + sizeof xdefaults); + strcpy (filename + homelen, xdefaults); + db =3D XrmGetFileDatabase (filename); + xfree (filename); } =20 #ifdef HAVE_XSCREENRESOURCESTRING @@ -380,24 +378,22 @@ static XrmDatabase get_environ_db (void) { XrmDatabase db; - char *p; - char *path =3D 0; + char *p =3D getenv ("XENVIRONMENT"); + char *filename =3D 0; =20 - if ((p =3D getenv ("XENVIRONMENT")) =3D=3D NULL) + if (!p) { - static char const xdefaults[] =3D ".Xdefaults-"; char *home =3D gethomedir (); - char const *host =3D SSDATA (Vsystem_name); - ptrdiff_t pathsize =3D (strlen (home) + sizeof xdefaults - + SBYTES (Vsystem_name)); - path =3D xrealloc (home, pathsize); - strcat (strcat (path, xdefaults), host); - p =3D path; + ptrdiff_t homelen =3D strlen (home); + ptrdiff_t filenamesize =3D (homelen + sizeof xdefaults + + SBYTES (Vsystem_name)); + p =3D filename =3D xrealloc (home, filenamesize); + lispstpcpy (stpcpy (filename + homelen, xdefaults), Vsystem_name);= } =20 db =3D XrmGetFileDatabase (p); =20 - xfree (path); + xfree (filename); =20 return db; } diff --git a/src/xsmfns.c b/src/xsmfns.c index cd4f9ce..8a835cf 100644 --- a/src/xsmfns.c +++ b/src/xsmfns.c @@ -230,8 +230,7 @@ smc_save_yourself_CB (SmcConn smcConn, props[props_idx]->vals[vp_idx++].value =3D emacs_program; =20 smid_opt =3D xmalloc (strlen (SMID_OPT) + strlen (client_id) + 1); - strcpy (smid_opt, SMID_OPT); - strcat (smid_opt, client_id); + strcpy (stpcpy (smid_opt, SMID_OPT), client_id); =20 props[props_idx]->vals[vp_idx].length =3D strlen (smid_opt); props[props_idx]->vals[vp_idx++].value =3D smid_opt; @@ -242,8 +241,7 @@ smc_save_yourself_CB (SmcConn smcConn, if (cwd) { chdir_opt =3D xmalloc (strlen (CHDIR_OPT) + strlen (cwd) + 1); - strcpy (chdir_opt, CHDIR_OPT); - strcat (chdir_opt, cwd); + strcpy (stpcpy (chdir_opt, CHDIR_OPT), cwd); =20 props[props_idx]->vals[vp_idx].length =3D strlen (chdir_opt); props[props_idx]->vals[vp_idx++].value =3D chdir_opt; --=20 1.9.3 --------------070702040902030504060003--