Merge from trunk
authorStefan Monnier <monnier@iro.umontreal.ca>
Fri, 23 Jul 2010 15:23:09 +0000 (17:23 +0200)
committerStefan Monnier <monnier@iro.umontreal.ca>
Fri, 23 Jul 2010 15:23:09 +0000 (17:23 +0200)
19 files changed:
1  2 
doc/lispref/elisp.texi
doc/lispref/functions.texi
doc/lispref/vol1.texi
doc/lispref/vol2.texi
lisp/ChangeLog.trunk
lisp/subr.el
src/ChangeLog.trunk
src/alloc.c
src/buffer.c
src/bytecode.c
src/data.c
src/doc.c
src/eval.c
src/fns.c
src/image.c
src/keyboard.c
src/lisp.h
src/lread.c
src/print.c

@@@ -460,14 -460,13 +460,14 @@@ Function
  * Function Cells::          Accessing or setting the function definition
                                of a symbol.
  * Obsolete Functions::      Declaring functions obsolete.
- * Inline Functions::      Defining functions that the compiler
+ * Inline Functions::        Defining functions that the compiler
                                will open code.
- * Declaring Functions::           Telling the compiler that a function is defined.
+ * Declaring Functions::     Telling the compiler that a function is defined.
 +* Function Currying::       Making wrapper functions that pre-specify
 +                              some arguments.
  * Function Safety::         Determining whether a function is safe to call.
  * Related Topics::          Cross-references to specific Lisp primitives
 -                              that have a special bearing on how
 -                              functions work.
 +                              that have a special bearing on how functions work.
  
  Lambda Expressions
  
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc lisp/subr.el
Simple merge
Simple merge
diff --cc src/alloc.c
Simple merge
diff --cc src/buffer.c
Simple merge
diff --cc src/bytecode.c
@@@ -411,36 -402,8 +411,32 @@@ DEFUN ("byte-code", Fbyte_code, Sbyte_c
  The first argument, BYTESTR, is a string of byte code;
  the second, VECTOR, a vector of constants;
  the third, MAXDEPTH, the maximum stack depth used in this function.
 -If the third argument is incorrect, Emacs may crash.  */)
 -  (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth)
 +If the third argument is incorrect, Emacs may crash.
 +
 +If ARGS-TEMPLATE is specified, it is an argument list specification,
 +according to which any remaining arguments are pushed on the stack
 +before executing BYTESTR.
 +
 +usage: (byte-code BYTESTR VECTOR MAXDEP &optional ARGS-TEMPLATE &rest ARGS) */)
-      (nargs, args)
-      int nargs;
-      Lisp_Object *args;
++     (int nargs, Lisp_Object *args)
 +{
 +  Lisp_Object args_tmpl = nargs >= 4 ? args[3] : Qnil;
 +  int pnargs = nargs >= 4 ? nargs - 4 : 0;
 +  Lisp_Object *pargs = nargs >= 4 ? args + 4 : 0;
 +  return exec_byte_code (args[0], args[1], args[2], args_tmpl, pnargs, pargs);
 +}
 +
 +/* Execute the byte-code in BYTESTR.  VECTOR is the constant vector, and
 +   MAXDEPTH is the maximum stack depth used (if MAXDEPTH is incorrect,
 +   emacs may crash!).  If ARGS_TEMPLATE is non-nil, it should be a lisp
 +   argument list (including &rest, &optional, etc.), and ARGS, of size
 +   NARGS, should be a vector of the actual arguments.  The arguments in
 +   ARGS are pushed on the stack according to ARGS_TEMPLATE before
 +   executing BYTESTR.  */
 +
 +Lisp_Object
