Browse Source

new functionality for "format": "%d$...".

Roberto Ierusalimschy 28 years ago
parent
commit
da4dbe65b2
2 changed files with 31 additions and 16 deletions
  1. 15 6
      manual.tex
  2. 16 10
      strlib.c

+ 15 - 6
manual.tex

@@ -1,4 +1,4 @@
-% $Id: manual.tex,v 2.9 1997/07/01 17:41:34 roberto Exp roberto $
+% $Id: manual.tex,v 2.10 1997/07/02 17:09:48 roberto Exp roberto $
 
 
 \documentstyle[fullpage,11pt,bnf]{article}
 \documentstyle[fullpage,11pt,bnf]{article}
 
 
@@ -38,7 +38,7 @@ Waldemar Celes
 \tecgraf\ --- Computer Science Department --- PUC-Rio
 \tecgraf\ --- Computer Science Department --- PUC-Rio
 }
 }
 
 
-\date{\small \verb$Date: 1997/07/01 17:41:34 $}
+\date{\small \verb$Date: 1997/07/02 17:09:48 $}
 
 
 \maketitle
 \maketitle
 
 
@@ -826,8 +826,8 @@ The function not only shows when a tag method is called,
 but also its arguments, its results and the default behavior.
 but also its arguments, its results and the default behavior.
 Please notice that the code shown here is only illustrative;
 Please notice that the code shown here is only illustrative;
 the real behavior is hard coded in the interpreter,
 the real behavior is hard coded in the interpreter,
-and it is much more efficient than this simulation. 
-All functions used in these descriptions 
+and it is much more efficient than this simulation.
+All functions used in these descriptions
 (\verb|rawgetglobal|, \verb|tonumber|, \verb|call|, etc)
 (\verb|rawgetglobal|, \verb|tonumber|, \verb|call|, etc)
 are described in \See{predefined}.
 are described in \See{predefined}.
 
 
@@ -994,7 +994,7 @@ Notice: the function \verb|getglobal| is pre-defined in Lua \see{predefined}.
 
 
 \item[``setglobal'':]\index{setglobal event}
 \item[``setglobal'':]\index{setglobal event}
 called whenever Lua assigns to a global variable.
 called whenever Lua assigns to a global variable.
-This method cannot be set for numbers, strings, and tables and 
+This method cannot be set for numbers, strings, and tables and
 userdata with default tags.
 userdata with default tags.
 \begin{verbatim}
 \begin{verbatim}
       function setglobal (varname, newvalue)
       function setglobal (varname, newvalue)
@@ -1280,7 +1280,7 @@ returns a reference to the object at the top of the C2lua stack,
 and pops it.
 and pops it.
 
 
 As a general rule, all API functions pop from the stack
 As a general rule, all API functions pop from the stack
-all elements that they use. 
+all elements that they use.
 
 
 Because userdata are objects,
 Because userdata are objects,
 the function \verb|lua_pushusertag| may create a new userdata.
 the function \verb|lua_pushusertag| may create a new userdata.
@@ -1885,6 +1885,15 @@ will produce the string:
  new line"
  new line"
 \end{verbatim}
 \end{verbatim}
 
 
+Conversions can be applied to the n-th argument in the argument list,
+rather than the next unused argument.
+In this case, the conversion character \verb|%| is replaced
+by the sequence \verb|%d$|, where \verb|d| is a
+decimal digit in the range [1,9],
+giving the position of the argument in the argument list.
+For instance, the call \verb|format("%2$d -> %1$03d", 1, 34)| will
+result in \verb|"34 -> 001"|.
+
 The options \verb|c|, \verb|d|, \verb|E|, \verb|e|, \verb|f|,
 The options \verb|c|, \verb|d|, \verb|E|, \verb|e|, \verb|f|,
 \verb|g| \verb|i|, \verb|o|, \verb|u|, \verb|X|, and \verb|x| all
 \verb|g| \verb|i|, \verb|o|, \verb|u|, \verb|X|, and \verb|x| all
 expect a number as argument,
 expect a number as argument,

