+ int bytepos = 0, position = 0, translated = 0, argn = 1;
+ Lisp_Object list;
+
+ /* Adjust the bounds of each text property
+ to the proper start and end in the output string. */
+
+ /* Put the positions in PROPS in increasing order, so that
+ we can do (effectively) one scan through the position
+ space of the format string. */
+ props = Fnreverse (props);
+
+ /* BYTEPOS is the byte position in the format string,
+ POSITION is the untranslated char position in it,
+ TRANSLATED is the translated char position in BUF,
+ and ARGN is the number of the next arg we will come to. */
+ for (list = props; CONSP (list); list = XCDR (list))
+ {
+ Lisp_Object item;
+ int pos;
+
+ item = XCAR (list);
+
+ /* First adjust the property start position. */
+ pos = XINT (XCAR (item));
+
+ /* Advance BYTEPOS, POSITION, TRANSLATED and ARGN
+ up to this position. */
+ for (; position < pos; bytepos++)
+ {
+ if (! discarded[bytepos])
+ position++, translated++;
+ else if (discarded[bytepos] == 1)
+ {
+ position++;
+ if (translated == info[argn].start)
+ {
+ translated += info[argn].end - info[argn].start;
+ argn++;
+ }
+ }
+ }
+
+ XSETCAR (item, make_number (translated));
+
+ /* Likewise adjust the property end position. */
+ pos = XINT (XCAR (XCDR (item)));
+
+ for (; bytepos < pos; bytepos++)
+ {
+ if (! discarded[bytepos])
+ position++, translated++;
+ else if (discarded[bytepos] == 1)
+ {
+ position++;
+ if (translated == info[argn].start)
+ {
+ translated += info[argn].end - info[argn].start;
+ argn++;
+ }
+ }
+ }
+
+ XSETCAR (XCDR (item), make_number (translated));
+ }
+