- exec_byte_code (bytestr, vector, maxdepth, args_template, nargs, args)
-      Lisp_Object bytestr, vector, maxdepth, args_template;
-      int nargs;
-      Lisp_Object *args;
++exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
++              Lisp_Object args_template, int nargs, Lisp_Object *args)
  {
    int count = SPECPDL_INDEX ();
  #ifdef BYTE_CODE_METER
diff --cc src/data.c
@@@ -440,18 -411,9 +414,17 @@@ DEFUN ("byte-code-function-p", Fbyte_co
    return Qnil;
  }
  
 +DEFUN ("funvecp", Ffunvecp, Sfunvecp, 1, 1, 0,
 +       doc: /* Return t if OBJECT is a `function vector' object.  */)
 +     (object)
 +     Lisp_Object object;
 +{
 +  return FUNVECP (object) ? Qt : Qnil;
 +}
 +
  DEFUN ("char-or-string-p", Fchar_or_string_p, Schar_or_string_p, 1, 1, 0,
         doc: /* Return t if OBJECT is a character or a string.  */)
-      (object)
-      register Lisp_Object object;
+   (register Lisp_Object object)
  {
    if (CHARACTERP (object) || STRINGP (object))
      return Qt;
diff --cc src/doc.c
Simple merge
diff --cc src/eval.c
@@@ -177,23 -167,14 +177,14 @@@ int handling_signal
  Lisp_Object Vmacro_declaration_function;
  
  extern Lisp_Object Qrisky_local_variable;
 -
  extern Lisp_Object Qfunction;
  
- static Lisp_Object funcall_lambda P_ ((Lisp_Object, int, Lisp_Object *,
-                                      Lisp_Object));
- static void unwind_to_catch P_ ((struct catchtag *, Lisp_Object)) NO_RETURN;
- #if __GNUC__
- /* "gcc -O3" enables automatic function inlining, which optimizes out
-    the arguments for the invocations of these functions, whereas they
-    expect these values on the stack.  */
- Lisp_Object apply1 () __attribute__((noinline));
- Lisp_Object call2 () __attribute__((noinline));
- #endif
 -static Lisp_Object funcall_lambda (Lisp_Object, int, Lisp_Object*);
++static Lisp_Object funcall_lambda (Lisp_Object, int, Lisp_Object *,
++                                 Lisp_Object);
+ static void unwind_to_catch (struct catchtag *, Lisp_Object) NO_RETURN;
  \f
  void
- init_eval_once ()
+ init_eval_once (void)
  {
    specpdl_size = 50;
    specpdl = (struct specbinding *) xmalloc (specpdl_size * sizeof (struct specbinding));
@@@ -511,11 -482,10 +492,10 @@@ The second VAL is not computed until af
  each VAL can use the new value of variables set earlier in the `setq'.
  The return value of the `setq' form is the value of the last VAL.
  usage: (setq [SYM VAL]...)  */)
-      (args)
-      Lisp_Object args;
+   (Lisp_Object args)
  {
    register Lisp_Object args_left;
 -  register Lisp_Object val, sym;
 +  register Lisp_Object val, sym, lex_binding;
    struct gcpro gcpro1;
  
    if (NILP (args))
@@@ -561,23 -522,11 +540,22 @@@ DEFUN ("function", Ffunction, Sfunction
  In byte compilation, `function' causes its argument to be compiled.
  `quote' cannot do that.
  usage: (function ARG)  */)
-      (args)
-      Lisp_Object args;
+   (Lisp_Object args)
  {
 +  Lisp_Object quoted = XCAR (args);
 +
    if (!NILP (Fcdr (args)))
      xsignal2 (Qwrong_number_of_arguments, Qfunction, Flength (args));
 -  return Fcar (args);
 +
 +  if (!NILP (Vinternal_interpreter_environment)
 +      && CONSP (quoted)
 +      && EQ (XCAR (quoted), Qlambda))
 +    /* This is a lambda expression within a lexical environment;
 +       return an interpreted closure instead of a simple lambda.  */
 +    return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment, quoted));
 +  else
 +    /* Simply quote the argument.  */
 +    return quoted;
  }
  
  
@@@ -598,9 -547,9 +576,9 @@@ To test whether your function was calle
  either (i) add an extra optional argument and give it an `interactive'
  spec that specifies non-nil unconditionally (such as \"p\"); or (ii)
  use `called-interactively-p'.  */)
-      ()
+   (void)
  {
 -  return (INTERACTIVE && interactive_p (1)) ? Qt : Qnil;
 +  return interactive_p (1) ? Qt : Qnil;
  }
  
  
@@@ -1044,10 -973,9 +1013,9 @@@ Each element of VARLIST is a symbol (wh
  or a list (SYMBOL VALUEFORM) (which binds SYMBOL to the value of VALUEFORM).
  Each VALUEFORM can refer to the symbols already bound by this VARLIST.
  usage: (let* VARLIST BODY...)  */)
-      (args)
-      Lisp_Object args;
+   (Lisp_Object args)
  {
 -  Lisp_Object varlist, val, elt;
 +  Lisp_Object varlist, var, val, elt, lexenv;
    int count = SPECPDL_INDEX ();
    struct gcpro gcpro1, gcpro2, gcpro3;
  
@@@ -1101,10 -1009,9 +1069,9 @@@ Each element of VARLIST is a symbol (wh
  or a list (SYMBOL VALUEFORM) (which binds SYMBOL to the value of VALUEFORM).
  All the VALUEFORMs are evalled before any symbols are bound.
  usage: (let VARLIST BODY...)  */)
-      (args)
-      Lisp_Object args;
+   (Lisp_Object args)
  {
 -  Lisp_Object *temps, tem;
 +  Lisp_Object *temps, tem, lexenv;
    register Lisp_Object elt, varlist;
    int count = SPECPDL_INDEX ();
    register int argnum;
@@@ -3294,10 -3064,7 +3210,8 @@@ usage: (funcall FUNCTION &rest ARGUMENT
  }
  \f
  Lisp_Object
- apply_lambda (fun, args, eval_flag, lexenv)
-      Lisp_Object fun, args;
-      int eval_flag;
-      Lisp_Object lexenv;
 -apply_lambda (Lisp_Object fun, Lisp_Object args, int eval_flag)
++apply_lambda (Lisp_Object fun, Lisp_Object args, int eval_flag,
++            Lisp_Object lexenv)
  {
    Lisp_Object args_left;
    Lisp_Object numargs;
@@@ -3395,11 -3111,7 +3309,9 @@@ funcall_funvec (fun, nargs, args
     FUN must be either a lambda-expression or a compiled-code object.  */
  
  static Lisp_Object
- funcall_lambda (fun, nargs, arg_vector, lexenv)
-      Lisp_Object fun;
-      int nargs;
-      register Lisp_Object *arg_vector;
-      Lisp_Object lexenv;
 -funcall_lambda (Lisp_Object fun, int nargs, register Lisp_Object *arg_vector)
++funcall_lambda (Lisp_Object fun, int nargs,
++              register Lisp_Object *arg_vector,
++              Lisp_Object lexenv)
  {
    Lisp_Object val, syms_left, next;
    int count = SPECPDL_INDEX ();
diff --cc src/fns.c
Simple merge
diff --cc src/image.c
Simple merge
diff --cc src/keyboard.c
Simple merge
diff --cc src/lisp.h
@@@ -2720,29 -2698,27 +2724,29 @@@ EXFUN (list4, 4)
  EXFUN (list5, 5);
  EXFUN (Flist, MANY);
  EXFUN (Fmake_list, 2);
- extern Lisp_Object allocate_misc P_ ((void));
+ extern Lisp_Object allocate_misc (void);
  EXFUN (Fmake_vector, 2);
  EXFUN (Fvector, MANY);
 +EXFUN (Ffunvec, MANY);
  EXFUN (Fmake_symbol, 1);
  EXFUN (Fmake_marker, 0);
  EXFUN (Fmake_string, 2);
- extern Lisp_Object build_string P_ ((const char *));
- extern Lisp_Object make_string P_ ((const char *, int));
- extern Lisp_Object make_unibyte_string P_ ((const char *, int));
- extern Lisp_Object make_multibyte_string P_ ((const char *, int, int));
- extern Lisp_Object make_event_array P_ ((int, Lisp_Object *));
- extern Lisp_Object make_uninit_string P_ ((int));
- extern Lisp_Object make_uninit_multibyte_string P_ ((int, int));
- extern Lisp_Object make_string_from_bytes P_ ((const char *, int, int));
- extern Lisp_Object make_specified_string P_ ((const char *, int, int, int));
+ extern Lisp_Object build_string (const char *);
+ extern Lisp_Object make_string (const char *, int);
+ extern Lisp_Object make_unibyte_string (const char *, int);
+ extern Lisp_Object make_multibyte_string (const char *, int, int);
+ extern Lisp_Object make_event_array (int, Lisp_Object *);
+ extern Lisp_Object make_uninit_string (int);
+ extern Lisp_Object make_uninit_multibyte_string (int, int);
+ extern Lisp_Object make_string_from_bytes (const char *, int, int);
+ extern Lisp_Object make_specified_string (const char *, int, int, int);
  EXFUN (Fpurecopy, 1);
- extern Lisp_Object make_pure_string P_ ((const char *, int, int, int));
+ extern Lisp_Object make_pure_string (const char *, int, int, int);
  extern Lisp_Object make_pure_c_string (const char *data);
- extern Lisp_Object pure_cons P_ ((Lisp_Object, Lisp_Object));
- extern Lisp_Object make_pure_vector P_ ((EMACS_INT));
+ extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object);
+ extern Lisp_Object make_pure_vector (EMACS_INT);
  EXFUN (Fgarbage_collect, 0);
- extern Lisp_Object make_funvec P_ ((Lisp_Object, int, int, Lisp_Object *));
++extern Lisp_Object make_funvec (Lisp_Object, int, int, Lisp_Object *);
  EXFUN (Fmake_byte_code, MANY);
  EXFUN (Fmake_bool_vector, 2);
  extern Lisp_Object Qchar_table_extra_slots;
@@@ -2912,36 -2889,37 +2917,37 @@@ EXFUN (Feval, 1)
  EXFUN (Fapply, MANY);
  EXFUN (Ffuncall, MANY);
  EXFUN (Fbacktrace, 0);
- extern Lisp_Object apply1 P_ ((Lisp_Object, Lisp_Object));
- extern Lisp_Object call0 P_ ((Lisp_Object));
- extern Lisp_Object call1 P_ ((Lisp_Object, Lisp_Object));
- extern Lisp_Object call2 P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
- extern Lisp_Object call3 P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object));
- extern Lisp_Object call4 P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object));
- extern Lisp_Object call5 P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object));
- extern Lisp_Object call6 P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object));
- extern Lisp_Object call7 P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object));
+ extern Lisp_Object apply1 (Lisp_Object, Lisp_Object);
+ extern Lisp_Object call0 (Lisp_Object);
+ extern Lisp_Object call1 (Lisp_Object, Lisp_Object);
+ extern Lisp_Object call2 (Lisp_Object, Lisp_Object, Lisp_Object);
+ extern Lisp_Object call3 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
+ extern Lisp_Object call4 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
+ extern Lisp_Object call5 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
+ extern Lisp_Object call6 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
+ extern Lisp_Object call7 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
  EXFUN (Fdo_auto_save, 2);
