XEmacs 21.2.4
authortomo <tomo>
Mon, 17 May 1999 09:41:37 +0000 (09:41 +0000)
committertomo <tomo>
Mon, 17 May 1999 09:41:37 +0000 (09:41 +0000)
50 files changed:
lib-src/movemail.c
lisp/ChangeLog
lisp/about.el
lisp/auto-autoloads.el
lisp/cus-face.el
lisp/custom-load.el
lisp/easymenu.el
lisp/etags.el
lisp/faces.el
lisp/isearch-mode.el
lisp/menubar-items.el
lisp/menubar.el
lisp/msw-faces.el
lisp/package-get.el
lisp/package-ui.el
lisp/process.el
lisp/subr.el
lisp/wid-edit.el
man/ChangeLog
man/internals/internals.texi
man/lispref/text.texi
nt/ChangeLog
nt/xemacs.mak
src/ChangeLog
src/chartab.c
src/chartab.h
src/config.h.in
src/dgif_lib.c
src/dired.c
src/editfns.c
src/emacs.c
src/fileio.c
src/fns.c
src/frame-msw.c
src/gifrlib.h
src/glyphs-msw.c
src/gui.c
src/gui.h
src/input-method-motif.c
src/input-method-xlib.c
src/insdel.c
src/linuxplay.c
src/lisp.h
src/m/arm.h [new file with mode: 0644]
src/m/mips-nec.h [new file with mode: 0644]
src/menubar-x.c
src/menubar.c
src/mule-charset.c
src/process-unix.c
src/s/cygwin32.h

index 0419719..f345020 100644 (file)
@@ -65,10 +65,15 @@ Boston, MA 02111-1307, USA.  */
 #include "../src/systime.h"
 #include <stdlib.h>
 #include <string.h>
+#include "getopt.h"
 #ifdef MAIL_USE_POP
 #include "pop.h"
+#include <regex.h>
 #endif
 
+extern char *optarg;
+extern int optind, opterr;
+
 #ifndef HAVE_STRERROR
 static char * strerror (int errnum);
 #endif /* HAVE_STRERROR */
@@ -146,15 +151,43 @@ static int pop_retr (popserver server, int msgno, int (*action)(), void *arg);
 static int mbx_write (char *, FILE *);
 static int mbx_delimit_begin (FILE *);
 static int mbx_delimit_end (FILE *);
+static struct re_pattern_buffer* compile_regex (char* regexp_pattern);
+static int pop_search_top (popserver server, int msgno, int lines, 
+                          struct re_pattern_buffer* regexp);
 #endif
 
 /* Nonzero means this is name of a lock file to delete on fatal error.  */
 char *delete_lockname;
 
+int verbose=0;
+#ifdef MAIL_USE_POP
+int reverse=0;
+int keep_messages=0;
+struct re_pattern_buffer* regexp_pattern=0;
+int match_lines=10;
+#endif
+
+#define VERBOSE(x) if (verbose) { printf x; fflush(stdout); }
+
+struct option longopts[] =
+{
+  { "inbox",                   required_argument,         NULL,        'i'     },
+  { "outfile",                 required_argument,         NULL,        'o'     },
+#ifdef MAIL_USE_POP
+  { "password",                        required_argument,         NULL,        'p'     },
+  { "reverse-pop-order",               no_argument,               NULL,        'x'     },
+  { "keep-messages",           no_argument,               NULL,        'k'     },
+  { "regex",                   required_argument,         NULL,        'r'     },
+  { "match-lines",             required_argument,         NULL,        'l'     },
+#endif
+  { "verbose",                         no_argument,               NULL,        'v'     },
+  { 0 }
+};
+
 int
 main (int argc, char *argv[])
 {
-  char *inname, *outname;
+  char *inname=0, *outname=0, *poppass=0;
 #ifndef DISABLE_DIRECT_ACCESS
   int indesc, outdesc;
   int nread;
@@ -172,14 +205,72 @@ main (int argc, char *argv[])
 
   delete_lockname = 0;
 
-  if (argc < 3)
+  while (1)
     {
-      fprintf (stderr, "Usage: movemail inbox destfile [POP-password]\n");
-      exit(1);
+#ifdef MAIL_USE_POP
+      char* optstring = "i:o:p:l:r:xvk";
+#else
+      char* optstring = "i:o:v";
+#endif
+      int opt = getopt_long (argc, argv, optstring, longopts, 0);
+  
+      if (opt == EOF)
+       break;
+
+      switch (opt)
+       {
+       case 0:
+         break;
+       case 1:                 /* one of the standard arguments seen */
+         if (!inname)
+           inname = optarg;
+         else if (!outname)
+           outname = optarg;
+         else
+           poppass = optarg;
+         break;
+
+       case 'i':               /* infile */
+         inname = optarg;
+         break;
+         
+       case 'o':               /* outfile */
+         outname = optarg;
+         break;
+#ifdef MAIL_USE_POP
+       case 'p':               /* pop password */
+         poppass = optarg;     
+         break;
+       case 'k':               keep_messages=1;        break;
+       case 'x':               reverse = 1;            break;
+       case 'l':               /* lines to match */
+         match_lines = atoi (optarg);
+         break;
+
+       case 'r':               /* regular expression */
+         regexp_pattern = compile_regex (optarg);
+         break;
+#endif
+       case 'v':               verbose = 1;    break;
+       }
     }
 
-  inname = argv[1];
-  outname = argv[2];
+  while (optind < argc)
+      {
+         if (!inname)
+             inname = argv[optind];
+         else if (!outname)
+             outname = argv[optind];
+         else
+             poppass = argv[optind];
+         optind++;
+      }
+    
+  if (!inname || !outname)
+    {
+      fprintf (stderr, "Usage: movemail [-rvxk] [-l lines ] [-i] inbox [-o] destfile [[-p] POP-password]\n");
+      exit(1);
+    }
 
 #ifdef MAIL_USE_MMDF
   mmdf_init (argv[0]);
@@ -210,7 +301,7 @@ main (int argc, char *argv[])
 #ifdef MAIL_USE_POP
   if (!strncmp (inname, "po:", 3))
     {
-      int retcode = popmail (inname + 3, outname, argc > 3 ? argv[3] : NULL);
+      int retcode = popmail (inname + 3, outname, poppass);
       exit (retcode);
     }
 
@@ -487,9 +578,9 @@ xmalloc (unsigned int size)
 #include <stdio.h>
 #include <pwd.h>
 
-#define NOTOK (-1)
-#define OK 0
-#define DONE 1
+#define POP_ERROR      (-1)
+#define POP_RETRIEVED (0)
+#define POP_DONE (1)
 
 char *progname;
 FILE *sfi;
@@ -502,11 +593,13 @@ static int
 popmail (char *user, char *outfile, char *password)
 {
   int nmsgs, nbytes;
-  register int i;
+  register int i, idx;
   int mbfi;
+  short* retrieved_list;
   FILE *mbf;
   popserver server;
 
+  VERBOSE(("opening server\r"));
   server = pop_open (0, user, password, POP_NO_GETPASS);
   if (! server)
     {
@@ -514,6 +607,7 @@ popmail (char *user, char *outfile, char *password)
       return (1);
     }
 
+  VERBOSE(("stat'ing messages\r"));
   if (pop_stat (server, &nmsgs, &nbytes))
     {
       error (pop_error, NULL, NULL);
@@ -522,10 +616,15 @@ popmail (char *user, char *outfile, char *password)
 
   if (!nmsgs)
     {
+      VERBOSE(("closing server\n"));
       pop_close (server);
       return (0);
     }
 
+  /* build a retrieved table */
+  retrieved_list = (short*) xmalloc (sizeof (short) * (nmsgs+1));
+  memset (retrieved_list, 0, sizeof (short) * (nmsgs+1));
+
   mbfi = open (outfile, O_WRONLY | O_CREAT | O_EXCL, 0666);
   if (mbfi < 0)
     {
@@ -546,23 +645,35 @@ popmail (char *user, char *outfile, char *password)
       return (1);
     }
 
-  for (i = 1; i <= nmsgs; i++)
+  for (idx = 0; idx < nmsgs; idx++)
     {
-      mbx_delimit_begin (mbf);
-      if (pop_retr (server, i, mbx_write, mbf) != OK)
-       {
-         error (Errmsg, NULL, NULL);
-         close (mbfi);
-         return (1);
-       }
-      mbx_delimit_end (mbf);
-      fflush (mbf);
-      if (ferror (mbf))
+      i = reverse ? nmsgs - idx : idx + 1;
+      VERBOSE(("checking message %d     \r", i));
+      
+      if (!regexp_pattern 
+         || 
+         pop_search_top (server, i, match_lines, regexp_pattern) == POP_RETRIEVED)
        {
-         error ("Error in fflush: %s", strerror (errno), NULL);
-         pop_close (server);
-         close (mbfi);
-         return (1);
+         VERBOSE(("retrieving message %d     \r", i));
+          mbx_delimit_begin (mbf);
+         if (pop_retr (server, i, mbx_write, mbf) != POP_RETRIEVED)
+           {
+             error (Errmsg, NULL, NULL);
+             close (mbfi);
+             return (1);
+           }
+
+         retrieved_list[i]=1;
+
+         mbx_delimit_end (mbf);
+         fflush (mbf);
+         if (ferror (mbf))
+           {
+             error ("Error in fflush: %s", strerror (errno), NULL);
+             pop_close (server);
+             close (mbfi);
+             return (1);
+           }
        }
     }
 
@@ -586,16 +697,24 @@ popmail (char *user, char *outfile, char *password)
       return (1);
     }
 
-  for (i = 1; i <= nmsgs; i++)
+  if (!keep_messages)
     {
-      if (pop_delete (server, i))
+      for (i = 1; i <= nmsgs; i++)
        {
-         error (pop_error, NULL, NULL);
-         pop_close (server);
-         return (1);
+         if (retrieved_list[i] == 1)
+           {
+             VERBOSE(("deleting message %d     \r", i));
+             if (pop_delete (server, i))
+               {
+                 error (pop_error, NULL, NULL);
+                 pop_close (server);
+                 return (1);
+               }
+           }
        }
     }
 
+  VERBOSE(("closing server             \n"));
   if (pop_quit (server))
     {
       error (pop_error, NULL, NULL);
@@ -615,7 +734,7 @@ pop_retr (popserver server, int msgno, int (*action)(), void *arg)
     {
       strncpy (Errmsg, pop_error, sizeof (Errmsg));
       Errmsg[sizeof (Errmsg)-1] = '\0';
-      return (NOTOK);
+      return (POP_ERROR);
     }
 
   while (! (ret = pop_retrieve_next (server, &line)))
@@ -623,11 +742,11 @@ pop_retr (popserver server, int msgno, int (*action)(), void *arg)
       if (! line)
        break;
 
-      if ((*action)(line, arg) != OK)
+      if ((*action)(line, arg) != POP_RETRIEVED)
        {
          strcpy (Errmsg, strerror (errno));
          pop_close (server);
-         return (NOTOK);
+         return (POP_ERROR);
        }
     }
 
@@ -635,10 +754,56 @@ pop_retr (popserver server, int msgno, int (*action)(), void *arg)
     {
       strncpy (Errmsg, pop_error, sizeof (Errmsg));
       Errmsg[sizeof (Errmsg)-1] = '\0';
-      return (NOTOK);
+      return (POP_ERROR);
     }
 
-  return (OK);
+  return (POP_RETRIEVED);
+}
+
+/* search the top lines of each message looking for a match */
+static int
+pop_search_top (popserver server, int msgno, int lines, struct re_pattern_buffer* regexp)
+{
+  char *line;
+  int ret;
+  int match = POP_DONE;
+
+  if (pop_top_first (server, msgno, lines, &line))
+    {
+      strncpy (Errmsg, pop_error, sizeof (Errmsg));
+      Errmsg[sizeof (Errmsg)-1] = '\0';
+      return (POP_ERROR);
+    }
+
+  while (! (ret = pop_top_next (server, &line)))
+    {
+      if (! line)
+       break;
+
+      /*      VERBOSE (("checking %s\n", line));*/
+      if (match != POP_RETRIEVED)
+       {
+         if ((ret = re_match (regexp, line, strlen (line), 0, 0)) == -2 )
+           {
+             strcpy (Errmsg, "error in regular expression");
+             pop_close (server);
+             return (POP_ERROR);
+           }
+         else if (ret >=0)
+           {
+             match = POP_RETRIEVED;
+           }
+       }
+    }
+
+  if (ret)
+    {
+      strncpy (Errmsg, pop_error, sizeof (Errmsg));
+      Errmsg[sizeof (Errmsg)-1] = '\0';
+      return (POP_ERROR);
+    }
+
+  return match;
 }
 
 /* Do this as a macro instead of using strcmp to save on execution time. */
@@ -654,31 +819,57 @@ mbx_write (char *line, FILE *mbf)
   if (IS_FROM_LINE (line))
     {
       if (fputc ('>', mbf) == EOF)
-       return (NOTOK);
+       return (POP_ERROR);
     }
   if (fputs (line, mbf) == EOF) 
-    return (NOTOK);
+    return (POP_ERROR);
   if (fputc (0x0a, mbf) == EOF)
-    return (NOTOK);
-  return (OK);
+    return (POP_ERROR);
+  return (POP_RETRIEVED);
 }
 
 static int
 mbx_delimit_begin (FILE *mbf)
 {
   if (fputs ("\f\n0, unseen,,\n", mbf) == EOF)
-    return (NOTOK);
-  return (OK);
+    return (POP_ERROR);
+  return (POP_RETRIEVED);
 }
 
 static int
 mbx_delimit_end (FILE *mbf)
 {
   if (putc ('\037', mbf) == EOF)
-    return (NOTOK);
-  return (OK);
+    return (POP_ERROR);
+  return (POP_RETRIEVED);
 }
 
+/* Turn a name, which is an ed-style (but Emacs syntax) regular
+   expression, into a real regular expression by compiling it. */
+static struct re_pattern_buffer*
+compile_regex (char* regexp_pattern)
+{
+  char *err;
+  struct re_pattern_buffer *patbuf=0;
+  
+  patbuf = (struct re_pattern_buffer*) xmalloc (sizeof (struct re_pattern_buffer));
+  patbuf->translate = NULL;
+  patbuf->fastmap = NULL;
+  patbuf->buffer = NULL;
+  patbuf->allocated = 0;
+
+  err = (char*) re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf);
+  if (err != NULL)
+    {
+      error ("%s while compiling pattern", err, NULL);
+      return 0;
+    }
+
+  return patbuf;
+}
+
+
+
 #endif /* MAIL_USE_POP */
 \f
 #ifndef HAVE_STRERROR
index 6c2d639..92e8583 100644 (file)
@@ -1,3 +1,132 @@
+1998-11-28  SL Baur  <steve@altair.xemacs.org>
+
+       * XEmacs 21.2-beta4 is released.
+
+1998-11-27  Jan Vroonhof  <vroonhof@math.ethz.ch>
+
+       * easymenu.el (easy-menu-add-item): Wraper around add-menu-btton.
+       (easy-menu-item-present-p): Wrapper around find-menu-item.
+       (easy-menu-remove-item): Wrapper around delete-menu-item.
+
+       * menubar.el (delete-menu-item): Add 'from-menu' argument.
+       (add-menu-button): Add 'in-menu' argument.
+       (add-menu-item-1): Add in-menu support to helper function.
+
+1998-11-27  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+       * isearch-mode.el (isearch-mode): Fix keymap lossage.
+
+1998-11-26  Jan Vroonhof  <vroonhof@math.ethz.ch>
+
+       * faces.el (get-custom-frame-properties): Revert Hrvoje Niksic change 
+       of Dec 4, 1997.
+
+1998-11-25  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * process.el (shell-command-on-region): Report if the command
+       succeeded or failed.
+
+1998-11-24  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * subr.el (buffer-substring-no-properties): Comment out.
+
+1998-11-07  Adrian Aichner  <aichner@ecf.teradyne.com>
+
+       * msw-faces.el (mswindows-find-smaller-font): Turning font names
+         into font instances first, like `x-frob-font-size' does.
+         (mswindows-find-larger-font): ditto
+
+1998-11-04  Greg Klanderman  <greg@alphatech.com>
+
+       * package-ui.el (pui-install-selected-packages): fix args in call
+       to `package-get'.
+
+1998-10-29  Jan Vroonhof  <vroonhof@math.ethz.ch>
+
+       * package-get.el (host-name): New widget type.
+       (package-get-remote): Better customization using new type.
+       (package-get-download-sites): idem dito.
+
+       (package-get-custom): Do not use package-get-all untill we have
+       runtime dependencies.
+
+       (package-get-remove-copy): Default to 't' we no longer need this
+       kludge as we do not currently use depenencies.
+       
+       (package-get-was-current): New variable.
+       (package-get-require-base): New 'force-current' argument.
+       (package-get-update-base): idem
+       (package-get-package-provider):  idem
+       (package-get-locate-index-file): New 'no-remote' argument.
+       (package-get-locate-file): idem.
+       
+       (package-get-maybe-save-index): New function.
+       (package-get-update-base): Use it.
+
+1998-10-28 Greg Klanderman <greg@alphatech.com>
+
+       * package-get.el (package-get-remote): default to nil; by default, 
+       don't go out to the net via EFS.  They must select a download site.
+       (package-get-download-sites): new variable.
+       (package-get-download-menu): new function.
+       (package-get-locate-index-file): new function.
+       (package-get-update-base): use it.
+
+       * menubar-items.el (default-menubar): add "Update Package Index"
+       and "Add Download Site" menus under Options | Manage Packages.
+
+1998-10-19  Greg Klanderman  <greg@alphatech.com>
+
+       * package-get.el (package-get): bugfix code checking installed version
+       for case where package is not currently installed.
+       (package-get-require-signed-base-updates): new variable.
+       (package-get-update-base-from-buffer): remove REMOTE-SOURCE arg, it was 
+       deemed not a goot thing.  Use the variable
+       package-get-allow-unsigned-base-updates instead.
+
+1998-10-16 Greg Klanderman <greg@alphatech.com>
+
+       * package-get.el (package-get): Don't install an older version than 
+       we already have unless explicitly told to.  Issue a warning.
+
+       * package-ui.el (pui-add-required-packages): when adding
+       dependencies, don't add packages that are up to date.
+       (pui-package-symbol-char):  Don't consider a package out of date 
+       if you have a newer version installed than the latest version in
+       package-get-base.
+
+       * package-get.el (package-get-base-filename): document that it may 
+       be a path relative to package-get-remote;  new default value.
+       (package-get-locate-file): new function.
+       (package-get-update-base): use it to expand package-get-base-filename.
+       (package-get-save-base): new function to save the package-get database
+       to file.
+       (package-get-update-base-from-buffer): add REMOTE-SOURCE argument.
+       (package-get-update-base): pass the REMOTE-SOURCE arg.
+       (package-get-update-base-entry): call package-get-custom-add-entry.
+       (package-get-file-installed-p): removed; no longer needed.
+       (package-get-create-custom): ditto.
+       (toplevel): remove code to build and load package-get-custom.el
+       (package-get-custom-add-entry): new function.
+
+1998-10-12  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * wid-edit.el (widget-button-click): Don't switch window.
+
+1998-10-22  Jan Vroonhof  <vroonhof@math.ethz.ch>
+
+       * cus-face.el (custom-set-face-update-spec): Add autoload cookie
+
+1998-10-20  Malcolm Box  <malcolm@brownale.demon.co.uk>
+        
+       * etags.el (find-tag-default): Run find-tag-hook using
+       run-hooks rather than funcall
+
+1998-10-19  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * isearch-mode.el (isearch-mode): Set the current minor mode maps
+       and the current local map as the parents to isearch-mode-map.
+
 1998-10-15  SL Baur  <steve@altair.xemacs.org>
 
        * XEmacs 21.2-beta3 is released.
