author Ryan C. Gordon <>
Thu, 09 Apr 2015 22:33:39 -0400
changeset 9542 618662dc9e82
parent 8149 681eb46b8ac4
child 9619 b94b6d0bff0f
permissions -rwxr-xr-x
Closing the iOS-improvements branch.

-- Copyright (C) 1997-2014 Sam Lantinga <>
-- This software is provided 'as-is', without any express or implied
-- warranty.  In no event will the authors be held liable for any damages
-- arising from the use of this software.
-- Permission is granted to anyone to use this software for any purpose,
-- including commercial applications, and to alter it and redistribute it
-- freely.
-- Meta-build system using premake created and maintained by
-- Benjamin Henning <>


	This function contains a wrapper for the I/O file operations, providing a few
	custom functions which simplify the file I/O process (especially useful for
	the vast amount of generation used by the meta-build system).

-- Given a filename and open mode (look at for more information), opens
-- the file with various contained functions for printing to the file, writing
-- to the file, reading from the file, or closing the file. If the filename is
-- nil, then this will open a file in a special text mode. In that case, the
-- mode is ignored. Returned is an instanced table with all of the
-- aforementioned functions.
-- The print function is associated with textprint/fileprint, the write function
-- with textwrite/filewrite, the read function with fileread, and the close
-- function with textclose/fileclose.
function fileopen(file, mode)
	if file == nil then
		return { texth = "", print = textprint, write = textwrite, read = nil, close = textclose }
		return { fileh =, mode), print = fileprint, write = filewrite, read = fileread, close = fileclose }

-- Given a filename and file mode, reads the entire contents of the file and
-- returns the contents as a string.
function readfile(file, mode)
	local file = fileopen(file, mode)
	local content = file:read()
	return content

-- Given a file, the number of tabs to indent, and a line to print, append the
-- line tabbed n times with an appended newline to the end of the input text.
function textprint(f, tabs, line)
	for i = 0, tabs - 1, 1 do
		f.texth = f.texth .. "\t"
	f.texth = f.texth .. line .. "\n"

-- Given a file, the number of tabs to indent, and a line to print, append the
-- line tabbed n times with an appended newline to the end of the input file.
function fileprint(f, tabs, line)
	for i = 0, tabs - 1, 1 do
	f.fileh:write(line .. "\n")

-- Given a file and some text, append the text to the end of the input text.
function textwrite(f, text)
	f.texth = f.texth .. text

-- Given a file and some text, append the text to the end of the input file.
function filewrite(f, text)

-- Given a file, read all the contents of the file and return them as a string.
function fileread(file)
	return file.fileh:read("*all")

-- Given a file opened in text mode, return the result of the current file
-- operations as a text string.
function textclose(file)
	return file.texth

-- Given a file opened regularly, close the file handle resource, preventing
-- any future I/O operations.
function fileclose(file)

-- Given a source path, builds a table containing all directories and recursive
-- subdirectories which contain files, and returns the table. Each entry in the
-- table will have a '/' at the end of its path, plus they will all be relative
-- to the parent source path. The table will contain a single entry with the
-- value '/' to indicate the source path itself.
function createDirTable(sourcePath)
	local dirs = os.matchdirs(sourcePath.."/**")
	for k,d in pairs(dirs) do
		dirs[k] = string.sub(d, #sourcePath + 1) .. "/"
	table.insert(dirs, "/")
	return dirs

-- This works like os.pathsearch, but for directories. Look at the premake
-- documentation for os.pathsearch for more information.
os.dirpathsearch = function(subdir, path, path_delimiter)
	for i,p in ipairs(explode(path, path_delimiter)) do
		local needle = p .. "/" .. subdir
		if os.isdir(needle) then
			return needle
	return nil

-- Given a variable number of environmental variable names, this will join them
-- together based on the current OS path delimeter and quietly ignoring those
-- variables which do not exist on this system. The resulting path is always
-- normalized for Unix-based path separators, regardless of the system.
os.getenvpath = function(...)
	local path = ""
	local pathDelimeter = ":"
	if"windows") then
		pathDelimeter = ";"
	for i,a in ipairs(arg) do
		local value = os.getenv(a)
		if value then
			if #path > 0 then
				path = path .. pathDelimeter
			path = path .. value
	-- normalize path to unix
	return path:gsub("\\", "/"):gsub("//", "/")