#ident "@(#)fset.c 1.10"
/*
* fset.c - keep track of all our format strings
* Modified by Rex Feany (laeos@laeos.net) for Xaric
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_ASSERT_H
# include <assert.h>
#endif
#include "irc.h"
#include "ircaux.h"
#include "screen.h"
#include "output.h"
#include "misc.h"
#include "vars.h"
#include "fset.h"
#include "alist.h"
#include "tcommand.h"
#include "format.h" /* default formats */
static struct format_set
{
const char *name;
char *value;
char *old;
int modified;
int len;
} formatset_array[] = {
/*--start--*/
{"FORMAT_381", DEF_FORMAT_381, NULL, 0, 0 },
{"FORMAT_391", DEF_FORMAT_391, NULL, 0, 0 },
{"FORMAT_443", DEF_FORMAT_443, NULL, 0, 0 },
{"FORMAT_471", DEF_FORMAT_471, NULL, 0, 0 },
{"FORMAT_473", DEF_FORMAT_473, NULL, 0, 0 },
{"FORMAT_474", DEF_FORMAT_474, NULL, 0, 0 },
{"FORMAT_475", DEF_FORMAT_475, NULL, 0, 0 },
{"FORMAT_476", DEF_FORMAT_476, NULL, 0, 0 },
{"FORMAT_ACTION", DEF_FORMAT_ACTION, NULL, 0, 0 },
{"FORMAT_ACTION_OTHER", DEF_FORMAT_ACTION_OTHER, NULL, 0, 0 },
{"FORMAT_ACTION_PRIV", DEF_FORMAT_ACTION_PRIV, NULL, 0, 0 },
{"FORMAT_ALIAS", DEF_FORMAT_ALIAS, NULL, 0, 0 },
{"FORMAT_ASSIGN", DEF_FORMAT_ASSIGN, NULL, 0, 0 },
{"FORMAT_AWAY", DEF_FORMAT_AWAY, NULL, 0, 0 },
{"FORMAT_BACK", DEF_FORMAT_BACK, NULL, 0, 0 },
{"FORMAT_BANS", DEF_FORMAT_BANS, NULL, 0, 0 },
{"FORMAT_BANS_HEADER", DEF_FORMAT_BANS_HEADER, NULL, 0, 0 },
{"FORMAT_BWALL", DEF_FORMAT_BWALL, NULL, 0, 0 },
{"FORMAT_CHANNEL_SIGNOFF", DEF_FORMAT_CHANNEL_SIGNOFF, NULL, 0, 0 },
{"FORMAT_CONNECT", DEF_FORMAT_CONNECT, NULL, 0, 0 },
{"FORMAT_CTCP", DEF_FORMAT_CTCP, NULL, 0, 0 },
{"FORMAT_CTCP_REPLY", DEF_FORMAT_CTCP_REPLY, NULL, 0, 0 },
{"FORMAT_CTCP_UNKNOWN", DEF_FORMAT_CTCP_UNKNOWN, NULL, 0, 0 },
{"FORMAT_DCC", DEF_FORMAT_DCC, NULL, 0, 0 },
{"FORMAT_DCC_CHAT", DEF_FORMAT_DCC_CHAT, NULL, 0, 0 },
{"FORMAT_DCC_CONNECT", DEF_FORMAT_DCC_CONNECT, NULL, 0, 0 },
{"FORMAT_DCC_ERROR", DEF_FORMAT_DCC_ERROR, NULL, 0, 0 },
{"FORMAT_DCC_LOST", DEF_FORMAT_DCC_LOST, NULL, 0, 0 },
{"FORMAT_DCC_REQUEST", DEF_FORMAT_DCC_REQUEST, NULL, 0, 0 },
{"FORMAT_DESYNC", DEF_FORMAT_DESYNC, NULL, 0, 0 },
{"FORMAT_DISCONNECT", DEF_FORMAT_DISCONNECT, NULL, 0, 0 },
{"FORMAT_ENCRYPTED_NOTICE", DEF_FORMAT_ENCRYPTED_NOTICE, NULL, 0, 0 },
{"FORMAT_ENCRYPTED_PRIVMSG", DEF_FORMAT_ENCRYPTED_PRIVMSG, NULL, 0, 0 },
{"FORMAT_FLOOD", DEF_FORMAT_FLOOD, NULL, 0, 0 },
{"FORMAT_HOOK", DEF_FORMAT_HOOK, NULL, 0, 0 },
{"FORMAT_IGNORE_INVITE", DEF_FORMAT_IGNORE_INVITE, NULL, 0, 0 },
{"FORMAT_IGNORE_MSG", DEF_FORMAT_IGNORE_MSG, NULL, 0, 0 },
{"FORMAT_IGNORE_MSG_AWAY", DEF_FORMAT_IGNORE_MSG_AWAY, NULL, 0, 0 },
{"FORMAT_IGNORE_NOTICE", DEF_FORMAT_IGNORE_NOTICE, NULL, 0, 0 },
{"FORMAT_IGNORE_WALL", DEF_FORMAT_IGNORE_WALL, NULL, 0, 0 },
{"FORMAT_INVITE", DEF_FORMAT_INVITE, NULL, 0, 0 },
{"FORMAT_INVITE_USER", DEF_FORMAT_INVITE_USER, NULL, 0, 0 },
{"FORMAT_JOIN", DEF_FORMAT_JOIN, NULL, 0, 0 },
{"FORMAT_KICK", DEF_FORMAT_KICK, NULL, 0, 0 },
{"FORMAT_KICK_USER", DEF_FORMAT_KICK_USER, NULL, 0, 0 },
{"FORMAT_KILL", DEF_FORMAT_KILL, NULL, 0, 0 },
{"FORMAT_LEAVE", DEF_FORMAT_LEAVE, NULL, 0, 0 },
{"FORMAT_LINKS", DEF_FORMAT_LINKS, NULL, 0, 0 },
{"FORMAT_LIST", DEF_FORMAT_LIST, NULL, 0, 0 },
{"FORMAT_MODE", DEF_FORMAT_MODE, NULL, 0, 0 },
{"FORMAT_MODE_CHANNEL", DEF_FORMAT_MODE_CHANNEL, NULL, 0, 0 },
{"FORMAT_MSG", DEF_FORMAT_MSG, NULL, 0, 0 },
{"FORMAT_MSGLOG", DEF_FORMAT_MSGLOG, NULL, 0, 0 },
{"FORMAT_MSG_GROUP", DEF_FORMAT_MSG_GROUP, NULL, 0, 0 },
{"FORMAT_NAMES", DEF_FORMAT_NAMES, NULL, 0, 0 },
{"FORMAT_NAMES_BANNER", DEF_FORMAT_NAMES_BANNER, NULL, 0, 0 },
{"FORMAT_NAMES_FOOTER", DEF_FORMAT_NAMES_FOOTER, NULL, 0, 0 },
{"FORMAT_NAMES_IRCOP", DEF_FORMAT_NAMES_IRCOP, NULL, 0, 0 },
{"FORMAT_NAMES_NICKCOLOR", DEF_FORMAT_NAMES_NICKCOLOR, NULL, 0, 0 },
{"FORMAT_NAMES_NONOP", DEF_FORMAT_NAMES_NONOP, NULL, 0, 0 },
{"FORMAT_NAMES_OP", DEF_FORMAT_NAMES_OP, NULL, 0, 0 },
{"FORMAT_NAMES_OPCOLOR", DEF_FORMAT_NAMES_OPCOLOR, NULL, 0, 0 },
{"FORMAT_NAMES_VOICE", DEF_FORMAT_NAMES_VOICE, NULL, 0, 0 },
{"FORMAT_NAMES_VOICECOLOR", DEF_FORMAT_NAMES_VOICECOLOR, NULL, 0, 0 },
{"FORMAT_NETADD", DEF_FORMAT_NETADD, NULL, 0, 0 },
{"FORMAT_NETJOIN", DEF_FORMAT_NETJOIN, NULL, 0, 0 },
{"FORMAT_NETSPLIT", DEF_FORMAT_NETSPLIT, NULL, 0, 0 },
{"FORMAT_NETSPLIT_HEADER", DEF_FORMAT_NETSPLIT_HEADER, NULL, 0, 0 },
{"FORMAT_NICKNAME", DEF_FORMAT_NICKNAME, NULL, 0, 0 },
{"FORMAT_NICKNAME_OTHER", DEF_FORMAT_NICKNAME_OTHER, NULL, 0, 0 },
{"FORMAT_NICKNAME_USER", DEF_FORMAT_NICKNAME_USER, NULL, 0, 0 },
{"FORMAT_NICK_AUTO", DEF_FORMAT_NICK_AUTO, NULL, 0, 0 },
{"FORMAT_NICK_COMP", DEF_FORMAT_NICK_COMP, NULL, 0, 0 },
{"FORMAT_NICK_MSG", DEF_FORMAT_NICK_MSG, NULL, 0, 0 },
{"FORMAT_NONICK", DEF_FORMAT_NONICK, NULL, 0, 0 },
{"FORMAT_NOTE", DEF_FORMAT_NOTE, NULL, 0, 0 },
{"FORMAT_NOTICE", DEF_FORMAT_NOTICE, NULL, 0, 0 },
{"FORMAT_NOTIFY_OFF", DEF_FORMAT_NOTIFY_OFF, NULL, 0, 0 },
{"FORMAT_NOTIFY_ON", DEF_FORMAT_NOTIFY_ON, NULL, 0, 0 },
{"FORMAT_NOTIFY_SIGNOFF", DEF_FORMAT_NOTIFY_SIGNOFF, NULL, 0, 0 },
{"FORMAT_NOTIFY_SIGNOFF_UH", DEF_FORMAT_NOTIFY_SIGNOFF_UH, NULL, 0, 0 },
{"FORMAT_NOTIFY_SIGNON", DEF_FORMAT_NOTIFY_SIGNON, NULL, 0, 0 },
{"FORMAT_NOTIFY_SIGNON_UH", DEF_FORMAT_NOTIFY_SIGNON_UH, NULL, 0, 0 },
{"FORMAT_OPER", DEF_FORMAT_OPER, NULL, 0, 0 },
{"FORMAT_PUBLIC", DEF_FORMAT_PUBLIC, NULL, 0, 0 },
{"FORMAT_PUBLIC_MSG", DEF_FORMAT_PUBLIC_MSG, NULL, 0, 0 },
{"FORMAT_PUBLIC_NOTICE", DEF_FORMAT_PUBLIC_NOTICE, NULL, 0, 0 },
{"FORMAT_PUBLIC_OTHER", DEF_FORMAT_PUBLIC_OTHER, NULL, 0, 0 },
{"FORMAT_SCANDIR_LIST_FOOTER", DEF_FORMAT_SCANDIR_LIST_FOOTER, NULL, 0, 0 },
{"FORMAT_SCANDIR_LIST_HEADER", DEF_FORMAT_SCANDIR_LIST_HEADER, NULL, 0, 0 },
{"FORMAT_SCANDIR_LIST_LINE", DEF_FORMAT_SCANDIR_LIST_LINE, NULL, 0, 0 },
{"FORMAT_SEND_ACTION", DEF_FORMAT_SEND_ACTION, NULL, 0, 0 },
{"FORMAT_SEND_ACTION_OTHER", DEF_FORMAT_SEND_ACTION_OTHER, NULL, 0, 0 },
{"FORMAT_SEND_AWAY", DEF_FORMAT_SEND_AWAY, NULL, 0, 0 },
{"FORMAT_SEND_CTCP", DEF_FORMAT_SEND_CTCP, NULL, 0, 0 },
{"FORMAT_SEND_DCC_CHAT", DEF_FORMAT_SEND_DCC_CHAT, NULL, 0, 0 },
{"FORMAT_SEND_MSG", DEF_FORMAT_SEND_MSG, NULL, 0, 0 },
{"FORMAT_SEND_NOTICE", DEF_FORMAT_SEND_NOTICE, NULL, 0, 0 },
{"FORMAT_SEND_PUBLIC", DEF_FORMAT_SEND_PUBLIC, NULL, 0, 0 },
{"FORMAT_SEND_PUBLIC_OTHER", DEF_FORMAT_SEND_PUBLIC_OTHER, NULL, 0, 0 },
{"FORMAT_SERVER", DEF_FORMAT_SERVER, NULL, 0, 0 },
{"FORMAT_SERVER_MSG1", DEF_FORMAT_SERVER_MSG1, NULL, 0, 0 },
{"FORMAT_SERVER_MSG1_FROM", DEF_FORMAT_SERVER_MSG1_FROM, NULL, 0, 0 },
{"FORMAT_SERVER_MSG2", DEF_FORMAT_SERVER_MSG2, NULL, 0, 0 },
{"FORMAT_SERVER_MSG2_FROM", DEF_FORMAT_SERVER_MSG2_FROM, NULL, 0, 0 },
{"FORMAT_SERVER_NOTICE", DEF_FORMAT_SERVER_NOTICE, NULL, 0, 0 },
{"FORMAT_SET", DEF_FORMAT_SET, NULL, 0, 0 },
{"FORMAT_SET_NOVALUE", DEF_FORMAT_SET_NOVALUE, NULL, 0, 0 },
{"FORMAT_SIGNOFF", DEF_FORMAT_SIGNOFF, NULL, 0, 0 },
{"FORMAT_SILENCE", DEF_FORMAT_SILENCE, NULL, 0, 0 },
{"FORMAT_SMODE", DEF_FORMAT_SMODE, NULL, 0, 0 },
{"FORMAT_STATUS", DEF_FORMAT_STATUS, NULL, 0, 0 },
{"FORMAT_STATUS2", DEF_FORMAT_STATUS2, NULL, 0, 0 },
{"FORMAT_TIMER", DEF_FORMAT_TIMER, NULL, 0, 0 },
{"FORMAT_TOPIC", DEF_FORMAT_TOPIC, NULL, 0, 0 },
{"FORMAT_TOPIC_CHANGE", DEF_FORMAT_TOPIC_CHANGE, NULL, 0, 0 },
{"FORMAT_TOPIC_CHANGE_HEADER", DEF_FORMAT_TOPIC_CHANGE_HEADER, NULL, 0, 0 },
{"FORMAT_TOPIC_SETBY", DEF_FORMAT_TOPIC_SETBY, NULL, 0, 0 },
{"FORMAT_TOPIC_UNSET", DEF_FORMAT_TOPIC_UNSET, NULL, 0, 0 },
{"FORMAT_TRACE_OPER", DEF_FORMAT_TRACE_OPER, NULL, 0, 0 },
{"FORMAT_TRACE_SERVER", DEF_FORMAT_TRACE_SERVER, NULL, 0, 0 },
{"FORMAT_TRACE_USER", DEF_FORMAT_TRACE_USER, NULL, 0, 0 },
{"FORMAT_USAGE", DEF_FORMAT_USAGE, NULL, 0, 0 },
{"FORMAT_USERMODE", DEF_FORMAT_USERMODE, NULL, 0, 0 },
{"FORMAT_USERS", DEF_FORMAT_USERS, NULL, 0, 0 },
{"FORMAT_USERS_HEADER", DEF_FORMAT_USERS_HEADER, NULL, 0, 0 },
{"FORMAT_USERS_USER", DEF_FORMAT_USERS_USER, NULL, 0, 0 },
{"FORMAT_VERSION", DEF_FORMAT_VERSION, NULL, 0, 0 },
{"FORMAT_WALL", DEF_FORMAT_WALL, NULL, 0, 0 },
{"FORMAT_WALLOP", DEF_FORMAT_WALLOP, NULL, 0, 0 },
{"FORMAT_WHO", DEF_FORMAT_WHO, NULL, 0, 0 },
{"FORMAT_WHOIS_AWAY", DEF_FORMAT_WHOIS_AWAY, NULL, 0, 0 },
{"FORMAT_WHOIS_CHANNELS", DEF_FORMAT_WHOIS_CHANNELS, NULL, 0, 0 },
{"FORMAT_WHOIS_FOOTER", DEF_FORMAT_WHOIS_FOOTER, NULL, 0, 0 },
{"FORMAT_WHOIS_HEADER", DEF_FORMAT_WHOIS_HEADER, NULL, 0, 0 },
{"FORMAT_WHOIS_IDLE", DEF_FORMAT_WHOIS_IDLE, NULL, 0, 0 },
{"FORMAT_WHOIS_NAME", DEF_FORMAT_WHOIS_NAME, NULL, 0, 0 },
{"FORMAT_WHOIS_NICK", DEF_FORMAT_WHOIS_NICK, NULL, 0, 0 },
{"FORMAT_WHOIS_OPER", DEF_FORMAT_WHOIS_OPER, NULL, 0, 0 },
{"FORMAT_WHOIS_SERVER", DEF_FORMAT_WHOIS_SERVER, NULL, 0, 0 },
{"FORMAT_WHOIS_SIGNON", DEF_FORMAT_WHOIS_SIGNON, NULL, 0, 0 },
{"FORMAT_WHOLEFT_FOOTER", DEF_FORMAT_WHOLEFT_FOOTER, NULL, 0, 0 },
{"FORMAT_WHOLEFT_HEADER", DEF_FORMAT_WHOLEFT_HEADER, NULL, 0, 0 },
{"FORMAT_WHOLEFT_USER", DEF_FORMAT_WHOLEFT_USER, NULL, 0, 0 },
{"FORMAT_WHOWAS_HEADER", DEF_FORMAT_WHOWAS_HEADER, NULL, 0, 0 },
{"FORMAT_WHOWAS_NICK", DEF_FORMAT_WHOWAS_NICK, NULL, 0, 0 },
{"FORMAT_WIDELIST", DEF_FORMAT_WIDELIST, NULL, 0, 0 },
{"FORMAT_WINDOW_SET", DEF_FORMAT_WINDOW_SET, NULL, 0, 0 },
/*--end--*/
{NULL, NULL}
};
/*** Private ***/
/* reset a format to its original value */
static inline void
reset_var (xformat fmt)
{
if (formatset_array[fmt].modified) {
new_free(&formatset_array[fmt].value);
formatset_array[fmt].value = formatset_array[fmt].old;
formatset_array[fmt].modified = 0;
formatset_array[fmt].len = 0;
say ("Reset [%s]", formatset_array[fmt].name);
}
}
/* reset every format to there original values */
static inline void
reset_all (void)
{
xformat i;
for (i = 0; i < NUMBER_OF_FSET; i++)
if (formatset_array[i].modified)
reset_var(i);
}
/* find a variable by name */
/* return location, or -1 if there were none found */
static xformat
find_format (const char *name, int *cnt)
{
int loc;
assert(name);
assert(cnt);
*cnt = 0;
if ((find_fixed_array_item(formatset_array, sizeof (struct format_set), NUMBER_OF_FSET, name, cnt, &loc) == NULL))
return -1;
if ( *cnt < 0 )
*cnt = -*cnt;
assert(loc < NUMBER_OF_FSET);
return loc;
}
/* set a format */
static void
set_format (xformat loc, const char *value)
{
struct format_set *var = &(formatset_array[loc]);
if ( value && *value == '\0' ) {
put_it ("%s", convert_output_format (get_fset_var (FORMAT_SET_FSET), "%s %s", var->name, var->value ? var->value : empty_str));
return;
}
if ( var->modified == 0 ) {
var->old = var->value;
var->value = NULL;
var->modified = 1;
}
var->len = 0;
if (value)
malloc_strcpy (&(var->value), value);
else if (var->value)
new_free (&(var->value));
say ("Value of %s set to %s", var->name, var->value ? var->value : "<EMPTY>");
}
static void
set_format_range (xformat loc, int cnt, const char *arg)
{
int end = loc + cnt;
assert(loc >= 0 && loc < NUMBER_OF_FSET);
assert(cnt >= 0 && cnt < NUMBER_OF_FSET);
assert(end >= 0 && end < NUMBER_OF_FSET);
for ( ; loc < end ; loc++ )
set_format(loc, arg);
}
/*** Public ***/
/**
* get_format_len - return printable length of format
* @which: what format
*
* When the format is displayed, how many printable
* character spaces will it use?
**/
unsigned int
get_format_len(xformat which)
{
char *conv;
/* if already calculated, or NULL value */
if (formatset_array[which].len || !formatset_array[which].value)
return formatset_array[which].len;
/* XXX */
conv = convert_output_format(formatset_array[which].value, "", NULL);
conv = stripansicodes(conv);
return (formatset_array[which].len = strlen(conv));
}
/**
* get_format - fetch a format string
* @which: The ID of the format string.
*
* Return the format string for a given format.
**/
const char *
get_format(xformat which)
{
return formatset_array[which].value;
}
/**
* save_formats - write out the changed formats.
* @outfile: file handle to write commands to.
*
* Write out any changes made to the format table in a format that
* we can load later.
**/
int
save_formats (FILE * outfile)
{
int count = 0;
xformat i;
assert(outfile);
for (i = 0; i < NUMBER_OF_FSET; i++)
if ( formatset_array[i].modified ) {
count++;
if (formatset_array[i].value)
fprintf (outfile, "FSET %s %s\n", formatset_array[i].name, formatset_array[i].value);
else
fprintf (outfile, "FSET -%s\n", formatset_array[i].name);
}
bitchsay ("Saved %d formats.", count);
return 0;
}
/**
* get_format_byname - given a name, return the format string.
* @name: Which format to return.
*
* Return a malloc'ed copy of the format string
* given a name, like "FORMAT_FOO"
**/
char *
get_format_byname (const char *name)
{
int cnt;
int loc;
assert(name);
if ((find_fixed_array_item(formatset_array, sizeof (struct format_set), NUMBER_OF_FSET, name, &cnt, &loc) == NULL))
return NULL;
if (cnt >= 0)
return NULL;
assert(loc >= 0 && loc < NUMBER_OF_FSET);
return m_strdup(formatset_array[loc].value);
}
/**
* cmd_freset - reset modified formats to there compiled-in defaults
* @cmd: command struct
* @args: command arguments
*
* Takes either one or zero arguments.
* With no arguments, resets all variables to there defaults.
* With one argument of a variable name, reset that variable.
**/
void
cmd_freset(struct command *cmd, char *args)
{
char *var;
int cnt = 0;
assert(cmd);
if ((var = next_arg (args, &args)) != NULL) {
xformat loc = find_format (var, &cnt);
switch (cnt) {
case 0:
say ("No such variable \"%s\"", var);
break;
case 1:
reset_var(loc);
break;
default:
say ("%s is ambiguous", var);
set_format_range(loc, cnt, empty_str);
break;
}
} else {
reset_all();
}
}
/**
* cmd_fset - modify or query the format table
* @cmd: command struct
* @args: command arguments
*
* Takes zero, one, or two arguments.
* With no arguments, print out the whole format table.
* With one argument, display the value of any matching formats.
* With one argument prefixed with '-' unset the format.
* Two arguments, the format and the value to change it to.
**/
void
cmd_fset (struct command *cmd, char *args)
{
char *var;
int cnt;
assert(cmd);
if ((var = next_arg (args, &args)) != NULL)
{
xformat loc;
if (*var == '-') {
var++;
args = NULL;
}
loc = find_format (var, &cnt);
switch (cnt) {
case 0:
say ("No such variable \"%s\"", var);
break;
case 1:
set_format(loc, args);
break;
default:
say ("%s is ambiguous", var);
set_format_range(loc, cnt, empty_str);
break;
}
} else
set_format_range(0, NUMBER_OF_FSET - 1, empty_str);
}
syntax highlighted by Code2HTML, v. 0.9.1