util.c
author Myhailo Danylenko <isbear@ukrpost.net>
Sat, 05 Mar 2016 15:45:33 +0200
changeset 61 745b73f91607
parent 50 2278dd806ad3
permissions -rw-r--r--
docs: Update api
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
50
2278dd806ad3 Add header to utils
Myhailo Danylenko <isbear@ukrpost.net>
parents: 25
diff changeset
    23
/// Utility Lua Routines
2278dd806ad3 Add header to utils
Myhailo Danylenko <isbear@ukrpost.net>
parents: 25
diff changeset
    24
/// To handle conversion of enums and flag fields to/from human-readable strings.
2278dd806ad3 Add header to utils
Myhailo Danylenko <isbear@ukrpost.net>
parents: 25
diff changeset
    25
0
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    26
enum_value_t string2enum (const char *string, const string2enum_t *set)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    27
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    28
	while (set->string) {
20
0ce7093df25f Pre-publish changes
Myhailo Danylenko <isbear@ukrpost.net>
parents: 4
diff changeset
    29
		if (!strcasecmp (string, set->string))
0
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
		++set;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    32
	}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    33
	return set->value;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    34
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    35
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    36
const char *enum2string (enum_value_t value, const string2enum_t *set)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    37
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    38
	while (set->string) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    39
		if (value == set->value)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    40
			return set->string;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    41
		++set;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    42
	}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    43
	return NULL;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    44
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    45
4
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    46
/// argument enum field
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    47
/// 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
    48
/// 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
    49
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
    50
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    51
	if (lua_type (L, index) == LUA_TNUMBER)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    52
		return lua_tointeger (L, index);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    53
	else
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    54
		return string2enum (luaL_checkstring (L, index), set);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    55
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    56
4
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    57
/// return enum field
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    58
/// String. If no string found, plain number will be returned.
0
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    59
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
    60
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    61
	const char *string = enum2string (value, set);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    62
	if (string != NULL)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    63
		lua_pushstring (L, string);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    64
	else
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    65
		lua_pushinteger (L, value);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    66
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    67
4
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    68
/// argument flags field
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    69
/// Can be just plain number, then it is passed as is.
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    70
/// 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
    71
/// Or can be a table of the following format:
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
    72
/// * 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
    73
/// * 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
    74
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
    75
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    76
	int type = lua_type (L, index);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    77
	if (type == LUA_TNUMBER)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    78
		return lua_tointeger (L, index);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    79
	else if (type == LUA_TSTRING)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    80
		return string2enum (lua_tostring (L, index), set);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    81
	else if (type == LUA_TTABLE) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    82
		enum_value_t retval = 0;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    83
		lua_pushnil (L);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    84
		while (lua_next (L, index) != 0) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    85
			type = lua_type (L, -2);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    86
			if (type == LUA_TNUMBER) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    87
				type = lua_type (L, -1);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    88
				if (type == LUA_TNUMBER)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    89
					retval |= lua_tointeger (L, -1);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    90
				else if (type == LUA_TSTRING)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    91
					retval |= string2enum (lua_tostring (L, -1), set);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    92
				else
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    93
					luaL_argerror (L, index, "wrong value type of flag");
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    94
			} else if (type == LUA_TSTRING) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    95
				if (lua_toboolean (L, -1))
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    96
					retval |= string2enum (lua_tostring (L, -2), set);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    97
			} else
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    98
				luaL_argerror (L, index, "wrong key type of flags table");
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
    99
			lua_pop (L, 1);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   100
		}
25
1ce483608721 Flag field parser fix (unused)
Myhailo Danylenko <isbear@ukrpost.net>
parents: 23
diff changeset
   101
		return retval;
0
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   102
	} else
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   103
		luaL_argerror (L, index, "integer, string, or table of ones expected");
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   104
	return 0; // never happens
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   105
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   106
4
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
   107
/// returned flags field
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
   108
/// 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
   109
/// Not present flags are not present in table either.
5770be2d5f3f Documentation updates
Myhailo Danylenko <isbear@ukrpost.net>
parents: 0
diff changeset
   110
/// 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
   111
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
   112
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   113
	enum_value_t matched = 0;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   114
	lua_newtable (L);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   115
	while (set->string) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   116
		if (value & set->value) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   117
			matched |= set->value & value;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   118
			lua_pushstring (L, set->string);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   119
			lua_pushboolean (L, 1);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   120
			lua_settable (L, -3);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   121
		}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   122
		++set;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   123
	}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   124
	if (value ^ matched) {
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   125
		lua_pushinteger (L, 1);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   126
		lua_pushinteger (L, value ^ matched);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   127
		lua_settable (L, -3);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   128
	}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   129
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   130
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   131
void *luaL_malloc (lua_State *L, size_t 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
	void      *ud;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   134
	lua_Alloc  allocf = lua_getallocf (L, &ud);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   135
	return (*allocf) (ud, NULL, 0, size);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   136
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   137
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   138
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
   139
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   140
	void      *ud;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   141
	lua_Alloc  allocf = lua_getallocf (L, &ud);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   142
	return (*allocf) (ud, ptr, osize, nsize);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   143
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   144
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   145
void  luaL_free (lua_State *L, void *ptr)
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   146
{
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   147
	void      *ud;
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   148
	lua_Alloc  allocf = lua_getallocf (L, &ud);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   149
	(*allocf) (ud, ptr, 1, 0);
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   150
}
84fdfb0344c9 Initial commit
Myhailo Danylenko <isbear@ukrpost.net>
parents:
diff changeset
   151