Function: multiple-command-partition-arguments

multiple-command-partition-arguments is a byte-compiled function defined in subr.el.gz.

Signature

(multiple-command-partition-arguments COMMAND ARGUMENTS &optional SHELLP)

Documentation

Partition ARGUMENTS of COMMAND to avoid command line length limits.

This function is for running commands on each element of ARGUMENTS where ARGUMENTS might be so long that invoking a single shell command on the entirety of ARGUMENTS at once might exceed the system's limits on program argument list length or total command line length. COMMAND is a string or list of strings, beginning with the command to be run on ARGUMENTS (unless SHELLP), and including any arguments that must be passed to every invocation of the command. ARGUMENTS is a list of strings. Each one is a single argument. If SHELLP is non-nil, implicitly include shell-file-name and shell-command-switch at the front of COMMAND, and account for quoting and for space characters required between each argument. Return list of partitions of ARGUMENTS such that running a command formed of COMMAND plus any one of those partitions will not exceed the relevant system limits.

This function takes a conservative approach and does not try to minimize the number of partitions of ARGUMENTS, because doing that would require a great deal of platform-specific information, and also information about encoding which is not currently made available to Lisp.

View in manual

Probably introduced at or before Emacs version 31.1.

Source Code

;; Defined in /usr/src/emacs/lisp/subr.el.gz
(defun multiple-command-partition-arguments (command arguments &optional shellp)
  "Partition ARGUMENTS of COMMAND to avoid command line length limits.
This function is for running commands on each element of ARGUMENTS where
ARGUMENTS might be so long that invoking a single shell command on the
entirety of ARGUMENTS at once might exceed the system's limits on
program argument list length or total command line length.
COMMAND is a string or list of strings, beginning with the command to be
run on ARGUMENTS (unless SHELLP), and including any arguments that must
be passed to every invocation of the command.
ARGUMENTS is a list of strings.  Each one is a single argument.
If SHELLP is non-nil, implicitly include `shell-file-name' and
`shell-command-switch' at the front of COMMAND, and account for quoting
and for space characters required between each argument.
Return list of partitions of ARGUMENTS such that running a command
formed of COMMAND plus any one of those partitions will not exceed the
relevant system limits.

This function takes a conservative approach and does not try to minimize
the number of partitions of ARGUMENTS, because doing that would require
a great deal of platform-specific information, and also information
about encoding which is not currently made available to Lisp."
  ;; An alternative on POSIX platforms would be to convert an E2BIG
  ;; errno into a Lisp condition and then the calling code could decide
  ;; what to do.  But that would impose a performance penalty because
  ;; shelling out is relatively expensive.  So the idea is to just
  ;; always preemptively call `multiple-command-partition-arguments'.
  (let* ((command
          (if shellp
              (nconc (list shell-file-name shell-command-switch)
                     (ensure-list command))
            (ensure-list command)))
         (fixed-args-len
          (apply #'+ (mapcar #'length
                             (if (eq system-type 'windows-nt)
                                 command
                               (nconc command process-environment)))))
         (spaces-and-quotation
          (or shellp (eq system-type 'windows-nt)))
         (next-len 0)
         next all-partitions)
    (when spaces-and-quotation
      ;; On MS-Windows every single argument will need to be quoted
      ;; regardless of whether it contains any whitespace etc..
      (incf fixed-args-len 2)
      (incf fixed-args-len (* 3 (length command))))
    (dolist (arg arguments)
      (let ((len (if spaces-and-quotation
                     (+ (length arg) 3)
                   (length arg))))
        (cond ((<= (+ fixed-args-len next-len len)
                   (connection-local-value command-line-max-length))
               (push arg next)
               (incf next-len len))
              ((<= (+ fixed-args-len len)
                   (connection-local-value command-line-max-length))
               (push (nreverse next) all-partitions)
               (setq next (list arg) next-len len))
              (t
               (error "Impossible to partition arguments to fit system limits")))))
    (nreverse (if next
                  (cons (nreverse next) all-partitions)
                all-partitions))))