首页 > 代码库 > Lua2.4 打开文件 inout.c
Lua2.4 打开文件 inout.c
这里根据 luac.c 里的函数调用顺序,依次展开相关的代码。首先要看的就是 lua_openfile,该函数定义于 inout.c 中:
/* ** Function to open a file to be input unit. ** Return the file. */ FILE *lua_openfile (char *fn) { lua_setinput (fileinput); if (fn == NULL) { fp = stdin; fn = "(stdin)"; } else fp = fopen (fn, "r"); if (fp == NULL) return NULL; lua_linenumber = 1; lua_parsedfile = luaI_createfixedstring(fn)->str; return fp; }
函数一开始调用 lua_setinput,传给它一个函数指针。
lua_setinput 定义于 lex.c 中,给词法分析器一个函数指针,以后词法分析程序需要从该函数指针中得到一个个的输入字符。
这里 lua_setinput 的实际输入参数是 fileinput,fileinput 定义如下:
/* ** Function to get the next character from the input file */ static int fileinput (void) { return fgetc (fp); }
可以看出,这个函数的作用就是每次调用它时从文件中取得一个字符。
回到 lua_openfile ,如果传入的文件名为空,则程序认为从标准输入读入内容。设置文件描述符为标准输入 stdin,设置它的文件名为 “(stdin)”。
如果传入正常的文件名,则打开它。如果打开失败,返回 NULL。
设置当前的行号为 1。
设置当前的要分析的文件为当前打开的文件。luaI_createfixedstring 函数是在 Lua 的字符串存储空间中生成一个不可回收的字符串,这个方法以后会提到。
最后,函数返回文件描述符 fp;
lua_openfile 分析完了。
再看看相应的 lua_closefile
/* ** Function to close an opened file */ void lua_closefile (void) { if (fp != NULL && fp != stdin) { fclose (fp); fp = NULL; } }
这个函数就是关闭由 lua_openfile 打开的文件。
lua_openstring, lua_closestring 和上面的打开关闭文件的操作类似,就不再重复了。
注意,lua_openstring 时,给它设置的文件名为 "(string)", 这个格式和上面的以标准输入为输入文件的文件名格式相同。
这样是为了程序上的统一,就是看到文件是一个括号里有一个字符串,就知道文件并非真正的文件,而只是为了维持写程序时概念上的统一。
这也是写程序中比较常用的技巧,就是把特例转化为某种特殊的一般情况。
到这里,和编译器相关的 inout.c 中的内容已经说完了。这里可以回答在编译器那里提出的 compile 里打开关闭文件相关的问题了。
那里提出的为什么要调用 lua_openfile 这样的问题,这里解答一下,把输入输出这样的放到一块是出于设计上的考量,程序结构很清晰。
再夸一句,Lua 的设计做的很好,模块化做得很漂亮,代码质量也很高。
luac.c 里提到和打开关闭文件相关的问题已经解答了。不过,在上面的看代码的过程中又发现一些新的问题,列在下面:
> lua_setinput 在词法分析里的作用?相关的词法分析内容又是什么?
> luaI_createfixedstring 是什么? 那个 TaggedString 是个什么数据结构?
记点题外话,其实也不算是偏题太远。目前计划的是 Lua2.4 先跟编译器这条线儿,这条线儿结束了,再看看解释器那条。只看代码,写代码相关的东西,原理性的东西,不影响解释的情况下,尽量少说。因为原理性的东西,网上还是比较多的,相关的书籍也有很多。这里说的原理性的东西主要是指编译原理相关的。
----------------------------------------
记一下到目前为止的问题:
inout.c
> lua_setinput 在词法分析里的作用?相关的词法分析内容又是什么?
> luaI_createfixedstring 是什么? 那个 TaggedString 是个什么数据结构?
luac.c
> do_compile 里的 TFunc 是什么?那个初始化 luaI_initTFunc 是什么?
> lua_parser 是什么? do_dump 方法里调的那几个方法又分别是干什么的?
----------------------------------------
Lua2.4 打开文件 inout.c