5.1 RTL macros

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

5.1 RTL macros

D Burgess-4
Further to trying to avoid changes to Lua source modules, I have created
the following macros for Lua 5.1. These macros were prompted by my
repeated changing the code on different platforms (e.g. no console,
no IO library) and the recent thread on Embedded Lua..

The changes which are minor and I think something like this would
be worthwile in a minor revision of 5.1.

The realloc/free macros exist because although one can override the
allocator with lua_newstate(), the libary code with the calls to
realloc and free means that they still get linked (whether called ot not).

For the lua library (not the standalone interpreter) and lua_loadfile() aside
this leaves liolib.c as the only module that contains any RTL file functions.

Let me know what you think,

David B.

** added to luaconf.h **

/*
** defines the only allocation functions used by lua
*/
#ifndef LUAI_REALLOC
#define LUAI_REALLOC(p,n) realloc((p),(n))
#endif
#ifndef LUAI_FREE
#define LUAI_FREE(x) free((x))
#endif

/*
** defines the output routine for atpanic() errors
*/
#ifndef LUAI_PRTERROR
#define LUAI_PRTERROR(x) fputs((x),stderr)
#endif
/*
** defines the output routine for print()
*/
#ifndef LUAI_PRTOUTPUT
#define LUAI_PRTOUTPUT(x) fputs((x),stdout)
#endif
/*
** defines the console input mechanism for debug.debug()
** undefine it if you have no console input or
** you do not require it
*/
#ifndef LUAI_CONINPUTLINE
#define LUAI_CONINPUTLINE(b,l) fgets((b), (l), stdin)
#endif
Reply | Threaded
Open this post in threaded view
|

Re: 5.1 RTL macros

Andreas Stenius-2
My vote goes in this direction too.

As it is, I patch all occurences of fputs et al, since I only have one
line of communication and doesn't use stdin/-out/-err..


//Andreas

Reply | Threaded
Open this post in threaded view
|

Re: 5.1 RTL macros

D Burgess-4
It occurs to me I forgot the readable() in loadlib.c
Reply | Threaded
Open this post in threaded view
|

Re: 5.1 RTL macros

Luiz Henrique de Figueiredo
In reply to this post by D Burgess-4
> Further to trying to avoid changes to Lua source modules, I have created
> the following macros for Lua 5.1.

> #ifndef LUAI_REALLOC
> #define LUAI_REALLOC(p,n) realloc((p),(n))
> #endif

The point being made by me and Roberto is that you could simply do this in
luaconf.h:

#define realloc myrealloc

Lua header files are included after system files precisely to allow this.
Or are we missing someting?
--lhf
Reply | Threaded
Open this post in threaded view
|

Re: 5.1 RTL macros

D Burgess-4
Yes, you right about the realloc(). I think it good in luaconf.h to
let everyone one know about the only two allocation routines that lua
uses. And it reminds me that I have to probably change it.

The primary issue for me here is the macroizing of the fgets/fputs usage
that exists in lauxlib.c ldblib.c and lbaselib.c.

To give real examples:

atpanic() - the puts gets an event log write and the refernce to
stderr is removed
because it does not exist. Or we add a syslog call. Or stderr is not
even defined.
The macro does not obviate the need for lua_atpanic().

print() in lbaselib() - my most common replacement is write(1,...).
Again the reference to stdout is problematic. It may work ok it may not.


debug.debug() in ldblib.c - the console input / output. The usual change is
to #ifdef the debug() function out of existence when we dont have a
stdin/stderr.

luaL_loadfile() in lauxlib.c for which I did not provide a luaconf
solution. This
is often a hassle. I usually just provide a total replacement function for
loading from; virtual file systems, os pipes, multi language file systems,
file IO with charset translation capabilities. Loading lua script exclusively
from resource files. And finally I suspect the embedders will always
change the lua_Reader. I concede that this is a tough one to generalize,
but it would be nice if the IO functions here could be easily macroed.
ungetc() does not help.

Let me reiterate that the main issue here is getting ANSI IO out of
all of the library code except liolib.c. This is a requirement when
fopen() et al are either unavailable or disfunctional.

thanks
David B


On 4/5/06, Luiz Henrique de Figueiredo <[hidden email]> wrote:

> > Further to trying to avoid changes to Lua source modules, I have created
> > the following macros for Lua 5.1.
>
> > #ifndef LUAI_REALLOC
> > #define LUAI_REALLOC(p,n) realloc((p),(n))
> > #endif
>
> The point being made by me and Roberto is that you could simply do this in
> luaconf.h:
>
> #define realloc myrealloc
>
> Lua header files are included after system files precisely to allow this.
> Or are we missing someting?
> --lhf
>
Reply | Threaded
Open this post in threaded view
|

Re: 5.1 RTL macros

Lisa Parratt
D Burgess wrote:
> ungetc() does not help.

ARGH! NO! THE HORRORS!

That gave me nightmares for weeks, that did. ungetc is a disgusting
abomination that shouldn't even exist, let alone be used.

--
Lisa
Reply | Threaded
Open this post in threaded view
|

Re: 5.1 RTL macros

David Jones-2

On Apr 05, 2006, at 12:27, Lisa Parratt wrote:

> D Burgess wrote:
>> ungetc() does not help.
>
> ARGH! NO! THE HORRORS!
>
> That gave me nightmares for weeks, that did. ungetc is a disgusting
> abomination that shouldn't even exist, let alone be used.

It's often useful in lexing.  The functionality of ungetc will always
be needed, and I think that's unavoidable.  So if it didn't exist then
lots of programs would end up implementing their own version of
Standard C IO streams, but with one byte of pushback.

