Inform - Support - Patches

About Patches  

Compiler  
Library  

DM4 Errata  

Issue C63004     [previous patch]

Special characters in Glulx abbreviations
Submitted by: Miron Schmidt     Appeared in: Compiler 6.30 or before     Fixed in: -
Problem

When special characters appear in abbreviation strings, Glulx Inform interprets them literally. For example, when the game includes the directive, Abbreviate "^ "; then it's not possible anymore to have the string "^ " print a new_line followed by a space. Instead, the literal string is printed. This doesn't happen when compiled for the Z-machine.

Here's a little example code to demonstrate:

  !% -e ! Use abbreviations

  Abbreviate "^ ";
  Abbreviate "~ ";
  Abbreviate "@@64miron";

  Include "Parser";
  Include "VerbLib";

  Object Room "Room" with description "A room." has light;

  [ Initialise;
      location = Room;
      new_line; new_line;
      print "First line.^ ^";
      print "~ Second line.~ ^";
      print "miron@@64mironseigenedomain.de^";
     new_line; new_line;
  ];

  Include "Grammar";
Solution (by David Kinder)

Apply this patch:

--- inform/compiler/header.h 2004-02-22 10:33:14.125000000 +0000
+++ header.h 2004-04-04 22:01:39.421875000 +0100
@@ -2525,6 +2525,7 @@
 extern int   no_abbreviations;
 extern int   abbrevs_lookup_table_made, is_abbreviation;
 extern uchar *abbreviations_at;
+extern uchar *abbreviations_gl;
 extern int  *abbrev_values;
 extern int  *abbrev_quality;
 extern int  *abbrev_freqs;
--- inform/compiler/files.c 2004-01-07 19:21:20.734375000 +0000
+++ files.c 2004-04-04 22:12:07.125000000 +0100
@@ -233,7 +233,7 @@
     (*size) += 1;
     break;
   case 3:
-    cx = (char *)abbreviations_at + ent->u.val*MAX_ABBREV_LENGTH;
+    cx = (char *)abbreviations_gl + ent->u.val*MAX_ABBREV_LENGTH;
     while (*cx) {
       sf_put(*cx);
       cx++;
--- inform/compiler/text.c 2004-01-07 19:22:17.828125000 +0000
+++ text.c 2004-04-04 22:33:02.234375000 +0100
@@ -41,8 +41,10 @@
                                           with ASCII character n, or -1
                                           if none of the abbreviations do    */
 int no_abbreviations;                  /* No of abbreviations defined so far */
-uchar *abbreviations_at;                 /* Memory to hold the text of any
+uchar *abbreviations_at;               /* Memory to hold the text of any
                                           abbreviation strings declared      */
+uchar *abbreviations_gl;               /* Memory to hold the Glulx encoded
+                                          text of abbreviations              */
 /* ------------------------------------------------------------------------- */
 /*   Glulx string compression storage                                        */
 /* ------------------------------------------------------------------------- */
@@ -134,6 +136,11 @@
                     abbrev_values[k]=l;
                     l=abbrev_quality[j]; abbrev_quality[j]=abbrev_quality[k];
                     abbrev_quality[k]=l;
+                    if (glulx_mode && compression_switch) {
+                      p1=(char *)abbreviations_gl+j*MAX_ABBREV_LENGTH;
+                      p2=(char *)abbreviations_gl+k*MAX_ABBREV_LENGTH;
+                      strcpy(p,p1); strcpy(p1,p2); strcpy(p2,p);
+                    }
                     bubble_sort = TRUE;
                 }
             }
@@ -182,14 +189,31 @@
 }

 extern void make_abbreviation(char *text)
-{
+{ int ats = 0; char *p1, *p2;
+
     strcpy((char *)abbreviations_at
             + no_abbreviations*MAX_ABBREV_LENGTH, text);
+    p1 = strings_holding_area;

     is_abbreviation = TRUE;
     abbrev_values[no_abbreviations] = compile_string(text, TRUE, TRUE);
     is_abbreviation = FALSE;

+    if (glulx_mode && compression_switch) {
+      /* Copy the translated text, but, since abbreviations are */
+      /* printed literally in Glulx, convert '@@' to just '@'   */
+      p2 = (char *)abbreviations_gl + no_abbreviations*MAX_ABBREV_LENGTH;
+      while (*p1 != '\0') {
+        if (*p1 == '@') {
+          ats++; if (ats == 2) {
+            ats = 0; p1++; continue;
+          }
+        } else ats = 0;
+        *p2++ = *p1++;
+      }
+      *p1 = '\0';
+    }
+
     /*   The quality is the number of Z-chars saved by using this            */
     /*   abbreviation: note that it takes 2 Z-chars to print it.             */

@@ -1006,7 +1030,7 @@
     compression_table_size += 2;
     break;
   case 3:
-    cx = (char *)abbreviations_at + ent->u.val*MAX_ABBREV_LENGTH;
+    cx = (char *)abbreviations_gl + ent->u.val*MAX_ABBREV_LENGTH;
     compression_table_size += (1 + 1 + strlen(cx));
     break;
   case 9:
@@ -2081,6 +2105,8 @@
           "huffman entities");
         hufflist = my_calloc(sizeof(huffentity_t *), MAX_CHARACTER_SET,
           "huffman node list");
+        abbreviations_gl = my_malloc(MAX_ABBREVS*MAX_ABBREV_LENGTH,
+          "abbrev glulx text");
       }
       compressed_offsets = my_calloc(sizeof(int32), MAX_NUM_STATIC_STRINGS,
         "static strings index table");
@@ -2092,6 +2118,7 @@
     my_free(&strings_holding_area, "static strings holding area");
     my_free(&low_strings, "low (abbreviation) strings");
     my_free(&abbreviations_at, "abbreviations");
+    my_free(&abbreviations_gl, "abbrev glulx text");
     my_free(&abbrev_values,    "abbrev values");
     my_free(&abbrev_quality,   "abbrev quality");
     my_free(&abbrev_freqs,     "abbrev freqs");


Last updated 17 April 2013. This web site has not been fully supported since April 2008. Information may be out of date. This page was originally managed by Roger Firth.