krfkeith / minimac

Automatically exported from code.google.com/p/minimac
0 stars 0 forks source link

Quoting doesn't work properly when the quotes contain only a macro and are alone on a line. #2

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Invoke mm.
2. Type `hello`hi there!`, followed by a carriage return, and then ~hello~
followed by another carriage return.
3. mm will print 'hi there!' instead of the expected 'hello' (contrary to
the example in the manual).

What is the expected output? What do you see instead?

You'd expect anything between ~ and ~ to be printed literally without
expansions. However, if all that's between the tildae is a single macro
expansion, this doesn't happen: the macro is expanded when it ought not be.

What version of the product are you using? On what operating system?

I'm using version 0.2.3-alpha on Ubuntu Jaunty. I compiled using "make
-Wall -o mm mm-0.2.3-alpha.c"

Please provide any additional information below.

Sample input/output:

+ mm
`hello`hi there!`
~hello~
hi there!
"hello"
"hello"
"$hello$"
"hi there!"
~hello
~
hello

~hello~
hi there!
~hello ~
hello 
~hello~
hi there!
+

A bit of playing around with gdb reveals the problem:
This only happens when the next character after the ending ~ is a character
that forces expansion. The quoted string is then expanded alone, and if it
is exactly a macro expansion, then the result is that the quoted string
gets expanded. A simple fix is to edit line 2117:

2116:  case QUOTING:
2117:   if(c==quote_c){ state=EXPANDING; outc(b, bz); reset(); return; }

The outc and reset there push the buffer immediately into the output and
then reset it, without checking for macro expansions. As I understand it,
the buffer should only go back to the beginning of the quoted region that
is now ending, so we're not missing any macros that might be in the buffer
which should be expanded. However, this changes the program's behavior. As
it is now, you can quote, say, the first half of a macro, and then put the
rest outside quotes and get a valid macro that gets substituted, like this:

+ mm
`hello`hi`
~hel~lo
hi
+

With the modification in place, this technique no longer works, and you'd get:

+ mm
`hello`hi`
~hel~lo
hello
+

To get both behaviors, you'd probably need to add some more complicated
logic when you hit a $ or newline: check whether the expansion buffer
contains only a quoted string, and decide to expand or not based on that.

Of course, you could decide that this is desired behavior, and just change
the example in the manual.

Finally, I'd just like to say that I'm a huge fan of mm. I needed a
*simple* macro language that I could learn quickly and that would work
gracefully with the code that I had. MM is exactly that, without many of
the limitations of gcc and without the insane complexity of m4. Plus, it's
super-lightweight. Seriously, you rock!

Original issue reported on code.google.com by pmawhor...@gmail.com on 10 Oct 2009 at 5:54

GoogleCodeExporter commented 8 years ago
Hmmm... well, it looks like my quick fix comes with some other problems. Using 
the
simple outc() call, you can no longer push quoted strings onto the stack. This 
is
certainly bad behavior, so it looks like this issue will either need a more
complicated fix, or just a change to the manual to note the unexpected behavior 
when
a quoted macro ends a line.

Original comment by pmawhor...@gmail.com on 10 Oct 2009 at 7:45

GoogleCodeExporter commented 8 years ago
I haven't looked at the source in some months, it will be a few days before I 
get a
chance to wrap my head around it again.

Thanks for the very clear write-up on the issue, and your very kind and 
encouraging
feedback.

Original comment by mwhi...@gmail.com on 11 Oct 2009 at 2:29