texlive[46684] Build/source/texk/web2c/mfluadir: added generic font

commits+lscarso at tug.org commits+lscarso at tug.org
Tue Feb 20 11:17:33 CET 2018


Revision: 46684
          http://tug.org/svn/texlive?view=revision&revision=46684
Author:   lscarso
Date:     2018-02-20 11:17:32 +0100 (Tue, 20 Feb 2018)
Log Message:
-----------
added generic font parser to mflua.lua

Modified Paths:
--------------
    trunk/Build/source/texk/web2c/mfluadir/ChangeLog
    trunk/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua

Modified: trunk/Build/source/texk/web2c/mfluadir/ChangeLog
===================================================================
--- trunk/Build/source/texk/web2c/mfluadir/ChangeLog	2018-02-20 05:44:02 UTC (rev 46683)
+++ trunk/Build/source/texk/web2c/mfluadir/ChangeLog	2018-02-20 10:17:32 UTC (rev 46684)
@@ -2,9 +2,9 @@
 
 	* MFLua 0.9.
 	* Fixed a bug on clean up string in runscript.
+	* Added generic font parser to mflua.lua
 
 
-
 2017-04-16 Luigi Scarso <luigi.scarso at gmail.com>
 
 	* MFLua 0.8. New primitive runscript, cleanup of the Lua code.

Modified: trunk/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua
===================================================================
--- trunk/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua	2018-02-20 05:44:02 UTC (rev 46683)
+++ trunk/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua	2018-02-20 10:17:32 UTC (rev 46684)
@@ -2855,3 +2855,938 @@
 
 
 