I'm curious as to why you don't like it so much.  Is it buggy vendor
implementations? Non-portable C code that relied on more than one byte
of ungetc? Having to implement a C-like stream interface on top of an
abstraction that didn't provide anything like ungetc? Or something
else?

drj

Reply | Threaded
Open this post in threaded view
|

Re: 5.1 RTL macros

D Burgess-4
David Jones wrote:
>  Having to implement a C-like stream interface on top of an
> abstraction that didn't provide anything like ungetc?

Excellent guess. Does not port so well and yes the the
code to handle  is not difficult, but I would rather not
write the code.

DB
Reply | Threaded
Open this post in threaded view
|

Re: 5.1 RTL macros

Lisa Parratt
In reply to this post by David Jones-2
David Jones wrote:
> It's often useful in lexing.  The functionality of ungetc will always be
> needed, and I think that's unavoidable.  So if it didn't exist then lots
> of programs would end up implementing their own version of Standard C IO
> streams, but with one byte of pushback.

Meh - few excuses that still hold in this day and age for not buffering
in memory before processing, imho.

> I'm curious as to why you don't like it so much.  Is it buggy vendor
> implementations? Non-portable C code that relied on more than one byte
> of ungetc? Having to implement a C-like stream interface on top of an
> abstraction that didn't provide anything like ungetc? Or something else?

All of the above. It also adds a special case when coding
implementations - makes the code fugly imho.

--
Lisa
Reply | Threaded
Open this post in threaded view
|

Re: 5.1 RTL macros

David Jones-2

On Apr 05, 2006, at 14:05, Lisa Parratt wrote:

> David Jones wrote:
>> It's often useful in lexing.  The functionality of ungetc will always
>> be needed, and I think that's unavoidable.  So if it didn't exist
>> then lots of programs would end up implementing their own version of
>> Standard C IO streams, but with one byte of pushback.
>
> Meh - few excuses that still hold in this day and age for not
> buffering in memory before processing, imho.

Well, implementing ones own buffering is less-efficient, error prone,
and not always simple.  How do I decide which bit to buffer?  Is my
buffer a single array, in which case how do I arrange access to
previous bytes (like ungetc) without copying; or is it multiple arrays,
in which case how do I provide a natural access to the bytes within it?

In fact I think C is increasingly deployed in smaller and smaller
devices.  The 8-bit microcontrollers are growing up to a point where
they can feasibly implement a reasonable approximation to C.  The
desktop and server machines are so fast that people are switching away
from C and to languages like Python for interactive GUIs.

Personally, if I'm programming for a system that's big enough to
implement mmap() (or equivalent) then I probably want to be using
Python, not C.  Conversely, if I'm using C, I'm not likely to be on a
very big system and I probably do want to look after my bytes.

>> I'm curious as to why you don't like it so much.  Is it buggy vendor
>> implementations? Non-portable C code that relied on more than one
>> byte of ungetc? Having to implement a C-like stream interface on top
>> of an abstraction that didn't provide anything like ungetc? Or
>> something else?
>
> All of the above. It also adds a special case when coding
> implementations - makes the code fugly imho.

So in a world where ungetc didn't exist, do you think the two uses of
it in lua would be made any simpler?  Because one has to weigh up the
ugliness of a support library against the ugliness of applications
using that library.

drj

Reply | Threaded
Open this post in threaded view
|

Re: 5.1 RTL macros

David Jones-2
In reply to this post by D Burgess-4

On Apr 05, 2006, at 12:58, D Burgess wrote:

> David Jones wrote:
>>  Having to implement a C-like stream interface on top of an
>> abstraction that didn't provide anything like ungetc?
>
> Excellent guess. Does not port so well and yes the the
> code to handle  is not difficult, but I would rather not
> write the code.

Well, nor would I.  That's why I'm glad it's specified in the C
standard so that somebody else can write it, and I can moan about how
bad their implementation is instead.

So how do you suggest the two bits of Lua that use ungetc are changed
so that they don't use ungetc?

drj

Reply | Threaded
Open this post in threaded view
|

Re: 5.1 RTL macros

D Burgess-4
David Jones wrote:
> So how do you suggest the two bits of Lua that use ungetc are changed
> so that they don't use ungetc?

in lauxlib.c

typedef struct LoadF {
  int extraline;
+  int firstchar;
  LUA_FILE f;
  char buff[LUAL_BUFFERSIZE];
} LoadF;

in the getF function
+  if (lf->firstchar != (int)-1) {
+   lf->buff[0] = (char)lf->firstchar;
+    lf->firstchar = (int)-1;
+    *size=1;
+   return lf->buff;
+  }
Reply | Threaded
Open this post in threaded view
|

Re: 5.1 RTL macros

David Jones-2

On Apr 06, 2006, at 01:26, D Burgess wrote:

> David Jones wrote:
>> So how do you suggest the two bits of Lua that use ungetc are changed
>> so that they don't use ungetc?
>
> in lauxlib.c
>
> typedef struct LoadF {
>   int extraline;
> +  int firstchar;
>   LUA_FILE f;
>   char buff[LUAL_BUFFERSIZE];
> } LoadF;
>
> in the getF function
> +  if (lf->firstchar != (int)-1) {
> +   lf->buff[0] = (char)lf->firstchar;
> +    lf->firstchar = (int)-1;
> +    *size=1;
> +   return lf->buff;
> +  }

Didn't you just tell me that you didn't want to implement ungetc
yourself?

This is buggy.  In C a char can be negative for representations of
characters that are not in the required execution character set.

drj