- extern Lisp_Object apply_lambda P_ ((Lisp_Object, Lisp_Object, int, Lisp_Object));
- extern Lisp_Object internal_catch P_ ((Lisp_Object, Lisp_Object (*) (Lisp_Object), Lisp_Object));
- extern Lisp_Object internal_lisp_condition_case P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
- extern Lisp_Object internal_condition_case P_ ((Lisp_Object (*) (void), Lisp_Object, Lisp_Object (*) (Lisp_Object)));
- extern Lisp_Object internal_condition_case_1 P_ ((Lisp_Object (*) (Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object)));
- extern Lisp_Object internal_condition_case_2 P_ ((Lisp_Object (*) (Lisp_Object, Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object)));
- extern Lisp_Object internal_condition_case_n P_ ((Lisp_Object (*) (int, Lisp_Object *), int, Lisp_Object *, Lisp_Object, Lisp_Object (*) (Lisp_Object)));
- extern void specbind P_ ((Lisp_Object, Lisp_Object));
- extern void record_unwind_protect P_ ((Lisp_Object (*) (Lisp_Object), Lisp_Object));
- extern Lisp_Object unbind_to P_ ((int, Lisp_Object));
- extern void error P_ ((/* char *, ... */)) NO_RETURN;
- extern void do_autoload P_ ((Lisp_Object, Lisp_Object));
- extern Lisp_Object un_autoload P_ ((Lisp_Object));
 -extern Lisp_Object apply_lambda (Lisp_Object, Lisp_Object, int);
