util.c
author Myhailo Danylenko <isbear@ukrpost.net>
Tue, 19 May 2009 02:12:02 +0300
changeset 23 13f03e604c8a
parent 20 0ce7093df25f
child 25 1ce483608721
permissions -rw-r--r--
License notes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
23
13f03e604c8a License notes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 20
diff changeset
     1
13f03e604c8a License notes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 20
diff changeset
     2
/* Copyright 2009 Myhailo Danylenko
13f03e604c8a License notes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 20
diff changeset
     3
13f03e604c8a License notes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 20
diff changeset
     4
This code is free software: you can redistribute it and/or modify
13f03e604c8a License notes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 20
diff changeset
     5
it under the terms of the GNU General Public License as published by
13f03e604c8a License notes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 20
diff changeset
     6
the Free Software Foundation, either version 2 of the License, or
13f03e604c8a License notes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 20
diff changeset
     7
(at your option) any later version.
13f03e604c8a License notes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 20
diff changeset
     8
13f03e604c8a License notes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 20
diff changeset
     9
This program is distributed in the hope that it will be useful,
13f03e604c8a License notes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 20
diff changeset
    10
but WITHOUT ANY WARRANTY; without even the implied warranty of
13f03e604c8a License notes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 20
diff changeset
    11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13f03e604c8a License notes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 20
diff changeset
    12
GNU General Public License for more details.
13f03e604c8a License notes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 20
diff changeset
    13
13f03e604c8a License notes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 20
diff changeset
    14
You should have received a copy of the GNU General Public License
13f03e604c8a License notes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 20
diff changeset
    15
along with this program.  If not, see <http://www.gnu.org/licenses/>. */
0
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    16
20
0ce7093df25f Pre-publish changes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 4
diff changeset
    17
#include <strings.h>
0
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    18
#include <lua.h>
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    19
#include <lauxlib.h>
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    20
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    21
#include "util.h"
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    22
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    23
enum_value_t string2enum (const char *string, const string2enum_t *set)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    24
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    25
	while (set->string) {
20
0ce7093df25f Pre-publish changes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 4
diff changeset
    26
		if (!strcasecmp (string, set->string))
0
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    27
			return set->value;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    28
		++set;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    29
	}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    30
	return set->value;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    31
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    32
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    33
const char *enum2string (enum_value_t value, const string2enum_t *set)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    34
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    35
	while (set->string) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    36
		if (value == set->value)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    37
			return set->string;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    38
		++set;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    39
	}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    40
	return NULL;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    41
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    42
4
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    43
/// argument enum field
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    44
/// String that will be converted to number or just plain number, that will be passed as is.
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    45
/// Note, that if enum name is not recognized no error will be raised and default vale will be used.
0
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    46
enum_value_t luaL_checkenum (lua_State *L, int index, const string2enum_t *set)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    47
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    48
	if (lua_type (L, index) == LUA_TNUMBER)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    49
		return lua_tointeger (L, index);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    50
	else
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    51
		return string2enum (luaL_checkstring (L, index), set);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    52
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    53
4
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    54
/// return enum field
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    55
/// String. If no string found, plain number will be returned.
0
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    56
void luaL_pushenum (lua_State *L, enum_value_t value, const string2enum_t *set)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    57
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    58
	const char *string = enum2string (value, set);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    59
	if (string != NULL)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    60
		lua_pushstring (L, string);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    61
	else
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    62
		lua_pushinteger (L, value);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    63
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    64
4
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    65
/// argument flags field
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    66
/// Can be just plain number, then it is passed as is.
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    67
/// Can be a string, then it is recognized as a single enabled flag.
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    68
/// Or can be a table of the following format:
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    69
/// * integer keys should have string values, that will be used as enabled flag names or numerical values, that will be just ORed;
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    70
/// * string keys should be flag names, that will be enabled, if corresponding value contains true value.
0
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    71
enum_value_t luaL_checkenum_multi (lua_State *L, int index, const string2enum_t *set)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    72
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    73
	int type = lua_type (L, index);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    74
	if (type == LUA_TNUMBER)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    75
		return lua_tointeger (L, index);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    76
	else if (type == LUA_TSTRING)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    77
		return string2enum (lua_tostring (L, index), set);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    78
	else if (type == LUA_TTABLE) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    79
		enum_value_t retval = 0;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    80
		lua_pushnil (L);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    81
		while (lua_next (L, index) != 0) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    82
			type = lua_type (L, -2);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    83
			if (type == LUA_TNUMBER) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    84
				type = lua_type (L, -1);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    85
				if (type == LUA_TNUMBER)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    86
					retval |= lua_tointeger (L, -1);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    87
				else if (type == LUA_TSTRING)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    88
					retval |= string2enum (lua_tostring (L, -1), set);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    89
				else
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    90
					luaL_argerror (L, index, "wrong value type of flag");
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    91
			} else if (type == LUA_TSTRING) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    92
				if (lua_toboolean (L, -1))
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    93
					retval |= string2enum (lua_tostring (L, -2), set);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    94
			} else
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    95
				luaL_argerror (L, index, "wrong key type of flags table");
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    96
			lua_pop (L, 1);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    97
		}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    98
	} else
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    99
		luaL_argerror (L, index, "integer, string, or table of ones expected");
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   100
	return 0; // never happens
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   101
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   102
4
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
   103
/// returned flags field
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
   104
/// Is always a table with present flag names as keys with true values.
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
   105
/// Not present flags are not present in table either.
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
   106
/// Not recognized values, if present, will be stored as a number in a first sequential table member (table[1]).
0
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   107
void luaL_pushenum_multi (lua_State *L, enum_value_t value, const string2enum_t *set)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   108
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   109
	enum_value_t matched = 0;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   110
	lua_newtable (L);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   111
	while (set->string) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   112
		if (value & set->value) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   113
			matched |= set->value & value;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   114
			lua_pushstring (L, set->string);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   115
			lua_pushboolean (L, 1);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   116
			lua_settable (L, -3);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   117
		}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   118
		++set;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   119
	}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   120
	if (value ^ matched) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   121
		lua_pushinteger (L, 1);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   122
		lua_pushinteger (L, value ^ matched);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   123
		lua_settable (L, -3);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   124
	}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   125
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   126
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   127
void *luaL_malloc (lua_State *L, size_t size)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   128
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   129
	void      *ud;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   130
	lua_Alloc  allocf = lua_getallocf (L, &ud);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   131
	return (*allocf) (ud, NULL, 0, size);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   132
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   133
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   134
void *luaL_realloc (lua_State *L, void *ptr, size_t osize, size_t nsize)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   135
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   136
	void      *ud;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   137
	lua_Alloc  allocf = lua_getallocf (L, &ud);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   138
	return (*allocf) (ud, ptr, osize, nsize);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   139
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   140
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   141
void  luaL_free (lua_State *L, void *ptr)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   142
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   143
	void      *ud;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   144
	lua_Alloc  allocf = lua_getallocf (L, &ud);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   145
	(*allocf) (ud, ptr, 1, 0);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   146
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   147