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}
 
@@ -38,7 +38,7 @@ Waldemar Celes
 \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
 
@@ -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.
 Please notice that the code shown here is only illustrative;
 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)
 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}
 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.
 \begin{verbatim}
       function setglobal (varname, newvalue)
@@ -1280,7 +1280,7 @@ returns a reference to the object at the top of the C2lua stack,
 and pops it.
 
 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,
 the function \verb|lua_pushusertag| may create a new userdata.
@@ -1885,6 +1885,15 @@ will produce the string:
  new line"
 \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|,
 \verb|g| \verb|i|, \verb|o|, \verb|u|, \verb|X|, and \verb|x| all
 expect a number as argument,

+ 16 - 10
strlib.c

@@ -3,7 +3,7 @@
 ** 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 <stdio.h>
@@ -468,7 +468,7 @@ void luaI_addquoted (char *s)
 static void str_format (void)
 {
   int arg = 1;
-  char *strfrmt = luaL_check_string(arg++);
+  char *strfrmt = luaL_check_string(arg);
   luaI_emptybuff();  /* initialize */
   while (*strfrmt) {
     if (*strfrmt != '%')
@@ -478,29 +478,35 @@ static void str_format (void)
     else { /* format item */
       char form[MAX_FORMAT];      /* store the format ('%...') */
       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? */
         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 */
       switch (*strfrmt++) {
         case 'q':
-          luaI_addquoted(luaL_check_string(arg++));
+          luaI_addquoted(luaL_check_string(arg));
           continue;
         case 's': {
-          char *s = luaL_check_string(arg++);
+          char *s = luaL_check_string(arg);
           buff = openspace(strlen(s));
           sprintf(buff, form, s);
           break;
         }
         case 'c':  case 'd':  case 'i': case 'o':
         case 'u':  case 'x':  case 'X':
-          sprintf(buff, form, (int)luaL_check_number(arg++));
+          sprintf(buff, form, (int)luaL_check_number(arg));
           break;
         case 'e':  case 'E': case 'f': case 'g':
-          sprintf(buff, form, luaL_check_number(arg++));
+          sprintf(buff, form, luaL_check_number(arg));
           break;
         default:  /* also treat cases 'pnLlh' */
           lua_error("invalid format option in function `format'");