++extern Lisp_Object apply_lambda (Lisp_Object, Lisp_Object, int, Lisp_Object);
+ extern Lisp_Object internal_catch (Lisp_Object, Lisp_Object (*) (Lisp_Object), Lisp_Object);
+ extern Lisp_Object internal_lisp_condition_case (Lisp_Object, Lisp_Object, Lisp_Object);
+ extern Lisp_Object internal_condition_case (Lisp_Object (*) (void), Lisp_Object, Lisp_Object (*) (Lisp_Object));
+ extern Lisp_Object internal_condition_case_1 (Lisp_Object (*) (Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object));
+ extern Lisp_Object internal_condition_case_2 (Lisp_Object (*) (Lisp_Object, Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object));
+ extern Lisp_Object internal_condition_case_n (Lisp_Object (*) (int, Lisp_Object *), int, Lisp_Object *, Lisp_Object, Lisp_Object (*) (Lisp_Object));
+ extern void specbind (Lisp_Object, Lisp_Object);
+ extern void record_unwind_protect (Lisp_Object (*) (Lisp_Object), Lisp_Object);
+ extern Lisp_Object unbind_to (int, Lisp_Object);
+ extern void error (const char *, ...) NO_RETURN;
+ extern void verror (const char *, va_list) NO_RETURN;
+ extern void do_autoload (Lisp_Object, Lisp_Object);
+ extern Lisp_Object un_autoload (Lisp_Object);
  EXFUN (Ffetch_bytecode, 1);