+ 16 - 10
strlib.c

@@ -3,7 +3,7 @@
 ** String library to LUA
 ** String library to LUA
 */
 */
 
 
-char *rcs_strlib="$Id: strlib.c,v 1.45 1997/06/19 17:45:28 roberto Exp roberto $";
+char *rcs_strlib="$Id: strlib.c,v 1.46 1997/06/19 18:49:40 roberto Exp roberto $";
 
 
 #include <string.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdio.h>
@@ -468,7 +468,7 @@ void luaI_addquoted (char *s)
 static void str_format (void)
 static void str_format (void)
 {
 {
   int arg = 1;
   int arg = 1;
-  char *strfrmt = luaL_check_string(arg++);
+  char *strfrmt = luaL_check_string(arg);
   luaI_emptybuff();  /* initialize */
   luaI_emptybuff();  /* initialize */
   while (*strfrmt) {
   while (*strfrmt) {
     if (*strfrmt != '%')
     if (*strfrmt != '%')
@@ -478,29 +478,35 @@ static void str_format (void)
     else { /* format item */
     else { /* format item */
       char form[MAX_FORMAT];      /* store the format ('%...') */
       char form[MAX_FORMAT];      /* store the format ('%...') */
       char *buff;
       char *buff;
-      char *initf = strfrmt-1;  /* -1 to include % */
-      strfrmt = match(strfrmt, "[-+ #]*(%d*)%.?(%d*)", 0);
+      char *initf = strfrmt;
+      form[0] = '%';
+      strfrmt = match(strfrmt, "%d?%$?[-+ #]*(%d*)%.?(%d*)", 0);
       if (capture[0].len > 3 || capture[1].len > 3)  /* < 1000? */
       if (capture[0].len > 3 || capture[1].len > 3)  /* < 1000? */
         lua_error("invalid format (width or precision too long)");
         lua_error("invalid format (width or precision too long)");
-      strncpy(form, initf, strfrmt-initf+1); /* +1 to include convertion */
-      form[strfrmt-initf+1] = 0;
+      if (isdigit((unsigned char)initf[0]) && initf[1] == '$') {
+        arg = initf[0] - '0';
+        initf += 2;  /* skip the 'n$' */
+      }
+      arg++;
+      strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include convertion */
+      form[strfrmt-initf+2] = 0;
       buff = openspace(1000);  /* to store the formated value */
       buff = openspace(1000);  /* to store the formated value */
       switch (*strfrmt++) {
       switch (*strfrmt++) {
         case 'q':
         case 'q':
-          luaI_addquoted(luaL_check_string(arg++));
+          luaI_addquoted(luaL_check_string(arg));
           continue;
           continue;
         case 's': {
         case 's': {
-          char *s = luaL_check_string(arg++);
+          char *s = luaL_check_string(arg);
           buff = openspace(strlen(s));
           buff = openspace(strlen(s));
           sprintf(buff, form, s);
           sprintf(buff, form, s);
           break;
           break;
         }
         }
         case 'c':  case 'd':  case 'i': case 'o':
         case 'c':  case 'd':  case 'i': case 'o':
         case 'u':  case 'x':  case 'X':
         case 'u':  case 'x':  case 'X':
-          sprintf(buff, form, (int)luaL_check_number(arg++));
+          sprintf(buff, form, (int)luaL_check_number(arg));
           break;
           break;
         case 'e':  case 'E': case 'f': case 'g':
         case 'e':  case 'E': case 'f': case 'g':
-          sprintf(buff, form, luaL_check_number(arg++));
+          sprintf(buff, form, luaL_check_number(arg));
           break;
           break;
         default:  /* also treat cases 'pnLlh' */
         default:  /* also treat cases 'pnLlh' */
           lua_error("invalid format option in function `format'");
           lua_error("invalid format option in function `format'");