+--------------------------------------------------------------------------------
+--
+-- gf module
+--
+--------------------------------------------------------------------------------
+--
+-- In-memory parser, i.e. reads all the gf into memory
+-- and then parses the byte stream
+--
+
+local GF =   {}
+do 
+
+   local sub	= string.sub
+   local len	= string.len
+   local byte	= string.byte
+   local format	= string.format
+   local rep     = string.rep
+
+   local gfdata=''
+   local gfdata_index
+   local gfdata_len
+
+   local chars={}
+   local current_char
+   local current_row  -- aka n
+   local current_col  -- aka m
+   local white=0
+   local black=white+1
+   local paint_switch
+   chars.xxx1 = {}
+   chars.xxx2 = {}
+   chars.xxx3 = {}
+   chars.xxx4 = {}
+   chars.yyy  = {}
+   chars.nop  = {}
+   chars.all_nop = {} -- collect a xxx1 or xxx2 or xxx3 or xxx4 or yyy or nop
+   chars.locators = {}
+
+
+
+
+   local defDEBUG = false
+   local function DEBUG(k,s)
+      print("DEBUG:"..tostring(k).."="..tostring(s))
+   end
+
+
+   local function error_msg(msg)
+      io.write(format("! mflua GF: char %s: %s",current_char, msg))
+      io.write(format(" position=%s ",gfdata_index))
+      print()
+   end
+   GF.error = error_msg
+
+   local function warning_msg(msg)
+      print(format("\n! mflua GF: char %s: %s.",current_char, msg))
+   end
+   GF.warning = warning_msg
+
+
+
+   --
+   -- read n bytes starting from from gfdata_index included
+   -- and move gfdata_index
+   --
+   local function readbytes(n)
+      if (gfdata_index+n-1)<1 then 
+	 GF.warning("attempt to read before the beginning of the file")
+	 return nil
+      end
+      if (gfdata_index+n-1)>gfdata_len then
+	 GF.warning("attempt to read beyond the end of the file")
+	 return nil
+      end
+      local s 
+      if (n<0) then
+	 s = sub(gfdata,gfdata_index+n+1,gfdata_index)
+      elseif n>0 then
+	 s = sub(gfdata,gfdata_index,gfdata_index+n-1)
+      else
+	 s =''
+      end
+      gfdata_index = gfdata_index+n
+      return s
+   end
+
+
+   local function read4bytes()
+      local b0 = byte(readbytes(1))
+      local b1 = byte(readbytes(1))
+      local b2 = byte(readbytes(1))
+      local b3 = byte(readbytes(1))
+      local v =  (b3+b2*256+b1*65536+b0*16777216)
+      if v >2147483647 then
+	 v = v -4294967296
+      end
+      return v
+   end
+
+
+   local function readrev4bytes()
+      local b3 = byte(readbytes(-1))
+      local b2 = byte(readbytes(-1))
+      local b1 = byte(readbytes(-1))
+      local b0 = byte(readbytes(-1))
+      local v =  (b3+b2*256+b1*65536+b0*16777216)
+      if v >2147483647 then
+	 v = v -4294967296
+      end
+      return v
+   end
+
+
+   local function readuntileof()
+      if gfdata_index>gfdata_len then 
+	 GF.warning("wrong index")
+	 return nil
+      end
+      local s = sub(gfdata,gfdata_index,gfdata_len)
+      gfdata_index = gfdata_len +1
+      return s
+   end
+
+
+   local function datanotfinished()
+      return (gfdata_index <= gfdata_len)
+   end
+
+
+   local function moveindex_after(p)
+      gfdata_index = p+1
+   end
+
+
+
+   error = {}
+   error.ok = 0
+   error.base = error.ok
+   error.pre	= error.base +1
+   error.parse	= error.base +2
+   error.post	= error.base +3
+   error.boc       = error.base +4
+   error.load	= error.base +127
+   error.parse    	= error.base +128
+   error.parsechar	= error.base +129
+   error.paint	= {}
+   for j=0,63 do
+      error.paint[j]	= error.base +130+j
+   end
+   error.paint_switch=error.base +130+64
+   error.paint1    = error.base +130+64+1
+   error.paint2    = error.base +130+64+2
+   error.paint3    = error.base +130+64+3
+   error.eoc       = error.base +130+64+6
+   error.skip0     = error.base +130+64+7
+   error.skip1     = error.base +130+64+8
+   error.skip2     = error.base +130+64+9
+   error.skip3     = error.base +130+64+10
+   error.new_row   = {}
+   for j=0,164 do
+      error.new_row[j]= error.base +130+64+10+1+j
+   end
+
+   error.post_post=error.base +130+64+10+1+165
+
+   error.skip223=error.base +130+64+10+1+166
+
+
+   error_name_t = {}
+   for  k,v in pairs(error) do
+      error_name_t[v] = k
+   end
+   local function error_name(res)
+      if res==nil then
+	 return "unknown error code"
+      elseif error_name_t[res] == nil then
+	 return "unknown error code"
+      else
+	 return error_name_t[res]
+      end
+   end
+
+   local opcodes = {}
+
+   -- {beginning of the \\{paint} commands}
+   for j=0,63 do
+      local s = format("paint_%d",j)
+      opcodes[s] = j
+   end
+   opcodes.paint1=64	-- {move right a given number of columns, then   black${}\swap{}$white}
+   opcodes.paint2=65
+   opcodes.paint3=66
+   opcodes.boc=67		-- {beginning of a character}
+   opcodes.boc1=68		-- {short form of |boc|}
+   opcodes.eoc=69		-- {end of a character}
+   opcodes.skip0=70	-- {skip no blank rows}
+   opcodes.skip1=71	-- {skip over blank rows}
+   opcodes.skip2=72	
+   opcodes.skip3=73
+   --opcodes.new_row_0=74	-- {move down one row and then right}
+   --:
+   --opcodes.new_row_164=238
+   for j=0,164 do
+      local s = format("new_row_%d",j)
+      opcodes[s] = j+74
+   end
+
+   --opcodes.max_new_row=164	-- {the largest \\{new\_row} command is |new_row_164|}
+   opcodes.xxx1=239	-- {for \&{special} strings}
+   opcodes.xxx2=240
+   opcodes.xxx3=241	-- {for long \&{special} strings}
+   opcodes.xxx4=242
+   opcodes.yyy=243		-- {for \&{numspecial} numbers}
+   opcodes.nop=244		-- no operation
+   opcodes.char_loc=245	-- {character locators in the postamble}
+   opcodes.char_loc0=246
+   opcodes.pre=247		-- {preamble}
+   opcodes.post=248	-- {postamble beginning}
+   opcodes.post_post=249	-- {postamble ending} 
+
+   opcodes.undefined_1=250
+   opcodes.undefined_2=251
+   opcodes.undefined_3=252
+   opcodes.undefined_4=253
+   opcodes.undefined_5=254
+   opcodes.undefined_6=255
+
+   local revopcode = {}
+   for k,v in pairs(opcodes) do revopcode[v] = k end
+
+
+
+   complement_paint_switch = function()
+      local res = error.ok
+      if( paint_switch==black or paint_switch==white) then
+	 paint_switch=(paint_switch+1)%2
+      else
+	 GF.error("wrong value for paint_switch")
+	 res = error.paint_switch
+      end
+      return res
+   end
+
+   local paint = function(n)
+      local res = error.ok
+      local c = chars[current_char]
+      local row = c[current_row] 
+      if row==nil then
+	 GF.error("error in paint_"..tostring(n)..", row is nil")
+      end
+      if paint_switch==black then
+	 for i=current_col,current_col+n-1 do
+	    row[i]=true
+	 end
+      end
+      res = complement_paint_switch()
+      current_col = current_col + n
+      if res~=error.ok then
+	 if n<64 then
+	    GF.error("error in paint_"..tostring(n))
+	    res = error.paint[n]
+	 elseif  (64<=n and n<256) then
+	    GF.error("error in paint1")
+	    res = error.paint1
+	 elseif (256<=n and n<65536) then
+	    GF.error("error in paint2")
+	    res = error.paint2
+	 elseif (65536<=n and n<16777216) then
+	    GF.error("error in paint3")
+	    res = error.paint3
+	 end
+      end
+      return res
+   end
+
+
+   opcodes.func = {}
+
+
+   opcodes.func[opcodes.paint_0]= function()
+      local res = error.ok
+      res = complement_paint_switch()
+      if res~=error.ok then
+	 GF.error("error in paint_0")
+	 res = error.paint[0]
+      end
+      return res
+   end
+
+   --opcodes.func[opcodes.paint_1]= function() return paint(1) end
+   --:
+   --opcodes.func[opcodes.paint_63]= function() return paint(63) end
+   for i=1, 63 do
+      local key = format("paint_%d",i)
+      local index = opcodes[key]
+      opcodes.func[index] = function() return paint(i) end
+   end 
+
+   opcodes.func[opcodes.paint1]= function()
+      local res = error.ok
+      local b = byte(readbytes(1))
+      if (64<=b and b<256) then
+	 paint(b)
+      else
+	 GF.error("wrong value " ..tostring(b) .. " in paint1")
+	 res = error.paint1
+      end
+      return res
+   end
+
+
+   opcodes.func[opcodes.paint2]= function()
+      local res = error.ok
+      local b1 = byte(readbytes(1))
+      local b2 = byte(readbytes(1))
+      local b = b2+b1*256
+      if (256<=b and b<65536) then
+	 paint(b)
+      else
+	 GF.error("wrong value " ..tostring(b) .. " in paint2")
+	 res = error.paint2
+      end
+      return res
+   end
+
+
+
+   opcodes.func[opcodes.paint3]= function()
+      local res = error.ok
+      local b1 = byte(readbytes(1))
+      local b2 = byte(readbytes(1))
+      local b3 = byte(readbytes(1))
+      local b  = b3+b2*256+ (b1*65536)
+      if (65536<=b and b<16777216) then
+	 paint(b)
+      else
+	 GF.error("wrong value " ..tostring(b) .. " in paint3")
+	 res = error.paint3
+      end
+      return res
+   end
+
+
+   opcodes.func[opcodes.boc]= function()
+      local pos = gfdata_index
+      local c = read4bytes()
+      local p = read4bytes()
+      local min_m = read4bytes()
+      local max_m = read4bytes()
+      local min_n = read4bytes()
+      local max_n = read4bytes()
+      current_char = c
+      chars[current_char] = chars[current_char] or {}
+      chars[current_char]['p'] = p
+      chars[current_char]['max_m'] = max_m
+      chars[current_char]['min_m'] = min_m
+      chars[current_char]['max_n'] = max_n
+      chars[current_char]['min_n'] = min_n
+      chars[current_char]['opened'] = true
+      chars[current_char]['stream_pos'] = gfdata_index
+      chars[current_char]['max_col'] = max_m
+      chars[current_char]['min_col'] = min_m
+      chars[current_char]['max_row'] = max_n
+      chars[current_char]['min_row'] = min_n
+      current_col = min_m
+      current_row = max_n 
+      chars[current_char][current_row]={}
+      paint_switch = white
+      return error.ok
+   end
+
+
+   opcodes.func[opcodes.boc1]= function()
+      local pos = gfdata_index
+      local c = byte(readbytes(1))
+      local del_m = byte(readbytes(1))
+      local max_m = byte(readbytes(1))
+      local del_n = byte(readbytes(1))
+      local max_n = byte(readbytes(1))
+      local p = -1
+      local min_m = max_m - del_m
+      local min_n = max_n - del_n
+      current_char = c
+      chars[current_char] = chars[current_char] or {}
+      chars[current_char]['p'] = p
+      chars[current_char]['max_m'] = max_m
+      chars[current_char]['min_m'] = min_m
+      chars[current_char]['max_n'] = max_n
+      chars[current_char]['min_n'] = min_n
+      chars[current_char]['opened'] = true
+      chars[current_char]['stream_pos'] = gfdata_index
+      chars[current_char]['max_col'] = max_m
+      chars[current_char]['min_col'] = min_m
+      chars[current_char]['max_row'] = max_n
+      chars[current_char]['min_row'] = min_n
+      current_col = min_m
+      current_row = max_n
+      chars[current_char][current_row]={}
+      paint_switch = white
+      return error.ok
+   end
+
+
+   opcodes.func[opcodes.eoc]= function()
+      local res = error.ok
+      if chars[current_char].opened == true then
+	 chars[current_char].opened = false
+	 res = error.ok
+      else
+	 GF.error("error closing char")
+	 res = error.eoc
+      end
+      --
+      -- use them as stack to tie the nop 
+      -- opcodes to current_char
+      table.insert(chars.xxx1,{current_char,-1})
+      table.insert(chars.xxx2,{current_char,-1})
+      table.insert(chars.xxx3,{current_char,-1})
+      table.insert(chars.xxx4,{current_char,-1})
+      table.insert(chars.yyy,{current_char,-1})
+      table.insert(chars.nop,{current_char,-1})
+      table.insert(chars.all_nop,{'eoc',current_char,-1})
+      return res  
+   end
+
+
+   opcodes.func[opcodes.skip0]= function()
+      if chars[current_char]==nil or chars[current_char].min_m==nil then
+	 GF.error("error in skip0")
+	 return error.skip0
+      end
+      current_row = current_row -1 
+      current_col = chars[current_char].min_m
+      paint_switch = white
+      chars[current_char][current_row]={}
+      return error.ok
+   end
+
+
+   opcodes.func[opcodes.skip1]= function()
+      if chars[current_char]==nil or chars[current_char].min_m==nil then
+	 GF.error("error in skip1")
+	 return error.skip1
+      end
+      local b = byte(readbytes(1))
+      current_row = current_row -(b+1) 
+      current_col = chars[current_char].min_m
+      paint_switch = white
+      chars[current_char][current_row]={}
+      return error.ok
+   end
+
+
+   opcodes.func[opcodes.skip2]= function()
+      if chars[current_char]==nil or chars[current_char].min_m==nil then
+	 GF.error("error in skip2")
+	 return error.skip2
+      end
+      local b0 = byte(readbytes(1))
+      local b1 = byte(readbytes(1))
+      local b =  b1+256*b0
+      current_row = current_row - (b+1) 
+      current_col = chars[current_char].min_m
+      paint_switch = white
+      chars[current_char][current_row]={}
+      return error.ok
+   end
+
+
+   opcodes.func[opcodes.skip3]= function()
+      if chars[current_char]==nil or chars[current_char].min_m==nil then
+	 GF.error("error in skip3 ")
+	 return error.skip3
+      end
+      local b0 = byte(readbytes(1))
+      local b1 = byte(readbytes(1))
+      local b2 = byte(readbytes(1))
+      local b =  b2+b1*256+b3*65536
+      current_row = current_row - (b+1)
+      current_col = chars[current_char].min_m
+      paint_switch = white
+      chars[current_char][current_row]={}
+      return error.ok
+   end
+
+
+   local function new_row(n)
+      if chars[current_char]==nil or chars[current_char].min_m==nil then
+	 GF.error("error in new_row_"..n)
+	 return error.new_row[n]
+      end
+      current_row = current_row - 1
+      current_col  = chars[current_char].min_m+n
+      paint_switch = black
+      chars[current_char][current_row]={}
+      return error.ok
+      
+   end
+
+   opcodes.func[opcodes.new_row_0]= function()
+      if chars[current_char]==nil or chars[current_char].min_m==nil then
+	 GF.error("error in new_row_0")
+	 return error.new_row[0]
+      end
+      current_row = current_row - 1
+      current_col  = chars[current_char].min_m
+      paint_switch = black
+      chars[current_char][current_row]={}
+      return error.ok
+   end
+
+   --opcodes.func[opcodes.new_row_1]= function() new_row(1) end
+   --:
+   --opcodes.func[opcodes.new_row_164]= function() new_row(i)end
+   for i=1, 164 do
+      local key = format("new_row_%d",i)
+      local index = opcodes[key]
+      opcodes.func[index] = function() return new_row(i) end
+   end 
+
+   --opcodes.func[opcodes.max_new_row]= function()
+   --   return new_row(opcodes.max_new_row)
+   --end
+
+   opcodes.func[opcodes.xxx1]= function()
+      local stream_pos = gfdata_index
+      local b = byte(readbytes(1))
+      local k = readbytes(b)
+      table.insert(chars.xxx1,{k,stream_pos})
+      table.insert(chars.all_nop,{'xxx1',k,stream_pos})
+      return error.ok
+   end
+
+   opcodes.func[opcodes.xxx2]= function()
+      local stream_pos = gfdata_index
+      local b0 = byte(readbytes(1))
+      local b1 = byte(readbytes(1))
+      local k = readbytes(b1+ b0*256)
+      table.insert(chars.xxx2,{k,stream_pos})
+      table.insert(chars.all_nop,{'xxx2',k,stream_pos})
+      return error.ok
+   end
+
+
+   opcodes.func[opcodes.xxx3]= function()
+      local stream_pos = gfdata_index
+      local b0 = byte(readbytes(1))
+      local b1 = byte(readbytes(1))
+      local b2 = byte(readbytes(1))
+      local k = readbytes(b2+ b1*256+b0*65536)
+      table.insert(chars.xxx3,{k,stream_pos})
+      table.insert(chars.all_nop,{'xxx3', k,stream_pos})
+      return error.ok
+   end
+
+   opcodes.func[opcodes.xxx4]= function()
+      local stream_pos = gfdata_index
+      local k = readbytes(read4bytes())
+      -- k must be positive
+      if k<=0 then
+	 k = k +4294967296
+      end
+      table.insert(chars.xxx4,{k,stream_pos})
+      table.insert(chars.all_nop,{'xxx4',k,stream_pos})
+      return error.ok
+   end
+
+   opcodes.func[opcodes.yyy]= function()
+      local stream_pos = gfdata_index
+      local v =  read4bytes()
+      table.insert(chars.yyy,{v,stream_pos})
+      table.insert(chars.all_nop,{'yyy',v,stream_pos})
+      return error.ok
+   end
+
+   opcodes.func[opcodes.nop]= function()
+      table.insert(chars.nop,gfdata_index)
+      table.insert(chars.all_nop,{'nop','',gfdata_index})
+      return error.ok
+   end
+
+   opcodes.func[opcodes.char_loc]= function()
+      local c	=  byte(readbytes(1))
+      local dx	=  read4bytes()
+      local dy	=  read4bytes()
+      local w	=  read4bytes()
+      local p	=  read4bytes()
+      local char_locator = {}
+      char_locator['c']	= c 
+      char_locator['dx']	= dx
+      char_locator['dy']	= dy
+      char_locator['w']	= w
+      char_locator['p']	= p
+      table.insert(chars.locators,char_locator)
+      return error.ok
+   end
+
+
+   opcodes.func[opcodes.char_loc0]= function()
+      local c	= byte(readbytes(1))
+      local dm	= byte(readbytes(1))
+      local w	= read4bytes()
+      local p	= read4bytes()
+      local dy	= 0
+      local dx	= 65536*dm
+      local char_locator = {}
+      char_locator['c']	= c 
+      char_locator['dx']	= dx
+      char_locator['dy']	= dy
+      char_locator['w']	= w
+      char_locator['p']	= p
+      table.insert(chars.locators,char_locator)
+      return error.ok
+   end
+
+
+   opcodes.func[opcodes.pre]= function()
+      local i	=  byte(readbytes(1))
+      local k	=  byte(readbytes(1))
+      local x	=  readbytes(k)
+      chars.GF_format	= i
+      chars.GF_comment	= x
+      return error.ok
+   end
+
+   opcodes.func[opcodes.post]= function()
+      local p	=  read4bytes()
+      local ds	=  read4bytes()
+      local cs	=  read4bytes()
+      local hppp	=  read4bytes()
+      local vppp	=  read4bytes()
+      local min_m  =  read4bytes()
+      local max_m  =  read4bytes()
+      local min_n  =  read4bytes()
+      local max_n  =  read4bytes()
+      chars['ds']		= ds
+      chars['cs']		= cs
+      chars['hppp']	= hppp
+      chars['vppp']	= vppp
+      chars['min_m']	=  min_m
+      chars['max_m']	=  max_m
+      chars['min_n']	=  min_n
+      chars['max_n']	=  max_n
+      return error.ok
+   end
+
+   opcodes.func[opcodes.post_post]= function()
+      local q	=  read4bytes()
+      local i      =  byte(readbytes(1))
+      local pad223 =  readbytes(4)
+      if ( pad223~='\223\223\223\223' ) then
+	 GF.error("error post_post_1 "..pad223)
+	 return error.post_post
+      end
+      local s = readuntileof()
+      local ctr223 = rep('\223',len(s))
+      if ctr223 ~= s then
+	 GF.error("error post_post_2 "..pad223)
+	 return error.post_post
+      end
+      chars.GF_format_post = i
+      return error.ok
+   end
+
+   opcodes.func[opcodes.undefined_1]= function()
+      GF.warning("undefined command 1")
+      return error.ok
+   end
+   opcodes.func[opcodes.undefined_2]= function()
+      GF.warning("undefined command 2")
+      return error.ok
+   end
+   opcodes.func[opcodes.undefined_3]= function()
+      GF.warning("undefined command 3")
+      return error.ok
+   end
+   opcodes.func[opcodes.undefined_4]= function()
+      GF.warning("undefined command 4")
+      return error.ok
+   end
+   opcodes.func[opcodes.undefined_5]= function()
+      GF.warning("undefined command 5")
+      return error.ok
+   end
+   opcodes.func[opcodes.undefined_6]= function()
+      GF.warning("undefined command 6")
+      return error.ok
+   end
+
+
+
+   --------------------------------------------------------------------------------
+   --
+   --------------------------------------------------------------------------------
+
+   local function load(gffile)
+      gfdata = ''
+      local f,res = io.open(gffile,'rb')
+      if f==nil then
+	 GF.error(res)
+	 gfdata_index=0
+	 return error.load
+      else 
+	 gfdata		= f:read("*a")
+	 gfdata_len		= len(gfdata)
+	 gfdata_index	=1 
+      end  
+      f:close()
+      return  error.ok
+   end
+
+
+   local function parse_pre()
+      gfdata_index=1 
+      local res = error.ok
+      local b = byte(readbytes(1))
+      if b==opcodes.pre then
+	 local i=byte(readbytes(1))
+	 local k=byte(readbytes(1))
+	 local x=readbytes(k)
+	 chars.GF_format=i
+	 chars.comments=x
+      else 
+	 GF.error("error parsing pre")
+	 res = error.pre
+      end
+      return res
+   end
+
+
+   local function parse_rest()
+      local b = byte(readbytes(1))
+      local func = opcodes.func
+      local res = error.ok
+      local cond = true
+      while (cond) do
+	 if func[b] then
+	    res = (func[b])()
+	    if res~=error.ok then
+	       cond = false  
+	    elseif datanotfinished() then  
+	       b = byte(readbytes(1))
+	    else
+	       res = error.ok
+	       cond = false
+	    end
+	 else
+	    cond = false
+	    GF.error("wrong opcode while parsing char")  
+	    res = error.parsechar
+	 end
+      end   
+      return res
+   end
+
+
+   local function  parse()
+      if gfdata_len == 0 then  
+	 GF.error("no data")
+	 return error.parse
+      end
+      local res 
+      res = parse_pre()
+      if res~=error.ok then
+	 GF.error("wrong preamble")
+	 return res
+      end
+      res = parse_rest()
+      if not(res==error.ok) then
+	 GF.error("error while reading characters")
+	 return res
+      end
+      return res  
+   end
+
+
+   ----------------------------------------------------------------------------------
+   -- Parse from the end 
+   ----------------------------------------------------------------------------------
+
+   local function skip223()
+      local i = gfdata_len
+      local cond = true
+      while cond do
+	 local c = byte(sub(gfdata,i,i))
+	 if c==223 then
+	    i=i-1
+	 else
+	    cond=false
+	 end
+      end
+      if i<3 then
+	 GF.error("error skip suffix ")
+	 res = error.skip223
+      else
+	 res = error.ok
+	 gfdata_index =  i
+      end
+      return res
+   end
+
+
+   local function parse_char_fromlocator()
+      local cond = true
+      local func = opcodes.func
+      local b,res
+      while cond do
+	 b = byte(readbytes(1))
+	 if func[b] then
+	    res = (func[b])()
+	    if res ~= error.ok then
+	       cond = false 
+	       return res
+	    elseif b==opcodes.eoc then
+	       cond = false
+	    else
+	       cond = true 
+	    end
+	 else
+	    GF.error("wrong char from locator")
+	    cond = false
+	    return error.parse
+	 end
+      end
+      if chars[current_char] and chars[current_char].p == -1 then
+	 return error.ok
+      end
+      moveindex_after(chars[current_char].p)
+      return parse_char_fromlocator()
+      
+   end
+
+   local function parse_from_end()
+      if gfdata_len == 0 then  
+	 GF.error("no data")
+	 return error.parse
+      end
+      local res = error.ok
+      gfdata_index = gfdata_len
+      res = skip223()
+      if res ~= error.ok then
+	 return res
+      end
+      --
+      -- read identification byte
+      --
+      chars.GF_format_post = byte(readbytes(-1))
+      --
+      -- read post_post
+      -- 
+      local q = readrev4bytes()
+      if q<=0 then
+	 q = q +4294967296
+      end
+      if q<1 or q>gfdata_len then
+	 GF.error("wrong pointer to post")
+	 return error.parse
+      end
+      --
+      -- reading post
+      -- 
+      moveindex_after(q)
+      q = byte(readbytes(1))
+      if q~=opcodes.post then
+	 GF.error("expected  post opcode")
+	 return error.parse
+      end
+      --
+      res = opcodes.func[opcodes.post]()
+      if res~=error.ok then
+	 GF.error("reading postamble")
+	 return error.parse
+      end
+      --
+      -- read char locators 
+      --
+      local cond		= true
+      local char_loc	= opcodes.char_loc
+      local char_loc0	= opcodes.char_loc0
+      local post_post	= opcodes.post_post
+      local f		= opcodes.func
+      while cond do
+	 q = byte(readbytes(1))
+	 if q==char_loc or q==char_loc0 then
+	    f[q]()
+	 elseif q==post_post then
+	    cond = false
+	    res = error.ok
+	 else
+	    GF.error("reading char locators")
+	    cond = false 
+	    return error.parse
+	 end
+      end
+      --
+      -- read  chars
+      --
+      if #chars.locators == 0 then
+	 GF.error("no char locators")
+	 return error.parse
+      end
+      for i,v in ipairs(chars.locators) do
+	 local p  = v.p
+	 if p>-1 then
+	    moveindex_after(p)
+	    res = parse_char_fromlocator()
+	    if res ~= error.ok then
+	       break;
+	    end
+	 end
+      end
+      return res
+   end
+
+
+   --------------------------------------------------------------------------------
+
+   -- Already assigned before:
+   -- GF.warning = warning_msg
+   -- GF.error = error_msg
+   GF.load		= load
+   GF.parse	= parse
+   GF.chars        = chars
+   GF.errorcode    = error
+   GF.error_name   = error_name
+   GF.parse_from_end = parse_from_end
+   --
+   -- TODO: parsing by reading a file
+   -- 
+
+
+end
+-- Add GF to the mflua table
+mflua.GF = GF



More information about the tex-live-commits mailing list