index 1bb1241..e70d07e 100644 (file)
@@ -1384,6 +1384,7 @@ above.  We couldn't have done it without them.\n\n"
        (print-short "Yasuhiko Kiuchi" "kiuchi@dsp.ksp.fujixerox.co.jp")
        (print-short "Greg Klanderman" "greg.klanderman@alum.mit.edu")
        (print-short "Valdis Kletnieks" "Valdis.Kletnieks@vt.edu")
+       (print-short "Norbert Koch" "n.koch@delta-ii.de")
        (print-short "Rob Kooper" "kooper@cc.gatech.edu")
        (print-short "Peter Skov Knudsen" "knu@dde.dk")
        (print-short "Jens Krinke" "krinke@ips.cs.tu-bs.de")
@@ -1510,6 +1511,7 @@ above.  We couldn't have done it without them.\n\n"
        (print-short "Jason Yanowitz" "yanowitz@eternity.cs.umass.edu")
        (print-short "La Monte Yarroll" "piggy@hilbert.maths.utas.edu.au")
        (print-short "Blair Zajac" "blair@olympia.gps.caltech.edu")
+       (print-short "Volker Zell" "vzell@de.oracle.com")
        (print-short "Daniel Zivkovic" "daniel@canada.sun.com")
        (print-short "Karel Zuiderveld" "Karel.Zuiderveld@cv.ruu.nl")
        "\n"))
index c5965ae..517e889 100644 (file)
@@ -665,11 +665,15 @@ The format is suitable for use with `easy-menu-define'." nil nil)
 
 ;;;***
 \f
-;;;### (autoloads (custom-set-faces custom-declare-face) "cus-face" "lisp/cus-face.el")
+;;;### (autoloads (custom-set-faces custom-set-face-update-spec custom-declare-face) "cus-face" "lisp/cus-face.el")
 
 (autoload 'custom-declare-face "cus-face" "\
 Like `defface', but FACE is evaluated as a normal argument." nil nil)
 
+(autoload 'custom-set-face-update-spec "cus-face" "\
+Customize the FACE for display types matching DISPLAY, merging
+  in the new items from PLIST" nil nil)
+
 (autoload 'custom-set-faces "cus-face" "\
 Initialize faces according to user preferences.
 The arguments should be a list where each entry has the form:
@@ -1204,22 +1208,38 @@ Install a pre-bytecompiled XEmacs package into package hierarchy." t nil)
 
 ;;;***
 \f
-;;;### (autoloads (package-get-custom package-get-package-provider package-get package-get-dependencies package-get-all package-get-update-all package-get-delete-package package-get-update-base-from-buffer package-get-update-base package-get-update-base-entry package-get-require-base) "package-get" "lisp/package-get.el")
+;;;### (autoloads (package-get-custom package-get-package-provider package-get package-get-dependencies package-get-all package-get-update-all package-get-delete-package package-get-save-base package-get-update-base-from-buffer package-get-update-base package-get-update-base-entry package-get-require-base package-get-download-menu) "package-get" "lisp/package-get.el")
+
+(autoload 'package-get-download-menu "package-get" "\
+Build the `Add Download Site' menu." nil nil)
 
 (autoload 'package-get-require-base "package-get" "\
-Require that a package-get database has been loaded." nil nil)
+Require that a package-get database has been loaded.
+If the optional FORCE-CURRENT argument or the value of
+`package-get-always-update' is Non-nil, try to update the database
+from a location in `package-get-remote'. Otherwise a local copy is used
+if available and remote access is never done.
+
+Please use FORCE-CURRENT only when the user is explictly dealing with packages
+and remote access is likely in the near future." nil nil)
 
 (autoload 'package-get-update-base-entry "package-get" "\
 Update an entry in `package-get-base'." nil nil)
 
 (autoload 'package-get-update-base "package-get" "\
-Update the package-get database file with entries from DB-FILE." t nil)
+Update the package-get database file with entries from DB-FILE.
+Unless FORCE-CURRENT is non-nil never try to update the database." t nil)
 
 (autoload 'package-get-update-base-from-buffer "package-get" "\
 Update the package-get database with entries from BUFFER.
 BUFFER defaults to the current buffer.  This command can be
 used interactively, for example from a mail or news buffer." t nil)
 
+(autoload 'package-get-save-base "package-get" "\
+Write the package-get database to FILE.
+
+Note: This database will be unsigned of course." t nil)
+
 (autoload 'package-get-delete-package "package-get" "\
 Delete an installation of PACKAGE below directory PKG-TOPDIR.
 PACKAGE is a symbol, not a string.
@@ -1272,7 +1292,10 @@ successfully installed but errors occurred during initialization, or
 Search for a package that provides SYM and return the name and
   version.  Searches in `package-get-base' for SYM.   If SYM is a
   consp, then it must match a corresponding (provide (SYM VERSION)) from 
-  the package." t nil)
+  the package.
+
+If FORCE-CURRENT is non-nil make sure the database is up to date. This might
+lead to Emacs accessing remote sites." t nil)
 
 (autoload 'package-get-custom "package-get" "\
 Fetch and install the latest versions of all customized packages." t nil)
index 1660a7a..6be65ba 100644 (file)
@@ -226,6 +226,7 @@ If FRAME is nil, use the default face."
         (fontobj (font-create-object font)))
     (font-family fontobj)))
 
+;;;###autoload
 (defun custom-set-face-update-spec (face display plist)
   "Customize the FACE for display types matching DISPLAY, merging
   in the new items from PLIST"
index a8af512..44c3135 100644 (file)
@@ -75,7 +75,6 @@
 (custom-add-loads 'isearch '("isearch-mode"))
 (custom-add-loads 'font-lock-faces '("font-lock"))
 (custom-add-loads 'modeline '("modeline"))
-(custom-add-loads 'packages '("package-get-custom"))
 (custom-add-loads 'editing '("simple" "abbrev" "fill" "mouse" "cus-edit" "dragdrop"))
 (custom-add-loads 'matching '("simple" "isearch-mode" "hyper-apropos"))
 (custom-add-loads 'i18n '("cus-edit"))
index 3bd9f34..9678183 100644 (file)
@@ -23,7 +23,9 @@
 ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 ;; 02111-1307, USA.
 
-;;; Synched up with: Not synched with FSF.
+;;; Synched up with: Not synched with FSF but coordinated with the FSF
+;;;                  easymenu maintor for compatability with FSF 20.4.
+;;; Please: Coordinate changes with Inge Frick <inge@nada.kth.se>
 
 ;; Commentary:
 
 ;; - Function: easy-menu-remove MENU
 ;;     Remove MENU from the current menubar.
 
+;; - Function: easy-menu-add-item
+;;     Add item or submenu to existing menu
+
+;; - Function: easy-menu-item-present-p
+;;     Locate item
+
+;; - Function: easy-menu-remove-item
+;;     Delete item from menu.
+
 ;; Emacs 19 never uses `easy-menu-add' or `easy-menu-remove', menus
 ;; automatically appear and disappear when the keymaps specified by
 ;; the MAPS argument to `easy-menu-define' are activated.
@@ -200,6 +211,50 @@ is a list of menu items, as above."
             (assoc (car menu) current-menubar)
             (delete-menu-item (list (car menu)))))))
 
+(defsubst easy-menu-normalize (menu)
+  (if (symbolp menu)
+      (symbol-value menu)
+    menu))
+
+(defun easy-menu-add-item (menu path item &optional before)
+  "At the end of the submenu of MENU with path PATH add ITEM.
+If ITEM is already present in this submenu, then this item will be changed.
+otherwise ITEM will be added at the end of the submenu, unless the optional
+argument BEFORE is present, in which case ITEM will instead be added
+before the item named BEFORE.
+MENU is either a symbol, which have earlier been used as the first
+argument in a call to `easy-menu-define', or the value of such a symbol
+i.e. a menu, or nil which stands for the current menubar.
+PATH is a list of strings for locating the submenu where ITEM is to be
+added.  If PATH is nil, MENU itself is used.  Otherwise, the first
+element should be the name of a submenu directly under MENU.  This
+submenu is then traversed recursively with the remaining elements of PATH.
+ITEM is either defined as in `easy-menu-define', a menu defined earlier
+by `easy-menu-define' or `easy-menu-create-menu' or an item returned
+from `easy-menu-item-present-p' or `easy-menu-remove-item'."
+  (add-menu-button path item before (easy-menu-normalize menu)))                  
+
+(defun easy-menu-item-present-p (menu path name)
+  "In submenu of MENU with path PATH, return true iff item NAME is present.
+MENU and PATH are defined as in `easy-menu-add-item'.
+NAME should be a string, the name of the element to be looked for.
+
+The return value can be used as as an argument to `easy-menu-add-item'."
+  (car (find-menu-item (or (easy-menu-normalize menu) current-menubar)
+                      (append path (list name)))))
+
+(defun easy-menu-remove-item (menu path name)
+  "From submenu of MENU with path PATH remove item NAME.
+MENU and PATH are defined as in `easy-menu-add-item'.
+NAME should be a string, the name of the element to be removed.
+
+The return value can be used as as an argument to `easy-menu-add-item'."
+  (delete-menu-item (append path (list name))
+                   (easy-menu-normalize menu)))
+  
+
+
+
 ;; Think up a good title for the menu.  Take the major-mode of the
 ;; buffer, strip the -mode part, convert hyphens to spaces, and
 ;; capitalize it.
index 5edc1d4..08d26b5 100644 (file)
@@ -554,7 +554,7 @@ Make it buffer-local in a mode hook.  The function is called with no
  arguments.")
 
 (defvar find-tag-hook nil
-  "Function to call after a tag is found.
+  "*Function to call after a tag is found.
 Make it buffer-local in a mode hook.  The function is called with no
  arguments.")
 
@@ -777,11 +777,11 @@ Variables of note:
     (push-mark)
     (goto-char tag-point)
     (if find-tag-hook
-       (funcall find-tag-hook)
+               (run-hooks 'find-tag-hook)
       (if local-find-tag-hook
-         (funcall local-find-tag-hook))))
+                 (run-hooks 'local-find-tag-hook))))
   (setq tags-loop-scan (list 'find-tag nil nil)
-       tags-loop-operate nil)
+               tags-loop-operate nil)
   ;; Return t in case used as the tags-loop-scan.
   t)
 
index c847f37..1870bec 100644 (file)
@@ -1249,9 +1249,7 @@ If FRAME is nil, return the default frame properties."
             ;; and cache it...
             (set-frame-property frame 'custom-properties cache))
           cache))
-       ;; We avoid this cache, because various frame and device
-       ;; properties can change.
-       ;;(default-custom-frame-properties)
+       (default-custom-frame-properties)
        (t
         (setq default-custom-frame-properties
               (extract-custom-frame-properties (selected-frame))))))
index 961a0b7..8a611f2 100644 (file)
@@ -460,6 +460,10 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
 
          isearch-mode (gettext " Isearch")
          )
+    (let ((map (append (current-minor-mode-maps)
+                      (list (current-local-map)))))
+      (if (keymapp map)
+         (set-keymap-parents isearch-mode-map map)))
 
     ;; XEmacs change: without clearing the match data, sometimes old values
     ;; of isearch-other-end get used.  Don't ask me why...
index 0eb7865..7879ea0 100644 (file)
        ["Browse..." customize-browse])
       
       ("Manage Packages"
+       ("Add Download Site"
+        :filter (lambda (&rest junk)
+                  (package-get-download-menu)))
+       ["Update Package Index" package-get-update-base]
        ["List & Install" pui-list-packages]
        ("Using Custom"
        ("Select" :filter (lambda (&rest junk)
index fa55059..4ac3cf6 100644 (file)
@@ -218,7 +218,7 @@ If some menu in the ITEM-PATH-LIST does not exist, an error is signalled."
                                      (car item-path-list)))))
        (cons result parent)))))
 
-(defun add-menu-item-1 (leaf-p menu-path new-item before)
+(defun add-menu-item-1 (leaf-p menu-path new-item before in-menu)
   ;; This code looks like it could be cleaned up some more
   ;; Do we really need 6 calls to find-menu-item?
   (when before (setq before (normalize-menu-item-name before)))
@@ -226,7 +226,7 @@ If some menu in the ITEM-PATH-LIST does not exist, an error is signalled."
          (cond ((vectorp new-item) (aref new-item 0))
                ((consp   new-item) (car  new-item))
                (t nil)))
-        (menubar current-menubar)
+        (menubar (or in-menu current-menubar))
         (menu (condition-case ()
                   (car (find-menu-item menubar menu-path))
                 (error nil)))
@@ -292,7 +292,7 @@ If some menu in the ITEM-PATH-LIST does not exist, an error is signalled."
     (set-menubar-dirty-flag)
     new-item))
 
-(defun add-menu-button (menu-path menu-leaf &optional before)
+(defun add-menu-button (menu-path menu-leaf &optional before in-menu)
   "Add a menu item to some menu, creating the menu first if necessary.
 If the named item exists already, it is changed.
 MENU-PATH identifies the menu under which the new menu item should be inserted.
@@ -301,12 +301,16 @@ MENU-PATH identifies the menu under which the new menu item should be inserted.
 MENU-LEAF is a menubar leaf node.  See the documentation of `current-menubar'.
 BEFORE, if provided, is the name of a menu item before which this item should
  be added, if this item is not on the menu already.  If the item is already
- present, it will not be moved."
-  (add-menu-item-1 t menu-path menu-leaf before))
+ present, it will not be moved.
+If IN-MENU is present use that instead of `current-menubar' as the menu to
+change.
+"
+  ;; Note easymenu.el uses the fact that menu-leaf can be a submenu.
+  (add-menu-item-1 t menu-path menu-leaf before in-menu))
 
 ;; I actually liked the old name better, but the interface has changed too
 ;; drastically to keep it. --Stig 
-(defun add-submenu (menu-path submenu &optional before)
+(defun add-submenu (menu-path submenu &optional before in-menu)
   "Add a menu to the menubar or one of its submenus.
 If the named menu exists already, it is changed.
 MENU-PATH identifies the menu under which the new menu should be inserted.
@@ -319,7 +323,7 @@ BEFORE, if provided, is the name of a menu before which this menu should
  be added, if this menu is not on its parent already.  If the menu is already
  present, it will not be moved."
   (check-menu-syntax submenu nil)
-  (add-menu-item-1 nil menu-path submenu before))
+  (add-menu-item-1 nil menu-path submenu before in-menu))
 
 (defun purecopy-menubar (x)
   ;; this calls purecopy on the strings, and the contents of the vectors,
@@ -340,11 +344,12 @@ BEFORE, if provided, is the name of a menu before which this menu should
        (t
         (purecopy x))))
 
-(defun delete-menu-item (path)
+(defun delete-menu-item (path &optional from-menu)
   "Remove the named menu item from the menu hierarchy.
 PATH is a list of strings which identify the position of the menu item in 
 the menu hierarchy.  The documentation of `add-submenu' describes menu-paths."
-  (let* ((pair (condition-case nil (find-menu-item current-menubar path)
+  (let* ((pair (condition-case nil (find-menu-item (or from-menu
+                                                      current-menubar) path)
                 (error nil)))
         (item (car pair))
         (parent (or (cdr pair) current-menubar)))
index b2e52f4..e77f415 100644 (file)
@@ -145,6 +145,9 @@ font. If it fails, it returns nil."
 (defun mswindows-find-smaller-font (font &optional device)
   "Loads a new version of the given font (or font name) 1 point smaller.
 Returns the font if it succeeds, nil otherwise."
+  (if (stringp font) (setq font (make-font-instance font device)))
+  (if (font-instance-p font) (setq font (font-instance-truename font)))
+  (if (stringp font) (setq font (make-font-instance font device)))
   (if (font-instance-p font)
       (let (old-size (name (mswindows-font-canonicalize-name font)))
        (string-match "^[a-zA-Z ]+:[a-zA-Z ]*:\\([0-9]+\\):" name)
@@ -160,6 +163,9 @@ Returns the font if it succeeds, nil otherwise."
 (defun mswindows-find-larger-font (font &optional device)
   "Loads a new version of the given font (or font name) 1 point larger.
 Returns the font if it succeeds, nil otherwise."
+  (if (stringp font) (setq font (make-font-instance font device)))
+  (if (font-instance-p font) (setq font (font-instance-truename font)))
+  (if (stringp font) (setq font (make-font-instance font device)))
   (if (font-instance-p font)
       (let (old-size (name (mswindows-font-canonicalize-name font)))
        (string-match "^[a-zA-Z ]+:[a-zA-Z ]*:\\([0-9]+\\):" name)
index 023fe91..383e0ff 100644 (file)
@@ -3,6 +3,8 @@
 ;; Copyright (C) 1998 by Pete Ware
 
 ;; Author: Pete Ware <ware@cis.ohio-state.edu>
+;; Heavy-Modifications: Greg Klanderman <greg@alphatech.com>
+;;                      Jan Vroonhof    <vroonhof@math.ethz.ch>
 ;; Keywords: internal
 
 ;; This file is part of XEmacs.
@@ -29,6 +31,9 @@
 ;; package-get -
 ;;     Retrieve a package and any other required packages from an archive
 ;;
+;;
+;; Note (JV): Most of this no longer aplies!
+;;
 ;; The idea:
 ;;     A new XEmacs lisp-only release is generated with the following steps:
 ;;     1. The maintainer runs some yet to be written program that
@@ -160,39 +165,123 @@ one version of a package available.")
   :type 'directory
   :group 'package-get)
 
-;; JV Any Custom expert know to get "Host" and "Dir" for the remote option
-(defcustom package-get-remote
-  '(("ftp.xemacs.org" "/pub/xemacs/packages"))
+(define-widget 'host-name 'string
+  "A Host name."
+  :tag "Host")
+
+(defcustom package-get-remote nil
   "*List of remote sites to contact for downloading packages.
 List format is '(site-name directory-on-site).  Each site is tried in
 order until the package is found.  As a special case, `site-name' can be
 `nil', in which case `directory-on-site' is treated as a local directory."
   :tag "Package repository"
   :type '(repeat (choice (list :tag "Local" (const :tag "Local" nil) directory )
-                        (list :tag "Remote" string string) ))
+                        (list :tag "Remote" host-name directory) ))
   :group 'package-get)
 
