This repository has been archived on 2021-04-17. You can view files and clone it, but cannot push or open issues or pull requests.
uIRC/src/mode/mode.c

109 lines
2.7 KiB
C

/*
* This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
* Copyright (c) 2019-2021 Alex-David Denes
*
* uIRC is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* uIRC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
*/
#include "uirc/mode.h"
#include <assert.h> // assert()
#include <ctype.h> // isalpha()
#include <inttypes.h> // int_least8_t
#include <stdbool.h> // bool
#include <stddef.h> // ptrdiff_t
#if ('b' - 'a' != 1 || 'B' - 'A' != 1 || 'z' - 'a' != 25)
#error "System is not US-ASCII." // This is crucial for the conversions below
#endif
static const char mode_maps[] = {
[IRC_MODE_WALLOPS] = 'w', [IRC_MODE_INVISIBLE] = 'i', [IRC_MODE_AWAY] = 'a', [IRC_MODE_RESTRICTED] = 'r',
[IRC_MODE_OPERATOR] = 'o', [IRC_MODE_LOCALOPERATOR] = 'O', [IRC_MODE_SERVERNOTICES] = 's',
};
char
IRC_MODE(enum uirc_table_mode mode)
{
return mode_maps[mode];
}
static int_least8_t
uirc_mode_index(char mode)
{
int_least8_t index = 0;
if (islower(mode)) {
index += mode - 'a';
} else if (isupper(mode)) {
index += ('z' - 'a'); // We offset the index by the size of the lower characters
index += mode - 'A';
} else
return -1;
return index;
}
bool
uirc_mode_toggle(char m, IRC_Modes ms)
{
int_least8_t i = uirc_mode_index(m);
if (i < 0) return false;
ms[i] = !ms[i];
return true;
}
bool
uirc_mode_enable(char m, IRC_Modes ms)
{
int_least8_t i = uirc_mode_index(m);
if (i < 0) return false;
ms[i] = true;
return true;
}
bool
uirc_mode_disable(char m, IRC_Modes ms)
{
int_least8_t i = uirc_mode_index(m);
if (i < 0) return false;
ms[i] = false;
return true;
}
void
uirc_mode_copy(IRC_Modes d, IRC_Modes const s)
{
for (unsigned long i = 0; i < sizeof(IRC_Modes) / sizeof(*s); i++) d[i] = s[i];
}
bool
uirc_mode_fetch(char m, IRC_Modes ms)
{
int_least8_t i = uirc_mode_index(m);
assert(i != -1);
return ms[i];
}
const char*
uirc_mode_bmconv(IRC_Modes ms)
{
static char bitmask[4];
unsigned short i = sizeof(bitmask) - 1;
bitmask[i--] = '\0';
bitmask[i--] = '0';
bitmask[i--] = (uirc_mode_fetch(IRC_MODE_WALLOPS, ms)) ? '1' : '0';
bitmask[i--] = (uirc_mode_fetch(IRC_MODE_INVISIBLE, ms)) ? '1' : '0';
return bitmask;
}