parsav  Diff

Differences From Artifact [573a13128c]:

To Artifact [bc01716315]:


     1      1   -- vim: ft=terra
     2      2   local m = {
     3      3   	shorthand = {maxlen = 14}
     4      4   }
            5  +
            6  +local pstring = lib.mem.ptr(int8)
     5      7   
     6      8   -- swap in place -- faster on little endian
     7      9   m.netswap_ip = macro(function(ty, src, dest)
     8     10   	if ty:astype().type ~= 'integer' then error('bad type') end
     9     11   	local bytes = ty:astype().bytes
    10     12   	src = `[&uint8](src)
    11     13   	dest = `[&uint8](dest)
................................................................................
   182    184   		else dgtct = dgtct + 1 end
   183    185   	end else
   184    186   		buf = buf - 1
   185    187   		@buf = 0x30
   186    188   	end
   187    189   	return buf
   188    190   end
          191  +
          192  +terra m.ndigits(n: intptr, base: intptr): intptr
          193  +	var c = base
          194  +	var i = 1
          195  +	while true do
          196  +		if n < c then return i end
          197  +		c = c * base
          198  +		i = i + 1
          199  +	end
          200  +end
          201  +
          202  +terra m.fsz_parse(f: pstring): {intptr, bool}
          203  +-- take a string representing a file size and return {nbytes, true}
          204  +-- or {0, false} if the parse fails
          205  +	if f.ct == 0 then f.ct = lib.str.sz(f.ptr) end
          206  +	var sz: intptr = 0
          207  +	for i = 0, f.ct do
          208  +		if f(i) == @',' then goto skip end
          209  +		if f(i) >= 0x30 and f(i) <= 0x39 then
          210  +			sz = sz * 10
          211  +			sz = sz + f(i) - 0x30
          212  +		else
          213  +			if i+1 == f.ct or f(i) == 0 then return sz, true end
          214  +			if i+2 == f.ct or f(i+1) == 0 then
          215  +				if f(i) == @'b' then return sz/8, true end -- bits
          216  +			else
          217  +				var s: intptr = 0
          218  +				if i+3 == f.ct or f(i+2) == 0 then 
          219  +					s = i + 1
          220  +				elseif (i+4 == f.ct or f(i+3) == 0) and f(i+1) == @'i' then
          221  +				-- grudgingly tolerate ~mebibits~ and its ilk, without
          222  +				-- affecting the result in any way
          223  +					s = i + 2
          224  +				else return 0, false end
          225  +
          226  +				if f(s) == @'b' then sz = sz/8 -- bits
          227  +				elseif f(s) ~= @'B' then return 0, false end -- wth
          228  +			end
          229  +			var c = f(i)
          230  +			if c >= @'A' and c <= @'Z' then c = c - 0x20 end
          231  +			switch c do -- normal char literal syntax doesn't work here, leads to llvm error (!!)
          232  +				case [uint8]([string.byte('k')]) then return sz * [1024ULL ^ 1], true end
          233  +				case [uint8]([string.byte('m')]) then return sz * [1024ULL ^ 2], true end
          234  +				case [uint8]([string.byte('g')]) then return sz * [1024ULL ^ 3], true end
          235  +				case [uint8]([string.byte('t')]) then return sz * [1024ULL ^ 4], true end
          236  +				case [uint8]([string.byte('e')]) then return sz * [1024ULL ^ 5], true end
          237  +				case [uint8]([string.byte('y')]) then return sz * [1024ULL ^ 6], true end
          238  +				else return sz, true
          239  +			end
          240  +		end
          241  +	::skip::end
          242  +	return sz, true
          243  +end
   189    244   
   190    245   return m