diff options
| author | Andreas Schwab | 2015-08-23 13:43:34 +0200 |
|---|---|---|
| committer | Andreas Schwab | 2015-08-23 16:33:39 +0200 |
| commit | 6b1765e05db432007ede6f1af3744e71063a728b (patch) | |
| tree | f8e0b1cf2b8238a292b6896cf664079765f53861 | |
| parent | 0b0c9565d050bfecc581b342c40b719917395896 (diff) | |
| download | emacs-6b1765e05db432007ede6f1af3744e71063a728b.tar.gz emacs-6b1765e05db432007ede6f1af3744e71063a728b.zip | |
Revert "Extend ‘format’ to translate curved quotes"
This reverts commit 244c801689d2f7a80480d83cd7d092d4762ebe08.
| -rw-r--r-- | doc/lispref/help.texi | 12 | ||||
| -rw-r--r-- | doc/lispref/strings.texi | 69 | ||||
| -rw-r--r-- | etc/NEWS | 13 | ||||
| -rw-r--r-- | lisp/calc/calc-help.el | 2 | ||||
| -rw-r--r-- | lisp/emacs-lisp/derived.el | 5 | ||||
| -rw-r--r-- | lisp/info.el | 6 | ||||
| -rw-r--r-- | src/editfns.c | 200 |
7 files changed, 120 insertions, 187 deletions
diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi index ab1696e6712..ca8ae3f314a 100644 --- a/doc/lispref/help.texi +++ b/doc/lispref/help.texi | |||
| @@ -347,11 +347,19 @@ and @samp{\=\=} puts @samp{\=} into the output. | |||
| 347 | @strong{Please note:} Each @samp{\} must be doubled when written in a | 347 | @strong{Please note:} Each @samp{\} must be doubled when written in a |
| 348 | string in Emacs Lisp. | 348 | string in Emacs Lisp. |
| 349 | 349 | ||
| 350 | @defvar text-quoting-style | ||
| 350 | @cindex curved quotes | 351 | @cindex curved quotes |
| 351 | @cindex curly quotes | 352 | @cindex curly quotes |
| 352 | The value of the @code{text-quoting-style} variable specifies the style | 353 | The value of this variable specifies the style |
| 353 | @code{substitute-command-keys} uses when generating left and right | 354 | @code{substitute-command-keys} uses when generating left and right |
| 354 | quotes. @xref{Formatting Strings}, for more information. | 355 | quotes. If the variable's value is @code{curve}, the style is |
| 356 | @t{‘like this’} with curved single quotes. If the value is | ||
| 357 | @code{straight}, the style is @t{'like this'} with straight | ||
| 358 | apostrophes. If the value is @code{grave}, the style is @t{`like | ||
| 359 | this'} with grave accent and apostrophe. The default value @code{nil} | ||
| 360 | acts like @code{curve} if curved single quotes are displayable, and | ||
| 361 | like @code{grave} otherwise. | ||
| 362 | @end defvar | ||
| 355 | 363 | ||
| 356 | @defun substitute-command-keys string | 364 | @defun substitute-command-keys string |
| 357 | This function scans @var{string} for the above special sequences and | 365 | This function scans @var{string} for the above special sequences and |
diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 8de1473b83d..580eb43acca 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi | |||
| @@ -805,27 +805,22 @@ formatting feature described here; they differ from @code{format} only | |||
| 805 | in how they use the result of formatting. | 805 | in how they use the result of formatting. |
| 806 | 806 | ||
| 807 | @defun format string &rest objects | 807 | @defun format string &rest objects |
| 808 | This function returns a string that is equivalent to copying | 808 | This function returns a new string that is made by copying |
| 809 | @var{string} and then replacing any format specification | 809 | @var{string} and then replacing any format specification |
| 810 | in the copy with encodings of the corresponding @var{objects}. The | 810 | in the copy with encodings of the corresponding @var{objects}. The |
| 811 | arguments @var{objects} are the computed values to be formatted. | 811 | arguments @var{objects} are the computed values to be formatted. |
| 812 | 812 | ||
| 813 | The characters in @var{string}, other than the format specifications, | 813 | The characters in @var{string}, other than the format specifications, |
| 814 | are copied directly into the output, including their text properties, | 814 | are copied directly into the output, including their text properties, |
| 815 | if any. If the output equals @var{string}, this function may return | 815 | if any. |
| 816 | @var{string} itself rather than a new copy. | ||
| 817 | @end defun | 816 | @end defun |
| 818 | 817 | ||
| 819 | @cindex @samp{%} in format | 818 | @cindex @samp{%} in format |
| 820 | @cindex format specification | 819 | @cindex format specification |
| 821 | @cindex curved quotes | ||
| 822 | @cindex curly quotes | ||
| 823 | A format specification is a sequence of characters beginning with a | 820 | A format specification is a sequence of characters beginning with a |
| 824 | @samp{%} or is a curved single quotation mark. Except for @samp{%%} | 821 | @samp{%}. Thus, if there is a @samp{%d} in @var{string}, the |
| 825 | and quotation marks, each format specification says how to represent | 822 | @code{format} function replaces it with the printed representation of |
| 826 | one of the arguments @var{objects}. For example, if there | 823 | one of the values to be formatted (one of the arguments @var{objects}). |
| 827 | is a @samp{%d} in @var{string}, the @code{format} function replaces it | ||
| 828 | with the decimal representation of the integer to be formatted. | ||
| 829 | For example: | 824 | For example: |
| 830 | 825 | ||
| 831 | @example | 826 | @example |
| @@ -835,12 +830,11 @@ For example: | |||
| 835 | @end group | 830 | @end group |
| 836 | @end example | 831 | @end example |
| 837 | 832 | ||
| 838 | Since @code{format} interprets @samp{%}, @samp{‘} and @samp{’} | 833 | Since @code{format} interprets @samp{%} characters as format |
| 839 | characters as format | ||
| 840 | specifications, you should @emph{never} pass an arbitrary string as | 834 | specifications, you should @emph{never} pass an arbitrary string as |
| 841 | the first argument. This is particularly true when the string is | 835 | the first argument. This is particularly true when the string is |
| 842 | generated by some Lisp code. Unless the string is @emph{known} to | 836 | generated by some Lisp code. Unless the string is @emph{known} to |
| 843 | never include any of the three special characters, pass @code{"%s"}, described | 837 | never include any @samp{%} characters, pass @code{"%s"}, described |
| 844 | below, as the first argument, and the string as the second, like this: | 838 | below, as the first argument, and the string as the second, like this: |
| 845 | 839 | ||
| 846 | @example | 840 | @example |
| @@ -914,27 +908,17 @@ is shorter. | |||
| 914 | Replace the specification with a single @samp{%}. This format | 908 | Replace the specification with a single @samp{%}. This format |
| 915 | specification is unusual in that it does not use a value. For example, | 909 | specification is unusual in that it does not use a value. For example, |
| 916 | @code{(format "%% %d" 30)} returns @code{"% 30"}. | 910 | @code{(format "%% %d" 30)} returns @code{"% 30"}. |
| 917 | |||
| 918 | @item ‘ | ||
| 919 | @itemx ’ | ||
| 920 | @cindex curved quotes | ||
| 921 | @cindex curly quotes | ||
| 922 | Replace the specification with a left or right quote, respectively. | ||
| 923 | Although typically a curved single quotation mark stands for itself, | ||
| 924 | other quoting styles are available as per the variable | ||
| 925 | @samp{text-quoting-style} described below. | ||
| 926 | @end table | 911 | @end table |
| 927 | 912 | ||
| 928 | Any other format character after @samp{%} results in an @samp{Invalid format | 913 | Any other format character results in an @samp{Invalid format |
| 929 | operation} error. | 914 | operation} error. |
| 930 | 915 | ||
| 931 | Here are several examples, which assume the typical quoting style | 916 | Here are several examples: |
| 932 | where curved single quotes stand for themselves: | ||
| 933 | 917 | ||
| 934 | @example | 918 | @example |
| 935 | @group | 919 | @group |
| 936 | (format "The name of this buffer is ‘%s’." (buffer-name)) | 920 | (format "The name of this buffer is %s." (buffer-name)) |
| 937 | @result{} "The name of this buffer is ‘strings.texi’." | 921 | @result{} "The name of this buffer is strings.texi." |
| 938 | 922 | ||
| 939 | (format "The buffer object prints as %qs." (current-buffer)) | 923 | (format "The buffer object prints as %qs." (current-buffer)) |
| 940 | @result{} "The buffer object prints as ‘strings.texi’." | 924 | @result{} "The buffer object prints as ‘strings.texi’." |
| @@ -948,7 +932,7 @@ where curved single quotes stand for themselves: | |||
| 948 | 932 | ||
| 949 | @cindex field width | 933 | @cindex field width |
| 950 | @cindex padding | 934 | @cindex padding |
| 951 | A @samp{%} specification can have a @dfn{width}, which is a decimal number | 935 | A specification can have a @dfn{width}, which is a decimal number |
| 952 | between the @samp{%} and the specification character. If the printed | 936 | between the @samp{%} and the specification character. If the printed |
| 953 | representation of the object contains fewer characters than this | 937 | representation of the object contains fewer characters than this |
| 954 | width, @code{format} extends it with padding. The width specifier is | 938 | width, @code{format} extends it with padding. The width specifier is |
| @@ -964,7 +948,7 @@ the width specifier normally consists of spaces inserted on the left: | |||
| 964 | If the width is too small, @code{format} does not truncate the | 948 | If the width is too small, @code{format} does not truncate the |
| 965 | object's printed representation. Thus, you can use a width to specify | 949 | object's printed representation. Thus, you can use a width to specify |
| 966 | a minimum spacing between columns with no risk of losing information. | 950 | a minimum spacing between columns with no risk of losing information. |
| 967 | In the following two examples, @samp{%7s} specifies a minimum width | 951 | In the following three examples, @samp{%7s} specifies a minimum width |
| 968 | of 7. In the first case, the string inserted in place of @samp{%7s} | 952 | of 7. In the first case, the string inserted in place of @samp{%7s} |
| 969 | has only 3 letters, and needs 4 blank spaces as padding. In the | 953 | has only 3 letters, and needs 4 blank spaces as padding. In the |
| 970 | second case, the string @code{"specification"} is 13 letters wide but | 954 | second case, the string @code{"specification"} is 13 letters wide but |
| @@ -972,12 +956,12 @@ is not truncated. | |||
| 972 | 956 | ||
| 973 | @example | 957 | @example |
| 974 | @group | 958 | @group |
| 975 | (format "The word ‘%7s’ has %d letters in it." | 959 | (format "The word '%7s' has %d letters in it." |
| 976 | "foo" (length "foo")) | 960 | "foo" (length "foo")) |
| 977 | @result{} "The word ‘ foo’ has 3 letters in it." | 961 | @result{} "The word ' foo' has 3 letters in it." |
| 978 | (format "The word ‘%7s’ has %d letters in it." | 962 | (format "The word '%7s' has %d letters in it." |
| 979 | "specification" (length "specification")) | 963 | "specification" (length "specification")) |
| 980 | @result{} "The word ‘specification’ has 13 letters in it." | 964 | @result{} "The word 'specification' has 13 letters in it." |
| 981 | @end group | 965 | @end group |
| 982 | @end example | 966 | @end example |
| 983 | 967 | ||
| @@ -1022,14 +1006,14 @@ variable @samp{text-quoting-style} described below. | |||
| 1022 | (format "%q-6d is padded on the right" 123) | 1006 | (format "%q-6d is padded on the right" 123) |
| 1023 | @result{} "‘123 ’ is padded on the right" | 1007 | @result{} "‘123 ’ is padded on the right" |
| 1024 | 1008 | ||
| 1025 | (format "The word ‘%-7s’ actually has %d letters in it." | 1009 | (format "The word '%-7s' actually has %d letters in it." |
| 1026 | "foo" (length "foo")) | 1010 | "foo" (length "foo")) |
| 1027 | @result{} "The word ‘foo ’ actually has 3 letters in it." | 1011 | @result{} "The word 'foo ' actually has 3 letters in it." |
| 1028 | @end group | 1012 | @end group |
| 1029 | @end example | 1013 | @end example |
| 1030 | 1014 | ||
| 1031 | @cindex precision in format specifications | 1015 | @cindex precision in format specifications |
| 1032 | The @samp{%} specification characters allow an optional @dfn{precision} | 1016 | All the specification characters allow an optional @dfn{precision} |
| 1033 | before the character (after the width, if present). The precision is | 1017 | before the character (after the width, if present). The precision is |
| 1034 | a decimal-point @samp{.} followed by a digit-string. For the | 1018 | a decimal-point @samp{.} followed by a digit-string. For the |
| 1035 | floating-point specifications (@samp{%e}, @samp{%f}, @samp{%g}), the | 1019 | floating-point specifications (@samp{%e}, @samp{%f}, @samp{%g}), the |
| @@ -1040,19 +1024,6 @@ shows only the first three characters of the representation for | |||
| 1040 | @var{object}. Precision has no effect for other specification | 1024 | @var{object}. Precision has no effect for other specification |
| 1041 | characters. | 1025 | characters. |
| 1042 | 1026 | ||
| 1043 | @defvar text-quoting-style | ||
| 1044 | @cindex curved quotes | ||
| 1045 | @cindex curly quotes | ||
| 1046 | This variable specifies the style @code{format} uses when generating | ||
| 1047 | left and right quotes. If the value is @code{curve}, the style is | ||
| 1048 | @t{‘like this’} with curved single quotes. If the value is | ||
| 1049 | @code{straight}, the style is @t{'like this'} with straight | ||
| 1050 | apostrophes. If the value is @code{grave}, the style is @t{`like | ||
| 1051 | this'} with grave accent and apostrophe. The default value @code{nil} | ||
| 1052 | acts like @code{curve} if curved single quotes are displayable, and | ||
| 1053 | like @code{grave} otherwise. | ||
| 1054 | @end defvar | ||
| 1055 | |||
| 1056 | @node Case Conversion | 1027 | @node Case Conversion |
| 1057 | @section Case Conversion in Lisp | 1028 | @section Case Conversion in Lisp |
| 1058 | @cindex upper case | 1029 | @cindex upper case |
| @@ -910,19 +910,6 @@ denied" instead of "permission denied". The old behavior was problematic | |||
| 910 | in languages like German where downcasing rules depend on grammar. | 910 | in languages like German where downcasing rules depend on grammar. |
| 911 | 911 | ||
| 912 | +++ | 912 | +++ |
| 913 | ** ‘format’ now replaces curved single quotes. | ||
| 914 | That is, it replaces strings' curved single quotes (also known as | ||
| 915 | curly quotes) as per the value of the new custom variable | ||
| 916 | ‘text-quoting-style’: ‘curve’ means replace curved quotes with | ||
| 917 | themselves ‘like this’, ‘straight’ means use straight apostrophes | ||
| 918 | 'like this', ‘grave’ means use grave accent and apostrophe `like | ||
| 919 | this', and nil (default) means use curved quotes if displayable and | ||
| 920 | grave accent and apostrophe otherwise. Because it now may be used | ||
| 921 | in many contexts where it's a no-op, ‘format’ is no longer required to | ||
| 922 | create a string, and may return its first argument if the argument | ||
| 923 | already has the correct value. | ||
| 924 | |||
| 925 | +++ | ||
| 926 | ** New ‘format’ flag ‘q’ | 913 | ** New ‘format’ flag ‘q’ |
| 927 | The new ‘q’ flag causes ‘format’ to quote the output representation as | 914 | The new ‘q’ flag causes ‘format’ to quote the output representation as |
| 928 | per the value of ‘text quoting-style’. E.g., (format "%qs failed" | 915 | per the value of ‘text quoting-style’. E.g., (format "%qs failed" |
diff --git a/lisp/calc/calc-help.el b/lisp/calc/calc-help.el index 01ab49510cd..50a0291e4cd 100644 --- a/lisp/calc/calc-help.el +++ b/lisp/calc/calc-help.el | |||
| @@ -365,7 +365,7 @@ C-w Describe how there is no warranty for Calc." | |||
| 365 | (let (Info-history) | 365 | (let (Info-history) |
| 366 | (Info-goto-node (buffer-substring (match-beginning 1) (match-end 1)))) | 366 | (Info-goto-node (buffer-substring (match-beginning 1) (match-end 1)))) |
| 367 | (let* ((string-target (or target thing)) | 367 | (let* ((string-target (or target thing)) |
| 368 | (quoted (concat "['`‘]" (regexp-quote string-target) "['’]")) | 368 | (quoted (format "['`‘]%s['’]" (regexp-quote string-target))) |
| 369 | (bracketed (format "\\[%s\\]\\|(%s)\\|\\<The[ \n]%s" | 369 | (bracketed (format "\\[%s\\]\\|(%s)\\|\\<The[ \n]%s" |
| 370 | quoted quoted quoted))) | 370 | quoted quoted quoted))) |
| 371 | (or (let ((case-fold-search nil)) | 371 | (or (let ((case-fold-search nil)) |
diff --git a/lisp/emacs-lisp/derived.el b/lisp/emacs-lisp/derived.el index 1f8572b278b..ee137f1771e 100644 --- a/lisp/emacs-lisp/derived.el +++ b/lisp/emacs-lisp/derived.el | |||
| @@ -331,10 +331,9 @@ which more-or-less shadow%s %s's corresponding table%s." | |||
| 331 | "\n\nThis mode " | 331 | "\n\nThis mode " |
| 332 | (concat | 332 | (concat |
| 333 | "\n\nIn addition to any hooks its parent mode " | 333 | "\n\nIn addition to any hooks its parent mode " |
| 334 | (if (string-match (concat "[`%‘]" | 334 | (if (string-match (format "[`‘]%s['’]" |
| 335 | (regexp-quote | 335 | (regexp-quote |
| 336 | (symbol-name parent)) | 336 | (symbol-name parent))) |
| 337 | "['%’]") | ||
| 338 | docstring) | 337 | docstring) |
| 339 | nil | 338 | nil |
| 340 | (format "`%s' " parent)) | 339 | (format "`%s' " parent)) |
diff --git a/lisp/info.el b/lisp/info.el index 8a43a8182aa..454fadaca03 100644 --- a/lisp/info.el +++ b/lisp/info.el | |||
| @@ -3398,12 +3398,10 @@ Give an empty topic name to go to the Index node itself." | |||
| 3398 | (re-search-forward (format | 3398 | (re-search-forward (format |
| 3399 | "[a-zA-Z]+: [a-zA-Z0-9_ *&]+ %s\\( \\|$\\)" | 3399 | "[a-zA-Z]+: [a-zA-Z0-9_ *&]+ %s\\( \\|$\\)" |
| 3400 | (regexp-quote name)) nil t) | 3400 | (regexp-quote name)) nil t) |
| 3401 | (search-forward (concat "['`‘]" name "['’]") nil t) | 3401 | (search-forward (format "['`‘]%s['’]" name) nil t) |
| 3402 | (and (string-match "\\`.*\\( (.*)\\)\\'" name) | 3402 | (and (string-match "\\`.*\\( (.*)\\)\\'" name) |
| 3403 | (search-forward | 3403 | (search-forward |
| 3404 | (concat "['`%‘]" | 3404 | (format "['`‘]%s['’]" (substring name 0 (match-beginning 1))) |
| 3405 | (substring name 0 (match-beginning 1)) | ||
| 3406 | "['%’]") | ||
| 3407 | nil t)) | 3405 | nil t)) |
| 3408 | (search-forward name nil t) | 3406 | (search-forward name nil t) |
| 3409 | ;; Try again without the " <1>" makeinfo can append | 3407 | ;; Try again without the " <1>" makeinfo can append |
diff --git a/src/editfns.c b/src/editfns.c index 0e1b0c8f01d..8ac0ef16999 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -3800,9 +3800,8 @@ DEFUN ("format", Fformat, Sformat, 1, MANY, 0, | |||
| 3800 | The first argument is a format control string. | 3800 | The first argument is a format control string. |
| 3801 | The other arguments are substituted into it to make the result, a string. | 3801 | The other arguments are substituted into it to make the result, a string. |
| 3802 | 3802 | ||
| 3803 | The format control string may contain ordinary characters, | 3803 | The format control string may contain %-sequences meaning to substitute |
| 3804 | %-sequences meaning to substitute the next available argument, | 3804 | the next available argument: |
| 3805 | and curved single quotation marks meaning to substitute quotes. | ||
| 3806 | 3805 | ||
| 3807 | %s means print a string argument. Actually, prints any object, with `princ'. | 3806 | %s means print a string argument. Actually, prints any object, with `princ'. |
| 3808 | %d means print as number in decimal (%o octal, %x hex). | 3807 | %d means print as number in decimal (%o octal, %x hex). |
| @@ -3850,12 +3849,6 @@ precision specifier says how many decimal places to show; if zero, the | |||
| 3850 | decimal point itself is omitted. For %s and %S, the precision | 3849 | decimal point itself is omitted. For %s and %S, the precision |
| 3851 | specifier truncates the string to the given width. | 3850 | specifier truncates the string to the given width. |
| 3852 | 3851 | ||
| 3853 | \\=‘ and \\=’ means print left and right quotes as per | ||
| 3854 | ‘text-quoting-style’. | ||
| 3855 | |||
| 3856 | Return the first argument if it contains no format directives. | ||
| 3857 | Otherwise, return a new string. | ||
| 3858 | |||
| 3859 | usage: (format STRING &rest OBJECTS) */) | 3852 | usage: (format STRING &rest OBJECTS) */) |
| 3860 | (ptrdiff_t nargs, Lisp_Object *args) | 3853 | (ptrdiff_t nargs, Lisp_Object *args) |
| 3861 | { | 3854 | { |
| @@ -3868,7 +3861,6 @@ usage: (format STRING &rest OBJECTS) */) | |||
| 3868 | ptrdiff_t buf_save_value_index IF_LINT (= 0); | 3861 | ptrdiff_t buf_save_value_index IF_LINT (= 0); |
| 3869 | char *format, *end, *format_start; | 3862 | char *format, *end, *format_start; |
| 3870 | ptrdiff_t formatlen, nchars; | 3863 | ptrdiff_t formatlen, nchars; |
| 3871 | bool changed = false; | ||
| 3872 | /* True if the format is multibyte. */ | 3864 | /* True if the format is multibyte. */ |
| 3873 | bool multibyte_format = 0; | 3865 | bool multibyte_format = 0; |
| 3874 | /* True if the output should be a multibyte string, | 3866 | /* True if the output should be a multibyte string, |
| @@ -4020,7 +4012,6 @@ usage: (format STRING &rest OBJECTS) */) | |||
| 4020 | if (format == end) | 4012 | if (format == end) |
| 4021 | error ("Format string ends in middle of format specifier"); | 4013 | error ("Format string ends in middle of format specifier"); |
| 4022 | 4014 | ||
| 4023 | changed = true; | ||
| 4024 | memset (&discarded[format0 - format_start], 1, format - format0); | 4015 | memset (&discarded[format0 - format_start], 1, format - format0); |
| 4025 | conversion = *format; | 4016 | conversion = *format; |
| 4026 | if (conversion == '%') | 4017 | if (conversion == '%') |
| @@ -4493,20 +4484,6 @@ usage: (format STRING &rest OBJECTS) */) | |||
| 4493 | 4484 | ||
| 4494 | convbytes = format - src; | 4485 | convbytes = format - src; |
| 4495 | memset (&discarded[src + 1 - format_start], 2, convbytes - 1); | 4486 | memset (&discarded[src + 1 - format_start], 2, convbytes - 1); |
| 4496 | |||
| 4497 | if (quoting_style != CURVE_QUOTING_STYLE && convbytes == 3 | ||
| 4498 | && (unsigned char) src[0] == uLSQM0 | ||
| 4499 | && (unsigned char) src[1] == uLSQM1 | ||
| 4500 | && ((unsigned char) src[2] == uLSQM2 | ||
| 4501 | || (unsigned char) src[2] == uRSQM2)) | ||
| 4502 | { | ||
| 4503 | convbytes = 1; | ||
| 4504 | str[0] = (((unsigned char) src[2] == uLSQM2 | ||
| 4505 | && quoting_style == GRAVE_QUOTING_STYLE) | ||
| 4506 | ? '`' : '\''); | ||
| 4507 | src = (char *) str; | ||
| 4508 | changed = true; | ||
| 4509 | } | ||
| 4510 | } | 4487 | } |
| 4511 | else | 4488 | else |
| 4512 | { | 4489 | { |
| @@ -4518,7 +4495,6 @@ usage: (format STRING &rest OBJECTS) */) | |||
| 4518 | int c = BYTE8_TO_CHAR (uc); | 4495 | int c = BYTE8_TO_CHAR (uc); |
| 4519 | convbytes = CHAR_STRING (c, str); | 4496 | convbytes = CHAR_STRING (c, str); |
| 4520 | src = (char *) str; | 4497 | src = (char *) str; |
| 4521 | changed = true; | ||
| 4522 | } | 4498 | } |
| 4523 | } | 4499 | } |
| 4524 | 4500 | ||
| @@ -4566,119 +4542,113 @@ usage: (format STRING &rest OBJECTS) */) | |||
| 4566 | if (bufsize < p - buf) | 4542 | if (bufsize < p - buf) |
| 4567 | emacs_abort (); | 4543 | emacs_abort (); |
| 4568 | 4544 | ||
| 4569 | if (!changed) | 4545 | if (maybe_combine_byte) |
| 4570 | val = args[0]; | 4546 | nchars = multibyte_chars_in_text ((unsigned char *) buf, p - buf); |
| 4571 | else | 4547 | val = make_specified_string (buf, nchars, p - buf, multibyte); |
| 4572 | { | ||
| 4573 | if (maybe_combine_byte) | ||
| 4574 | nchars = multibyte_chars_in_text ((unsigned char *) buf, p - buf); | ||
| 4575 | val = make_specified_string (buf, nchars, p - buf, multibyte); | ||
| 4576 | 4548 | ||
| 4577 | /* If the format string has text properties, or any of the string | 4549 | /* If the format string has text properties, or any of the string |
| 4578 | arguments has text properties, set up text properties of the | 4550 | arguments has text properties, set up text properties of the |
| 4579 | result string. */ | 4551 | result string. */ |
| 4580 | 4552 | ||
| 4581 | if (string_intervals (args[0]) || arg_intervals) | 4553 | if (string_intervals (args[0]) || arg_intervals) |
| 4582 | { | 4554 | { |
| 4583 | Lisp_Object len, new_len, props; | 4555 | Lisp_Object len, new_len, props; |
| 4584 | struct gcpro gcpro1; | 4556 | struct gcpro gcpro1; |
| 4585 | 4557 | ||
| 4586 | /* Add text properties from the format string. */ | 4558 | /* Add text properties from the format string. */ |
| 4587 | len = make_number (SCHARS (args[0])); | 4559 | len = make_number (SCHARS (args[0])); |
| 4588 | props = text_property_list (args[0], make_number (0), len, Qnil); | 4560 | props = text_property_list (args[0], make_number (0), len, Qnil); |
| 4589 | GCPRO1 (props); | 4561 | GCPRO1 (props); |
| 4590 | 4562 | ||
| 4591 | if (CONSP (props)) | 4563 | if (CONSP (props)) |
| 4564 | { | ||
| 4565 | ptrdiff_t bytepos = 0, position = 0, translated = 0; | ||
| 4566 | ptrdiff_t argn = 1; | ||
| 4567 | Lisp_Object list; | ||
| 4568 | |||
| 4569 | /* Adjust the bounds of each text property | ||
| 4570 | to the proper start and end in the output string. */ | ||
| 4571 | |||
| 4572 | /* Put the positions in PROPS in increasing order, so that | ||
| 4573 | we can do (effectively) one scan through the position | ||
| 4574 | space of the format string. */ | ||
| 4575 | props = Fnreverse (props); | ||
| 4576 | |||
| 4577 | /* BYTEPOS is the byte position in the format string, | ||
| 4578 | POSITION is the untranslated char position in it, | ||
| 4579 | TRANSLATED is the translated char position in BUF, | ||
| 4580 | and ARGN is the number of the next arg we will come to. */ | ||
| 4581 | for (list = props; CONSP (list); list = XCDR (list)) | ||
| 4592 | { | 4582 | { |
| 4593 | ptrdiff_t bytepos = 0, position = 0, translated = 0; | 4583 | Lisp_Object item; |
| 4594 | ptrdiff_t argn = 1; | 4584 | ptrdiff_t pos; |
| 4595 | Lisp_Object list; | ||
| 4596 | |||
| 4597 | /* Adjust the bounds of each text property | ||
| 4598 | to the proper start and end in the output string. */ | ||
| 4599 | |||
| 4600 | /* Put the positions in PROPS in increasing order, so that | ||
| 4601 | we can do (effectively) one scan through the position | ||
| 4602 | space of the format string. */ | ||
| 4603 | props = Fnreverse (props); | ||
| 4604 | |||
| 4605 | /* BYTEPOS is the byte position in the format string, | ||
| 4606 | POSITION is the untranslated char position in it, | ||
| 4607 | TRANSLATED is the translated char position in BUF, | ||
| 4608 | and ARGN is the number of the next arg we will come to. */ | ||
| 4609 | for (list = props; CONSP (list); list = XCDR (list)) | ||
| 4610 | { | ||
| 4611 | Lisp_Object item; | ||
| 4612 | ptrdiff_t pos; | ||
| 4613 | 4585 | ||
| 4614 | item = XCAR (list); | 4586 | item = XCAR (list); |
| 4615 | 4587 | ||
| 4616 | /* First adjust the property start position. */ | 4588 | /* First adjust the property start position. */ |
| 4617 | pos = XINT (XCAR (item)); | 4589 | pos = XINT (XCAR (item)); |
| 4618 | 4590 | ||
| 4619 | /* Advance BYTEPOS, POSITION, TRANSLATED and ARGN | 4591 | /* Advance BYTEPOS, POSITION, TRANSLATED and ARGN |
| 4620 | up to this position. */ | 4592 | up to this position. */ |
| 4621 | for (; position < pos; bytepos++) | 4593 | for (; position < pos; bytepos++) |
| 4594 | { | ||
| 4595 | if (! discarded[bytepos]) | ||
| 4596 | position++, translated++; | ||
| 4597 | else if (discarded[bytepos] == 1) | ||
| 4622 | { | 4598 | { |
| 4623 | if (! discarded[bytepos]) | 4599 | position++; |
| 4624 | position++, translated++; | 4600 | if (translated == info[argn].start) |
| 4625 | else if (discarded[bytepos] == 1) | ||
| 4626 | { | 4601 | { |
| 4627 | position++; | 4602 | translated += info[argn].end - info[argn].start; |
| 4628 | if (translated == info[argn].start) | 4603 | argn++; |
| 4629 | { | ||
| 4630 | translated += info[argn].end - info[argn].start; | ||
| 4631 | argn++; | ||
| 4632 | } | ||
| 4633 | } | 4604 | } |
| 4634 | } | 4605 | } |
| 4606 | } | ||
| 4635 | 4607 | ||
| 4636 | XSETCAR (item, make_number (translated)); | 4608 | XSETCAR (item, make_number (translated)); |
| 4637 | 4609 | ||
| 4638 | /* Likewise adjust the property end position. */ | 4610 | /* Likewise adjust the property end position. */ |
| 4639 | pos = XINT (XCAR (XCDR (item))); | 4611 | pos = XINT (XCAR (XCDR (item))); |
| 4640 | 4612 | ||
| 4641 | for (; position < pos; bytepos++) | 4613 | for (; position < pos; bytepos++) |
| 4614 | { | ||
| 4615 | if (! discarded[bytepos]) | ||
| 4616 | position++, translated++; | ||
| 4617 | else if (discarded[bytepos] == 1) | ||
| 4642 | { | 4618 | { |
| 4643 | if (! discarded[bytepos]) | 4619 | position++; |
| 4644 | position++, translated++; | 4620 | if (translated == info[argn].start) |
| 4645 | else if (discarded[bytepos] == 1) | ||
| 4646 | { | 4621 | { |
| 4647 | position++; | 4622 | translated += info[argn].end - info[argn].start; |
| 4648 | if (translated == info[argn].start) | 4623 | argn++; |
| 4649 | { | ||
| 4650 | translated += info[argn].end - info[argn].start; | ||
| 4651 | argn++; | ||
| 4652 | } | ||
| 4653 | } | 4624 | } |
| 4654 | } | 4625 | } |
| 4655 | |||
| 4656 | XSETCAR (XCDR (item), make_number (translated)); | ||
| 4657 | } | 4626 | } |
| 4658 | 4627 | ||
| 4659 | add_text_properties_from_list (val, props, make_number (0)); | 4628 | XSETCAR (XCDR (item), make_number (translated)); |
| 4660 | } | 4629 | } |
| 4661 | 4630 | ||
| 4662 | /* Add text properties from arguments. */ | 4631 | add_text_properties_from_list (val, props, make_number (0)); |
| 4663 | if (arg_intervals) | ||
| 4664 | for (n = 1; n < nargs; ++n) | ||
| 4665 | if (info[n].intervals) | ||
| 4666 | { | ||
| 4667 | len = make_number (SCHARS (args[n])); | ||
| 4668 | new_len = make_number (info[n].end - info[n].start); | ||
| 4669 | props = text_property_list (args[n], make_number (0), | ||
| 4670 | len, Qnil); | ||
| 4671 | props = extend_property_ranges (props, new_len); | ||
| 4672 | /* If successive arguments have properties, be sure that | ||
| 4673 | the value of `composition' property be the copy. */ | ||
| 4674 | if (n > 1 && info[n - 1].end) | ||
| 4675 | make_composition_value_copy (props); | ||
| 4676 | add_text_properties_from_list (val, props, | ||
| 4677 | make_number (info[n].start)); | ||
| 4678 | } | ||
| 4679 | |||
| 4680 | UNGCPRO; | ||
| 4681 | } | 4632 | } |
| 4633 | |||
| 4634 | /* Add text properties from arguments. */ | ||
| 4635 | if (arg_intervals) | ||
| 4636 | for (n = 1; n < nargs; ++n) | ||
| 4637 | if (info[n].intervals) | ||
| 4638 | { | ||
| 4639 | len = make_number (SCHARS (args[n])); | ||
| 4640 | new_len = make_number (info[n].end - info[n].start); | ||
| 4641 | props = text_property_list (args[n], make_number (0), len, Qnil); | ||
| 4642 | props = extend_property_ranges (props, new_len); | ||
| 4643 | /* If successive arguments have properties, be sure that | ||
| 4644 | the value of `composition' property be the copy. */ | ||
| 4645 | if (n > 1 && info[n - 1].end) | ||
| 4646 | make_composition_value_copy (props); | ||
| 4647 | add_text_properties_from_list (val, props, | ||
| 4648 | make_number (info[n].start)); | ||
| 4649 | } | ||
| 4650 | |||
| 4651 | UNGCPRO; | ||
| 4682 | } | 4652 | } |
| 4683 | 4653 | ||
| 4684 | /* If we allocated BUF or INFO with malloc, free it too. */ | 4654 | /* If we allocated BUF or INFO with malloc, free it too. */ |