-(defcustom package-get-remove-copy nil
+(defcustom package-get-download-sites
+  '(
+    ;; North America
+    ("xemacs.org" "ftp.xemacs.org" "pub/xemacs/packages")
+    ("cso.uiuc.edu" "ftp.cso.uiuc.edu" "pub/packages/xemacs/packages")
+
+    ;; South America
+    ("unicamp.br" "ftp.unicamp.br" "pub/xemacs/packages")
+
+    ;; Europe
+    ("sunsite.cnlab-switch.ch" "sunsite.cnlab-switch.ch" "mirror/xemacs/packages")
+    ("tu-darmstadt.de" "ftp.tu-darmstadt.de" "pub/editors/xemacs/packages")
+    ("sunsite.auc.dk" "sunsite.auc.dk" "pub/emacs/xemacs/packages")
+    ("pasteur.fr" "ftp.pasteur.fr" "pub/computing/xemacs/packages")
+    ("cenatls.cena.dgac.fr" "ftp.cenatls.cena.dgac.fr" "pub/Emacs/xemacs/packages")
+    ("kfki.hu" "ftp.kfki.hu" "pub/packages/xemacs/packages")
+    ("uniroma2.it" "ftp.uniroma2.it" "unix/misc/dist/XEMACS/packages")
+    ("icm.edu.pl" "ftp.icm.edu.pl" "pub/unix/editors/xemacs/packages")
+    ("sunet.se" "ftp.sunet.se" "pub/gnu/xemacs/packages")
+    ("doc.ic.ac.uk" "ftp.doc.ic.ac.uk" "packages/xemacs/packages")
+    ("srcc.msu.su" "ftp1.srcc.msu.su" "mirror/ftp.xemacs.org/packages")
+
+    ;; Asia
+    ("usyd.edu.au" "ftp.usyd.edu.au" "pub/Xemacs/packages")
+    ("netlab.is.tsukuba.ac.jp" "ftp.netlab.is.tsukuba.ac.jp" "pub/GNU/xemacs/packages")
+    ("jaist.ac.jp" "ftp.jaist.ac.jp" "pub/GNU/xemacs/packages")
+    ("ring.aist.go.jp" "ring.aist.go.jp" "pub/text/xemacs/packages")
+    ("ring.asahi-net.or.jp" "ring.asahi-net.or.jp" "pub/text/xemacs/packages")
+    ("SunSITE.sut.ac.jp" "SunSITE.sut.ac.jp" "pub/archives/packages/xemacs/packages")
+    ("dti.ad.jp" "ftp.dti.ad.jp" "pub/unix/editor/xemacs/packages")
+    ("kreonet.re.kr" "ftp.kreonet.re.kr" "pub/tools/emacs/xemacs/packages")
+    )
+  "*List of remote sites available for downloading packages.
+List format is '(site-description site-name directory-on-site).
+SITE-DESCRIPTION is a textual description of the site.  SITE-NAME
+is the internet address of the download site.  DIRECTORY-ON-SITE
+is the directory on the site in which packages may be found.
+This variable is used to initialize `package-get-remote', the
+variable actually used to specify package download sites."
+  :tag "Package download sites"
+  :type '(repeat (list hostname directory))
+  :group 'package-get)
+
+(defcustom package-get-remove-copy t
   "*After copying and installing a package, if this is T, then remove the
 copy.  Otherwise, keep it around."
   :type 'boolean
   :group 'package-get)
 
-(defcustom package-get-base-filename
-  "/ftp.xemacs.org:/pub/xemacs/packages/package-index.LATEST"
-  "*Name of the default package database file, usually on ftp.xemacs.org."
+;; #### it may make sense for this to be a list of names.
+;; #### also, should we rename "*base*" to "*index*" or "*db*"?
+;;      "base" is a pretty poor name.
+(defcustom package-get-base-filename "package-index.LATEST.pgp"
+  "*Name of the default package-get database file.
+This may either be a relative path, in which case it is interpreted
+with respect to `package-get-remote', or an absolute path."
   :type 'file
   :group 'package-get)
 
+(defcustom package-get-always-update nil
+  "*If Non-nil always make sure we are using the latest package index (base).
+Otherwise respect the `force-current' argument of `package-get-require-base'."
+  :type 'boolean
+  :group 'package-get)
+
+(defcustom package-get-require-signed-base-updates t
+  "*If set to a non-nil value, require explicit user confirmation for updates
+to the package-get database which cannot have their signature verified via PGP.
+When nil, updates which are not PGP signed are allowed without confirmation."
+  :type 'boolean
+  :group 'package-get)
+
+(defvar package-get-was-current nil
+  "Non-nil we did our best to fetch a current database.")
+
 ;;;###autoload
-(defun package-get-require-base ()
-  "Require that a package-get database has been loaded."
-  (when (or (not (boundp 'package-get-base))
-            (not package-get-base))
-    (package-get-update-base))
-  (when (or (not (boundp 'package-get-base))
-            (not package-get-base))
-    (error "Package-get database not loaded")))
+(defun package-get-download-menu ()
+  "Build the `Add Download Site' menu."
+  (mapcar (lambda (site)
+            (vector (car site)
+                    `(push (quote ,(cdr site))
+                           package-get-remote)))
+          package-get-download-sites))
+
+;;;###autoload
+(defun package-get-require-base (&optional force-current)
+  "Require that a package-get database has been loaded.
+If the optional FORCE-CURRENT argument or the value of
+`package-get-always-update' is Non-nil, try to update the database
+from a location in `package-get-remote'. Otherwise a local copy is used
+if available and remote access is never done.
+
+Please use FORCE-CURRENT only when the user is explictly dealing with packages
+and remote access is likely in the near future."
+  (setq force-current (or force-current package-get-always-update))
+  (unless (and (boundp 'package-get-base)
+              package-get-base
+              (or (not force-current) package-get-was-current))
+    (package-get-update-base nil force-current))
+  (if (or (not (boundp 'package-get-base))
+         (not package-get-base))
+      (error "Package-get database not loaded")
+    (setq package-get-was-current force-current)))
 
 (defconst package-get-pgp-signed-begin-line "^-----BEGIN PGP SIGNED MESSAGE-----"
   "Text for start of PGP signed messages.")
@@ -204,21 +293,72 @@ copy.  Otherwise, keep it around."
 ;;;###autoload
 (defun package-get-update-base-entry (entry)
   "Update an entry in `package-get-base'."
-  (let ((existing (assoc (car entry) package-get-base)))
+  (let ((existing (assq (car entry) package-get-base)))
     (if existing
         (setcdr existing (cdr entry))
-      (setq package-get-base (cons entry package-get-base)))))
+      (setq package-get-base (cons entry package-get-base))
+      (package-get-custom-add-entry (car entry) (car (cdr entry))))))
+
+(defun package-get-locate-file (file &optional nil-if-not-found no-remote)
+  "Locate an existing FILE with respect to `package-get-remote'.
+If FILE is an absolute path or is not found, simply return FILE.
+If optional argument NIL-IF-NOT-FOUND is non-nil, return nil
+if FILE can not be located.
+If NO-REMOTE is non-nil never search remote locations."
+  (if (file-name-absolute-p file)
+      file
+    (let ((entries package-get-remote)
+          (expanded nil))
+      (while entries
+       (unless (and no-remote (caar entries))
+         (let ((expn (package-get-remote-filename (car entries) file)))
+           (if (and expn (file-exists-p expn))
+               (setq entries  nil
+                     expanded expn))))
+        (setq entries (cdr entries)))
+      (or expanded
+          (and (not nil-if-not-found)
+               file)))))
+
+(defun package-get-locate-index-file (no-remote)
+  "Locate the package-get index file.  Do not return remote paths if NO-REMOTE
+is non-nil."
+  (or (package-get-locate-file package-get-base-filename t no-remote)
+      (locate-data-file package-get-base-filename)
+      package-get-base-filename))
+
+(defvar package-get-user-package-location user-init-directory)
+
+(defun package-get-maybe-save-index (filename)
+  "Offer to save the current buffer as the local package index file,
+if different."
+  (let ((location (package-get-locate-index-file t)))
+    (unless (and filename (equal filename location))
+      (unless (equal (md5 (current-buffer))
+                    (with-temp-buffer
+                      (insert-file-contents location)
+                      (md5 (current-buffer))))
+       (unless (file-writable-p location)
+         (setq location (expand-file-name package-get-base-filename
+               (expand-file-name "etc/" package-get-user-package-location))))
+       (when (y-or-n-p (concat "Update package index in" location "? "))
+         (write-file location))))))
+      
 
 ;;;###autoload
-(defun package-get-update-base (&optional db-file)
-  "Update the package-get database file with entries from DB-FILE."
-  (interactive (list
-                (read-file-name "Load package-get database: "
-                                (file-name-directory package-get-base-filename)
-                                package-get-base-filename
-                                t
-                                (file-name-nondirectory package-get-base-filename))))
-  (setq db-file (expand-file-name (or db-file package-get-base-filename)))
+(defun package-get-update-base (&optional db-file force-current)
+  "Update the package-get database file with entries from DB-FILE.
+Unless FORCE-CURRENT is non-nil never try to update the database."
+  (interactive
+   (let ((dflt (package-get-locate-index-file nil)))
+     (list (read-file-name "Load package-get database: "
+                           (file-name-directory dflt)
+                           dflt
+                           t
+                           (file-name-nondirectory dflt)))))
+  (setq db-file (expand-file-name (or db-file
+                                      (package-get-locate-index-file
+                                        (not force-current)))))
   (if (not (file-exists-p db-file))
       (error "Package-get database file `%s' does not exist" db-file))
   (if (not (file-readable-p db-file))
@@ -229,7 +369,9 @@ copy.  Otherwise, keep it around."
           (set-buffer buf)
           (erase-buffer buf)
           (insert-file-contents-internal db-file)
-          (package-get-update-base-from-buffer buf))
+          (package-get-update-base-from-buffer buf)
+         (if (file-remote-p db-file)
+             (package-get-maybe-save-index db-file)))
       (kill-buffer buf))))
 
 ;;;###autoload
@@ -253,7 +395,8 @@ used interactively, for example from a mail or news buffer."
       (when (re-search-forward package-get-pgp-signature-end-line nil t)
         (setq end (point)))
       (if (not (and content-beg content-end beg end))
-          (or (yes-or-no-p "Package-get entries not PGP signed, continue? ")
+          (or (not package-get-require-signed-base-updates)
+              (yes-or-no-p "Package-get entries not PGP signed, continue? ")
               (error "Package-get database not updated")))
       (if (and content-beg content-end beg end)
           (if (not (condition-case nil
@@ -261,7 +404,8 @@ used interactively, for example from a mail or news buffer."
                            (load-library "mc-pgp")
                            (fboundp 'mc-pgp-verify-region))
                      (error nil)))
-              (or (yes-or-no-p
+              (or (not package-get-require-signed-base-updates)
+                  (yes-or-no-p
                    "No mailcrypt; can't verify package-get DB signature, continue? ")
                   (error "Package-get database not updated"))))
       (if (and beg end
@@ -271,10 +415,13 @@ used interactively, for example from a mail or news buffer."
                         (mc-pgp-verify-region beg end)
                       (file-error
                        (and (string-match "No such file" (nth 2 err))
-                            (yes-or-no-p
-                             "Can't find PGP, continue without package-get DB verification? ")))
+                            (or (not package-get-require-signed-base-updates)
+                                (yes-or-no-p
+                                 (concat "Can't find PGP, continue without "
+                                         "package-get DB verification? ")))))
                       (t nil)))))
           (error "Package-get PGP signature failed to verify"))
+      ;; ToDo: We shoud call package-get-maybe-save-index on the region
       (package-get-update-base-entries content-beg content-end)
       (message "Updated package-get database"))))
 
@@ -299,12 +446,45 @@ BEG and END in the current buffer."
           (setq count (1+ count))))
       (message "Got %d package-get database entries" count))))
 
