DavidKinder / Inform6

The latest version of the Inform 6 compiler, used for generating interactive fiction games.
http://inform-fiction.org/
Other
208 stars 35 forks source link

-a prints unprintable chars when abbreviations are applied #292

Closed heasm66 closed 4 months ago

heasm66 commented 6 months ago

In disassembly (-a), @print and @print_ret prints unprintable characters (ascii 1) when printing a string containing an abbreviation.

206  +00092 <*> print        "w���"

This is because translate_text in text.c modifies the text_in parameter when applying the abbreviation by replacing the text that is being abbreviated with values of 1 instead of the characters.

The assembly are printed after the call to translate_text and is therefore mangled.

One easy fix would be to make a local undamaged copy of the text before the call to translate_text in assemblez_instruction and use it instead when printing tthe assembly.

heasm66 commented 6 months ago

Suggestion:

 998   extern void assemblez_instruction(const assembly_instruction *AI)
 999   {
1000       int32 operands_pc;
1001       int32 start_pc;
1002       int32 offset, j, topbits=0, types_byte1, types_byte2;
1003       int operand_rules, min=0, max=0, no_operands_given, at_seq_point = FALSE;
1004       assembly_operand o1, o2;
1005       opcodez opco;
     +     char text_temp[35];
1006    
1007       ASSERT_ZCODE();
...
1081       if (operand_rules==TEXT)
1082       {   int32 i;
     +         for (i = 0; i < 35; i++) text_temp[i] = AI->text[i]; //Copy uncorrupted text
1083           j = translate_text(-1, AI->text, STRCTX_GAMEOPC);
1084          if (j < 0) {
1085               error("text translation failed");
1086               j = 0;
1087           }
...
1199       Instruction_Done:
1200
1201       if (asm_trace_level > 0)
1202      {   int i;
1203           printf("%5d  +%05lx %3s %-12s ", ErrorReport.line_number,
1204               ((long int) offset),
1205               (at_seq_point)?"<*>":"   ", opco.name);
1206
1207           if ((AI->internal_number == print_zc)
1208               || (AI->internal_number == print_ret_zc))
1209           {   printf("\"");
1210 -             for (i=0;(AI->text)[i]!=0 && i<35; i++) printf("%c",(AI->text)[i]);
1210 +             for (i=0;(AI->text)[i]!=0 && i<35; i++) printf("%c",text_temp[i]);
1211              if (i == 35) printf("...");
1212               printf("\"");
1213          }
erkyrath commented 5 months ago

Since this is for tracing, I think it's better to print an abbreviation marker. (I've tried hard to get rid of all the fixed-length string buffers!)

heasm66 commented 5 months ago

That explains why I had a hard time finding any internal example for a short temp string...

The actual text isn't especially important so an abbreviation marker is perfectly fine.

erkyrath commented 4 months ago

Fixed in https://github.com/DavidKinder/Inform6/pull/293 .