/*
* Group handling for Msged
*
* Written 2000 by Tobias Ernst and released to the Public Domain
*
*/
#include <time.h>
#include <string.h>
#include "addr.h"
#include "areas.h"
#include "dirute.h"
#include "nedit.h"
#include "msged.h" /* SW */
#include "group.h"
#include "memextra.h"
#include "strextra.h"
struct group
{
char *name;
int username; /* offset ... */
int template; /* offset ... */
};
static int ngroups=0, nmaxgroups=0;
static struct group *groups=NULL;
/* Search a group by name.
Result is offset into groups array if found, -1 if not.
*/
static int group_searchhandle(char *name)
{
int i;
static int lastmatch = 0;
if (!ngroups)
return 0;
if (lastmatch < ngroups)
{
if (!stricmp(name, groups[lastmatch].name))
{
return lastmatch + 1;
}
}
for (i = 0; i < ngroups; i++)
{
if (!stricmp(name, groups[i].name))
{
lastmatch = i;
return i + 1;
}
}
return 0;
}
int group_gethandle(char *name, int crifnec)
{
int handle = group_searchhandle(name);
if (handle == 0 && crifnec != 0)
{
if (!ngroups)
{
groups=xmalloc(sizeof(struct group)*(nmaxgroups = 1));
}
if (ngroups >= nmaxgroups)
{
groups=xrealloc(groups, sizeof(struct group)*(nmaxgroups *= 2));
}
groups[ngroups].name = xstrdup(name);
groups[ngroups].username = -1;
groups[ngroups].template = -1;
handle = ngroups + 1;
ngroups++;
}
return handle;
}
char **group_buildlist(char *firstentry)
{
char **itms;
int nitms;
int i = 0, j;
nitms= ngroups + (firstentry != NULL);
itms = xmalloc(sizeof(char *) * (nitms + 1));
if (firstentry != NULL)
{
itms[0] = xstrdup(firstentry);
i++;
}
for (j = 0; j < ngroups; j++, i++)
{
itms[i] = xstrdup(groups[j].name);
}
itms[i] = NULL;
return itms;
}
int group_getusername(int handle)
{
if (handle >= 1 && handle <= ngroups)
{
return groups[handle - 1].username;
}
return 0;
}
int group_gettemplate(int handle)
{
if (handle >= 1 && handle <= ngroups)
{
return groups[handle - 1].template;
}
return 0;
}
void group_destroy(void)
{
int i;
for (i = 0; i < ngroups; i++)
{
xfree(groups[i].name);
}
if (groups != NULL)
{
xfree(groups);
}
groups = NULL;
ngroups = 0;
}
void group_setsettings(int handle, int username, int template)
{
if (handle >= 1 && handle <= ngroups)
{
groups[handle - 1].template = template;
groups[handle - 1].username = username;
}
}
/* gets the name that the user used to define this group */
char *group_getname(int handle)
{
if (handle >= 1 && handle <= ngroups)
{
return groups[handle - 1].name;
}
else
{
return "internal boundary error";
}
}
int *grouparealist = NULL;
void group_build_arealist(void)
{
int i;
int groupno = SW->group;
int lastgroup = -1;
if (grouparealist == NULL)
{
grouparealist = malloc((SW->areas + ngroups) * sizeof(int));
}
SW->groupareas = 0; SW->grouparea = 0;
if (groupno)
{
for (i = 0; i < SW->areas && arealist[i].group != groupno; i++);
if (i == SW->areas) /* not a single area in this group */
{
groupno = 0;
}
}
for (i = 0; i < SW->areas; i++)
{
if (!groupno || arealist[i].group == groupno)
{
/* when we insert an area, we see if the group has changed, which
means that a separator might be needed. */
if (SW->groupseparators &&
arealist[i].group != lastgroup &&
arealist[i].group != 0 && /* no separater for areas w/o group */
(groupno != 0 || /* we display only a single group, so a
separator is allowed as group "title"
header - otherwise ... */
(ST->sort_criteria && (
ST->sort_criteria[0] == 'g' || /* separators only work when */
ST->sort_criteria[0] == 'G') /* alist is sorted by group */
)
)
)
{
lastgroup = arealist[i].group;
grouparealist[SW->groupareas] = -lastgroup;
SW->groupareas++;
}
/* now we actually insert the area. */
grouparealist[SW->groupareas] = i;
if (i == SW->area)
{
SW->grouparea = SW->groupareas;
}
SW->groupareas++;
}
}
while (grouparealist[SW->grouparea] < 0)
{
SW->grouparea++;
}
SW->area = grouparealist[SW->grouparea];
}
void group_destroy_arealist(void)
{
if (grouparealist != NULL)
{
xfree(grouparealist);
grouparealist = NULL;
}
}
int group_set_group(int group)
{
int lastgroup = SW->group;
if (group <= ngroups)
{
SW->group = group;
group_build_arealist();
}
return lastgroup;
}
syntax highlighted by Code2HTML, v. 0.9.1