- extern void init_eval_once P_ ((void));
- extern Lisp_Object safe_call P_ ((int, Lisp_Object *));
- extern Lisp_Object safe_call1 P_ ((Lisp_Object, Lisp_Object));
+ extern void init_eval_once (void);
+ extern Lisp_Object safe_call (int, Lisp_Object *);
+ extern Lisp_Object safe_call1 (Lisp_Object, Lisp_Object);
  extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object);
- extern void init_eval P_ ((void));
- extern void syms_of_eval P_ ((void));
+ extern void init_eval (void);
+ extern void syms_of_eval (void);
  
  /* Defined in editfns.c */
  EXFUN (Fpropertize, MANY);
@@@ -3340,13 -3318,11 +3346,13 @@@ extern int read_bytecode_char (int)
  
  /* Defined in bytecode.c */
  extern Lisp_Object Qbytecode;
 -EXFUN (Fbyte_code, 3);
 +EXFUN (Fbyte_code, MANY);
- extern void syms_of_bytecode P_ ((void));
+ extern void syms_of_bytecode (void);
  extern struct byte_stack *byte_stack_list;
- extern void mark_byte_stack P_ ((void));
- extern void unmark_byte_stack P_ ((void));
- extern Lisp_Object exec_byte_code P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
-                                      Lisp_Object, int, Lisp_Object *));
+ extern void mark_byte_stack (void);
+ extern void unmark_byte_stack (void);
++extern Lisp_Object exec_byte_code (Lisp_Object, Lisp_Object, Lisp_Object,
++                                 Lisp_Object, int, Lisp_Object *);
  
  /* Defined in macros.c */
  extern Lisp_Object Qexecute_kbd_macro;
