diff options
Diffstat (limited to 'lib-src')
-rw-r--r-- | lib-src/ChangeLog | 193 | ||||
-rw-r--r-- | lib-src/Makefile.in | 120 | ||||
-rw-r--r-- | lib-src/ctags.c | 2 | ||||
-rw-r--r-- | lib-src/ebrowse.c | 29 | ||||
-rw-r--r-- | lib-src/emacsclient.c | 39 | ||||
-rw-r--r-- | lib-src/etags.c | 145 | ||||
-rwxr-xr-x | lib-src/grep-changelog | 265 | ||||
-rw-r--r-- | lib-src/hexl.c | 37 | ||||
-rw-r--r-- | lib-src/make-docfile.c | 135 | ||||
-rw-r--r-- | lib-src/movemail.c | 39 | ||||
-rw-r--r-- | lib-src/ntlib.h | 1 | ||||
-rw-r--r-- | lib-src/pop.c | 3 | ||||
-rw-r--r-- | lib-src/test-distrib.c | 88 | ||||
-rw-r--r-- | lib-src/testfile | bin | 222 -> 0 bytes | |||
-rw-r--r-- | lib-src/update-game-score.c | 327 |
15 files changed, 567 insertions, 856 deletions
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index 53a69b44378..07a72ecaf0d 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,12 +1,139 @@ +2014-12-27 Eli Zaretskii <eliz@gnu.org> + + * Makefile.in (etags_libs, ebrowse${EXEEXT}, profile${EXEEXT}) + (make-docfile${EXEEXT}, movemail${EXEEXT}) + (update-game-score${EXEEXT}): Put $(NTLIB) before $(LOADLIBES), + since GCC sometimes calls stpcpy when it sees strcpy, under + optimization switches. + +2014-12-14 Paul Eggert <eggert@cs.ucla.edu> + + * etags.c (analyze_regex): Rename from analyse_regex. + +2014-12-14 Glenn Morris <rgm@gnu.org> + + * grep-changelog: Remove file. + * Makefile.in (INSTALLABLE_SCRIPTS): Remove. + (all, install, uninstall): Remove INSTALLABLE_SCRIPTS. + +2014-11-23 Glenn Morris <rgm@gnu.org> + + * Makefile.in (emacsclient.res): Fix yesterday's thinko. + +2014-11-22 Glenn Morris <rgm@gnu.org> + + * Makefile.in (emacsclient.res): Update deps for nt/emacsclient.rc + now being in the build directory, not the source directory. + + * Makefile.in (emacsclient.res): Add dependency on icons/emacs.ico. + 2014-10-20 Glenn Morris <rgm@gnu.org> - * Version 24.4 released. + * Merge in all changes up to 24.4 release. + +2014-09-23 Paul Eggert <eggert@cs.ucla.edu> + + movemail: don't dump core if the current time is outlandish + * movemail.c (popmail): Check for mbx_delimit_begin failure. + (mbx_delimit_begin): Fail if the current time is so outlandish + that localtime would fail or asctime would have undefined + behavior. Use strftime to avoid asctime undefined behavior. + +2014-09-01 Paul Eggert <eggert@cs.ucla.edu> + + --enable-silent-rules now suppresses more chatter. + * Makefile.in (AM_DEFAULT_VERBOSITY, AM_V_CC, am__v_CC_) + (am__v_CC_0, am__v_CC_1, AM_V_CCLD, am__v_CCLD_, am__v_CCLD_0) + (am__v_CCLD_1): New macros, taken from Automake. + (regex.o, etags${EXEEXT}, ctags${EXEEXT}, ebrowse${EXEEXT}) + (profile${EXEEXT}, make-docfile${EXEEXT}, movemail${EXEEXT}) + (pop.o, emacsclient${EXEEXT}, emacsclientw${EXEEXT}) + (emacsclientw${EXEEXT}, ntlib.o, hexl${EXEEXT}) + (update-game-score${EXEEXT}): Use them. + + * etags.c (emacs_strchr, emacs_strrchr): Remove. + All uses replaced by strchr and strrchr, which are on all + target platforms now. + +2014-07-15 Paul Eggert <eggert@cs.ucla.edu> + + Use "b" flag more consistently; avoid "t" (Bug#18006). + * make-docfile.c (READ_TEXT): Remove; all uses replaced by "r". + (READ_BINARY): Remove; all uses replaced by "rb". + +2014-07-14 Paul Eggert <eggert@cs.ucla.edu> + + Use binary-io module, O_BINARY, and "b" flag (Bug#18006). + * etags.c, hexl.c, make-docfile.c: + Include binary-io.h instead of fcntl.h and/or io.h. + (main): Use set_binary_mode or SET_BINARY + in place of handcrafted code. + * etags.c (main) [DOS_NT]: + * movemail.c (main) [WINDOWSNT]: + Don't mess with _fmode. + * etags.c (main, process_file_name, analyse_regex): + Use fopen/popen's "b" flag instead. + * movemail.c (main, popmail): Use open/lk_open/mkostemp's O_BINARY + instead. + +2014-07-13 Paul Eggert <eggert@cs.ucla.edu> + + * make-docfile.c: Simplify a bit, to simplify further refactoring. + (outfile): Remove static var. All uses changed to use stdout, + since it's always stdout anyway. While we're at it, prefer + putchar/puts/fputs to printf when there are no format strings. + (main): Use freopen rather than fopen, so that stdout is reused. + Move O_BINARY stuff after the freopen, so it affects the + reopened file. + (write_c_args): Omit first arg, since it's always stdout now. + All uses changed. 2014-07-12 Paul Eggert <eggert@cs.ucla.edu> * etags.c (Lisp_functions): Also record cl-defun etc. (Bug#17965) -2014-05-20 Paul Eggert <eggert@cs.ucla.edu> +2014-06-26 Glenn Morris <rgm@gnu.org> + + * Makefile.in (blessmail): Depend on lisp/mail/blessmail.el. + Use $<, $@. + (regex.o, etags${EXEEXT}, ctags${EXEEXT}, ebrowse${EXEEXT}) + (profile${EXEEXT}, make-docfile${EXEEXT}, movemail${EXEEXT}) + (pop.o, emacsclient${EXEEXT}, emacsclientw${EXEEXT}, ntlib.o) + (hexl${EXEEXT}, update-game-score${EXEEXT}, emacsclient.res): Use $<. + (ctags${EXEEXT}): Add $srcdir to dependency rather than using VPATH. + +2014-06-17 Paul Eggert <eggert@cs.ucla.edu> + + Omit redundant extern decls. + * emacsclient.c (getenv): Remove decl. + * make-docfile.c (write_globals): Add ATTRIBUTE_CONST for + Fbyteorder, Ftool_bar_height, Fmax_char, Fidentity. + +2014-06-15 Glenn Morris <rgm@gnu.org> + + * Makefile.in (LDFLAGS): Explicitly set via configure. + +2014-06-15 Eli Zaretskii <eliz@gnu.org> + + * Makefile.in (CPPFLAGS): Define. + +2014-06-15 Glenn Morris <rgm@gnu.org> + + * Makefile.in (../lib/libgnu.a): + Use `make -C' rather than `cd && make'. + + * Makefile.in (bootstrap-clean): New. + +2014-06-13 Glenn Morris <rgm@gnu.org> + + * Makefile.in (../lib/libgnu.a): + GNU make automatically passes command-line arguments to sub-makes. + +2014-05-26 Eli Zaretskii <eliz@gnu.org> + + * ntlib.h (lseek): Don't redirect to _lseek. + +2014-05-26 Paul Eggert <eggert@cs.ucla.edu> Fix rcs2log problems with CVS. Problem reported by Glenn Morris in @@ -16,12 +143,45 @@ (logdir, llogdir): Work even if TMPDIR begins with '-' or has spaces. (output_authors, main awk script): Parse more-recent CVS output format. -2014-05-03 Paul Eggert <eggert@cs.ucla.edu> +2014-05-19 Paul Eggert <eggert@cs.ucla.edu> + + Remove dependencies on getline and getdelim. + Also, remove update-game-scores's limits on game scores and + simplify its file-locking code. + * update-game-score.c (struct score_entry): Unify the username and + data members to a single user_data member, since they don't need to be + changed independently and getdelim and getline aren't helpful. + Make the score member char *, not intmax_t, so that scores are not + limited to intmax_t. All uses changed. + (lose_syserr): A zero errno stands for invalid data in score file. + (normalize_integer): New function. + (main): Use it. Check for invalid scores. Omit redundant stat check. + (read_score): First arg is now a string, not a FILE *. All uses + changed. Do not use getdelim or getline; that's way simpler. + (read_scores): Read the whole file, and let read_score handle each + line. + (score_compare): Compare strings representing integers, not integers. + (write_scores) [DOS_NT]: Eliminate unnecessary chmod. + (lock_file): Simplify locking code, eliminating goto. + Check for unlink failure. + +2014-05-18 Paul Eggert <eggert@cs.ucla.edu> + + Port ctags+etags build to Sun C 5.12. + * Makefile.in (etags_args): Remove, replacing with ... + (etags_cflags, etags_libs): New macros. All uses changed. + (ctags${EXEEXT}): Don't compile etags.c, as compiling etags.c in + parallel (once for ctags, once for etags) breaks parallel makes + with compilers that use the source file name to name temporaries, + such as Sun C 5.12. Instead, compile ctags.c. + * ctags.c: New file. + +2014-05-04 Paul Eggert <eggert@cs.ucla.edu> Handle systems without WCONTINUED consistently. (Bug#15110, 17339) * emacsclient.c (WCONTINUED): Move to ../src/syswait.h. -2014-04-29 Glenn Morris <rgm@gnu.org> +2014-04-30 Glenn Morris <rgm@gnu.org> * Makefile.in ($(DESTDIR)${archlibdir}): Avoid non-portable "`\" nesting. (Bug#17339) @@ -31,6 +191,23 @@ * update-game-score.c (write_scores): Condition fchmod call on DOS_NT, not WINDOWSNT. +2014-03-22 Glenn Morris <rgm@gnu.org> + + * Makefile.in (etags_deps, etags_args): New, to reduce duplication. + (etags${EXEEXT}, ctags${EXEEXT}): Use etags_deps, etags_args. + + * Makefile.in (etags${EXEEXT}, ebrowse${EXEEXT}, ctags${EXEEXT}) + (profile${EXEEXT}, make-docfile${EXEEXT}, movemail${EXEEXT}) + (emacsclient${EXEEXT}, emacsclientw${EXEEXT}, hexl${EXEEXT}) + (update-game-score${EXEEXT}, emacsclient.res): Use $@. + + * Makefile.in (../lib/libgnu.a): Explicitly pass MFLAGS. + + * Makefile.in (DONT_INSTALL): Remove test-distrib. + (test-distrib${EXEEXT}): Remove rule. + + * test-distrib.c, testfile: Remove. + 2014-03-10 Juanma Barranquero <lekktu@gmail.com> * emacsclient.c (main): #ifdef out previous change on Windows. @@ -2852,7 +3029,7 @@ filter), show help instead of blindingly dumping every single ChangeLog available. Doc fix. Update version. -2006-11-02 Tim Van Holder <tim.vanholder@gmail.com> (tiny change) +2006-11-02 Tim Van Holder <tim.vanholder@gmail.com> * emacsclient.c [WINDOWSNT]: Define HAVE_INET_SOCKETS. [!WINDOWSNT]: Include <netinet/in.h> if available. @@ -2877,7 +3054,7 @@ (set_tcp_socket): Prefer O_NONBLOCK, then O_NDELAY, then FIONBIO to set the socket in non-blocking mode. -2006-10-31 Tim Van Holder <tim.vanholder@gmail.com> (tiny change) +2006-10-31 Tim Van Holder <tim.vanholder@gmail.com> * emacsclient.c [!WINDOWSNT]: Include <netinet/in.h> and <sys/ioctl.h>. (INVALID_SOCKET): Define. @@ -7591,7 +7768,7 @@ (consider_token): DEFUNs now treated like funcs in ctags mode. * etags.c (LEVEL_OK_FOR_FUNCDEF): Remove. - (C_entries): Optimized the test that used LEVEL_OK_FOR_FUNCDEF. + (C_entries): Optimize the test that used LEVEL_OK_FOR_FUNCDEF. (C_entries): Remove a piece of useless code. (C_entries): Making typedef tags is delayed until a semicolon is met. This handles "typedef int X, Y, Z;" correctly. @@ -7991,7 +8168,7 @@ * Makefile.in (prefix, bindir, libdir, srcdir): New variables, as described in the top-level Makefile. (UTILITIES): Add make-path to the list of utility programs. - (../arch-lib): Replaced by the ${archlibdir} target, which places + (../arch-lib): Replace by the ${archlibdir} target, which places the executables in their permanent home. (install, install.sysv, install.xenix): Consolidated into one target which should work under all circumstances, modulo a few diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in index 4d9fdba7726..13a7a05156c 100644 --- a/lib-src/Makefile.in +++ b/lib-src/Makefile.in @@ -1,7 +1,7 @@ ### @configure_input@ -# Copyright (C) 1985, 1987-1988, 1993-1994, 2001-2014 Free Software -# Foundation, Inc. +# Copyright (C) 1985, 1987-1988, 1993-1994, 2001-2014 +# Free Software Foundation, Inc. # This file is part of GNU Emacs. @@ -28,6 +28,9 @@ EMACSOPT = -batch --no-site-file --no-site-lisp CC=@CC@ CFLAGS=@CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ + version=@version@ ## Used in $archlibdir. configuration=@configuration@ @@ -42,6 +45,19 @@ UPDATE_MANIFEST = @UPDATE_MANIFEST@ # Program name transformation. TRANSFORM = @program_transform_name@ +# 'make' verbosity. +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ + +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = + +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = + # ==================== Where To Install Things ==================== # Location to install Emacs.app under GNUstep / Mac OS X. @@ -121,14 +137,12 @@ CLIENTW = @CLIENTW@ INSTALLABLES = etags${EXEEXT} ctags${EXEEXT} emacsclient${EXEEXT} $(CLIENTW) \ ebrowse${EXEEXT} -INSTALLABLE_SCRIPTS = grep-changelog - # Things that Emacs runs internally, or during the build process, # which should not be installed in bindir. UTILITIES = profile${EXEEXT} movemail${EXEEXT} hexl${EXEEXT} \ update-game-score${EXEEXT} -DONT_INSTALL= test-distrib${EXEEXT} make-docfile${EXEEXT} +DONT_INSTALL= make-docfile${EXEEXT} # Like UTILITIES, but they're not system-dependent, and should not be # deleted by the distclean target. @@ -192,13 +206,14 @@ BASE_CFLAGS = $(C_SWITCH_SYSTEM) $(C_SWITCH_MACHINE) \ -I${srcdir} -I${srcdir}/../src -I${srcdir}/../lib ALL_CFLAGS = ${BASE_CFLAGS} ${PROFILING_CFLAGS} ${LDFLAGS} ${CPPFLAGS} ${CFLAGS} +## Unused. LINK_CFLAGS = ${BASE_CFLAGS} ${LDFLAGS} ${CFLAGS} CPP_CFLAGS = ${BASE_CFLAGS} ${PROFILING_CFLAGS} ${CPPFLAGS} ${CFLAGS} # Configuration files for .o files to depend on. config_h = ../src/config.h $(srcdir)/../src/conf_post.h -all: ${EXE_FILES} ${SCRIPTS} ${INSTALLABLE_SCRIPTS} +all: ${EXE_FILES} ${SCRIPTS} .PHONY: all need-blessmail maybe-blessmail @@ -207,9 +222,9 @@ $(EXE_FILES): ../lib/libgnu.a ## Only used if we need blessmail, but no harm in always defining. ## This makes the actual blessmail executable. -blessmail: - $(EMACS) $(EMACSOPT) -l $(srcdir)/../lisp/mail/blessmail.el - chmod +x blessmail +blessmail: $(srcdir)/../lisp/mail/blessmail.el + $(EMACS) $(EMACSOPT) -l $< + chmod +x $@ ## This checks if we need to run blessmail. ## Do not charge ahead and do it! Let the installer decide. @@ -255,7 +270,7 @@ $(DESTDIR)${archlibdir}: all fi .PHONY: install uninstall mostlyclean clean distclean maintainer-clean -.PHONY: extraclean check tags +.PHONY: bootstrap-clean extraclean check tags install: $(DESTDIR)${archlibdir} @echo @@ -264,17 +279,11 @@ install: $(DESTDIR)${archlibdir} for file in ${INSTALLABLES} ; do \ $(INSTALL_PROGRAM) $(INSTALL_STRIP) $${file} "$(DESTDIR)${bindir}"/`echo $${file} | sed -e 's/${EXEEXT}$$//' -e '$(TRANSFORM)'`${EXEEXT} ; \ done - for file in ${INSTALLABLE_SCRIPTS} ; do \ - $(INSTALL_SCRIPT) ${srcdir}/$${file} "$(DESTDIR)${bindir}"/`echo $${file} | sed '$(TRANSFORM)'` ; \ - done uninstall: for file in ${INSTALLABLES}; do \ rm -f "$(DESTDIR)${bindir}"/`echo $${file} | sed -e 's/${EXEEXT}$$//' -e '$(TRANSFORM)'`${EXEEXT} ; \ done - for file in ${INSTALLABLE_SCRIPTS}; do \ - rm -f "$(DESTDIR)${bindir}"/`echo $${file} | sed '$(TRANSFORM)'` ; \ - done if [ -d "$(DESTDIR)${archlibdir}" ]; then \ (cd "$(DESTDIR)${archlibdir}" && rm -f ${UTILITIES} ${SCRIPTS}) \ fi @@ -289,7 +298,7 @@ distclean: clean -rm -f TAGS -rm -f Makefile blessmail -maintainer-clean: distclean +bootstrap-clean maintainer-clean: distclean true extraclean: maintainer-clean @@ -303,61 +312,55 @@ tags: TAGS TAGS: etags${EXEEXT} etags *.[ch] -## This verifies that the non-ASCII characters in the file \`testfile\' -## have not been clobbered by whatever means were used to copy and -## distribute Emacs. If they were clobbered, all the .elc files were -## clobbered too. -test-distrib${EXEEXT}: ${srcdir}/test-distrib.c - $(CC) ${ALL_CFLAGS} -o test-distrib${EXEEXT} ${srcdir}/test-distrib.c - ./test-distrib ${srcdir}/testfile - ../lib/libgnu.a: $(config_h) - cd ../lib && $(MAKE) libgnu.a + $(MAKE) -C ../lib libgnu.a regex.o: $(srcdir)/../src/regex.c $(srcdir)/../src/regex.h $(config_h) - ${CC} -c ${CPP_CFLAGS} ${srcdir}/../src/regex.c + $(AM_V_CC)$(CC) -c $(CPP_CFLAGS) $< -etags${EXEEXT}: ${srcdir}/etags.c regex.o $(NTLIB) $(config_h) - $(CC) ${ALL_CFLAGS} -DEMACS_NAME="\"GNU Emacs\"" \ - -DVERSION="\"${version}\"" ${srcdir}/etags.c \ - regex.o $(LOADLIBES) $(NTLIB) -o etags${EXEEXT} -ebrowse${EXEEXT}: ${srcdir}/ebrowse.c ${srcdir}/../lib/min-max.h $(NTLIB) \ - $(config_h) - $(CC) ${ALL_CFLAGS} -DVERSION="\"${version}\"" \ - ${srcdir}/ebrowse.c $(LOADLIBES) $(NTLIB) -o ebrowse${EXEEXT} +etags_deps = ${srcdir}/etags.c regex.o $(NTLIB) $(config_h) +etags_cflags = -DEMACS_NAME="\"GNU Emacs\"" -DVERSION="\"${version}\"" -o $@ +etags_libs = regex.o $(NTLIB) $(LOADLIBES) + +etags${EXEEXT}: ${etags_deps} + $(AM_V_CCLD)$(CC) ${ALL_CFLAGS} $(etags_cflags) $< $(etags_libs) -## We depend on etags to assure that parallel makes do not write two +## ctags.c is distinct from etags.c so that parallel makes do not write two ## etags.o files on top of each other. -ctags${EXEEXT}: etags${EXEEXT} - $(CC) ${ALL_CFLAGS} -DCTAGS -DEMACS_NAME="\"GNU Emacs\"" \ - -DVERSION="\"${version}\"" ${srcdir}/etags.c \ - regex.o $(LOADLIBES) $(NTLIB) -o ctags${EXEEXT} +## FIXME? +## Can't we use a wrapper that calls 'etags --ctags'? +ctags${EXEEXT}: ${srcdir}/ctags.c ${etags_deps} + $(AM_V_CCLD)$(CC) ${ALL_CFLAGS} $(etags_cflags) $< $(etags_libs) + +ebrowse${EXEEXT}: ${srcdir}/ebrowse.c ${srcdir}/../lib/min-max.h $(NTLIB) \ + $(config_h) + $(AM_V_CCLD)$(CC) ${ALL_CFLAGS} -DVERSION="\"${version}\"" \ + $< $(NTLIB) $(LOADLIBES) -o $@ profile${EXEEXT}: ${srcdir}/profile.c $(NTLIB) $(config_h) - $(CC) ${ALL_CFLAGS} ${srcdir}/profile.c \ - $(LOADLIBES) $(NTLIB) $(LIB_CLOCK_GETTIME) -o profile${EXEEXT} + $(AM_V_CCLD)$(CC) ${ALL_CFLAGS} $< \ + $(NTLIB) $(LOADLIBES) $(LIB_CLOCK_GETTIME) -o $@ make-docfile${EXEEXT}: ${srcdir}/make-docfile.c $(NTLIB) $(config_h) - $(CC) ${ALL_CFLAGS} ${srcdir}/make-docfile.c $(LOADLIBES) $(NTLIB) \ - -o make-docfile${EXEEXT} + $(AM_V_CCLD)$(CC) ${ALL_CFLAGS} $< $(NTLIB) $(LOADLIBES) -o $@ movemail${EXEEXT}: ${srcdir}/movemail.c pop.o $(NTLIB) $(config_h) - $(CC) ${ALL_CFLAGS} ${MOVE_FLAGS} ${srcdir}/movemail.c pop.o \ - $(LOADLIBES) $(NTLIB) $(LIBS_MOVE) -o movemail${EXEEXT} + $(AM_V_CCLD)$(CC) ${ALL_CFLAGS} ${MOVE_FLAGS} $< pop.o \ + $(NTLIB) $(LOADLIBES) $(LIBS_MOVE) -o $@ pop.o: ${srcdir}/pop.c ${srcdir}/pop.h ${srcdir}/../lib/min-max.h $(config_h) - $(CC) -c ${CPP_CFLAGS} ${MOVE_FLAGS} ${srcdir}/pop.c + $(AM_V_CC)$(CC) -c ${CPP_CFLAGS} ${MOVE_FLAGS} $< emacsclient${EXEEXT}: ${srcdir}/emacsclient.c $(NTLIB) $(config_h) - $(CC) ${ALL_CFLAGS} ${srcdir}/emacsclient.c \ + $(AM_V_CCLD)$(CC) ${ALL_CFLAGS} $< \ -DVERSION="\"${version}\"" $(NTLIB) $(LOADLIBES) $(LIB_FDATASYNC) \ - $(LIB_WSOCK32) $(LIBS_ECLIENT) -o emacsclient${EXEEXT} + $(LIB_WSOCK32) $(LIBS_ECLIENT) -o $@ emacsclientw${EXEEXT}: ${srcdir}/emacsclient.c $(NTLIB) $(CLIENTRES) $(config_h) - $(CC) ${ALL_CFLAGS} $(CLIENTRES) -mwindows ${srcdir}/emacsclient.c \ + $(AM_V_CCLD)$(CC) ${ALL_CFLAGS} $(CLIENTRES) -mwindows $< \ -DVERSION="\"${version}\"" $(LOADLIBES) $(LIB_FDATASYNC) \ - $(LIB_WSOCK32) $(LIBS_ECLIENT) -o emacsclientw${EXEEXT} + $(LIB_WSOCK32) $(LIBS_ECLIENT) -o $@ NTINC = ${srcdir}/../nt/inc NTDEPS = $(NTINC)/ms-w32.h $(NTINC)/sys/stat.h $(NTINC)/inttypes.h \ @@ -367,18 +370,17 @@ NTDEPS = $(NTINC)/ms-w32.h $(NTINC)/sys/stat.h $(NTINC)/inttypes.h \ # The dependency on $(NTDEPS) is a trick intended to cause recompile of # programs on MinGW whenever some private header in nt/inc is modified. ntlib.o: ${srcdir}/ntlib.c ${srcdir}/ntlib.h $(NTDEPS) - $(CC) -c ${CPP_CFLAGS} ${srcdir}/ntlib.c + $(AM_V_CC)$(CC) -c ${CPP_CFLAGS} $< hexl${EXEEXT}: ${srcdir}/hexl.c $(NTLIB) $(config_h) - $(CC) ${ALL_CFLAGS} ${srcdir}/hexl.c $(LOADLIBES) -o hexl${EXEEXT} + $(AM_V_CCLD)$(CC) ${ALL_CFLAGS} $< $(LOADLIBES) -o $@ update-game-score${EXEEXT}: ${srcdir}/update-game-score.c $(NTLIB) $(config_h) - $(CC) ${ALL_CFLAGS} -DHAVE_SHARED_GAME_DIR="\"$(gamedir)\"" \ - ${srcdir}/update-game-score.c $(LOADLIBES) $(NTLIB) \ - -o update-game-score${EXEEXT} + $(AM_V_CCLD)$(CC) ${ALL_CFLAGS} \ + -DHAVE_SHARED_GAME_DIR="\"$(gamedir)\"" \ + $< $(NTLIB) $(LOADLIBES) -o $@ -emacsclient.res: $(NTINC)/../emacsclient.rc - $(WINDRES) -O coff --include-dir=$(NTINC)/.. -o emacsclient.res \ - $(NTINC)/../emacsclient.rc +emacsclient.res: ../nt/emacsclient.rc $(NTINC)/../icons/emacs.ico + $(WINDRES) -O coff --include-dir=$(NTINC)/.. -o $@ $< ## Makefile ends here. diff --git a/lib-src/ctags.c b/lib-src/ctags.c new file mode 100644 index 00000000000..0a6838a9dbb --- /dev/null +++ b/lib-src/ctags.c @@ -0,0 +1,2 @@ +#define CTAGS 1 +#include "etags.c" diff --git a/lib-src/ebrowse.c b/lib-src/ebrowse.c index 29a88e85f02..b7431593c3e 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 += 2; } len = 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 += len; if (HAS_FLAG (p->flags, F_TEMPLATE)) { ensure_scope_buffer_room (3); - strcat (scope_buffer, "<>"); + strcpy (scope_buffer + scope_buffer_len, "<>"); scope_buffer_len += 2; } @@ -2797,24 +2797,25 @@ operator_name (int *sc) s = token_string (LA1); MATCH (); - len = strlen (s) + 10; + ptrdiff_t slen = strlen (s); + len = slen + 10; if (len > id_size) { size_t new_size = max (len, 2 * id_size); id = (char *) xrealloc (id, new_size); id_size = new_size; } - strcpy (id, s); + char *z = stpcpy (id, s); /* Vector new or delete? */ if (LOOKING_AT ('[')) { - strcat (id, "["); + z = stpcpy (z, "["); MATCH (); if (LOOKING_AT (']')) { - strcat (id, "]"); + strcpy (z, "]"); MATCH (); } } @@ -2830,7 +2831,7 @@ operator_name (int *sc) id = (char *) xrealloc (id, new_size); id_size = new_size; } - strcpy (id, "operator"); + char *z = stpcpy (id, "operator"); /* 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 += strlen (s) + 2; if (len > id_size) { + ptrdiff_t idlen = z - id; size_t new_size = max (len, 2 * id_size); id = (char *) xrealloc (id, new_size); id_size = new_size; + z = id + idlen; } if (*s != ')' && *s != ']') - strcat (id, " "); - strcat (id, s); + *z++ = ' '; + z = stpcpy (z, s); MATCH (); /* If this is a simple operator like `+', stop now. */ @@ -3462,9 +3465,9 @@ open_file (char *file) buffer = (char *) xrealloc (buffer, buffer_size); } - strcpy (buffer, path->path); - strcat (buffer, "/"); - strcat (buffer, file); + char *z = stpcpy (buffer, path->path); + *z++ = '/'; + strcpy (z, file); fp = fopen (buffer, "r"); } diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index a1177f54576..cfc321a1830 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c @@ -82,10 +82,6 @@ char *w32_getenv (char *); #include <signal.h> #include <errno.h> - - -char *getenv (const char *); - #ifndef VERSION #define VERSION "unspecified" #endif @@ -909,9 +905,9 @@ get_server_config (const char *config_file, struct sockaddr_in *server, { char *path = xmalloc (strlen (home) + strlen (config_file) + EXTRA_SPACE); - strcpy (path, home); - strcat (path, "/.emacs.d/server/"); - strcat (path, config_file); + char *z = stpcpy (path, home); + z = stpcpy (z, "/.emacs.d/server/"); + strcpy (z, config_file); config = fopen (path, "rb"); free (path); } @@ -920,9 +916,9 @@ get_server_config (const char *config_file, struct sockaddr_in *server, { char *path = xmalloc (strlen (home) + strlen (config_file) + EXTRA_SPACE); - strcpy (path, home); - strcat (path, "/.emacs.d/server/"); - strcat (path, config_file); + char *z = stpcpy (path, home); + z = stpcpy (z, "/.emacs.d/server/"); + strcpy (z, config_file); config = fopen (path, "rb"); free (path); } @@ -1197,7 +1193,6 @@ set_local_socket (const char *local_socket_name) { /* socket_name is a file name component. */ long uid = geteuid (); - ptrdiff_t tmpdirlen; use_tmpdir = 1; tmpdir = egetenv ("TMPDIR"); if (!tmpdir) @@ -1216,12 +1211,11 @@ set_local_socket (const char *local_socket_name) #endif tmpdir = "/tmp"; } - tmpdirlen = strlen (tmpdir); socket_name_storage = - 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 = stpcpy (socket_name_storage, tmpdir); + z += sprintf (z, "/emacs%ld/", uid); + strcpy (z, server_name); local_socket_name = socket_name_storage; } @@ -1257,12 +1251,12 @@ set_local_socket (const char *local_socket_name) { /* We're running under su, apparently. */ long uid = pw->pw_uid; - ptrdiff_t tmpdirlen = strlen (tmpdir); char *user_socket_name - = 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); + = xmalloc (strlen (tmpdir) + strlen (server_name) + + EXTRA_SPACE); + char *z = stpcpy (user_socket_name, tmpdir); + z += sprintf (z, "/emacs%ld/", uid); + strcpy (z, server_name); if (strlen (user_socket_name) < sizeof (server.sun_path)) strcpy (server.sun_path, user_socket_name); @@ -1511,8 +1505,7 @@ start_daemon_and_retry_set_socket (void) const char *deq = "--daemon="; char *daemon_arg = 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] = daemon_arg; } execvp ("emacs", d_argv); diff --git a/lib-src/etags.c b/lib-src/etags.c index 5f1f99c4677..78b3fed1128 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c @@ -105,17 +105,13 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4"; #ifdef MSDOS # undef MSDOS # define MSDOS true -# include <fcntl.h> # include <sys/param.h> -# include <io.h> #else # define MSDOS false #endif /* MSDOS */ #ifdef WINDOWSNT -# include <fcntl.h> # include <direct.h> -# include <io.h> # define MAXPATHLEN _MAX_PATH # undef HAVE_NTGUI # undef DOS_NT @@ -131,6 +127,7 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4"; #include <errno.h> #include <sys/types.h> #include <sys/stat.h> +#include <binary-io.h> #include <c-strcase.h> #include <assert.h> @@ -317,7 +314,7 @@ static long readline_internal (linebuffer *, FILE *); static bool nocase_tail (const char *); static void get_tag (char *, char **); -static void analyse_regex (char *); +static void analyze_regex (char *); static void free_regexps (void); static void regex_tag_multiline (void); static void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); @@ -342,8 +339,6 @@ static char *skip_non_spaces (char *); static char *skip_name (char *); static char *savenstr (const char *, int); static char *savestr (const char *); -static char *etags_strchr (const char *, int); -static char *etags_strrchr (const char *, int); static char *etags_getcwd (void); static char *relative_filename (char *, char *); static char *absolute_filename (char *, char *); @@ -1002,13 +997,8 @@ main (int argc, char **argv) linebuffer filename_lb; bool help_asked = false; ptrdiff_t len; - char *optstring; - int opt; - - -#ifdef DOS_NT - _fmode = O_BINARY; /* all of files are treated as binary files */ -#endif /* DOS_NT */ + char *optstring; + int opt; progname = argv[0]; nincluded_files = 0; @@ -1195,15 +1185,10 @@ main (int argc, char **argv) if (streq (tagfile, "-")) { tagf = stdout; -#ifdef DOS_NT - /* Switch redirected `stdout' to binary mode (setting `_fmode' - doesn't take effect until after `stdout' is already open). */ - if (!isatty (fileno (stdout))) - setmode (fileno (stdout), O_BINARY); -#endif /* DOS_NT */ + SET_BINARY (fileno (stdout)); } else - tagf = fopen (tagfile, append_to_tagfile ? "a" : "w"); + tagf = fopen (tagfile, append_to_tagfile ? "ab" : "wb"); if (tagf == NULL) pfatal (tagfile); } @@ -1222,7 +1207,7 @@ main (int argc, char **argv) lang = argbuffer[i].lang; break; case at_regexp: - analyse_regex (argbuffer[i].what); + analyze_regex (argbuffer[i].what); break; case at_filename: this_file = argbuffer[i].what; @@ -1292,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 = stpcpy (cmd, "mv "); + z = stpcpy (z, tagfile); + z = stpcpy (z, " OTAGS;fgrep -v '\t"); + z = stpcpy (z, argbuffer[i].what); + z = stpcpy (z, "\t' OTAGS >"); + z = stpcpy (z, tagfile); + strcpy (z, ";rm OTAGS"); if (system (cmd) != EXIT_SUCCESS) fatal ("failed to execute shell command", (char *)NULL); } @@ -1306,7 +1291,7 @@ main (int argc, char **argv) append_to_tagfile = true; } - tagf = fopen (tagfile, append_to_tagfile ? "a" : "w"); + tagf = fopen (tagfile, append_to_tagfile ? "ab" : "wb"); if (tagf == NULL) pfatal (tagfile); put_entries (nodehead); /* write all the tags (CTAGS) */ @@ -1322,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 = stpcpy (cmd, "sort -u -o "); + z = stpcpy (z, tagfile); + *z++ = ' '; + strcpy (z, tagfile); exit (system (cmd)); } return EXIT_SUCCESS; @@ -1347,8 +1332,8 @@ get_compressor_from_suffix (char *file, char **extptr) /* File has been processed by canonicalize_filename, so we don't need to consider backslashes on DOS_NT. */ - slash = etags_strrchr (file, '/'); - suffix = etags_strrchr (file, '.'); + slash = strrchr (file, '/'); + suffix = strrchr (file, '.'); if (suffix == NULL || suffix < slash) return NULL; if (extptr != NULL) @@ -1435,7 +1420,7 @@ get_language_from_filename (char *file, int case_sensitive) return lang; /* If not found, try suffix after last dot. */ - suffix = etags_strrchr (file, '.'); + suffix = strrchr (file, '.'); if (suffix == NULL) return NULL; suffix += 1; @@ -1547,11 +1532,11 @@ process_file_name (char *file, language *lang) if (real_name == compressed_name) { char *cmd = concat (compr->command, " ", real_name); - inf = (FILE *) popen (cmd, "r"); + inf = popen (cmd, "rb"); free (cmd); } else - inf = fopen (real_name, "r"); + inf = fopen (real_name, "rb"); if (inf == NULL) { perror (real_name); @@ -1712,7 +1697,7 @@ find_entries (FILE *inf) /* Set lp to point at the first char after the last slash in the line or, if no slashes, at the first nonblank. Then set cp to the first successive blank and terminate the string. */ - lp = etags_strrchr (lb.buffer+2, '/'); + lp = strrchr (lb.buffer+2, '/'); if (lp != NULL) lp += 1; else @@ -1897,9 +1882,9 @@ pfnote (char *name, bool is_func, char *linestart, int linelen, int lno, /* If ctags mode, change name "main" to M<thisfilename>. */ if (CTAGS && !cxref_style && streq (name, "main")) { - register char *fp = etags_strrchr (curfdp->taggedfname, '/'); + char *fp = strrchr (curfdp->taggedfname, '/'); np->name = concat ("M", fp == NULL ? curfdp->taggedfname : fp + 1, ""); - fp = etags_strrchr (np->name, '.'); + fp = strrchr (np->name, '.'); if (fp != NULL && fp[1] != '\0' && fp[2] == '\0') fp[0] = '\0'; } @@ -3442,8 +3427,9 @@ C_entries (int c_ext, FILE *inf) case omethodtag: case omethodparm: objdef = omethodcolon; - linebuffer_setlen (&token_name, token_name.len + 1); - strcat (token_name.buffer, ":"); + int toklen = token_name.len; + linebuffer_setlen (&token_name, toklen + 1); + strcpy (token_name.buffer + toklen, ":"); break; } if (structdef == stagseen) @@ -4129,7 +4115,7 @@ Ada_funcs (FILE *inf) /* Skip a string i.e. "abcd". */ if (inquote || (*dbp == '"')) { - dbp = etags_strchr (dbp + !inquote, '"'); + dbp = strchr (dbp + !inquote, '"'); if (dbp != NULL) { inquote = false; @@ -4287,7 +4273,7 @@ Perl_functions (FILE *inf) cp++; if (cp == sp) continue; /* nothing found */ - if ((pos = etags_strchr (sp, ':')) != NULL + if ((pos = strchr (sp, ':')) != NULL && pos < cp && pos[1] == ':') /* The name is already qualified. */ make_tag (sp, cp - sp, true, @@ -5042,7 +5028,7 @@ TEX_decode_env (const char *evarname, const char *defenv) /* Allocate a token table */ for (len = 1, p = env; p;) - if ((p = etags_strchr (p, ':')) && *++p != '\0') + if ((p = strchr (p, ':')) && *++p != '\0') len++; TEX_toktab = xnew (len, linebuffer); @@ -5050,7 +5036,7 @@ TEX_decode_env (const char *evarname, const char *defenv) /* zero-length strings (leading ':', "::" and trailing ':') */ for (i = 0; *env != '\0';) { - p = etags_strchr (env, ':'); + p = strchr (env, ':'); if (!p) /* End of environment string. */ p = env + strlen (env); if (p - env > 0) @@ -5588,7 +5574,7 @@ scan_separators (char *name) /* Look at the argument of --regex or --no-regex and do the right thing. Same for each line of a regexp file. */ static void -analyse_regex (char *regex_arg) +analyze_regex (char *regex_arg) { if (regex_arg == NULL) { @@ -5614,12 +5600,12 @@ analyse_regex (char *regex_arg) char *regexfile = regex_arg + 1; /* regexfile is a file containing regexps, one per line. */ - regexfp = fopen (regexfile, "r"); + regexfp = fopen (regexfile, "rb"); if (regexfp == NULL) pfatal (regexfile); linebuffer_init (®exbuf); while (readline_internal (®exbuf, regexfp) > 0) - analyse_regex (regexbuf.buffer); + analyze_regex (regexbuf.buffer); free (regexbuf.buffer); fclose (regexfp); } @@ -5780,9 +5766,9 @@ substitute (char *in, char *out, struct re_registers *regs) /* Pass 1: figure out how much to allocate by finding all \N strings. */ if (out[size - 1] == '\\') fatal ("pattern error in \"%s\"", out); - for (t = etags_strchr (out, '\\'); + for (t = strchr (out, '\\'); t != NULL; - t = etags_strchr (t + 2, '\\')) + t = strchr (t + 2, '\\')) if (ISDIGIT (t[1])) { dig = t[1] - '0'; @@ -6064,7 +6050,7 @@ readline (linebuffer *lbp, FILE *stream) { char *endp = lbp->buffer + start; - while ((endp = etags_strchr (endp, '"')) != NULL + while ((endp = strchr (endp, '"')) != NULL && endp[-1] == '\\') endp++; if (endp != NULL) @@ -6249,43 +6235,6 @@ savenstr (const char *cp, int len) return memcpy (dp, cp, len); } -/* - * Return the ptr in sp at which the character c last - * appears; NULL if not found - * - * Identical to POSIX strrchr, included for portability. - */ -static char * -etags_strrchr (register const char *sp, register int c) -{ - register const char *r; - - r = NULL; - do - { - if (*sp == c) - r = sp; - } while (*sp++); - return (char *)r; -} - -/* - * Return the ptr in sp at which the character c first - * appears; NULL if not found - * - * Identical to POSIX strchr, included for portability. - */ -static char * -etags_strchr (register const char *sp, register int c) -{ - do - { - if (*sp == c) - return (char *)sp; - } while (*sp++); - return NULL; -} - /* Skip spaces (end of string is not space), return new pointer. */ static char * skip_spaces (char *cp) @@ -6411,15 +6360,15 @@ relative_filename (char *file, char *dir) /* Build a sequence of "../" strings for the resulting relative file name. */ i = 0; - while ((dp = etags_strchr (dp + 1, '/')) != NULL) + while ((dp = strchr (dp + 1, '/')) != NULL) i += 1; res = xnew (3*i + strlen (fp + 1) + 1, char); - res[0] = '\0'; + char *z = res; while (i-- > 0) - strcat (res, "../"); + z = stpcpy (z, "../"); /* Add the file name relative to the common root of file and dir. */ - strcat (res, fp + 1); + strcpy (z, fp + 1); free (afn); return res; @@ -6444,7 +6393,7 @@ absolute_filename (char *file, char *dir) res = concat (dir, file, ""); /* Delete the "/dirname/.." and "/." substrings. */ - slashp = etags_strchr (res, '/'); + slashp = strchr (res, '/'); while (slashp != NULL && slashp[0] != '\0') { if (slashp[1] == '.') @@ -6476,7 +6425,7 @@ absolute_filename (char *file, char *dir) } } - slashp = etags_strchr (slashp + 1, '/'); + slashp = strchr (slashp + 1, '/'); } if (res[0] == '\0') /* just a safety net: should never happen */ @@ -6497,7 +6446,7 @@ absolute_dirname (char *file, char *dir) char *slashp, *res; char save; - slashp = etags_strrchr (file, '/'); + slashp = strrchr (file, '/'); if (slashp == NULL) return savestr (dir); save = slashp[1]; diff --git a/lib-src/grep-changelog b/lib-src/grep-changelog deleted file mode 100755 index ab8c5e38618..00000000000 --- a/lib-src/grep-changelog +++ /dev/null @@ -1,265 +0,0 @@ -#! /usr/bin/perl - -# Copyright (C) 1999-2014 Free Software Foundation, Inc. -# -# This file is part of GNU Emacs. - -# GNU Emacs 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. - -# GNU Emacs 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 GNU Emacs. If not, see <http://www.gnu.org/licenses/>. - - -# Extract entries from ChangeLogs matching specified criteria. -# Optionally format the resulting output to a form suitable for RCS -# logs, like they are used in Emacs, for example. In this format, -# author lines, leading spaces, and file names are removed. - -require 5; -use strict; - -# Parse command line options. - -use vars qw($author $regexp $exclude $from_date $to_date - $rcs_log $with_date $version $help $reverse - @entries); - -use Getopt::Long; - -my $result; - -if (@ARGV == 0) { - - # No arguments cannot possibly mean "show everything"!! - $result = 0; - -} else { - - $result = GetOptions ("author=s" => \$author, - "text=s" => \$regexp, - "exclude=s" => \$exclude, - "from-date=s" => \$from_date, - "to-date=s" => \$to_date, - "rcs-log" => \$rcs_log, - "with-date" => \$with_date, - "reverse!" => \$reverse, - "version" => \$version, - "help" => \$help); - - # If date options are specified, check that they have the format - # YYYY-MM-DD. - - $result = 0 if $from_date && $from_date !~ /^\d\d\d\d-\d\d-\d\d$/; - $result = 0 if $to_date && $to_date !~ /^\d\d\d\d-\d\d-\d\d$/; -} - -# Print usage information and exit when necessary. - -if ($result == 0 || $help) { - print <<USAGE; - -Usage: $0 [options] [CHANGELOG...] - -Print entries in ChangeLogs matching various criteria. -Valid options are: - - --author=AUTHOR Match entries whose author line matches - regular expression AUTHOR - --text=TEXT Match entries whose text matches regular - expression TEXT - --exclude=TEXT Exclude entries matching TEXT - --from-date=YYYY-MM-DD Match entries not older than given date - --to-date=YYYY-MM-DD Match entries not younger than given date - --rcs-log Format output suitable for RCS log entries - --with-date Print short date line in RCS log - --reverse Show entries in reverse (chronological) order - --version Print version info - --help Print this help - -If no CHANGELOG is specified scan the files "ChangeLog" and -"ChangeLog.N+" in the current directory. Old-style dates in ChangeLogs -are not recognized. -USAGE - exit !$help; -} - -# Print version info and exit if `--version' was specified. - -if ($version) { - print "0.3\n"; - exit 0; -} - - -# Value is non-zero if HEADER matches according to command line -# options specified, i.e. it matches $author, and its date is in -# the range $from_date <= date <= $to_date. - -sub header_match_p { - my $header = shift; - - return 0 unless $header; - - # No match if AUTHOR-regexp specified and doesn't match. - return 0 if $author && $header !~ /$author/; - - # Check that the date of the entry matches if date options - # `--from-date' and/or `--to-date' were specified . Old-style - # dates in ChangeLogs are not recognized, and never match. - if ($from_date || $to_date) { - if ($header =~ /^(\d\d\d\d-\d\d-\d\d)/) { - my $date = $1; - return 0 if $from_date && $date lt $from_date; - return 0 if $to_date && $date gt $to_date; - } else { - # Don't bother recognizing old-style dates. - return 0; - } - } - - return 1; -} - - -# Value is non-zero if ENTRY matches the criteria specified on the -# command line, i.e. it matches $regexp, and it doesn't match -# $exclude. - -sub entry_match_p { - my $entry = shift; - - return 0 unless $entry; - - if ($regexp) { - return 1 if ($entry =~ /$regexp/ - && (!$exclude || $entry !~ $exclude)); - } else { - return 1 if !$exclude || $entry !~ $exclude; - } - - return 0; -} - - -# Print HEADER and/or ENTRY in a format suitable for what was -# specified on the command line. If $rcs_log is specified, author -# lines are not printed, and leading spaces and file names are removed -# from ChangeLog entries. - -sub print_log { - my ($header, $entry) = @_; - my $output = ''; - - if ($rcs_log) { - # Remove leading whitespace from entry. - $entry =~ s/^\s+//mg; - # Remove file name parts. - $entry =~ s/^\*.*\(/(/mg; - # Remove file name parts, 2. - $entry =~ s/^\*.*://mg; - if ($with_date) { - $header =~ /(\d\d\d\d-\d\d-\d\d)/; - $output = "!changelog-date $1\n"; - } - $output .= $entry; - } else { - $output .= $header . $entry; - } - - if ($reverse) { - push @entries, $output; - } else { - print $output; - } -} - -# Scan LOG for matching entries, and print them to standard output. - -sub parse_changelog { - my $log = shift; - my $entry = undef; - my $header = undef; - - @entries = () if $reverse; - - # Open the ChangeLog. - open (IN, "< $log") || die "Cannot open $log: $!"; - - while (defined(my $line = <IN>)) { - if ($line =~ /^\S/) { - # Line is an author-line. Print previous entry if - # it matches. - print_log ($header, $entry) - if header_match_p ($header) && entry_match_p ($entry); - - $entry = ""; - $header = $line; - - # Add empty lines below the header. - while (defined($line = <IN>) && $line =~ /^\s*$/) { - $header = "$header$line"; - } - } - - last unless defined $line; - - if ($line =~ /^\s*\*/) { - # LINE is the first line of a ChangeLog entry. Print - # previous entry if it matches. - print_log ($header, $entry) - if header_match_p ($header) && entry_match_p ($entry); - $entry = $line; - } else { - # Add LINE to the current entry. - $entry = "$entry$line"; - } - } - - # Print last entry if it matches. - print_log ($header, $entry) - if header_match_p ($header) && entry_match_p ($entry); - - close IN; - - if ($reverse) { - for (my $entry = @entries; $entry; $entry--) { - print $entries[$entry-1]; - } - } -} - - -# Main program. Process ChangeLogs. - -# If files were specified on the command line, parse those files in the -# order supplied by the user; otherwise parse default files ChangeLog and -# ChangeLog.NNN according to $reverse. -unless (@ARGV > 0) { - @ARGV = ("ChangeLog"); - - push @ARGV, - map {"ChangeLog.$_"} - sort {$b <=> $a} - map {/\.(\d+)$/; $1} - do { - opendir D, '.'; - grep /^ChangeLog\.\d+$/, readdir D; - }; - - @ARGV = reverse @ARGV if $reverse; -} - -while (defined (my $log = shift @ARGV)) { - parse_changelog ($log) if -f $log; -} - - -# grep-changelog ends here. diff --git a/lib-src/hexl.c b/lib-src/hexl.c index 9e21ddf9de6..51744ab08a2 100644 --- a/lib-src/hexl.c +++ b/lib-src/hexl.c @@ -24,15 +24,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <stdio.h> #include <ctype.h> -#ifdef DOS_NT -#include <fcntl.h> -#if __DJGPP__ >= 2 -#include <io.h> -#endif -#endif -#ifdef WINDOWSNT -#include <io.h> -#endif + +#include <binary-io.h> #define DEFAULT_GROUPING 0x01 #define DEFAULT_BASE 16 @@ -155,20 +148,12 @@ main (int argc, char **argv) if (un_flag) { - char buf[18]; - -#ifdef DOS_NT -#if (__DJGPP__ >= 2) || (defined WINDOWSNT) - if (!isatty (fileno (stdout))) - setmode (fileno (stdout), O_BINARY); -#else - (stdout)->_flag &= ~_IOTEXT; /* print binary */ - _setmode (fileno (stdout), O_BINARY); -#endif -#endif + SET_BINARY (fileno (stdout)); + for (;;) { - register int i, c = 0, d; + int i, c = 0, d; + char buf[18]; #define hexchar(x) (isdigit (x) ? x - '0' : x - 'a' + 10) @@ -210,15 +195,7 @@ main (int argc, char **argv) } else { -#ifdef DOS_NT -#if (__DJGPP__ >= 2) || (defined WINDOWSNT) - if (!isatty (fileno (fp))) - setmode (fileno (fp), O_BINARY); -#else - (fp)->_flag &= ~_IOTEXT; /* read binary */ - _setmode (fileno (fp), O_BINARY); -#endif -#endif + SET_BINARY (fileno (fp)); address = 0; string[0] = ' '; string[17] = '\0'; diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index 2eb2413815e..884b6c1001e 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c @@ -38,17 +38,16 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include <stdio.h> #include <stdlib.h> /* config.h unconditionally includes this anyway */ -#ifdef MSDOS -#include <fcntl.h> -#endif /* MSDOS */ + #ifdef WINDOWSNT /* Defined to be sys_fopen in ms-w32.h, but only #ifdef emacs, so this is really just insurance. */ #undef fopen -#include <fcntl.h> #include <direct.h> #endif /* WINDOWSNT */ +#include <binary-io.h> + #ifdef DOS_NT /* Defined to be sys_chdir in ms-w32.h, but only #ifdef emacs, so this is really just insurance. @@ -56,12 +55,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ Similarly, msdos defines this as sys_chdir, but we're not linking with the file where that function is defined. */ #undef chdir -#define READ_TEXT "rt" -#define READ_BINARY "rb" #define IS_SLASH(c) ((c) == '/' || (c) == '\\' || (c) == ':') #else /* not DOS_NT */ -#define READ_TEXT "r" -#define READ_BINARY "r" #define IS_SLASH(c) ((c) == '/') #endif /* not DOS_NT */ @@ -73,9 +68,6 @@ static void write_globals (void); #include <unistd.h> -/* Stdio stream for output to the DOC file. */ -FILE *outfile; - /* Name this program was invoked with. */ char *progname; @@ -135,33 +127,24 @@ main (int argc, char **argv) progname = argv[0]; - outfile = stdout; - - /* Don't put CRs in the DOC file. */ -#ifdef MSDOS - _fmode = O_BINARY; -#if 0 /* Suspicion is that this causes hanging. - So instead we require people to use -o on MSDOS. */ - (stdout)->_flag &= ~_IOTEXT; - _setmode (fileno (stdout), O_BINARY); -#endif - outfile = 0; -#endif /* MSDOS */ -#ifdef WINDOWSNT - _fmode = O_BINARY; - _setmode (fileno (stdout), O_BINARY); -#endif /* WINDOWSNT */ - /* If first two args are -o FILE, output to FILE. */ i = 1; if (argc > i + 1 && !strcmp (argv[i], "-o")) { - outfile = fopen (argv[i + 1], "w"); + if (! freopen (argv[i + 1], "w", stdout)) + { + perror (argv[i + 1]); + return EXIT_FAILURE; + } i += 2; } if (argc > i + 1 && !strcmp (argv[i], "-a")) { - outfile = fopen (argv[i + 1], "a"); + if (! freopen (argv[i + 1], "a", stdout)) + { + perror (argv[i + 1]); + return EXIT_FAILURE; + } i += 2; } if (argc > i + 1 && !strcmp (argv[i], "-d")) @@ -179,8 +162,7 @@ main (int argc, char **argv) ++i; } - if (outfile == 0) - fatal ("No output file specified", ""); + set_binary_mode (fileno (stdout), O_BINARY); if (generate_globals) start_globals (); @@ -215,13 +197,11 @@ put_filename (char *filename) filename = tmp + 1; } - putc (037, outfile); - putc ('S', outfile); - fprintf (outfile, "%s\n", filename); + printf ("\037S%s\n", filename); } -/* Read file FILENAME and output its doc strings to outfile. */ -/* Return 1 if file is not found, 0 if it is found. */ +/* Read file FILENAME and output its doc strings to stdout. + Return 1 if file is not found, 0 if it is found. */ static int scan_file (char *filename) @@ -232,19 +212,19 @@ scan_file (char *filename) if (!generate_globals) put_filename (filename); if (len > 4 && !strcmp (filename + len - 4, ".elc")) - return scan_lisp_file (filename, READ_BINARY); + return scan_lisp_file (filename, "rb"); else if (len > 3 && !strcmp (filename + len - 3, ".el")) - return scan_lisp_file (filename, READ_TEXT); + return scan_lisp_file (filename, "r"); else - return scan_c_file (filename, READ_TEXT); + return scan_c_file (filename, "r"); } static void start_globals (void) { - fprintf (outfile, "/* This file was auto-generated by make-docfile. */\n"); - fprintf (outfile, "/* DO NOT EDIT. */\n"); - fprintf (outfile, "struct emacs_globals {\n"); + puts ("/* This file was auto-generated by make-docfile. */"); + puts ("/* DO NOT EDIT. */"); + puts ("struct emacs_globals {"); } static char input_buffer[128]; @@ -373,7 +353,7 @@ scan_keyword_or_put_char (int ch, struct rcsoc_state *state) /* Skip a C string or C-style comment from INFILE, and return the character that follows. COMMENT non-zero means skip a comment. If - PRINTFLAG is positive, output string contents to outfile. If it is + PRINTFLAG is positive, output string contents to stdout. If it is negative, store contents in buf. Convert escape sequences \n and \t to newline and tab; discard \ followed by newline. If SAW_USAGE is non-zero, then any occurrences of the string `usage:' @@ -388,7 +368,7 @@ read_c_string_or_comment (FILE *infile, int printflag, int comment, int *saw_usa state.in_file = infile; state.buf_ptr = (printflag < 0 ? input_buffer : 0); - state.out_file = (printflag > 0 ? outfile : 0); + state.out_file = (printflag > 0 ? stdout : 0); state.pending_spaces = 0; state.pending_newlines = 0; state.keyword = (saw_usage ? "usage:" : 0); @@ -465,18 +445,18 @@ read_c_string_or_comment (FILE *infile, int printflag, int comment, int *saw_usa -/* Write to file OUT the argument names of function FUNC, whose text is in BUF. +/* Write to stdout the argument names of function FUNC, whose text is in BUF. MINARGS and MAXARGS are the minimum and maximum number of arguments. */ static void -write_c_args (FILE *out, char *func, char *buf, int minargs, int maxargs) +write_c_args (char *func, char *buf, int minargs, int maxargs) { register char *p; int in_ident = 0; char *ident_start IF_LINT (= NULL); size_t ident_length = 0; - fprintf (out, "(fn"); + fputs ("(fn", stdout); if (*buf == '(') ++buf; @@ -517,10 +497,10 @@ write_c_args (FILE *out, char *func, char *buf, int minargs, int maxargs) if (strncmp (ident_start, "void", ident_length) == 0) continue; - putc (' ', out); + putchar (' '); if (minargs == 0 && maxargs > 0) - fprintf (out, "&optional "); + fputs ("&optional ", stdout); minargs--; maxargs--; @@ -528,7 +508,7 @@ write_c_args (FILE *out, char *func, char *buf, int minargs, int maxargs) /* In C code, `default' is a reserved word, so we spell it `defalt'; demangle that here. */ if (ident_length == 6 && memcmp (ident_start, "defalt", 6) == 0) - fprintf (out, "DEFAULT"); + fputs ("DEFAULT", stdout); else while (ident_length-- > 0) { @@ -539,12 +519,12 @@ write_c_args (FILE *out, char *func, char *buf, int minargs, int maxargs) else if (c == '_') /* Print underscore as hyphen. */ c = '-'; - putc (c, out); + putchar (c); } } } - putc (')', out); + putchar (')'); } /* The types of globals. These are sorted roughly in decreasing alignment @@ -613,8 +593,8 @@ compare_globals (const void *a, const void *b) static void close_emacs_globals (void) { - fprintf (outfile, "};\n"); - fprintf (outfile, "extern struct emacs_globals globals;\n"); + puts ("};"); + puts ("extern struct emacs_globals globals;"); } static void @@ -641,7 +621,7 @@ write_globals (void) if (!seen_defun) { close_emacs_globals (); - fprintf (outfile, "\n"); + putchar ('\n'); seen_defun = 1; } break; @@ -651,9 +631,9 @@ write_globals (void) if (type) { - fprintf (outfile, " %s f_%s;\n", type, globals[i].name); - fprintf (outfile, "#define %s globals.f_%s\n", - globals[i].name, globals[i].name); + printf (" %s f_%s;\n", type, globals[i].name); + printf ("#define %s globals.f_%s\n", + globals[i].name, globals[i].name); } else { @@ -664,15 +644,26 @@ write_globals (void) || strcmp (globals[i].name, "Fkill_emacs") == 0 || strcmp (globals[i].name, "Fexit_recursive_edit") == 0 || strcmp (globals[i].name, "Fabort_recursive_edit") == 0) - fprintf (outfile, "_Noreturn "); - fprintf (outfile, "EXFUN (%s, ", globals[i].name); + fputs ("_Noreturn ", stdout); + + printf ("EXFUN (%s, ", globals[i].name); if (globals[i].value == -1) - fprintf (outfile, "MANY"); + fputs ("MANY", stdout); else if (globals[i].value == -2) - fprintf (outfile, "UNEVALLED"); + fputs ("UNEVALLED", stdout); else - fprintf (outfile, "%d", globals[i].value); - fprintf (outfile, ");\n"); + printf ("%d", globals[i].value); + putchar (')'); + + /* It would be nice to have a cleaner way to deal with these + special hacks, too. */ + if (strcmp (globals[i].name, "Fbyteorder") == 0 + || strcmp (globals[i].name, "Ftool_bar_height") == 0 + || strcmp (globals[i].name, "Fmax_char") == 0 + || strcmp (globals[i].name, "Fidentity") == 0) + fputs (" ATTRIBUTE_CONST", stdout); + + puts (";"); } while (i + 1 < num_globals @@ -941,9 +932,7 @@ scan_c_file (char *filename, const char *mode) int comment = c != '"'; int saw_usage; - putc (037, outfile); - putc (defvarflag ? 'V' : 'F', outfile); - fprintf (outfile, "%s\n", input_buffer); + printf ("\037%c%s\n", defvarflag ? 'V' : 'F', input_buffer); if (comment) getc (infile); /* Skip past `*'. */ @@ -985,8 +974,8 @@ scan_c_file (char *filename, const char *mode) while (c != ')'); *p = '\0'; /* Output them. */ - fprintf (outfile, "\n\n"); - write_c_args (outfile, input_buffer, argbuf, minargs, maxargs); + fputs ("\n\n", stdout); + write_c_args (input_buffer, argbuf, minargs, maxargs); } else if (defunflag && maxargs == -1 && !saw_usage) /* The DOC should provide the usage form. */ @@ -1422,12 +1411,10 @@ scan_lisp_file (const char *filename, const char *mode) In the latter case, the opening quote (and leading backslash-newline) have already been read. */ - putc (037, outfile); - putc (type, outfile); - fprintf (outfile, "%s\n", buffer); + printf ("\037%c%s\n", type, buffer); if (saved_string) { - fputs (saved_string, outfile); + fputs (saved_string, stdout); /* Don't use one dynamic doc string twice. */ free (saved_string); saved_string = 0; diff --git a/lib-src/movemail.c b/lib-src/movemail.c index d0d00fcf4cc..b0196b309d8 100644 --- a/lib-src/movemail.c +++ b/lib-src/movemail.c @@ -191,11 +191,6 @@ main (int argc, char **argv) uid_t real_gid = getgid (); uid_t priv_gid = getegid (); -#ifdef WINDOWSNT - /* Ensure all file i/o is in binary mode. */ - _fmode = _O_BINARY; -#endif - delete_lockname = 0; while ((c = getopt (argc, argv, ARGSTR)) != EOF) @@ -304,7 +299,7 @@ main (int argc, char **argv) memcpy (tempname, inname, inname_dirlen); strcpy (tempname + inname_dirlen, "EXXXXXX"); - desc = mkostemp (tempname, 0); + desc = mkostemp (tempname, O_BINARY); if (desc < 0) { int mkostemp_errno = errno; @@ -358,12 +353,12 @@ main (int argc, char **argv) #ifndef MAIL_USE_MMDF #ifdef MAIL_USE_SYSTEM_LOCK - indesc = open (inname, O_RDWR); + indesc = open (inname, O_RDWR | O_BINARY); #else /* if not MAIL_USE_SYSTEM_LOCK */ - indesc = open (inname, O_RDONLY); + indesc = open (inname, O_RDONLY | O_BINARY); #endif /* not MAIL_USE_SYSTEM_LOCK */ #else /* MAIL_USE_MMDF */ - indesc = lk_open (inname, O_RDONLY, 0, 0, 10); + indesc = lk_open (inname, O_RDONLY | O_BINARY, 0, 0, 10); #endif /* MAIL_USE_MMDF */ if (indesc < 0) @@ -372,7 +367,7 @@ main (int argc, char **argv) /* Make sure the user can read the output file. */ umask (umask (0) & 0377); - outdesc = open (outname, O_WRONLY | O_CREAT | O_EXCL, 0666); + outdesc = open (outname, O_WRONLY | O_BINARY | O_CREAT | O_EXCL, 0666); if (outdesc < 0) pfatal_with_name (outname); @@ -675,7 +670,7 @@ popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse return EXIT_SUCCESS; } - mbfi = open (outfile, O_WRONLY | O_CREAT | O_EXCL, 0666); + mbfi = open (outfile, O_WRONLY | O_BINARY | O_CREAT | O_EXCL, 0666); if (mbfi < 0) { pop_close (server); @@ -719,8 +714,8 @@ popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse for (i = start; i * increment <= end * increment; i += increment) { - mbx_delimit_begin (mbf); - if (pop_retr (server, i, mbf) != OK) + if (mbx_delimit_begin (mbf) != OK + || pop_retr (server, i, mbf) != OK) { error ("%s", Errmsg, 0); close (mbfi); @@ -837,15 +832,15 @@ mbx_write (char *line, int len, FILE *mbf) static int mbx_delimit_begin (FILE *mbf) { - time_t now; - struct tm *ltime; - char fromline[40] = "From movemail "; - - now = time (NULL); - ltime = localtime (&now); - - strcat (fromline, asctime (ltime)); - + time_t now = time (NULL); + struct tm *ltime = localtime (&now); + if (!ltime) + return NOTOK; + + char fromline[100]; + if (! strftime (fromline, sizeof fromline, + "From movemail %a %b %e %T %Y\n", ltime)) + return NOTOK; if (fputs (fromline, mbf) == EOF) return (NOTOK); return (OK); diff --git a/lib-src/ntlib.h b/lib-src/ntlib.h index dbb0195a30b..40ef9fa982d 100644 --- a/lib-src/ntlib.h +++ b/lib-src/ntlib.h @@ -90,7 +90,6 @@ int mkostemp (char * template, int flags); #define locking _locking #define logb _logb #define _longjmp longjmp -#define lseek _lseek #define popen _popen #define pclose _pclose #define umask _umask diff --git a/lib-src/pop.c b/lib-src/pop.c index ffe16c5f911..70011504a34 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 = alloca (strlen (line) + 3); - strcpy (buf, line); - strcat (buf, "\r\n"); + strcpy (stpcpy (buf, line), "\r\n"); ret = fullwrite (server->file, buf, strlen (buf)); if (ret < 0) diff --git a/lib-src/test-distrib.c b/lib-src/test-distrib.c deleted file mode 100644 index 88b95db9060..00000000000 --- a/lib-src/test-distrib.c +++ /dev/null @@ -1,88 +0,0 @@ -/* test-distrib.c --- testing distribution of nonprinting chars - -Copyright (C) 1987, 1993-1995, 1999, 2001-2014 Free Software Foundation, -Inc. - -This file is part of GNU Emacs. - -GNU Emacs 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. - -GNU Emacs 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 GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ - - -#include <config.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> - -/* Break string in two parts to avoid buggy C compilers that ignore characters - after nulls in strings. */ - -static char string1[] = "Testing distribution of nonprinting chars:\n\ -Should be 0177: \177 Should be 0377: \377 Should be 0212: \212.\n\ -Should be 0000: "; - -static char string2[] = ".\n\ -This file is read by the `test-distribution' program.\n\ -If you change it, you will make that program fail.\n"; - -/* Like `read' but keeps trying until it gets SIZE bytes or reaches eof. */ -static int -cool_read (int fd, char *buf, size_t size) -{ - ssize_t num; - ssize_t sofar = 0; - - while (1) - { - if ((num = read (fd, buf + sofar, size - sofar)) == 0) - return sofar; - else if (num < 0) - return num; - sofar += num; - } -} - -int -main (int argc, char **argv) -{ - int fd; - char buf[300]; - - if (argc != 2) - { - fprintf (stderr, "Usage: %s testfile\n", argv[0]); - exit (EXIT_FAILURE); - } - fd = open (argv[1], O_RDONLY); - if (fd < 0) - { - perror (argv[1]); - exit (EXIT_FAILURE); - } - if (cool_read (fd, buf, sizeof string1) != sizeof string1 || - strcmp (buf, string1) || - cool_read (fd, buf, sizeof string2) != sizeof string2 - 1 || - strncmp (buf, string2, sizeof string2 - 1)) - { - fprintf (stderr, "Data in file `%s' has been damaged.\n\ -Most likely this means that many nonprinting characters\n\ -have been corrupted in the files of Emacs, and it will not work.\n", - argv[1]); - exit (EXIT_FAILURE); - } - close (fd); - return EXIT_SUCCESS; -} - - -/* test-distrib.c ends here */ diff --git a/lib-src/testfile b/lib-src/testfile Binary files differdeleted file mode 100644 index 8230c35f405..00000000000 --- a/lib-src/testfile +++ /dev/null diff --git a/lib-src/update-game-score.c b/lib-src/update-game-score.c index cb6fdf73590..b311001bd62 100644 --- a/lib-src/update-game-score.c +++ b/lib-src/update-game-score.c @@ -76,9 +76,8 @@ static int unlock_file (const char *filename, void *state); struct score_entry { - intmax_t score; - char *username; - char *data; + char *score; + char *user_data; }; #define MAX_SCORES min (PTRDIFF_MAX, SIZE_MAX / sizeof (struct score_entry)) @@ -102,7 +101,8 @@ lose (const char *msg) static _Noreturn void lose_syserr (const char *msg) { - fprintf (stderr, "%s: %s\n", msg, strerror (errno)); + fprintf (stderr, "%s: %s\n", msg, + errno ? strerror (errno) : "Invalid data in score file"); exit (EXIT_FAILURE); } @@ -137,6 +137,38 @@ get_prefix (bool running_suid, const char *user_prefix) return user_prefix; } +static char * +normalize_integer (char *num) +{ + bool neg; + char *p; + while (*num != '\n' && isspace (*num)) + num++; + neg = *num == '-'; + num += neg || *num == '-'; + + if (*num == '0') + { + while (*++num == '0') + continue; + neg &= !!*num; + num -= !*num; + } + + for (p = num; '0' <= *p && *p <= '9'; p++) + continue; + + if (*p || p == num) + { + errno = 0; + return 0; + } + + if (neg) + *--num = '-'; + return num; +} + int main (int argc, char **argv) { @@ -144,9 +176,8 @@ main (int argc, char **argv) bool running_suid; void *lockstate; char *scorefile; - char *nl; + char *end, *nl, *user, *data; const char *prefix, *user_prefix = NULL; - struct stat buf; struct score_entry *scores; struct score_entry newscore; bool reverse = false; @@ -169,8 +200,8 @@ main (int argc, char **argv) break; case 'm': { - intmax_t m = strtoimax (optarg, 0, 10); - if (m < 0) + intmax_t m = strtoimax (optarg, &end, 10); + if (optarg == end || *end || m < 0) usage (EXIT_FAILURE); max_scores = min (m, MAX_SCORES); } @@ -190,25 +221,30 @@ main (int argc, char **argv) if (!scorefile) lose_syserr ("Couldn't allocate score file"); - strcpy (scorefile, prefix); - strcat (scorefile, "/"); - strcat (scorefile, argv[optind]); + char *z = stpcpy (scorefile, prefix); + *z++ = '/'; + strcpy (z, argv[optind]); - newscore.score = strtoimax (argv[optind + 1], 0, 10); + newscore.score = normalize_integer (argv[optind + 1]); + if (! newscore.score) + { + fprintf (stderr, "%s: Invalid score\n", argv[optind + 1]); + return EXIT_FAILURE; + } - newscore.data = argv[optind + 2]; - if (strlen (newscore.data) > MAX_DATA_LEN) - newscore.data[MAX_DATA_LEN] = '\0'; - nl = strchr (newscore.data, '\n'); + user = get_user_id (); + if (! user) + lose_syserr ("Couldn't determine user id"); + data = argv[optind + 2]; + if (strlen (data) > MAX_DATA_LEN) + data[MAX_DATA_LEN] = '\0'; + nl = strchr (data, '\n'); if (nl) *nl = '\0'; - - newscore.username = get_user_id (); - if (! newscore.username) - lose_syserr ("Couldn't determine user id"); - - if (stat (scorefile, &buf) < 0) - lose_syserr ("Failed to access scores file"); + newscore.user_data = malloc (strlen (user) + 1 + strlen (data) + 1); + if (! newscore.user_data + || sprintf (newscore.user_data, "%s %s", user, data) < 0) + lose_syserr ("Memory exhausted"); if (lock_file (scorefile, &lockstate) < 0) lose_syserr ("Failed to lock scores file"); @@ -244,137 +280,75 @@ main (int argc, char **argv) exit (EXIT_SUCCESS); } -static int -read_score (FILE *f, struct score_entry *score) +static char * +read_score (char *p, struct score_entry *score) { - int c; - if ((c = getc (f)) != EOF) - ungetc (c, f); - if (feof (f)) - return 1; - for (score->score = 0; (c = getc (f)) != EOF && isdigit (c); ) - { - if (INTMAX_MAX / 10 < score->score) - return -1; - score->score *= 10; - if (INTMAX_MAX - (c - '0') < score->score) - return -1; - score->score += c - '0'; - } - while ((c = getc (f)) != EOF - && isspace (c)) - ; - if (c == EOF) - return -1; - ungetc (c, f); -#ifdef HAVE_GETDELIM - { - size_t count = 0; - score->username = 0; - if (getdelim (&score->username, &count, ' ', f) < 1 - || score->username == NULL) - return -1; - /* Trim the space */ - score->username[strlen (score->username)-1] = '\0'; - } -#else - { - ptrdiff_t unameread = 0; - ptrdiff_t unamelen = 30; - char *username = malloc (unamelen); - if (!username) - return -1; - - while ((c = getc (f)) != EOF && c != ' ') - { - if (unameread >= unamelen - 1) - { - ptrdiff_t unamelen_max = min (PTRDIFF_MAX, SIZE_MAX); - if (unamelen <= unamelen_max / 2) - unamelen *= 2; - else if (unamelen < unamelen_max) - unamelen = unamelen_max; - else - { - errno = ENOMEM; - return -1; - } - username = realloc (username, unamelen); - if (!username) - return -1; - } - username[unameread] = c; - unameread++; - } - if (c == EOF) - return -1; - username[unameread] = '\0'; - score->username = username; - } -#endif -#ifdef HAVE_GETLINE - score->data = NULL; - errno = 0; - { - size_t len; - if (getline (&score->data, &len, f) < 0) - return -1; - score->data[strlen (score->data)-1] = '\0'; - } -#else - { - ptrdiff_t cur = 0; - ptrdiff_t len = 16; - char *buf = malloc (len); - if (!buf) - return -1; - while ((c = getc (f)) != EOF - && c != '\n') - { - if (cur >= len-1) - { - if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < len) - { - errno = ENOMEM; - return -1; - } - if (!(buf = realloc (buf, len *= 2))) - return -1; - } - buf[cur] = c; - cur++; - } - score->data = buf; - score->data[cur] = '\0'; - } -#endif - return 0; + score->score = p; + p = strchr (p, ' '); + if (!p) + return p; + *p++ = 0; + score->user_data = p; + p = strchr (p, '\n'); + if (!p) + return p; + *p++ = 0; + return p; } static int read_scores (const char *filename, struct score_entry **scores, ptrdiff_t *count, ptrdiff_t *alloc) { - int readval = -1; - ptrdiff_t scorecount = 0; - ptrdiff_t cursize = 0; - struct score_entry *ret = 0; - struct score_entry entry; + char *p, *filedata; + ptrdiff_t filesize, nread; + struct stat st; FILE *f = fopen (filename, "r"); - int retval = -1; if (!f) return -1; - while ((readval = read_score (f, &entry)) == 0) - if (push_score (&ret, &scorecount, &cursize, &entry) < 0) + if (fstat (fileno (f), &st) != 0) + return -1; + if (! (0 <= st.st_size && st.st_size < min (PTRDIFF_MAX, SIZE_MAX))) + { + errno = EOVERFLOW; + return -1; + } + filesize = st.st_size; + filedata = malloc (filesize + 1); + if (! filedata) + return -1; + nread = fread (filedata, 1, filesize + 1, f); + if (filesize < nread) + { + errno = 0; return -1; - if (readval > 0 && fclose (f) == 0) + } + if (nread < filesize) + filesize = nread; + if (ferror (f) || fclose (f) != 0) + return -1; + filedata[filesize] = 0; + if (strlen (filedata) != filesize) { - *count = scorecount; - *alloc = cursize; - *scores = ret; - retval = 0; + errno = 0; + return -1; } - return retval; + + *scores = 0; + *count = *alloc = 0; + for (p = filedata; p < filedata + filesize; ) + { + struct score_entry entry; + p = read_score (p, &entry); + if (!p) + { + errno = 0; + return -1; + } + if (push_score (scores, count, alloc, &entry) < 0) + return -1; + } + return 0; } static int @@ -382,7 +356,25 @@ score_compare (const void *a, const void *b) { const struct score_entry *sa = (const struct score_entry *) a; const struct score_entry *sb = (const struct score_entry *) b; - return (sb->score > sa->score) - (sb->score < sa->score); + char *sca = sa->score; + char *scb = sb->score; + size_t lena, lenb; + bool nega = *sca == '-'; + bool negb = *scb == '-'; + int diff = nega - negb; + if (diff) + return diff; + if (nega) + { + char *tmp = sca; + sca = scb + 1; + scb = tmp + 1; + } + lena = strlen (sca); + lenb = strlen (scb); + if (lena != lenb) + return lenb < lena ? -1 : 1; + return strcmp (scb, sca); } static int @@ -438,8 +430,7 @@ write_scores (const char *filename, const struct score_entry *scores, char *tempfile = malloc (strlen (filename) + strlen (".tempXXXXXX") + 1); if (!tempfile) return -1; - strcpy (tempfile, filename); - strcat (tempfile, ".tempXXXXXX"); + strcpy (stpcpy (tempfile, filename), ".tempXXXXXX"); fd = mkostemp (tempfile, 0); if (fd < 0) return -1; @@ -451,18 +442,12 @@ write_scores (const char *filename, const struct score_entry *scores, if (! f) return -1; for (i = 0; i < count; i++) - if (fprintf (f, "%"PRIdMAX" %s %s\n", - scores[i].score, scores[i].username, scores[i].data) - < 0) + if (fprintf (f, "%s %s\n", scores[i].score, scores[i].user_data) < 0) return -1; if (fclose (f) != 0) return -1; if (rename (tempfile, filename) != 0) return -1; -#ifdef DOS_NT - if (chmod (filename, 0644) < 0) - return -1; -#endif return 0; } @@ -476,33 +461,29 @@ lock_file (const char *filename, void **state) char *lockpath = malloc (strlen (filename) + strlen (lockext) + 60); if (!lockpath) return -1; - strcpy (lockpath, filename); - strcat (lockpath, lockext); + strcpy (stpcpy (lockpath, filename), lockext); *state = lockpath; - trylock: - attempts++; - /* If the lock is over an hour old, delete it. */ - if (stat (lockpath, &buf) == 0 - && 60 * 60 < time (0) - buf.st_ctime) - unlink (lockpath); - fd = open (lockpath, O_CREAT | O_EXCL, 0600); - if (fd < 0) + + while ((fd = open (lockpath, O_CREAT | O_EXCL, 0600)) < 0) { - if (errno == EEXIST) + if (errno != EEXIST) + return -1; + attempts++; + + /* Break the lock if it is over an hour old, or if we've tried + more than MAX_ATTEMPTS times. We won't corrupt the file, but + we might lose some scores. */ + if (MAX_ATTEMPTS < attempts + || (stat (lockpath, &buf) == 0 && 60 * 60 < time (0) - buf.st_ctime)) { - /* Break the lock; we won't corrupt the file, but we might - lose some scores. */ - if (attempts > MAX_ATTEMPTS) - { - unlink (lockpath); - attempts = 0; - } - sleep ((rand () % 2)+1); - goto trylock; + if (unlink (lockpath) != 0 && errno != ENOENT) + return -1; + attempts = 0; } - else - return -1; + + sleep ((rand () & 1) + 1); } + close (fd); return 0; } |