+;;;###autoload
+(defun package-get-save-base (file)
+  "Write the package-get database to FILE.
+
+Note: This database will be unsigned of course."
+  (interactive "FSave package-get database to: ")
+  (package-get-require-base t)
+  (let ((buf (get-buffer-create "*package database*")))
+    (unwind-protect
+        (save-excursion
+          (set-buffer buf)
+          (erase-buffer buf)
+          (goto-char (point-min))
+          (let ((entries package-get-base) entry plist)
+            (insert ";; Package Index file -- Do not edit manually.\n")
+            (insert ";;;@@@\n")
+            (while entries
+              (setq entry (car entries))
+              (setq plist (car (cdr entry)))
+              (insert "(package-get-update-base-entry (quote\n")
+              (insert (format "(%s\n" (symbol-name (car entry))))
+              (while plist
+                (insert (format "  %s%s %S\n"
+                                (if (eq plist (car (cdr entry))) "(" " ")
+                                (symbol-name (car plist))
+                                (car (cdr plist))))
+                (setq plist (cdr (cdr plist))))
+              (insert "))\n))\n;;;@@@\n")
+              (setq entries (cdr entries))))
+          (insert ";; Package Index file ends here\n")
+          (write-region (point-min) (point-max) file))
+      (kill-buffer buf))))
+
 (defun package-get-interactive-package-query (get-version package-symbol)
   "Perform interactive querying for package and optional version.
 Query for a version if GET-VERSION is non-nil.  Return package name as
 a symbol instead of a string if PACKAGE-SYMBOL is non-nil.
 The return value is suitable for direct passing to `interactive'."
-  (package-get-require-base)
+  (package-get-require-base t)
   (let ( (table (mapcar '(lambda (item)
                           (let ( (name (symbol-name (car item))) )
                             (cons name name)
@@ -347,7 +527,7 @@ This is just an interactive wrapper for `package-admin-delete-binary-package'."
 (defun package-get-update-all ()
   "Fetch and install the latest versions of all currently installed packages."
   (interactive)
-  (package-get-require-base)
+  (package-get-require-base t)
   ;; Load a fresh copy
   (catch 'exit
     (mapcar (lambda (pkg)
@@ -392,7 +572,7 @@ Returns nil upon error."
       (while this-requires
        (if (not (member (car this-requires) fetched-packages))
            (let* ((reqd-package (package-get-package-provider
-                                 (car this-requires)))
+                                 (car this-requires) t))
                   (reqd-version (cadr reqd-package))
                   (reqd-name (car reqd-package)))
              (if (null reqd-name)
@@ -415,7 +595,7 @@ Returns nil upon error."
 Uses `package-get-base' to determine just what is required and what
 package provides that functionality.  Returns the list of packages
 required by PACKAGES."
-  (package-get-require-base)
+  (package-get-require-base t)
   (let ((orig-packages packages)
         dependencies provided)
     (while packages
@@ -509,10 +689,13 @@ Returns `t' upon success, the symbol `error' if the package was
 successfully installed but errors occurred during initialization, or
 `nil' upon error."
   (interactive (package-get-interactive-package-query nil t))
+  (catch 'skip-update
   (let* ((this-package
          (package-get-info-version
           (package-get-info-find-package package-get-base
                                          package) version))
+         (latest (package-get-info-prop this-package 'version))
+         (installed (package-get-key package :version))
         (this-requires (package-get-info-prop this-package 'requires))
         (found nil)
         (search-dirs package-get-remote)
@@ -529,6 +712,22 @@ successfully installed but errors occurred during initialization, or
          (package-admin-get-install-dir package install-dir
                (or (eq package 'mule-base) (memq 'mule-base this-requires))))
 
+    ;; If they asked for the latest using version=nil, don't get an older
+    ;; version than we already have.
+    (if installed
+        (if (> (if (stringp installed)
+                   (string-to-number installed)
+                 installed)
+               (if (stringp latest)
+                   (string-to-number latest)
+                 latest))
+            (if (not (null version))
+                (warn "Installing %s package version %s, you had a newer version %s"
+                      package latest installed)
+              (warn "Skipping %s package, you have a newer version %s"
+                    package installed)
+              (throw 'skip-update t))))
+
     ;; Contrive a list of possible package filenames.
     ;; Ugly.  Is there a better way to do this?
     (setq filenames (cons base-filename nil))
@@ -537,7 +736,7 @@ successfully installed but errors occurred during initialization, or
                                (list (concat (match-string 1 base-filename)
                                              ".tgz")))))
 
-    (setq version (package-get-info-prop this-package 'version))
+    (setq version latest)
     (unless (and (eq conflict 'never)
                 (package-get-installedp package version))
       ;; Find the package from the search list in package-get-remote
@@ -657,7 +856,7 @@ successfully installed but errors occurred during initialization, or
     (if (and found package-get-remove-copy)
        (delete-file full-package-filename))
     package-status
-    ))
+    )))
 
 (defun package-get-info-find-package (which name)
   "Look in WHICH for the package called NAME and return all the info
@@ -758,13 +957,16 @@ some built in variables.  For now, use packages-package-list."
         (if (floatp version) version (string-to-number version))))
 
 ;;;###autoload
-(defun package-get-package-provider (sym)
+(defun package-get-package-provider (sym &optional force-current)
   "Search for a package that provides SYM and return the name and
   version.  Searches in `package-get-base' for SYM.   If SYM is a
   consp, then it must match a corresponding (provide (SYM VERSION)) from 
-  the package."
+  the package.
+
+If FORCE-CURRENT is non-nil make sure the database is up to date. This might
+lead to Emacs accessing remote sites."
   (interactive "SSymbol: ")
-  (package-get-require-base)
+  (package-get-require-base force-current)
   (let ((packages package-get-base)
        (done nil)
        (found nil))
@@ -774,12 +976,14 @@ some built in variables.  For now, use packages-package-list."
        (while (and (not done) this-package)
          (if (or (eq this-name sym)
                  (eq (cons this-name
-                           (package-get-info-prop (car this-package) 'version))
+                         (package-get-info-prop (car this-package) 'version))
                      sym)
-                 (member sym (package-get-info-prop (car this-package) 'provides)))
+                 (member sym
+                       (package-get-info-prop (car this-package) 'provides)))
              (progn (setq done t)
-                    (setq found (list (caar packages)
-                                      (package-get-info-prop (car this-package) 'version))))
+                    (setq found
+                      (list (caar packages)
+                        (package-get-info-prop (car this-package) 'version))))
            (setq this-package (cdr this-package)))))
       (setq packages (cdr packages)))
     found))
@@ -796,12 +1000,12 @@ some built in variables.  For now, use packages-package-list."
 (defun package-get-custom ()
   "Fetch and install the latest versions of all customized packages."
   (interactive)
-  (package-get-require-base)
+  (package-get-require-base t)
   ;; Load a fresh copy
   (load "package-get-custom.el")
   (mapcar (lambda (pkg)
            (if (eval (intern (concat (symbol-name (car pkg)) "-package")))
-               (package-get-all (car pkg) nil))
+               (package-get (car pkg) nil))
            t)
          package-get-base))
 
@@ -814,83 +1018,26 @@ some built in variables.  For now, use packages-package-list."
        (intern (substring (symbol-name pkg) 0 (match-beginning 0))))
        t)))
 
-(defun package-get-file-installed-p (file &optional paths)
-  "Return absolute-path of FILE if FILE exists in PATHS.
-If PATHS is omitted, `load-path' is used."
-  (if (null paths)
-      (setq paths load-path)
-    )
-  (catch 'tag
-    (let (path)
-      (while paths
-       (setq path (expand-file-name file (car paths)))
-       (if (file-exists-p path)
-           (throw 'tag path)
-         )
-       (setq paths (cdr paths))
-       ))))
+(defvar package-get-custom-groups nil
+  "List of package-get-custom groups")
+
+(defun package-get-custom-add-entry (package props)
+  (let* ((category (plist-get props 'category))
+         (group (intern (concat category "-packages")))
+         (custom-var (intern (concat (symbol-name package) "-package")))
+         (description (plist-get props 'description)))
+    (when (not (memq group package-get-custom-groups))
+      (setq package-get-custom-groups (cons package
+                                            package-get-custom-groups))
+      (eval `(defgroup ,group nil
+               ,(concat category " package group")
+               :group 'packages)))
+    (eval `(defcustom ,custom-var nil
+             ,description
+             :group ',group
+             :initialize 'package-get-ever-installed-p
+             :type 'boolean))))
 
-(defun package-get-create-custom ()
-  "Creates a package customization file package-get-custom.el.
-Entries in the customization file are retrieved from package-get-base.el."
-  (interactive)
-  ;; Load a fresh copy
-  (let ((custom-buffer (find-file-noselect 
-                       (or (package-get-file-installed-p 
-                            "package-get-custom.el")
-                           (expand-file-name
-                            "package-get-custom.el"
-                            (file-name-directory 
-                             (package-get-file-installed-p 
-                              "package-get-base.el"))
-                            ))))
-       (pkg-groups nil))
-
-    ;; clear existing stuff
-    (delete-region (point-min custom-buffer) 
-                  (point-max custom-buffer) custom-buffer)
-    (insert-string "(require 'package-get)\n" custom-buffer)
 
-    (mapcar (lambda (pkg)
-             (let ((category (plist-get (car (cdr pkg)) 'category)))
-               (or (memq (intern category) pkg-groups)
-                   (progn
-                     (setq pkg-groups (cons (intern category) pkg-groups))
-                     (insert-string 
-                      (concat "(defgroup " category "-packages nil\n"
-                              "  \"" category " package group\"\n"
-                              "  :group 'packages)\n\n") custom-buffer)))
-               
-               (insert-string 
-                (concat "(defcustom " (symbol-name (car pkg)) 
-                        "-package nil \n"
-                        "  \"" (plist-get (car (cdr pkg)) 'description) "\"\n"
-                        "  :group '" category "-packages\n"
-                        "  :initialize 'package-get-ever-installed-p\n"
-                        "  :type 'boolean)\n\n") custom-buffer)))
-           package-get-base) custom-buffer)
-  )
-
-;; need this first to avoid infinite dependency loops
 (provide 'package-get)
-
-;; potentially update the custom dependencies every time we load this
-(when nil ;; #### disable for now... -gk
-(unless noninteractive
-(let ((custom-file (package-get-file-installed-p "package-get-custom.el"))
-      (package-file (package-get-file-installed-p "package-get-base.el")))
-  ;; update custom file if it doesn't exist
-  (if (or (not custom-file)
-         (and (< (car (nth 5 (file-attributes custom-file)))
-                 (car (nth 5 (file-attributes package-file))))
-              (< (car (nth 5 (file-attributes custom-file)))
-                 (car (nth 5 (file-attributes package-file))))))
-      (save-excursion
-       (message "generating package customizations...")
-       (set-buffer (package-get-create-custom))
-       (save-buffer)
-       (message "generating package customizations...done")))
-  (load "package-get-custom.el")))
-)
-
 ;;; package-get.el ends here
index f13ed9b..3e49ae3 100644 (file)
@@ -213,9 +213,15 @@ disk."
 (defun pui-package-symbol-char (pkg-sym version)
   (progn
     (if (package-get-info-find-package packages-package-list pkg-sym)
-       (if (package-get-installedp pkg-sym version)
-           (list " " pui-up-to-date-package-face)
-         (list "*" pui-outdated-package-face))
+        (let ((installed (package-get-key pkg-sym :version)))
+          (if (>= (if (stringp installed)
+                      (string-to-number installed)
+                    installed)
+                  (if (stringp version)
+                      (string-to-number version)
+                    version))
+              (list " " pui-up-to-date-package-face)
+            (list "*" pui-outdated-package-face)))
       (list "-" pui-uninstalled-package-face))
     ))
 
@@ -332,8 +338,8 @@ and whether or not it is up-to-date."
                (message "Installing selected packages ...") (sit-for 0)
                (if (catch 'done
                      (mapcar (lambda (pkg)
-                               (if (not (package-get pkg
-                                       pui-package-install-dest-dir))
+                               (if (not (package-get pkg nil nil
+                                                      pui-package-install-dest-dir))
                                    (throw 'done nil)))
                              pui-selected-packages)
                      t)
@@ -353,7 +359,26 @@ and whether or not it is up-to-date."
   (interactive)
   (let ((tmpbuf "*Required-Packages*") do-select)
     (if pui-selected-packages
-       (let ((dependencies (package-get-dependencies pui-selected-packages)))
+       (let ((dependencies
+               (delq nil (mapcar
+                          (lambda (pkg)
+                            (let ((installed
+                                   (package-get-key pkg :version))
+                                  (current
+                                   (package-get-info-prop
+                                    (package-get-info-version
+                                     (package-get-info-find-package
+                                      package-get-base pkg) nil)
+                                    'version)))
+                              (if (< (if (stringp installed)
+                                         (string-to-number installed)
+                                       installed)
+                                     (if (stringp current)
+                                         (string-to-number current)
+                                       current))
+                                  pkg
+                                nil)))
+                          (package-get-dependencies pui-selected-packages)))))
          ;; Don't change window config when asking the user if he really
          ;; wants to add the packages.  We do this to avoid messing up
          ;; the window configuration if errors occur (we don't want to
@@ -471,7 +496,7 @@ buffer, the user can see which packages are installed, which are not, and
 which are out-of-date (a newer version is available).  The user can then
 select packages for installation via the keyboard or mouse."
   (interactive)
-  (package-get-require-base)
+  (package-get-require-base t)
   (let ( (outbuf (get-buffer-create pui-info-buffer))
         (sep-string "===============================================================================\n")
         start )
index fb46f35..1c93601 100644 (file)
@@ -245,6 +245,7 @@ In either case, the output is inserted after point (leaving mark after it)."
     (let ((buffer (get-buffer-create
                   (or output-buffer "*Shell Command Output*")))
          (success nil)
+         (exit-status nil)
          (directory default-directory))
       (unwind-protect
          (if (eq buffer (current-buffer))
@@ -254,9 +255,10 @@ In either case, the output is inserted after point (leaving mark after it)."
              (progn (setq buffer-read-only nil)
                     (delete-region (max start end) (point-max))
                     (delete-region (point-min) (max start end))
-                    (call-process-region (point-min) (point-max)
-                                         shell-file-name t t nil
-                                         shell-command-switch command)
+                    (setq exit-status
+                          (call-process-region (point-min) (point-max)
+                                               shell-file-name t t nil
+                                               shell-command-switch command))
                     (setq success t))
            ;; Clear the output buffer, 
            ;; then run the command with output there.
@@ -266,9 +268,10 @@ In either case, the output is inserted after point (leaving mark after it)."
              ;; XEmacs change
              (setq default-directory directory)
              (erase-buffer))
-           (call-process-region start end shell-file-name
-                                nil buffer nil
-                                shell-command-switch command)
+           (setq exit-status
+                 (call-process-region start end shell-file-name
+                                      nil buffer nil
+                                      shell-command-switch command))
            (setq success t))
        ;; Report the amount of output.
        (let ((lines (save-excursion
@@ -280,7 +283,9 @@ In either case, the output is inserted after point (leaving mark after it)."
                 (if success
                     (display-message
                      'command
-                     "(Shell command completed with no output)"))
+                     (if (eql exit-status 0)
+                         "(Shell command succeeded with no output)"
+                       "(Shell command failed with no output)")))
                 (kill-buffer buffer))
                ((and success (= lines 1))
                 (message "%s"
index d07033b..69af79b 100644 (file)
@@ -540,11 +540,12 @@ yourself.]"
 
 ;;;; Miscellanea.
 
-(defun buffer-substring-no-properties (beg end)
-  "Return the text from BEG to END, without text properties, as a string."
-  (let ((string (buffer-substring beg end)))
-    (set-text-properties 0 (length string) nil string)
-    string))
+;; This is now in C.
+;(defun buffer-substring-no-properties (beg end)
+;  "Return the text from BEG to END, without text properties, as a string."
+;  (let ((string (buffer-substring beg end)))
+;    (set-text-properties 0 (length string) nil string)
+;    string))
 
 (defun get-buffer-window-list (&optional buffer minibuf frame)
   "Return windows currently displaying BUFFER, or nil if none.
index a311bc4..e7a5d96 100644 (file)
@@ -1063,48 +1063,49 @@ Recommended as a parent keymap for modes using widgets.")
 
 (defun widget-button-click (event)
   "Invoke button below mouse pointer."
-  (interactive "@e")
-  (cond ((event-glyph event)
-        (widget-glyph-click event))
-       ((widget-event-point event)
-        (let* ((pos (widget-event-point event))
-               (button (get-char-property pos 'button)))
-          (if button
-              (let* ((extent (widget-get button :button-extent))
-                     (face (extent-property extent 'face))
-                     (mouse-face (extent-property extent 'mouse-face))
-                     (help-echo (extent-property extent 'help-echo)))
-                (unwind-protect
-                    (progn
-                      ;; Merge relevant faces, and make the result mouse-face.
-                      (let ((merge `(widget-button-pressed-face ,mouse-face)))
-                        (nconc merge (if (listp face)
-                                         face (list face)))
-                        (setq merge (delete-if-not 'find-face merge))
-                        (set-extent-property extent 'mouse-face merge))
-                      (unless (widget-apply button :mouse-down-action event)
-                        ;; Wait for button release.
-                        (while (not (button-release-event-p
-                                     (setq event (next-event))))
-                          (dispatch-event event)))
-                      ;; Disallow mouse-face and help-echo.
-                      (set-extent-property extent 'mouse-face nil)
-                      (set-extent-property extent 'help-echo nil)
-                      (setq pos (widget-event-point event))
-                      (unless (eq (current-buffer) (extent-object extent))
-                        ;; Barf if dispatch-event tripped us by
-                        ;; changing buffer.
-                        (error "Buffer changed during mouse motion"))
-                      ;; Do the associated action.
-                      (when (and pos (extent-in-region-p extent pos pos))
-                        (widget-apply-action button event)))
-                  ;; Unwinding: fully release the button.
-                  (set-extent-property extent 'mouse-face mouse-face)
-                  (set-extent-property extent 'help-echo help-echo)))
-            ;; This should not happen!
-            (error "`widget-button-click' called outside button"))))
-       (t
-        (message "You clicked somewhere weird"))))
+  (interactive "e")
+  (with-current-buffer (event-buffer event)
+    (cond ((event-glyph event)
+          (widget-glyph-click event))
+         ((widget-event-point event)
+          (let* ((pos (widget-event-point event))
+                 (button (get-char-property pos 'button)))
+            (if button
+                (let* ((extent (widget-get button :button-extent))
+                       (face (extent-property extent 'face))
+                       (mouse-face (extent-property extent 'mouse-face))
+                       (help-echo (extent-property extent 'help-echo)))
+                  (unwind-protect
+                      (progn
+                        ;; Merge relevant faces, and make the result mouse-face.
+                        (let ((merge `(widget-button-pressed-face ,mouse-face)))
+                          (nconc merge (if (listp face)
+                                           face (list face)))
+                          (setq merge (delete-if-not 'find-face merge))
+                          (set-extent-property extent 'mouse-face merge))
+                        (unless (widget-apply button :mouse-down-action event)
+                          ;; Wait for button release.
+                          (while (not (button-release-event-p
+                                       (setq event (next-event))))
+                            (dispatch-event event)))
+                        ;; Disallow mouse-face and help-echo.
+                        (set-extent-property extent 'mouse-face nil)
+                        (set-extent-property extent 'help-echo nil)
+                        (setq pos (widget-event-point event))
+                        (unless (eq (current-buffer) (extent-object extent))
+                          ;; Barf if dispatch-event tripped us by
+                          ;; changing buffer.
+                          (error "Buffer changed during mouse motion"))
+                        ;; Do the associated action.
+                        (when (and pos (extent-in-region-p extent pos pos))
+                          (widget-apply-action button event)))
+                    ;; Unwinding: fully release the button.
+                    (set-extent-property extent 'mouse-face mouse-face)
+                    (set-extent-property extent 'help-echo help-echo)))
+              ;; This should not happen!
+              (error "`widget-button-click' called outside button"))))
+         (t
+          (message "You clicked somewhere weird")))))
 
 (defun widget-button1-click (event)
   "Invoke glyph below mouse pointer."
index d329245..8217209 100644 (file)
@@ -1,3 +1,7 @@
+1998-11-28  SL Baur  <steve@altair.xemacs.org>
+
+       * XEmacs 21.2-beta4 is released.
+
 1998-10-15  SL Baur  <steve@altair.xemacs.org>
 
        * XEmacs 21.2-beta3 is released.
index 7b8e67e..59d4c50 100644 (file)
@@ -2045,7 +2045,7 @@ code generalization for future I18N work.
 @menu
 * Character-Related Data Types::
 * Working With Character and Byte Positions::
-* Conversion of External Data::
+* Conversion to and from External Data::
 * General Guidelines for Writing Mule-Aware Code::
 * An Example of Mule-Aware Code::
 @end menu
@@ -2053,9 +2053,9 @@ code generalization for future I18N work.
 @node Character-Related Data Types
 @subsection Character-Related Data Types
 
-First, we will list the basic character-related datatypes used by
-XEmacs.  Note that the separate @code{typedef}s are not required for the 
-code to work (all of them boil down to @code{unsigned char} or
+First, let's review the basic character-related datatypes used by
+XEmacs.  Note that the separate @code{typedef}s are not mandatory in the
+current implementation (all of them boil down to @code{unsigned char} or
 @code{int}), but they improve clarity of code a great deal, because one
 glance at the declaration can tell the intended use of the variable.
 
@@ -2093,6 +2093,8 @@ Without Mule support, a @code{Bufbyte} is equivalent to an
 
 @item Bufpos
 @itemx Charcount
+@cindex Bufpos
+@cindex Charcount
 A @code{Bufpos} represents a character position in a buffer or string.
 A @code{Charcount} represents a number (count) of characters.
 Logically, subtracting two @code{Bufpos} values yields a
@@ -2105,6 +2107,8 @@ ever visible to Lisp.
 
 @item Bytind
 @itemx Bytecount
+@cindex Bytind
+@cindex Bytecount
 A @code{Bytind} represents a byte position in a buffer or string.  A
 @code{Bytecount} represents the distance between two positions in bytes.
 The relationship between @code{Bytind} and @code{Bytecount} is the same
@@ -2112,6 +2116,8 @@ as the relationship between @code{Bufpos} and @code{Charcount}.
 
 @item Extbyte
 @itemx Extcount
+@cindex Extbyte
+@cindex Extcount
 When dealing with the outside world, XEmacs works with @code{Extbyte}s,
 which are equivalent to @code{unsigned char}.  Obviously, an
 @code{Extcount} is the distance between two @code{Extbyte}s.  Extbytes
@@ -2130,6 +2136,7 @@ learn about them.
 
 @table @code
 @item MAX_EMCHAR_LEN
+@cindex MAX_EMCHAR_LEN
 This preprocessor constant is the maximum number of buffer bytes per
 Emacs character, i.e. the byte length of an @code{Emchar}.  It is useful
 when allocating temporary strings to keep a known number of characters.
@@ -2155,10 +2162,12 @@ In the current Mule implementation, @code{MAX_EMCHAR_LEN} equals 4.
 Without Mule, it is 1.
 
 @item charptr_emchar
-@item set_charptr_emchar
-@code{charptr_emchar} macro takes a @code{Bufbyte} pointer and returns
-the underlying @code{Emchar}.  If it were a function, its prototype
-would be:
+@itemx set_charptr_emchar
+@cindex charptr_emchar
+@cindex set_charptr_emchar
+The @code{charptr_emchar} macro takes a @code{Bufbyte} pointer and
+returns the @code{Emchar} stored at that position.  If it were a
+function, its prototype would be:
 
 @example
 Emchar charptr_emchar (Bufbyte *p);
@@ -2200,14 +2209,19 @@ and increment the counter, at the same time.
 
 @item INC_CHARPTR
 @itemx DEC_CHARPTR
+@cindex INC_CHARPTR
+@cindex DEC_CHARPTR
 These two macros increment and decrement a @code{Bufbyte} pointer,
-respectively.  The pointer needs to be correctly positioned at the
-beginning of a valid character position.
+respectively.  They will adjust the pointer by the appropriate number of
+bytes according to the byte length of the character stored there.  Both
+macros assume that the memory address is located at the beginning of a
+valid character.
 
 Without Mule support, @code{INC_CHARPTR (p)} and @code{DEC_CHARPTR (p)}
 simply expand to @code{p++} and @code{p--}, respectively.
 
 @item bytecount_to_charcount
+@cindex bytecount_to_charcount
 Given a pointer to a text string and a length in bytes, return the
 equivalent length in characters.
 
@@ -2216,6 +2230,7 @@ Charcount bytecount_to_charcount (Bufbyte *p, Bytecount bc);
 @end example
 
 @item charcount_to_bytecount
+@cindex charcount_to_bytecount
 Given a pointer to a text string and a length in characters, return the
 equivalent length in bytes.
 
@@ -2224,6 +2239,7 @@ Bytecount charcount_to_bytecount (Bufbyte *p, Charcount cc);
 @end example
 
 @item charptr_n_addr
+@cindex charptr_n_addr
 Return a pointer to the beginning of the character offset @var{cc} (in
 characters) from @var{p}.
 
@@ -2232,55 +2248,118 @@ Bufbyte *charptr_n_addr (Bufbyte *p, Charcount cc);
 @end example
 @end table
 
-@node Conversion of External Data
-@subsection Conversion of External Data
+@node Conversion to and from External Data
+@subsection Conversion to and from External Data
 
 When an external function, such as a C library function, returns a
-@code{char} pointer, you should never treat it as @code{Bufbyte}.  This
-is because these returned strings may contain 8bit characters which can
-be misinterpreted by XEmacs, and cause a crash.  Instead, you should use
-a conversion macro.  Many different conversion macros are defined in
-@file{buffer.h}, so I will try to order them logically, by direction and
-by format.
-
-Thus the basic conversion macros are @code{GET_CHARPTR_INT_DATA_ALLOCA}
-and @code{GET_CHARPTR_EXT_DATA_ALLOCA}.  The former is used to convert
-external data to internal format, and the latter is used to convert the
-other way around.  The arguments each of these receives are @var{ptr}
-(pointer to the text in external format), @var{len} (length of texts in
-bytes), @var{fmt} (format of the external text), @var{ptr_out} (lvalue
-to which new text should be copied), and @var{len_out} (lvalue which
-will be assigned the length of the internal text in bytes).  The
-resulting text is stored to a stack-allocated buffer.  If the text
-doesn't need changing, these macros will do nothing, except for setting
-@var{len_out}.
+@code{char} pointer, you should almost never treat it as @code{Bufbyte}.
+This is because these returned strings may contain 8bit characters which
+can be misinterpreted by XEmacs, and cause a crash.  Likewise, when
+exporting a piece of internal text to the outside world, you should
+always convert it to an appropriate external encoding, lest the internal 
+stuff (such as the infamous \201 characters) leak out.
+
+The interface to conversion between the internal and external
+representations of text are the numerous conversion macros defined in
+@file{buffer.h}.  Before looking at them, we'll look at the external
+formats supported by these macros.
 
 Currently meaningful formats are @code{FORMAT_BINARY},
-@code{FORMAT_FILENAME}, @code{FORMAT_OS}, and @code{FORMAT_CTEXT}.
+@code{FORMAT_FILENAME}, @code{FORMAT_OS}, and @code{FORMAT_CTEXT}.  Here 
+is a description of these.
+
+@table @code
+@item FORMAT_BINARY
+Binary format.  This is the simplest format and is what we use in the
+absence of a more appropriate format.  This converts according to the
+@code{binary} coding system:
+
+@enumerate a
+@item
+On input, bytes 0--255 are converted into characters 0--255.
+@item
+On output, characters 0--255 are converted into bytes 0--255 and other
+characters are converted into `X'.
+@end enumerate
+
+@item FORMAT_FILENAME
+Format used for filenames.  In the original Mule, this is user-definable
+with the @code{pathname-coding-system} variable.  For the moment, we
+just use the @code{binary} coding system.
+
+@item FORMAT_OS
+Format used for the external Unix environment---@code{argv[]}, stuff
+from @code{getenv()}, stuff from the @file{/etc/passwd} file, etc.
 
-The two macros above take many arguments which makes them unwieldy.  For
-this reason, several convenience macros are defined with obvious
-functionality, but accepting less arguments:
+Perhaps should be the same as FORMAT_FILENAME.
+
+@item FORMAT_CTEXT
+Compound--text format.  This is the standard X format used for data
+stored in properties, selections, and the like.  This is an 8-bit
+no-lock-shift ISO2022 coding system.
+@end table
+
+The macros to convert between these formats and the internal format, and 
+vice versa, follow.
 
 @table @code
-@item GET_C_CHARPTR_EXT_DATA_ALLOCA
-@itemx GET_C_CHARPTR_INT_DATA_ALLOCA
-These two macros work on ``C char pointers'', which are zero-terminated, 
-and thus do not need @var{len} or @var{len_out} parameters.
+@item GET_CHARPTR_INT_DATA_ALLOCA
+@itemx GET_CHARPTR_EXT_DATA_ALLOCA
+These two are the most basic conversion macros.
+@code{GET_CHARPTR_INT_DATA_ALLOCA} converts external data to internal
+format, and @code{GET_CHARPTR_EXT_DATA_ALLOCA} converts the other way
+around.  The arguments each of these receives are @var{ptr} (pointer to
+the text in external format), @var{len} (length of texts in bytes),
+@var{fmt} (format of the external text), @var{ptr_out} (lvalue to which
+new text should be copied), and @var{len_out} (lvalue which will be
+assigned the length of the internal text in bytes).  The resulting text
+is stored to a stack-allocated buffer.  If the text doesn't need
+changing, these macros will do nothing, except for setting
+@var{len_out}.
+
+The macros above take many arguments which makes them unwieldy.  For
+this reason, a number of convenience macros are defined with obvious
+functionality, but accepting less arguments.  The general rule is that
+macros with @samp{INT} in their name convert text to internal Emacs
+representation, whereas the @samp{EXT} macros convert to external
+representation.
+
+@item GET_C_CHARPTR_INT_DATA_ALLOCA
+@itemx GET_C_CHARPTR_EXT_DATA_ALLOCA
+As their names imply, these macros work on C char pointers, which are
+zero-terminated, and thus do not need @var{len} or @var{len_out}
+parameters.
 
 @item GET_STRING_EXT_DATA_ALLOCA
 @itemx GET_C_STRING_EXT_DATA_ALLOCA
-These two macros work on Lisp strings, thus also not needing a @var{len}
-parameter.  However, @code{GET_STRING_EXT_DATA_ALLOCA} still provides a
-@var{len_out} parameter.  Note that for Lisp strings only one conversion
-direction makes sense.
+These two macros convert a Lisp string into an external representation.
+The difference between them is that @code{GET_STRING_EXT_DATA_ALLOCA}
+stores its output to a generic string, providing @var{len_out}, the
+length of the resulting external string.  On the other hand,
+@code{GET_C_STRING_EXT_DATA_ALLOCA} assumes that the caller will be
+satisfied with output string being zero-terminated.
+
+Note that for Lisp strings only one conversion direction makes sense.
 
 @item GET_C_CHARPTR_EXT_BINARY_DATA_ALLOCA
+@itemx GET_CHARPTR_EXT_BINARY_DATA_ALLOCA
+@itemx GET_STRING_BINARY_DATA_ALLOCA
+@itemx GET_C_STRING_BINARY_DATA_ALLOCA
 @itemx GET_C_CHARPTR_EXT_FILENAME_DATA_ALLOCA
-@itemx GET_C_CHARPTR_EXT_CTEXT_DATA_ALLOCA
 @itemx ...
-These macros are a combination of the above, but with the @var{fmt}
-argument encoded into the name of the macro.
+These macros convert internal text to a specific external
+representation, with the external format being encoded into the name of
+the macro.  Note that the @code{GET_STRING_...} and
+@code{GET_C_STRING...}  macros lack the @samp{EXT} tag, because they
+only make sense in that direction.
+
+@item GET_C_CHARPTR_INT_BINARY_DATA_ALLOCA
+@itemx GET_CHARPTR_INT_BINARY_DATA_ALLOCA
+@itemx GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA
+@itemx ...
+These macros convert external text of a specific format to its internal
+representation, with the external format being incoded into the name of
+the macro.
 @end table
 
 @node General Guidelines for Writing Mule-Aware Code
index 6ac2408..f66bf59 100644 (file)
@@ -53,6 +53,7 @@ buffer, together with their properties (when relevant).
                        position stored in a register.
 * Transposition::    Swapping two portions of a buffer.
 * Change Hooks::     Supplying functions to be run when text is changed.
+* Transformations::  MD5 and base64 support.
 @end menu
 
 @node Near Point
@@ -2668,3 +2669,139 @@ This obsolete variable holds one function to call after any buffer modification
 This variable is a normal hook that is run whenever a buffer is changed
 that was previously in the unmodified state.
 @end defvar
+
+@node Transformations
+@section Textual transformations---MD5 and base64 support
+@cindex MD5 digests
+@cindex base64
+
+Some textual operations inherently require examining each character in
+turn, and performing arithmetic operations on them.  Such operations
+can, of course, be implemented in Emacs Lisp, but tend to be very slow
+for large portions of text or data.  This is why some of them are
+implemented in C, with an appropriate interface for Lisp programmers.
+Examples of algorithms thus provided are MD5 and base64 support.
+
+MD5 is an algorithm for calculating message digests, as described in
+rfc1321.  Given a message of arbitrary length, MD5 produces an 128-bit
+``fingerprint'' (``message digest'') corresponding to that message.  It
+is considered computationally infeasible to produce two messages having
+the same MD5 digest, or to produce a message having a prespecified
+target digest.  MD5 is used heavily by various authentication schemes.
+
+Emacs Lisp interface to MD5 consists of a single function @code{md5}:
+
+@defun md5 object &optional start end
+This function returns the MD5 message digest of @var{object}, a buffer
+or string.
+
+Optional arguments @var{start} and @var{end} denote positions for
+computing the digest of a portion of @var{object}.
+
+Some examples of usage:
+
+@example
+@group
+;; @r{Calculate the digest of the entire buffer}
+(md5 (current-buffer))
+     @result{} "8842b04362899b1cda8d2d126dc11712"
+@end group
+
+@group
+;; @r{Calculate the digest of the current line}
+(md5 (current-buffer) (point-at-bol) (point-at-eol))
+     @result{} "60614d21e9dee27dfdb01fa4e30d6d00"
+@end group
+
+@group
+;; @r{Calculate the digest of your name and email address}
+(md5 (concat (format "%s <%s>" (user-full-name) user-mail-address)))
+     @result{} "0a2188c40fd38922d941fe6032fce516"
+@end group
+@end example
+@end defun
+
+Base64 is a portable encoding for arbitrary sequences of octets, in a
+form that need not be readable by humans.  It uses a 65-character subset
+of US-ASCII, as described in rfc2045.  Base64 is used by MIME to encode
+binary bodies, and to encode binary characters in message headers.
+
+The Lisp interface to base64 consists of four functions:
+
+@defun base64-encode-region beg end &optional no-line-break
+This function encodes the region between @var{beg} and @var{end} of the
+current buffer to base64 format.  This means that the original region is 
+deleted, and replaced with its base64 equivalent.
+
+Normally, encoded base64 output is multi-line, with 76-character lines.
+If @var{no-line-break} is non-@code{nil}, newlines will not be inserted, 
+resulting in single-line output.
+
+Mule note: you should make sure that you convert the multibyte
+characters (those that do not fit into 0--255 range) to something else,
+because they cannot be meaningfully converted to base64.  If the
+@code{base64-encode-region} encounters such characters, it will signal
+an error.
+
+@code{base64-encode-region} returns the length of the encoded text.
+
+@example
+@group
+;; @r{Encode the whole buffer in base64}
+(base64-encode-region (point-min) (point-max))
+@end group
+@end example
+
+The function can also be used interactively, in which case it works on
+the currently active region.
+@end defun
+
+@defun base64-encode-string string
+This function encodes @var{string} to base64, and returns the encoded
+string.
+
+For Mule, the same considerations apply as for
+@code{base64-encode-region}.
+
+@example
+@group
+(base64-encode-string "fubar")
+    @result{} "ZnViYXI="
+@end group
+@end example
+@end defun
+
+@defun base64-decode-region beg end
+This function decodes the region between @var{beg} and @var{end} of the
+current buffer.  The region should be in base64 encoding.
+
+If the region was decoded correctly, @code{base64-decode-region} returns
+the length of the decoded region.  If the decoding failed, @code{nil} is 
+returned.
+
+@example
+@group
+;; @r{Decode a base64 buffer, and replace it with the decoded version}
+(base64-decode-region (point-min) (point-max))
+@end group
+@end example
+@end defun
+
+@defun base64-decode-string string
+This function decodes @var{string} to base64, and returns the decoded
+string.  @var{string} should be valid base64-encoded text.
+
+If encoding was not possible, @code{nil} is returned.
+
+@example
+@group
+(base64-decode-string "ZnViYXI=")
+    @result{} "fubar"
+@end group
+
+@group
+(base64-decode-string "totally bogus")
+    @result{} nil
+@end group
+@end example
+@end defun
index 29e932c..4a04b57 100644 (file)
@@ -1,3 +1,12 @@
+1998-11-28  SL Baur  <steve@altair.xemacs.org>
+
+       * XEmacs 21.2-beta4 is released.
+
+1998-10-29  Andy Piper  <andyp@parallax.co.uk>
+
+       * xemacs.mak ($(LIB_SRC)/movemail.exe): add etags dependencies to
+       pull in getopt and friends.
+
 1998-10-15  SL Baur  <steve@altair.xemacs.org>
 
        * XEmacs 21.2-beta3 is released.
index 1a45c4f..91cfd85 100644 (file)
@@ -439,7 +439,7 @@ LIB_SRC_DEFINES = -DHAVE_CONFIG_H -DWIN32 -DWINDOWSNT
 # Individual dependencies
 ETAGS_DEPS = $(LIB_SRC)/getopt.c $(LIB_SRC)/getopt1.c $(LIB_SRC)/../src/regex.c
 $(LIB_SRC)/etags.exe : $(LIB_SRC)/etags.c $(ETAGS_DEPS)
-#### ootags???
+$(LIB_SRC)/movemail.exe: $(LIB_SRC)/movemail.c $(ETAGS_DEPS)
 
 LIB_SRC_TOOLS = \
        $(LIB_SRC)/make-docfile.exe     \
index aa84b92..765c3bf 100644 (file)
@@ -1,3 +1,165 @@
+1998-11-28  SL Baur  <steve@altair.xemacs.org>
+
+       * XEmacs 21.2-beta4 is released.
+
+1998-11-27  SL Baur  <steve@altair.xemacs.org>
+
+       * mule-charset.c (complex_vars_of_mule_charset): Fix graphic
+       property in control-1 charset.
+       From Julian Bradfield <jcb@daimi.au.dk>
+
+1998-11-26  Jan Vroonhof  <vroonhof@math.ethz.ch>
+
+       * gui-x.c (button_item_to_widget_value): Ignore :key-sequence
+       keyword.
+       Add stub for :label.
+
+       * gui.c (gui_item_add_keyval_pair): ditto.
+
+       * menubar-x.c (menu_item_descriptor_to_widget_value_1): Ignore
+       :key-sequence keyword.
+       Add stub for:label.
+       Support :active for submenus like the Windows code and FSF Emacs.
+
+1998-11-27  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * dired.c (make_directory_hash_table): make_string() is OK because 
+       readdir() Mule-encapsulates.
+
+1998-11-26  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * fns.c (Fbase64_encode_string): Fix docstring.
+       (Fbase64_decode_string): Ditto.
+
+1998-11-26  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * editfns.c (Ftranslate_region): Use
+       convert_bufbyte_string_into_emchar_string().
+
+1998-11-25  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * editfns.c (Ftranslate_region): Accept vectors and char-tables as 
+       well as strings.
+       (Ftranslate_region): Turn table into an array of Emchars for
+       larger regions.
+
+1998-11-25  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * chartab.c (Freset_char_table): Fix wrong placement of #endif.
+
+1998-11-24  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * chartab.c (Freset_char_table): Don't blindly fill chartables of
+       type `char' with nils.
+
+       * chartab.c (canonicalize_char_table_value): Coerce ints to chars
+       for tables of type `char'.
+
+1998-11-26  Didier Verna  <verna@inf.enst.fr>
+
+       * input-method-xlib.c (Initialize_Locale): don't call
+       XtSetLanguageProc. We've done the whole work here.
+       * input-method-xfs.c (Initialize_Locale): ditto.
+       * input-method-motif.c (Initialize_Locale): ditto.
+
+1998-11-26  Didier Verna  <verna@inf.enst.fr>
+
+       * process-unix.c (unix_create_process): handle properly
+       Vfile_name_coding_system for converting the program and directory
+       names. 
+
+1998-11-27  SL Baur  <steve@altair.xemacs.org>
+
+       * m/arm.h: New file.
+       From James LewisMoss <dres@ioa.com>
+
+1998-11-27  Takeshi Hagiwara  <hagiwara@ie.niigata-u.ac.jp>
+
+       * m/mips-nec.h:
+       Fix the realpath() problem of UnixWare2.1.3.
+       Patches for NEC's sysv4.2 machine.
+
+1998-11-25  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * dired.c (Fdirectory_files): Remove redundant code.
+
+1998-11-25  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * fns.c (free_malloced_ptr): New function.
+       (XMALLOC_OR_ALLOCA): New macro.
+       (XMALLOC_UNBIND): Ditto.
+       (Fbase64_encode_region): Use malloc() for large blocks; arrange it 
+       to be freed in case of non-local exit.
+       (Fbase64_encode_string): Ditto.
+       (Fbase64_decode_region): Ditto.
+       (Fbase64_decode_string): Ditto.
+       (STORE_BYTE): New macro.
+       (base64_decode_1): Use it.
+
+1998-11-25  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * fns.c (base64_value_to_char): Base64 stuff.
+
+1998-11-24  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * editfns.c (Fbuffer_substring): New function.
+
+       * lisp.h: Declare make_string_from_buffer_no_extents().
+
+       * insdel.c (make_string_from_buffer_1): New function.
+       (make_string_from_buffer_no_extents): Ditto.
+
+1998-11-15  Michael Sperber [Mr. Preprocessor]  <sperber@informatik.uni-tuebingen.de>
+
+       * linuxplay.c: Including <fcntl.h> instead of <sys/fcntl.h> makes
+       sound work on AIX with OSS installed.  Linux should still work.
+
+1998-11-03  Andy Piper  <andyp@parallax.co.uk>
+
+       * config.h.in: name change for cygwin/version.h
+
+       * configure.in: check for cygwin/version.h now.
+
+       * cygwin32.h: track CYGWIN_DLL_VERSION_MAJOR ->
+       CYGWIN_VERSION_DLL_MAJOR name change in cygwin b20.
+       move cygwin32/version.h to cygwin/version.h
+
+1998-11-03  Olivier Galibert  <galibert@pobox.com>
+
+       * lisp.h  (struct  Lisp_Bit_Vector): Fix declaration of  bits from
+       int to long.
+
+1998-10-22  Andy Piper  <andyp@parallax.co.uk>
+
+       * cygwin32.h: track CYGWIN_DLL_VERSION_MAJOR ->
+       CYGWIN_VERSION_DLL_MAJOR name change in cygwin b20.
+       enable BROKEN_SIGIO under b20 to make QUIT work.
+
+1998-10-22  Andy Piper  <andyp@parallax.co.uk>
+
+       * frame-msw.c (mswindows_size_frame_internal): force frame sizing
+       to fit within the constraints of the screen size. I.e. make the
+       frame small enough to fit and move it if some of it will be
+       off-screen.
+
+1998-10-19  Greg Klanderman  <greg@alphatech.com>
+
+       * dired.c: conditionalize inclusion of user-name-completion
+       primitives on non-Windows NT.  The needed functions don't exist on NT.
+
+1998-11-24  SL Baur  <steve@altair.xemacs.org>
+
+       * gifrlib.h: Clean up types for 64 bit compile.
+       * dgif_lib.c (DGifInitRead): Ditto.
+       (MakeSavedImage): Ditto.
+       * emacs.c (decode_path): Ditto.
+       From Steve Carney <carney@pa.dec.com>
+
+1998-10-16  William M. Perry  <wmperry@aventail.com>
+
+       * glyphs-msw.c (bitmap_table): Fixed typo in builtin bitmaps
+         (cehckboxes instead of checkboxes).
+
 1998-10-15  SL Baur  <steve@altair.xemacs.org>
 
        * XEmacs 21.2-beta3 is released.
index 470993b..498cb11 100644 (file)
@@ -552,13 +552,15 @@ Reset a char table to its default state.
   switch (ct->type)
     {
     case CHAR_TABLE_TYPE_CHAR:
+      fill_char_table (ct, make_char (0));
+      break;
     case CHAR_TABLE_TYPE_DISPLAY:
     case CHAR_TABLE_TYPE_GENERIC:
 #ifdef MULE
     case CHAR_TABLE_TYPE_CATEGORY:
+#endif /* MULE */
       fill_char_table (ct, Qnil);
       break;
-#endif /* MULE */
 
     case CHAR_TABLE_TYPE_SYNTAX:
       fill_char_table (ct, make_int (Sinherit));
@@ -775,7 +777,7 @@ get_non_ascii_char_table_value (struct Lisp_Char_Table *ct, int leading_byte,
 
 #endif /* MULE */
 
-static Lisp_Object
+Lisp_Object
 get_char_table (Emchar ch, struct Lisp_Char_Table *ct)
 {
 #ifdef MULE
@@ -987,6 +989,10 @@ canonicalize_char_table_value (Lisp_Object value, enum char_table_type type)
          CHECK_CHAR_COERCE_INT (cdr);
          return Fcons (car, cdr);
        }
+      break;
+    case CHAR_TABLE_TYPE_CHAR:
+      CHECK_CHAR_COERCE_INT (value);
+      break;
     default:
       break;
     }
index ac23e00..2aa4931 100644 (file)
@@ -180,6 +180,7 @@ struct chartab_range
 void fill_char_table (struct Lisp_Char_Table *ct, Lisp_Object value);
 void put_char_table (struct Lisp_Char_Table *ct, struct chartab_range *range,
                     Lisp_Object val);
+Lisp_Object get_char_table (Emchar, struct Lisp_Char_Table *);
 int map_char_table (struct Lisp_Char_Table *ct,
                    struct chartab_range *range,
                    int (*fn) (struct chartab_range *range,
index b78318e..eae4bbc 100644 (file)
@@ -194,7 +194,7 @@ char *alloca();
 #undef HAVE_ULIMIT_H
 #undef HAVE_X11_XLOCALE_H
 #undef HAVE_LINUX_VERSION_H
-#undef HAVE_CYGWIN32_VERSION_H
+#undef HAVE_CYGWIN_VERSION_H
 #undef HAVE_INTTYPES_H
 #undef HAVE_SYS_UN_H
 #undef HAVE_A_OUT_H
index d56832d..2ecab3f 100644 (file)
@@ -110,7 +110,7 @@ void DGifInitRead(GifFileType *GifFile)
     /* The GIF Version number is ignored at this time. Maybe we should do    */
     /* something more useful with it.                                       */
     Buf[GIF_STAMP_LEN] = 0;
-    if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
+    if (strncmp(GIF_STAMP, (const char *) Buf, GIF_VERSION_POS) != 0) {
        GifInternError(GifFile, D_GIF_ERR_NOT_GIF_FILE);
     }
 
@@ -856,7 +856,7 @@ SavedImage *MakeSavedImage(GifFileType *GifFile, SavedImage *CopyFrom)
                                  CopyFrom->ImageDesc.ColorMap->Colors);
 
            /* next, the raster */
-           sp->RasterBits = (char *)malloc(sizeof(GifPixelType)
+           sp->RasterBits = (GifPixelType*)malloc(sizeof(GifPixelType)
                                * CopyFrom->ImageDesc.Height
                                * CopyFrom->ImageDesc.Width);
            memcpy(sp->RasterBits,
index 076e339..c3083cd 100644 (file)
@@ -376,9 +376,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag,
          dp = readdir (d);
          if (!dp) break;
 
-         /* #### This is a bad idea, because d_name can contain
-             control characters, which can make XEmacs crash.  This
-             should be handled properly with FORMAT_FILENAME.  */
+         /* Cast to Bufbyte* is OK, as readdir() Mule-encapsulates.  */
          d_name = (Bufbyte *) dp->d_name;
          len = NAMLEN (dp);
          cclen = bytecount_to_charcount (d_name, len);
@@ -531,6 +529,10 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag,
 }
 
 \f
+
+/* The *pwent() functions do not exist on NT */
+#ifndef  WINDOWSNT
+
 static Lisp_Object user_name_completion (Lisp_Object user,
                                          int all_flag,
                                          int *uniq);
@@ -775,6 +777,7 @@ user_name_completion (Lisp_Object user, int all_flag, int *uniq)
     return Qt;
   return Fsubstring (bestmatch, Qzero, make_int (bestmatchsize));
 }
+#endif   /* ! defined WINDOWSNT */
 
 \f
 Lisp_Object
@@ -791,8 +794,8 @@ make_directory_hash_table (CONST char *path)
        {
          Bytecount len = NAMLEN (dp);
          if (DIRENTRY_NONEMPTY (dp))
-           Fputhash (make_ext_string ((Bufbyte *) dp->d_name, len,
-                                      FORMAT_FILENAME), Qt, hash);
+           /* Cast to Bufbyte* is OK, as readdir() Mule-encapsulates.  */
+           Fputhash (make_string ((Bufbyte *) dp->d_name, len), Qt, hash);
        }
       closedir (d);
     }
@@ -938,9 +941,11 @@ syms_of_dired (void)
   DEFSUBR (Fdirectory_files);
   DEFSUBR (Ffile_name_completion);
   DEFSUBR (Ffile_name_all_completions);
+#ifndef  WINDOWSNT
   DEFSUBR (Fuser_name_completion);
   DEFSUBR (Fuser_name_completion_1);
   DEFSUBR (Fuser_name_all_completions);
+#endif
   DEFSUBR (Ffile_attributes);
 }
 
index 442a00b..339b431 100644 (file)
@@ -39,6 +39,7 @@ Boston, MA 02111-1307, USA.  */
 #include "frame.h"
 #include "insdel.h"
 #include "window.h"
+#include "chartab.h"
 #include "line-number.h"
 
 #include "systime.h"
@@ -1622,6 +1623,23 @@ If BUFFER is nil, the current buffer is assumed.
   return make_string_from_buffer (b, begv, zv - begv);
 }
 
+/* It might make more sense to name this
+   `buffer-substring-no-extents', but this name is FSFmacs-compatible,
+   and what the function does is probably good enough for what the
+   user-code will typically want to use it for. */
+DEFUN ("buffer-substring-no-properties", Fbuffer_substring_no_properties, 0, 3, 0, /*
+Return the text from BEG to END, as a string, without copying the extents.
+*/
+       (start, end, buffer))
+{
+  /* This function can GC */
+  Bufpos begv, zv;
+  struct buffer *b = decode_buffer (buffer, 1);
+
+  get_buffer_range_char (b, start, end, &begv, &zv, GB_ALLOW_NIL);
+  return make_string_from_buffer_no_extents (b, begv, zv - begv);
+}
+
 DEFUN ("insert-buffer-substring", Finsert_buffer_substring, 1, 3, 0, /*
 Insert before point a substring of the contents of buffer BUFFER.
 BUFFER may be a buffer or a buffer name.
@@ -1783,42 +1801,149 @@ and don't mark the buffer as really changed.
   return Qnil;
 }
 
+/* #### Shouldn't this also accept a BUFFER argument, in the good old
+   XEmacs tradition?  */
 DEFUN ("translate-region", Ftranslate_region, 3, 3, 0, /*
-From START to END, translate characters according to TABLE.
-TABLE is a string; the Nth character in it is the mapping
-for the character with code N.  Returns the number of characters changed.
+Translate characters from START to END according to TABLE.
+
+If TABLE is a string, the Nth character in it is the mapping for the
+character with code N.
+
+If TABLE is a vector, its Nth element is the mapping for character
+with code N.  The values of elements may be characters, strings, or
+nil (nil meaning don't replace.)
+
+If TABLE is a char-table, its elements describe the mapping between
+characters and their replacements.  The char-table should be of type
+`char' or `generic'.
+
+Returns the number of substitutions performed.
 */
        (start, end, table))
 {
   /* This function can GC */
   Bufpos pos, stop;    /* Limits of the region. */
-  REGISTER Emchar oc;          /* Old character. */
-  REGISTER Emchar nc;          /* New character. */
-  int cnt;             /* Number of changes made. */
-  Charcount size;      /* Size of translate table. */
+  int cnt = 0;         /* Number of changes made. */
   int mc_count;
   struct buffer *buf = current_buffer;
+  Emchar oc;
 
   get_buffer_range_char (buf, start, end, &pos, &stop, 0);
-  CHECK_STRING (table);
-
-  size = XSTRING_CHAR_LENGTH (table);
-
-  cnt = 0;
   mc_count = begin_multiple_change (buf, pos, stop);
-  for (; pos < stop; pos++)
+  if (STRINGP (table))
+    {
+      struct Lisp_String *stable = XSTRING (table);
+      Charcount size = string_char_length (stable);
+#ifdef MULE
+      /* Under Mule, string_char(n) is O(n), so for large tables or
+         large regions it makes sense to create an array of Emchars.  */
+      if (size * (stop - pos) > 65536)
+       {
+         Emchar *etable = alloca_array (Emchar, size);
+         convert_bufbyte_string_into_emchar_string
+           (string_data (stable), string_length (stable), etable);
+         for (; pos < stop && (oc = BUF_FETCH_CHAR (buf, pos), 1); pos++)
+           {
+             if (oc < size)
+               {
+                 Emchar nc = etable[oc];
+                 if (nc != oc)
+                   {
+                     buffer_replace_char (buf, pos, nc, 0, 0);
+                     ++cnt;
+                   }
+               }
+           }
+       }
+      else
+#endif /* MULE */
+       {
+         for (; pos < stop && (oc = BUF_FETCH_CHAR (buf, pos), 1); pos++)
+           {
+             if (oc < size)
+               {
+                 Emchar nc = string_char (stable, oc);
+                 if (nc != oc)
+                   {
+                     buffer_replace_char (buf, pos, nc, 0, 0);
+                     ++cnt;
+                   }
+               }
+           }
+       }
+    }
+  else if (VECTORP (table))
+    {
+      Charcount size = XVECTOR_LENGTH (table);
+      Lisp_Object *vtable = XVECTOR_DATA (table);
+
+      for (; pos < stop && (oc = BUF_FETCH_CHAR (buf, pos), 1); pos++)
+       {
+         if (oc < size)
+           {
+             Lisp_Object replacement = vtable[oc];
+           retry:
+             if (CHAR_OR_CHAR_INTP (replacement))
+               {
+                 Emchar nc = XCHAR_OR_CHAR_INT (replacement);
+                 if (nc != oc)
+                   {
+                     buffer_replace_char (buf, pos, nc, 0, 0);
+                     ++cnt;
+                   }
+               }
+             else if (STRINGP (replacement))
+               {
+                 Charcount incr = XSTRING_CHAR_LENGTH (replacement) - 1;
+                 buffer_delete_range (buf, pos, pos + 1, 0);
+                 buffer_insert_lisp_string_1 (buf, pos, replacement, 0);
+                 pos += incr, stop += incr;
+                 ++cnt;
+               }
+             else if (!NILP (replacement))
+               {
+                 replacement = wrong_type_argument (Qchar_or_string_p, replacement);
+                 goto retry;
+               }
+           }
+       }
+    }
+  else if (CHAR_TABLEP (table)
+          && (XCHAR_TABLE_TYPE (table) == CHAR_TABLE_TYPE_GENERIC
+              || XCHAR_TABLE_TYPE (table) == CHAR_TABLE_TYPE_CHAR))
     {
-      oc = BUF_FETCH_CHAR (buf, pos);
-      if (oc >= 0 && oc < size)
+      struct Lisp_Char_Table *ctable = XCHAR_TABLE (table);
+
+      for (; pos < stop && (oc = BUF_FETCH_CHAR (buf, pos), 1); pos++)
        {
-         nc = string_char (XSTRING (table), oc);
-         if (nc != oc)
+         Lisp_Object replacement = get_char_table (oc, ctable);
+       retry2:
+         if (CHAR_OR_CHAR_INTP (replacement))
            {
-             buffer_replace_char (buf, pos, nc, 0, 0);
+             Emchar nc = XCHAR_OR_CHAR_INT (replacement);
+             if (nc != oc)
+               {
+                 buffer_replace_char (buf, pos, nc, 0, 0);
+                 ++cnt;
+               }
+           }
+         else if (STRINGP (replacement))
+           {
+             Charcount incr = XSTRING_CHAR_LENGTH (replacement) - 1;
+             buffer_delete_range (buf, pos, pos + 1, 0);
+             buffer_insert_lisp_string_1 (buf, pos, replacement, 0);
+             pos += incr, stop += incr;
              ++cnt;
            }
+         else if (!NILP (replacement))
+           {
+             replacement = wrong_type_argument (Qchar_or_string_p, replacement);
+             goto retry2;
+           }
        }
     }
+  else
+    dead_wrong_type_argument (Qstringp, table);
   end_multiple_change (buf, mc_count);
 
   return make_int (cnt);
@@ -2263,6 +2388,7 @@ syms_of_editfns (void)
   DEFSUBR (Fstring_to_char);
   DEFSUBR (Fchar_to_string);
   DEFSUBR (Fbuffer_substring);
+  DEFSUBR (Fbuffer_substring_no_properties);
 
   DEFSUBR (Fpoint_marker);
   DEFSUBR (Fmark_marker);
index edad0fc..09de76b 100644 (file)
@@ -2513,7 +2513,7 @@ decode_path (CONST char *path)
 
   GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA (path, newpath);
 
-  len = strlen (newpath);
+  len = strlen ((const char *) newpath);
   /* #### Does this make sense?  It certainly does for
      decode_env_path(), but it looks dubious here.  Does any code
      depend on decode_path("") returning nil instead of an empty
index 4893391..f46d1e0 100644 (file)
@@ -3346,7 +3346,10 @@ to the value of CODESYS.  If this is nil, no code conversion occurs.
     /* On VMS and APOLLO, must do the stat after the close
        since closing changes the modtime.  */
     /* As it does on Windows too - kkm */
-#if !defined (WINDOWSNT) /* !defined (VMS) && !defined (APOLLO) */
+    /* The spurious warnings appear on Linux too.  Rather than handling 
+       this on a per-system basis, unconditionally do the stat after the close - cgw */
+       
+#if 0 /* !defined (WINDOWSNT)  /* !defined (VMS) && !defined (APOLLO) */
     fstat (desc, &st);
 #endif
 
@@ -3364,9 +3367,9 @@ to the value of CODESYS.  If this is nil, no code conversion occurs.
     unbind_to (speccount, Qnil);
   }
 
-#if defined (WINDOWSNT) /* defined (VMS) || defined (APOLLO) */
+  /* # if defined (WINDOWSNT) /* defined (VMS) || defined (APOLLO) */
   stat ((char *) XSTRING_DATA (fn), &st);
-#endif
+  /* #endif */
 
 #ifdef CLASH_DETECTION
   if (!auto_saving)
index bc4cc9e..2f30628 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -49,6 +49,9 @@ Boston, MA 02111-1307, USA.  */
 #include "extents.h"
 #include "frame.h"
 #include "systime.h"
+#include "insdel.h"
+#include "lstream.h"
+#include "opaque.h"
 
 /* NOTE: This symbol is also used in lread.c */
 #define FEATUREP_SYNTAX
@@ -3522,7 +3525,428 @@ If FILENAME is omitted, the printname of FEATURE is used as the file name.
       return unbind_to (speccount, feature);
     }
 }
+\f
+/* base64 encode/decode functions.
+   Based on code from GNU recode. */
+
+#define MIME_LINE_LENGTH 76
+
+#define IS_ASCII(Character) \
+  ((Character) < 128)
+#define IS_BASE64(Character) \
+  (IS_ASCII (Character) && base64_char_to_value[Character] >= 0)
+
+/* Table of characters coding the 64 values.  */
+static char base64_value_to_char[64] =
+{
+  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',    /*  0- 9 */
+  'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',    /* 10-19 */
+  'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',    /* 20-29 */
+  'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',    /* 30-39 */
+  'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',    /* 40-49 */
+  'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',    /* 50-59 */
+  '8', '9', '+', '/'                                   /* 60-63 */
+};
+
+/* Table of base64 values for first 128 characters.  */
+static short base64_char_to_value[128] =
+{
+  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,     /*   0-  9 */
+  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,     /*  10- 19 */
+  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,     /*  20- 29 */
+  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,     /*  30- 39 */
+  -1,  -1,  -1,  62,  -1,  -1,  -1,  63,  52,  53,     /*  40- 49 */
+  54,  55,  56,  57,  58,  59,  60,  61,  -1,  -1,     /*  50- 59 */
+  -1,  -1,  -1,  -1,  -1,  0,   1,   2,   3,   4,      /*  60- 69 */
+  5,   6,   7,   8,   9,   10,  11,  12,  13,  14,     /*  70- 79 */
+  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,     /*  80- 89 */
+  25,  -1,  -1,  -1,  -1,  -1,  -1,  26,  27,  28,     /*  90- 99 */
+  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,     /* 100-109 */
+  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,     /* 110-119 */
+  49,  50,  51,  -1,  -1,  -1,  -1,  -1                        /* 120-127 */
+};
+
+/* The following diagram shows the logical steps by which three octets
+   get transformed into four base64 characters.
+
+                .--------.  .--------.  .--------.
+                |aaaaaabb|  |bbbbcccc|  |ccdddddd|
+                `--------'  `--------'  `--------'
+                    6   2      4   4       2   6
+              .--------+--------+--------+--------.
+              |00aaaaaa|00bbbbbb|00cccccc|00dddddd|
+              `--------+--------+--------+--------'
+
+              .--------+--------+--------+--------.
+              |AAAAAAAA|BBBBBBBB|CCCCCCCC|DDDDDDDD|
+              `--------+--------+--------+--------'
+
+   The octets are divided into 6 bit chunks, which are then encoded into
+   base64 characters.  */
+
+#define ADVANCE_INPUT(c, stream)                               \
+ (ec = Lstream_get_emchar (stream),                            \
+  ec == -1 ? 0 :                                               \
+  ((ec > 255) ?                                                        \
+   (error ("Non-ascii character detected in base64 input"), 0) \
+   : (c = (Bufbyte)ec, 1)))
+
+static Bytind
+base64_encode_1 (Lstream *istream, Bufbyte *to, int line_break)
+{
+  EMACS_INT counter = 0;
+  Bufbyte *e = to;
+  Emchar ec;
+  unsigned int value;
+
+  while (1)
+    {
+      Bufbyte c;
+      if (!ADVANCE_INPUT (c, istream))
+       break;
+
+      /* Wrap line every 76 characters.  */
+      if (line_break)
+       {
+         if (counter < MIME_LINE_LENGTH / 4)
+           counter++;
+         else
+           {
+             *e++ = '\n';
+             counter = 1;
+           }
+       }
+
+      /* Process first byte of a triplet.  */
+      *e++ = base64_value_to_char[0x3f & c >> 2];
+      value = (0x03 & c) << 4;
+
+      /* Process second byte of a triplet.  */
+      if (!ADVANCE_INPUT (c, istream))
+       {
+         *e++ = base64_value_to_char[value];
+         *e++ = '=';
+         *e++ = '=';
+         break;
+       }
+
+      *e++ = base64_value_to_char[value | (0x0f & c >> 4)];
+      value = (0x0f & c) << 2;
+
+      /* Process third byte of a triplet.  */
+      if (!ADVANCE_INPUT (c, istream))
+       {
+         *e++ = base64_value_to_char[value];
+         *e++ = '=';
+         break;
+       }
+
+      *e++ = base64_value_to_char[value | (0x03 & c >> 6)];
+      *e++ = base64_value_to_char[0x3f & c];
+    }
+
+  /* Complete last partial line.  */
+  if (line_break)
+    if (counter > 0)
+      *e++ = '\n';
+
+  return e - to;
+}
+#undef ADVANCE_INPUT
+
+#define ADVANCE_INPUT(c, stream)               \
+ (ec = Lstream_get_emchar (stream),            \
+  ec == -1 ? 0 : (c = (Bufbyte)ec, 1))
+
+#define INPUT_EOF_P(stream)                            \
+ (ADVANCE_INPUT (c2, stream)                           \
+  ? (Lstream_unget_emchar (stream, (Emchar)c2), 0)     \
+  : 1)
+
+#define STORE_BYTE(pos, val) do {                                      \
+  pos += set_charptr_emchar (pos, (Emchar)((unsigned char)(val)));     \
+  ++*ccptr;                                                            \
+} while (0)
+
+static Bytind
+base64_decode_1 (Lstream *istream, Bufbyte *to, Charcount *ccptr)
+{
+  EMACS_INT counter = 0;
+  Emchar ec;
+  Bufbyte *e = to;
+  unsigned long value;
+
+  *ccptr = 0;
+  while (1)
+    {
+      Bufbyte c, c2;
+
+      if (!ADVANCE_INPUT (c, istream))
+       break;
+
+      /* Accept wrapping lines, reversibly if at each 76 characters.  */
+      if (c == '\n')
+       {
+         if (!ADVANCE_INPUT (c, istream))
+           break;
+         if (INPUT_EOF_P (istream))
+           break;
+         /* FSF Emacs has this check, apparently inherited from
+             recode.  However, I see no reason to be this picky about
+             line length -- why reject base64 with say 72-byte lines?
+             (yes, there are programs that generate them.)  */
+         /*if (counter != MIME_LINE_LENGTH / 4) return -1;*/
+         counter = 1;
+       }
+      else
+       counter++;
+
+      /* Process first byte of a quadruplet.  */
+      if (!IS_BASE64 (c))
+       return -1;
+      value = base64_char_to_value[c] << 18;
+
+      /* Process second byte of a quadruplet.  */
+      if (!ADVANCE_INPUT (c, istream))
+       return -1;
+
+      if (!IS_BASE64 (c))
+       return -1;
+      value |= base64_char_to_value[c] << 12;
+
+      STORE_BYTE (e, value >> 16);
 
+      /* Process third byte of a quadruplet.  */
+      if (!ADVANCE_INPUT (c, istream))
+       return -1;
+
+      if (c == '=')
+       {
+         if (!ADVANCE_INPUT (c, istream))
+           return -1;
+         if (c != '=')
+           return -1;
+         continue;
+       }
+
+      if (!IS_BASE64 (c))
+       return -1;
+      value |= base64_char_to_value[c] << 6;
+
+      STORE_BYTE (e, 0xff & value >> 8);
+
+      /* Process fourth byte of a quadruplet.  */
+      if (!ADVANCE_INPUT (c, istream))
+       return -1;
+
+      if (c == '=')
+       continue;
+
+      if (!IS_BASE64 (c))
+       return -1;
+      value |= base64_char_to_value[c];
+
+      STORE_BYTE (e, 0xff & value);
+    }
+
+  return e - to;
+}
+#undef ADVANCE_INPUT
+#undef INPUT_EOF_P
+
+static Lisp_Object
+free_malloced_ptr (Lisp_Object unwind_obj)
+{
+  void *ptr = (void *)get_opaque_ptr (unwind_obj);
+  xfree (ptr);
+  free_opaque_ptr (unwind_obj);
+  return Qnil;
+}
+
+/* Don't use alloca for regions larger than this, lest we overflow
+   the stack.  */
+#define MAX_ALLOCA 65536
+
+/* We need to setup proper unwinding, because there is a number of
+   ways these functions can blow up, and we don't want to have memory
+   leaks in those cases.  */
+#define XMALLOC_OR_ALLOCA(ptr, len, type) do {                 \
+  if ((len) > MAX_ALLOCA)                                      \
+    {                                                          \
+      ptr = (type *)xmalloc ((len) * sizeof (type));           \
+      speccount = specpdl_depth ();                            \
+      record_unwind_protect (free_malloced_ptr,                        \
+                            make_opaque_ptr ((void *)ptr));    \
+    }                                                          \
+  else                                                         \
+    ptr = alloca_array (type, len);                            \
+} while (0)
+
+#define XMALLOC_UNBIND(ptr, len) do {          \
+  if ((len) > MAX_ALLOCA)                      \
+    unbind_to (speccount, Qnil);               \
+} while (0)
+
+DEFUN ("base64-encode-region", Fbase64_encode_region, 2, 3, "r", /*
+Base64-encode the region between BEG and END.
+Return the length of the encoded text.
+Optional third argument NO-LINE-BREAK means do not break long lines
+into shorter lines.
+*/
+       (beg, end, no_line_break))
+{
+  Bufbyte *encoded;
+  Bytind encoded_length;
+  Charcount allength, length;
+  struct buffer *buf = current_buffer;
+  Bufpos begv, zv, old_pt = BUF_PT (buf);
+  Lisp_Object input;
+  int speccount;
+
+  get_buffer_range_char (buf, beg, end, &begv, &zv, 0);
+
+  /* We need to allocate enough room for encoding the text.
+     We need 33 1/3% more space, plus a newline every 76
+     characters, and then we round up. */
+  length = zv - begv;
+  allength = length + length/3 + 1;
+  allength += allength / MIME_LINE_LENGTH + 1 + 6;
+
+  input = make_lisp_buffer_input_stream (buf, begv, zv, 0);
+  /* We needn't multiply allength with MAX_EMCHAR_LEN because all the
+     base64 characters will be single-byte.  */
+  XMALLOC_OR_ALLOCA (encoded, allength, Bufbyte);
+  encoded_length = base64_encode_1 (XLSTREAM (input), encoded,
+                                   NILP (no_line_break));
+  if (encoded_length > allength)
+    abort ();
+  Lstream_delete (XLSTREAM (input));
+
+  /* Now we have encoded the region, so we insert the new contents
+     and delete the old.  (Insert first in order to preserve markers.)  */
+  buffer_insert_raw_string_1 (buf, begv, encoded, encoded_length, 0);
+  XMALLOC_UNBIND (encoded, allength);
+  buffer_delete_range (buf, begv + encoded_length, zv + encoded_length, 0);
+
+  /* Simulate FSF Emacs: if point was in the region, place it at the
+     beginning.  */
+  if (old_pt >= begv && old_pt < zv)
+    BUF_SET_PT (buf, begv);
+
+  /* We return the length of the encoded text. */
+  return make_int (encoded_length);
+}
+
+DEFUN ("base64-encode-string", Fbase64_encode_string, 1, 1, 0, /*
+Base64 encode STRING and return the result.
+*/
+       (string))
+{
+  Charcount allength, length;
+  Bytind encoded_length;
+  Bufbyte *encoded;
+  Lisp_Object input, result;
+  int speccount;
+
+  CHECK_STRING (string);
+
+  length = XSTRING_CHAR_LENGTH (string);
+  allength = length + length/3 + 1 + 6;
+
+  input = make_lisp_string_input_stream (string, 0, -1);
+  XMALLOC_OR_ALLOCA (encoded, allength, Bufbyte);
+  encoded_length = base64_encode_1 (XLSTREAM (input), encoded, 0);
+  if (encoded_length > allength)
+    abort ();
+  Lstream_delete (XLSTREAM (input));
+  result = make_string (encoded, encoded_length);
+  XMALLOC_UNBIND (encoded, allength);
+  return result;
+}
+
+DEFUN ("base64-decode-region", Fbase64_decode_region, 2, 2, "r", /*
+Base64-decode the region between BEG and END.
+Return the length of the decoded text.
+If the region can't be decoded, return nil and don't modify the buffer.
+*/
+       (beg, end))
+{
+  struct buffer *buf = current_buffer;
+  Bufpos begv, zv, old_pt = BUF_PT (buf);
+  Bufbyte *decoded;
+  Bytind decoded_length;
+  Charcount length, cc_decoded_length;
+  Lisp_Object input;
+  int speccount;
+
+  get_buffer_range_char (buf, beg, end, &begv, &zv, 0);
+  length = zv - begv;
+
+  input = make_lisp_buffer_input_stream (buf, begv, zv, 0);
+  /* We need to allocate enough room for decoding the text. */
+  XMALLOC_OR_ALLOCA (decoded, length * MAX_EMCHAR_LEN, Bufbyte);
+  decoded_length = base64_decode_1 (XLSTREAM (input), decoded, &cc_decoded_length);
+  if (decoded_length > length * MAX_EMCHAR_LEN)
+    abort ();
+  Lstream_delete (XLSTREAM (input));
+
+  if (decoded_length < 0)
+    {
+      /* The decoding wasn't possible. */
+      XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN);
+      return Qnil;
+    }
+
+  /* Now we have decoded the region, so we insert the new contents
+     and delete the old.  (Insert first in order to preserve markers.)  */
+  BUF_SET_PT (buf, begv);
+  buffer_insert_raw_string_1 (buf, begv, decoded, decoded_length, 0);
+  XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN);
+  buffer_delete_range (buf, begv + cc_decoded_length,
+                      zv + cc_decoded_length, 0);
+
+  /* Simulate FSF Emacs: if point was in the region, place it at the
+     beginning.  */
+  if (old_pt >= begv && old_pt < zv)
+    BUF_SET_PT (buf, begv);
+
+  return make_int (cc_decoded_length);
+}
+
+DEFUN ("base64-decode-string", Fbase64_decode_string, 1, 1, 0, /*
+Base64-decode STRING and return the result.
+*/
+       (string))
+{
+  Bufbyte *decoded;
+  Bytind decoded_length;
+  Charcount length, cc_decoded_length;
+  Lisp_Object input, result;
+  int speccount;
+
+  CHECK_STRING (string);
+
+  length = XSTRING_CHAR_LENGTH (string);
+  /* We need to allocate enough room for decoding the text. */
+  XMALLOC_OR_ALLOCA (decoded, length * MAX_EMCHAR_LEN, Bufbyte);
+
+  input = make_lisp_string_input_stream (string, 0, -1);
+  decoded_length = base64_decode_1 (XLSTREAM (input), decoded,
+                                   &cc_decoded_length);
+  if (decoded_length > length * MAX_EMCHAR_LEN)
+    abort ();
+  Lstream_delete (XLSTREAM (input));
+
+  if (decoded_length < 0)
+    {
+      return Qnil;
+      XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN);
+    }
+
+  result = make_string (decoded, decoded_length);
+  XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN);
+  return result;
+}
 \f
 Lisp_Object Qyes_or_no_p;
 
@@ -3608,6 +4032,10 @@ syms_of_fns (void)
   DEFSUBR (Ffeaturep);
   DEFSUBR (Frequire);
   DEFSUBR (Fprovide);
+  DEFSUBR (Fbase64_encode_region);
+  DEFSUBR (Fbase64_encode_string);
+  DEFSUBR (Fbase64_decode_region);
+  DEFSUBR (Fbase64_decode_string);
 }
 
 void
index 2b1dee1..f7d154a 100644 (file)
@@ -26,6 +26,7 @@ Boston, MA 02111-1307, USA.  */
    Ultimately based on FSF.
    Substantially rewritten for XEmacs by Ben Wing.
    Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0.
+   Graphics features added and frame resizing fiddled with by Andy Piper.
  */
 
 #include <config.h>
@@ -594,7 +595,7 @@ void mswindows_size_frame_internal (struct frame* f, XEMACS_RECT_WH* dest)
   int pixel_width, pixel_height;
   int size_p = (dest->width >=0 || dest->height >=0);
   int move_p = (dest->top >=0 || dest->left >=0);
-
+  struct device* d = XDEVICE (FRAME_DEVICE (f));
   char_to_real_pixel_size (f, dest->width, dest->height, &pixel_width, &pixel_height);
   
   if (dest->width < 0)
@@ -607,7 +608,7 @@ void mswindows_size_frame_internal (struct frame* f, XEMACS_RECT_WH* dest)
     dest->left = rect.left;
   if (dest->top < 0)
     dest->top = rect.top;
-
+  
   rect.left = rect.top = 0;
   rect.right = pixel_width;
   rect.bottom = pixel_height;
@@ -617,12 +618,41 @@ void mswindows_size_frame_internal (struct frame* f, XEMACS_RECT_WH* dest)
                      GetMenu (FRAME_MSWINDOWS_HANDLE(f)) != NULL,
                      GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_EXSTYLE));
 
+  /* resize and move the window so that it fits on the screen. This is
+  not restrictive since this will happen later anyway in WM_SIZE.  We
+  have to do this after adjusting the rect to account for menubar
+  etc. */
+  pixel_width = rect.right - rect.left;
+  pixel_height = rect.bottom - rect.top;
+  if (pixel_width > DEVICE_MSWINDOWS_HORZRES(d))
+    {
+      pixel_width = DEVICE_MSWINDOWS_HORZRES(d);
+      size_p=1;
+    }
+  if (pixel_height > DEVICE_MSWINDOWS_VERTRES(d))
+    {
+      pixel_height = DEVICE_MSWINDOWS_VERTRES(d);
+      size_p=1;
+    }
+
+  /* adjust position so window is on screen */
+  if (dest->left + pixel_width > DEVICE_MSWINDOWS_HORZRES(d))
+    {
+      dest->left = DEVICE_MSWINDOWS_HORZRES(d) - pixel_width;
+      move_p=1;
+    }
+  if (dest->top + pixel_height > DEVICE_MSWINDOWS_VERTRES(d))
+    {
+      dest->top = DEVICE_MSWINDOWS_VERTRES(d) - pixel_height;
+      move_p=1;
+    }
+
   if (IsIconic (FRAME_MSWINDOWS_HANDLE(f)) 
       || IsZoomed (FRAME_MSWINDOWS_HANDLE(f)))
     ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_RESTORE);
 
   SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), NULL, 
-               dest->left, dest->top, rect.right - rect.left, rect.bottom - rect.top,
+               dest->left, dest->top, pixel_width, pixel_height,
                SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING
                | (size_p ? 0 : SWP_NOSIZE)
                | (move_p ? 0 : SWP_NOMOVE));
index 5b185d7..715cef2 100644 (file)
@@ -167,15 +167,15 @@ extern void GifWarning(GifFileType *GifFile, const char *err_str);
 
 /* This is the in-core version of an extension record */
 typedef struct {
-    int                ByteCount;
-    char       *Bytes;         /* on malloc(3) heap */
+    int                    ByteCount;
+    GifByteType        *Bytes;         /* on malloc(3) heap */
 } ExtensionBlock;
 
 /* This holds an image header, its unpacked raster bits, and extensions */
 typedef struct SavedImage {
     GifImageDesc       ImageDesc;
 
-    char               *RasterBits;            /* on malloc(3) heap */
+    GifPixelType       *RasterBits;            /* on malloc(3) heap */
 
     int                        Function;
     int                        ExtensionBlockCount;
index ddb16d4..7366c8e 100644 (file)
@@ -1041,7 +1041,7 @@ static CONST resource_t bitmap_table[] =
   { "size", OBM_SIZE },
   { "btsize", OBM_BTSIZE },
   { "check", OBM_CHECK },
-  { "cehckboxes", OBM_CHECKBOXES },
+  { "checkboxes", OBM_CHECKBOXES },
   { "btncorners" , OBM_BTNCORNERS },
   {0}
 };
index 2d4fb6d..18251ad 100644 (file)
--- a/src/gui.c
+++ b/src/gui.c
@@ -29,8 +29,8 @@ Boston, MA 02111-1307, USA.  */
 #include "bytecode.h"          /* for struct Lisp_Compiled_Function */
 
 Lisp_Object Q_active, Q_suffix, Q_keys, Q_style, Q_selected;
-Lisp_Object Q_filter, Q_config, Q_included;
-Lisp_Object Q_accelerator;
+Lisp_Object Q_filter, Q_config, Q_included, Q_key_sequence;
+Lisp_Object Q_accelerator, Q_label;
 Lisp_Object Qtoggle, Qradio;
 
 #ifdef HAVE_POPUPS
@@ -134,6 +134,8 @@ gui_item_add_keyval_pair (struct gui_item *pgui_item,
   else if (EQ (key, Q_style))   pgui_item->style    = val;
   else if (EQ (key, Q_selected)) pgui_item->selected = val;
   else if (EQ (key, Q_keys))    pgui_item->keys     = val;
+  else if (EQ (key, Q_key_sequence)) ;   /* ignored for FSF compatability */
+  else if (EQ (key, Q_label)) ;   /* ignored for 21.0 implement in 21.2  */
   else
     signal_simple_error_2 ("Unknown keyword in gui item", key, pgui_item->name);
 }
@@ -337,12 +339,14 @@ syms_of_gui (void)
   defkeyword (&Q_active,   ":active");
   defkeyword (&Q_suffix,   ":suffix");
   defkeyword (&Q_keys,     ":keys");
+  defkeyword (&Q_key_sequence,":key-sequence");
   defkeyword (&Q_style,    ":style");
   defkeyword (&Q_selected, ":selected");
   defkeyword (&Q_filter,   ":filter");
   defkeyword (&Q_config,   ":config");
   defkeyword (&Q_included, ":included");
   defkeyword (&Q_accelerator, ":accelerator");
+  defkeyword (&Q_label, ":label");
 
   defsymbol (&Qtoggle, "toggle");
   defsymbol (&Qradio, "radio");
index b0876e9..ab80f52 100644 (file)
--- a/src/gui.h
+++ b/src/gui.h
@@ -69,6 +69,7 @@ struct gui_item
 
 extern Lisp_Object Q_accelerator, Q_active, Q_config, Q_filter, Q_included;
 extern Lisp_Object Q_keys, Q_selected, Q_suffix, Qradio, Qtoggle;
+extern Lisp_Object Q_key_sequence, Q_label;
 
 void gui_item_init (struct gui_item *pgui_item);
 void gui_item_add_keyval_pair (struct gui_item *pgui_item,
index dd95167..a1cb446 100644 (file)
@@ -41,7 +41,12 @@ Initialize_Locale (void)
 {
   char *locale;
 
-  XtSetLanguageProc (NULL, (XtLanguageProc) NULL, NULL);
+  /* dverna - Nov. 98: ### DON'T DO THIS !!! The default XtLanguageProc
+     routine calls setlocale(LC_ALL, lang) which fucks up our lower-level
+     locale management, and especially the value of LC_NUMERIC. Anyway, since
+     at this point, we don't know yet whether we're gonna need an X11 frame,
+     we should really do it manually and not use Xlib's dumb default routine */
+  /*XtSetLanguageProc (NULL, (XtLanguageProc) NULL, NULL);*/
   if ((locale = setlocale (LC_ALL, "")) == NULL)
     {
       stderr_out ("Can't set locale.\n");
index 56d2dac..a66ea11 100644 (file)
@@ -79,7 +79,12 @@ Initialize_Locale (void)
 {
   char *locale;
 
-  XtSetLanguageProc (NULL, (XtLanguageProc) NULL, NULL);
+  /* dverna - Nov. 98: ### DON'T DO THIS !!! The default XtLanguageProc
+     routine calls setlocale(LC_ALL, lang) which fucks up our lower-level
+     locale management, and especially the value of LC_NUMERIC. Anyway, since
+     at this point, we don't know yet whether we're gonna need an X11 frame,
+     we should really do it manually and not use Xlib's dumb default routine */
+  /*XtSetLanguageProc (NULL, (XtLanguageProc) NULL, NULL);*/
   if ((locale = setlocale (LC_ALL, "")) == NULL)
     {
       stderr_out ("Can't set locale.\n");
index f516263..a85481c 100644 (file)
@@ -2992,22 +2992,20 @@ buffer_replace_char (struct buffer *buf, Bufpos pos, Emchar ch,
 /* Make a string from a buffer.  This needs to take into account the gap,
    and add any necessary extents from the buffer. */
 
-Lisp_Object
-make_string_from_buffer (struct buffer *buf, Bufpos pos, Charcount length)
+static Lisp_Object
+make_string_from_buffer_1 (struct buffer *buf, Bufpos pos, Charcount length,
+                          int no_extents)
 {
   /* This function can GC */
-  Lisp_Object val;
-  struct gcpro gcpro1;
-  Bytind bi_ind;
-  Bytecount bi_len;
+  Bytind    bi_ind = bufpos_to_bytind (buf, pos);
+  Bytecount bi_len = bufpos_to_bytind (buf, pos + length) - bi_ind;
+  Lisp_Object  val = make_uninit_string (bi_len);
 
-  bi_ind = bufpos_to_bytind (buf, pos);
-  bi_len = bufpos_to_bytind (buf, pos + length) - bi_ind;
-
-  val = make_uninit_string (bi_len);
+  struct gcpro gcpro1;
   GCPRO1 (val);
 
-  add_string_extents (val, buf, bi_ind, bi_len);
+  if (!no_extents)
+    add_string_extents (val, buf, bi_ind, bi_len);
 
   {
     Bytecount len1 = BI_BUF_GPT (buf) - bi_ind;
@@ -3039,6 +3037,19 @@ make_string_from_buffer (struct buffer *buf, Bufpos pos, Charcount length)
   return val;
 }
 
+Lisp_Object
+make_string_from_buffer (struct buffer *buf, Bufpos pos, Charcount length)
+{
+  return make_string_from_buffer_1 (buf, pos, length, 0);
+}
+
+Lisp_Object
+make_string_from_buffer_no_extents (struct buffer *buf, Bufpos pos,
+                                   Charcount length)
+{
+  return make_string_from_buffer_1 (buf, pos, length, 1);
+}
+
 void
 barf_if_buffer_read_only (struct buffer *buf, Bufpos from, Bufpos to)
 {
index 8c04648..bfe3e7d 100644 (file)
@@ -65,7 +65,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/fcntl.h>
+#include <fcntl.h>
 #include <sys/file.h>
 #include <sys/ioctl.h>
 #include <sys/signal.h>
index 8d7360e..232f48a 100644 (file)
@@ -960,7 +960,7 @@ struct Lisp_Bit_Vector
   struct lrecord_header lheader;
   Lisp_Object next;
   long size;
-  unsigned int bits[1];
+  unsigned long bits[1];
 };
 
 DECLARE_LRECORD (bit_vector, struct Lisp_Bit_Vector);
@@ -2048,6 +2048,7 @@ Bufpos bufpos_clip_to_bounds (Bufpos, Bufpos, Bufpos);
 Bytind bytind_clip_to_bounds (Bytind, Bytind, Bytind);
 void buffer_insert1 (struct buffer *, Lisp_Object);
 Lisp_Object make_string_from_buffer (struct buffer *, int, int);
+Lisp_Object make_string_from_buffer_no_extents (struct buffer *, int, int);
 Lisp_Object save_excursion_save (void);
 Lisp_Object save_restriction_save (void);
 Lisp_Object save_excursion_restore (Lisp_Object);
diff --git a/src/m/arm.h b/src/m/arm.h
new file mode 100644 (file)
index 0000000..2bf2940
--- /dev/null
@@ -0,0 +1,135 @@
+/* Machine description file for digital/intel arm/strongarm
+   Copyright (C) 1987 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 2, 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 XEmacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Synched up with: FSF 19.31. */
+
+/* Define WORD_MACHINE if addresses and such have
+ * to be corrected before they can be used as byte counts.  */
+
+#undef WORD_MACHINE
+
+/* Now define a symbol for the cpu type, if your compiler
+   does not define it automatically:
+   Ones defined so far include vax, m68000, ns16000, pyramid,
+   orion, tahoe, APOLLO and many others */
+
+#ifndef arm
+#define arm
+#endif
+
+/* crt0.c, if it is used, should use the i386-bsd style of entry.
+   with no extra dummy args.  On USG and XENIX,
+   NO_REMAP says this isn't used. */
+
+/* Mly 16-Jan-96 16:38:32: this is part of a prototype -- same bug present in 
+   other m*.h files */
+#define CRT0_DUMMIES int bogus_fp,
+
+/* crt0.c should define a symbol `start' and do .globl with a dot.  */
+
+#define DOT_GLOBAL_START
+
+#ifdef USG5_4 /* Older USG systems do not support the load average.  */
+/* Data type of load average, as read out of kmem.  */
+
+#define LOAD_AVE_TYPE long
+
+/* Convert that into an integer that is 100 for a load average of 1.0  */
+/* This is totally uncalibrated. */
+
+
+/* FSHIFT and FSCALE are defined in param.h, but are required by
+   LOAD_AVE_CVT, so they need to be defined here.  */
+
+#ifndef FSHIFT
+#define FSHIFT 8       /* bits to right of fixed binary point */
+#endif
+
+#ifndef FSCALE
+#define FSCALE (1<<FSHIFT)
+#endif
+
+#define LOAD_AVE_CVT(x) ((int) (((double) (x)) * 100.0 / FSCALE))
+#endif
+
+
+/* Define CANNOT_DUMP on machines where unexec does not work.
+   Then the function dump-emacs will not be defined
+   and temacs will do (load "loadup") automatically unless told otherwise.  */
+
+#undef CANNOT_DUMP
+
+/* Define VIRT_ADDR_VARIES if the virtual addresses of
+   pure and impure space as loaded can vary, and even their
+   relative order cannot be relied on.
+
+   Otherwise Emacs assumes that text space precedes data space,
+   numerically.  */
+
+#undef VIRT_ADDR_VARIES
+
+
+/* this brings in alloca() if we're using cc */
+#ifdef USG
+#define NO_REMAP 
+#define TEXT_START 0
+#endif /* USG */
+
+
+#ifdef USG5_4
+#define DATA_SEG_BITS 0x08000000
+#endif
+
+#ifdef MSDOS
+#define NO_REMAP
+#endif
+
+#ifdef WINDOWSNT
+#define VIRT_ADDR_VARIES
+#define DATA_END       get_data_end ()
+#define DATA_START     get_data_start ()
+#define HAVE_ALLOCA
+#endif
+
+#ifdef linux
+/* libc-linux/sysdeps/linux/i386/ulimit.c says that due to shared library, */
+/* we cannot get the maximum address for brk */
+#define ULIMIT_BREAK_VALUE (32*1024*1024)
+
+#define SEGMENT_MASK ((SEGMENT_SIZE)-1)
+#endif
+
+#if 0
+#ifdef __GNUC__
+/* GCC's alloca() is semi-broken.  See lisp.h.
+
+   This brokenness has been confirmed under both Linux and NetBSD.
+   It may also exist on non-Intel architectures. */
+#define BROKEN_ALLOCA_IN_FUNCTION_CALLS
+#endif
+#endif
+
+
+/* XEmacs change: John Hughes <john@AtlanTech.COM> says using vfork
+   under i386-unknown-sysv4.2 makes C-g sometimes cause a SIGSEGV
+   in TTY mode; the problem goes away if you use fork */
+#ifdef USG5_4_2
+#define vfork fork
+#endif
diff --git a/src/m/mips-nec.h b/src/m/mips-nec.h
new file mode 100644 (file)
index 0000000..15fefcc
--- /dev/null
@@ -0,0 +1,145 @@
+/* m- file for Mips machines.
+   Copyright (C) 1987, 1992, 1993, 1995 Free Software Foundation, Inc.
+
+   This file contains some changes for our SVR4 based SINIX-Mips 5.4.
+   I hope this is helpful to port the emacs to our RM?00 series and
+   maybe to the DC/OSx (Mips-based) machines of Pyramid Inc.
+     (Marco.Walther@mch.sni.de)
+
+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 2, 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 XEmacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Synched up with: FSF 19.31. */
+
+/* The following line tells the configuration script what sort of 
+   operating system this machine is likely to run.
+   USUAL-OPSYS="note"
+
+NOTE-START
+Use m-mips4.h for RISCOS version 4; use s-bsd4-3.h with the BSD world.
+Note that the proper m- file for the Decstation is m-pmax.h.
+This is the m- file for SNI RM*00 machines. Use s- sinix5-4.h file!
+With this the file mips-siemens.h is obsolete.
+NOTE-END  */
+
+/* Define WORD_MACHINE if addresses and such have
+ * to be corrected before they can be used as byte counts.  */
+
+#undef WORD_MACHINE
+
+/* Define how to take a char and sign-extend into an int.
+   On machines where char is signed, this is a no-op.  */
+
+#define SIGN_EXTEND_CHAR(c) ((signed char)(c))
+
+/* Now define a symbol for the cpu type, if your compiler
+   does not define it automatically:
+   Ones defined so far include vax, m68000, ns16000, pyramid,
+   orion, tahoe, APOLLO and many others */
+#ifndef mips
+#      define mips
+#endif
+
+/* Define EXPLICIT_SIGN_EXTEND if XINT must explicitly sign-extend
+   the 24-bit bit field into an int.  In other words, if bit fields
+   are always unsigned.
+
+   If you use NO_UNION_TYPE, this flag does not matter.  */
+
+#define EXPLICIT_SIGN_EXTEND
+
+/* Data type of load average, as read out of kmem.  */
+
+#define LOAD_AVE_TYPE long
+
+/* Convert that into an integer that is 100 for a load average of 1.0  */
+
+#define LOAD_AVE_CVT(x) (int) (((double) (x)) * 100.0 / 256.0)
+
+/* CDC EP/IX 1.4.3 uses /unix */
+
+#undef KERNEL_FILE
+#define KERNEL_FILE "/unix"
+
+/* Define CANNOT_DUMP on machines where unexec does not work.
+   Then the function dump-emacs will not be defined
+   and temacs will do (load "loadup") automatically unless told otherwise.  */
+
+#undef CANNOT_DUMP
+
+/* Define VIRT_ADDR_VARIES if the virtual addresses of
+   pure and impure space as loaded can vary, and even their
+   relative order cannot be relied on.
+
+   Otherwise Emacs assumes that text space precedes data space,
+   numerically.  */
+
+/* #define VIRT_ADDR_VARIES */
+
+/* Define C_ALLOCA if this machine does not support a true alloca
+   and the one written in C should be used instead.
+   Define HAVE_ALLOCA to say that the system provides a properly
+   working alloca function and it should be used.
+   Define neither one if an assembler-language alloca
+   in the file alloca.s should be used.  */
+
+#ifdef __GNUC__
+#define HAVE_ALLOCA
+#else
+#define C_ALLOCA
+#endif
+
+/* Define NO_REMAP if memory segmentation makes it not work well
+   to change the boundary between the text section and data section
+   when Emacs is dumped.  If you define this, the preloaded Lisp
+   code will not be sharable; but that's better than failing completely.  */
+
+#define NO_REMAP
+
+/* Describe layout of the address space in an executing process.  */
+/* MARCO ???
+*/
+#define TEXT_START 0x400000
+/*
+#define DATA_START 0x10000000
+#define DATA_SEG_BITS  0x10000000
+*/
+
+#undef ORDINARY_LINK
+
+#undef LIBS_DEBUG
+
+/* Alter some of the options used when linking.  */
+
+#undef LIBS_MACHINE
+/* #define LIBS_MACHINE "-lmld" */ /* mrb */
+#define START_FILES "pre-crt0.o /usr/ccs/lib/crt1.o /usr/ccs/lib/crti.o /usr/ccs/lib/values-Xt.o"
+
+#ifdef LIB_STANDARD
+#undef LIB_STANDARD
+#endif
+#define LIB_STANDARD "-lc /usr/ccs/lib/crtn.o"
+
+#ifdef __GNUC__
+#define C_DEBUG_SWITCH
+#define C_OPTIMIZE_SWITCH "-O"
+#define LD_SWITCH_MACHINE 
+#else
+#define C_DEBUG_SWITCH "-DSYSV"
+#define C_OPTIMIZE_SWITCH "-DSYSV "
+#define LD_SWITCH_MACHINE
+#endif
index a225eb5..4964779 100644 (file)
@@ -146,8 +146,10 @@ menu_item_descriptor_to_widget_value_1 (Lisp_Object desc,
        {
          Lisp_Object key, val;
          Lisp_Object include_p = Qnil, hook_fn = Qnil, config_tag = Qnil;
+         Lisp_Object active_p = Qt;
          Lisp_Object accel;
          int included_spec = 0;
+         int active_spec = 0;
          wv->type = CASCADE_TYPE;
          wv->enabled = 1;
          wv->name = (char *) XSTRING_DATA (LISP_GETTEXT (XCAR (desc)));
@@ -172,6 +174,8 @@ menu_item_descriptor_to_widget_value_1 (Lisp_Object desc,
                config_tag = val;
              else if (EQ (key, Q_filter))
                hook_fn = val;
+             else if (EQ (key, Q_active))
+               active_p = val, active_spec = 1;
              else if (EQ (key, Q_accelerator))
                {
                  if ( SYMBOLP (val)
@@ -180,6 +184,10 @@ menu_item_descriptor_to_widget_value_1 (Lisp_Object desc,
                  else
                    signal_simple_error ("bad keyboard accelerator", val);
                }
+             else if (EQ (key, Q_label))
+               {
+                 /* implement in 21.2 */
+               }
              else
                signal_simple_error ("unknown menu cascade keyword", cascade);
            }
@@ -191,7 +199,11 @@ menu_item_descriptor_to_widget_value_1 (Lisp_Object desc,
              wv = NULL;
              goto menu_item_done;
            }
-         if (!NILP (hook_fn))
+
+         if (active_spec)
+           active_p = Feval (active_p);
+         
+         if (!NILP (hook_fn) && !NILP (active_p))
            {
 #if defined LWLIB_MENUBARS_LUCID || defined LWLIB_MENUBARS_MOTIF
              if (filter_p || depth == 0)
@@ -236,6 +248,24 @@ menu_item_descriptor_to_widget_value_1 (Lisp_Object desc,
              wv->contents = title_wv;
              prev = sep_wv;
            }
+         wv->enabled = ! NILP (active_p);
+         if (deep_p && !wv->enabled  && !NILP (desc))
+           {
+             widget_value *dummy;
+             /* Add a fake entry so the menus show up */
+             wv->contents = dummy = xmalloc_widget_value ();
+             dummy->name = "(inactive)";
+             dummy->accel = NULL;
+             dummy->enabled = 0;
+             dummy->selected = 0;
+             dummy->value = NULL;
+             dummy->type = BUTTON_TYPE;
+             dummy->call_data = NULL;
+             dummy->next = NULL;
+             
+             goto menu_item_done;
+       }
+
        }
       else if (menubar_root_p)
        {
@@ -248,8 +278,7 @@ menu_item_descriptor_to_widget_value_1 (Lisp_Object desc,
          signal_simple_error ("menu name (first element) must be a string",
                                desc);
        }
-
-      wv->enabled = 1;
+      
       if (deep_p || menubar_root_p)
        {
          widget_value *next;
index 7b1fb16..4e2aa8a 100644 (file)
@@ -501,6 +501,13 @@ The possible keywords are this:
                     Basically, the filter function should have no
                     side-effects.
 
+ :key-sequence keys  Used in FSF Emacs as an hint to an equivalent keybinding.
+                     Ignored by XEnacs for easymenu.el compatability.
+
+ :label <form>       (unimplemented!) Like :suffix, but replaces label
+                     completely.
+                     (might be added in 21.2).
 For example:
 
  ("File"
index eb86610..d9b39b8 100644 (file)
@@ -1249,7 +1249,7 @@ complex_vars_of_mule_charset (void)
                  build_string ("iso8859-1"));
   Vcharset_control_1 =
     make_charset (-1, Qcontrol_1, LEADING_BYTE_CONTROL_1, 2,
-                 CHARSET_TYPE_94, 1, 0, 0,
+                 CHARSET_TYPE_94, 1, 1, 0,
                  CHARSET_LEFT_TO_RIGHT,
                  build_string ("Control characters"),
                  build_string (""));
index 6be1c1a..8220dcc 100644 (file)
@@ -735,7 +735,7 @@ unix_create_process (struct Lisp_Process *p,
 
   /* Nothing below here GCs so our string pointers shouldn't move. */
   new_argv = alloca_array (char *, nargv + 2);
-  new_argv[0] = (char *) XSTRING_DATA (program);
+  GET_C_STRING_FILENAME_DATA_ALLOCA (program, new_argv[0]);
   for (i = 0; i < nargv; i++)
     {
       Lisp_Object tem = argv[i];
@@ -743,7 +743,7 @@ unix_create_process (struct Lisp_Process *p,
       new_argv[i + 1] = (char *) XSTRING_DATA (tem);
     }
   new_argv[i + 1] = 0;
-  current_dir = (char *) XSTRING_DATA (cur_dir);
+  GET_C_STRING_FILENAME_DATA_ALLOCA (cur_dir, current_dir);
 
 #ifdef HAVE_PTYS
   if (!NILP (Vprocess_connection_type))
index 39490f3..3155383 100644 (file)
@@ -71,8 +71,8 @@ Boston, MA 02111-1307, USA.  */
 /* cheesy way to determine cygwin version */
 #ifndef NOT_C_CODE
 #include <signal.h>
-#ifdef HAVE_CYGWIN32_VERSION_H
-#include <cygwin32/version.h>
+#ifdef HAVE_CYGWIN_VERSION_H
+#include <cygwin/version.h>
 #else
 #ifdef SIGIO
 #define CYGWIN_B19
@@ -85,7 +85,7 @@ extern void cygwin32_win32_to_posix_path_list(const char*, char*);
 extern int cygwin32_win32_to_posix_path_list_buf_size(const char*);
 extern void cygwin32_posix_to_win32_path_list(const char*, char*);
 extern int cygwin32_posix_to_win32_path_list_buf_size(const char*);
-#ifndef CYGWIN_DLL_VERSION_MAJOR
+#ifndef CYGWIN_VERSION_DLL_MAJOR
 struct timeval;
 struct timezone;
 struct itimerval;
@@ -151,8 +151,12 @@ extern long random();
 #define DATA_END -1
 #define HEAP_IN_DATA
 #define UNEXEC "unexcw.o"
-/* #define BROKEN_SIGIO */
+
+#ifdef CYGWIN_VERSION_DLL_MAJOR
+#define BROKEN_SIGIO
+#else
 #define PROCESS_IO_BLOCKING
+#endif
 #define strnicmp strncasecmp
 #ifndef HAVE_SOCKETS
 #define HAVE_SOCKETS