@@@ -3402,27 -3378,39 +3408,39 @@@ struct terminal
  
  /* Defined in sysdep.c */
  #ifndef HAVE_GET_CURRENT_DIR_NAME
- extern char *get_current_dir_name P_ ((void));
+ extern char *get_current_dir_name (void);
+ #endif
+ extern void stuff_char (char c);
+ extern void init_sigio (int);
+ extern void sys_subshell (void);
+ extern void sys_suspend (void);
+ extern void discard_tty_input (void);
+ extern void init_sys_modes (struct tty_display_info *);
+ extern void reset_sys_modes (struct tty_display_info *);
+ extern void init_all_sys_modes (void);
+ extern void reset_all_sys_modes (void);
+ extern void wait_for_termination (int);
+ extern void flush_pending_output (int);
+ extern void child_setup_tty (int);
+ extern void setup_pty (int);
+ extern int set_window_size (int, int, int);
+ extern void create_process (Lisp_Object, char **, Lisp_Object);
+ extern int emacs_open (const char *, int, int);
+ extern int emacs_close (int);
+ extern int emacs_read (int, char *, unsigned int);
+ extern int emacs_write (int, const char *, unsigned int);
+ #ifndef HAVE_MEMSET
 -extern void *memset P_ ((void *, int, size_t));
++extern void *memset (void *, int, size_t);
+ #endif
+ #ifndef HAVE_MEMCPY
 -extern void *memcpy P_ ((void *, void *, size_t));
++extern void *memcpy (void *, void *, size_t);
+ #endif
+ #ifndef HAVE_MEMMOVE
 -extern void *memmove P_ ((void *, void *, size_t));
++extern void *memmove (void *, void *, size_t);
+ #endif
+ #ifndef HAVE_MEMCMP
 -extern int memcmp P_ ((void *, void *, size_t));
++extern int memcmp (void *, void *, size_t);
  #endif
- extern void stuff_char P_ ((char c));
- extern void init_sigio P_ ((int));
- extern void sys_subshell P_ ((void));
- extern void sys_suspend P_ ((void));
- extern void discard_tty_input P_ ((void));
- extern void init_sys_modes P_ ((struct tty_display_info *));
- extern void reset_sys_modes P_ ((struct tty_display_info *));
- extern void init_all_sys_modes P_ ((void));
- extern void reset_all_sys_modes P_ ((void));
- extern void wait_for_termination P_ ((int));
- extern void flush_pending_output P_ ((int));
- extern void child_setup_tty P_ ((int));
- extern void setup_pty P_ ((int));
- extern int set_window_size P_ ((int, int, int));
- extern void create_process P_ ((Lisp_Object, char **, Lisp_Object));
- extern int emacs_open P_ ((const char *, int, int));
- extern int emacs_close P_ ((int));
- extern int emacs_read P_ ((int, char *, unsigned int));
- extern int emacs_write P_ ((int, const char *, unsigned int));
  
  /* Defined in filelock.c */
  EXFUN (Funlock_buffer, 0);
diff --cc src/lread.c
@@@ -3446,9 -3253,7 +3389,7 @@@ isfloat_string (const char *cp, int ign
  
  \f
  static Lisp_Object
- read_vector (readcharfun, read_funvec)
-      Lisp_Object readcharfun;
-      int read_funvec;
 -read_vector (Lisp_Object readcharfun, int bytecodeflag)
++read_vector (Lisp_Object readcharfun, int read_funvec)
  {
    register int i;
    register int size;
diff --cc src/print.c
Simple merge