NetBSD/dist/cdk/cdk.c

1318 lines
26 KiB
C

#include <cdk.h>
/*
* $Author: christos $
* $Date: 2006/03/26 22:08:59 $
* $Revision: 1.6 $
*/
char *GPasteBuffer = 0;
/*
* This beeps then flushes the stdout stream.
*/
void Beep(void)
{
beep();
fflush (stdout);
}
/*
* This sets a string to the given character.
*/
void cleanChar (char *s, int len, char character)
{
int x;
for (x=0; x < len; x++)
{
s[x] = character;
}
s[--x] = '\0';
}
void cleanChtype (chtype *s, int len, chtype character)
{
int x;
for (x=0; x < len; x++)
{
s[x] = character;
}
s[--x] = '\0';
}
/*
* This takes an x and y position and realigns the values iff they sent in
* values like CENTER, LEFT, RIGHT, ...
*/
void alignxy (WINDOW *window, int *xpos, int *ypos, int boxWidth, int boxHeight)
{
int first, gap, last;
first = getbegx(window);
last = getmaxx(window);
if ((gap = (last - boxWidth)) < 0) gap = 0;
last = first + gap;
switch (*xpos)
{
case LEFT:
(*xpos) = first;
break;
case RIGHT:
(*xpos) = first + gap;
break;
case CENTER:
(*xpos) = first + (gap / 2);
break;
}
if ((*xpos) > last)
(*xpos) = last;
else if ((*xpos) < first)
(*xpos) = first;
first = getbegy(window);
last = getmaxy(window);
if ((gap = (last - boxHeight)) < 0) gap = 0;
last = first + gap;
switch (*ypos)
{
case TOP:
(*ypos) = first;
break;
case BOTTOM:
(*ypos) = first + gap;
break;
case CENTER:
(*ypos) = first + (gap/2);
break;
}
if ((*ypos) > last)
(*ypos) = last;
else if ((*ypos) < first)
(*ypos) = first;
}
/*
* This takes a string, a field width and a justifycation type
* and returns the justifcation adjustment to make, to fill
* the justification requirement.
*/
int justifyString (int boxWidth, int mesgLength, int justify)
{
/*
* Make sure the message isn't longer than the width.
* If it is, return 1.
*/
if (mesgLength >= boxWidth)
{
return (0);
}
/* Try to justify the message. */
if (justify == LEFT)
{
return (0);
}
else if (justify == RIGHT)
{
return ((boxWidth - mesgLength));
}
else if (justify == CENTER)
{
return ((int)((boxWidth - mesgLength) / 2));
}
else
{
return (justify);
}
}
/*
* This returns a substring of the given string.
*/
char *substring (char *string, int start, int width)
{
char *newstring = 0;
int mesglen = 0;
int y = 0;
int x = 0;
int lastchar = 0;
/* Make sure the string isn't null. */
if (string == 0)
{
return 0;
}
mesglen = (int)strlen (string);
/* Make sure we start in the correct place. */
if (start > mesglen)
{
return (newstring);
}
/* Create the new string. */
newstring = (char *)malloc (sizeof (char) * (width + 3));
/*cleanChar (newstring, width + 3, '\0');*/
if ((start + width) > mesglen)
{
lastchar = mesglen;
}
else
{
lastchar = width + start;
}
for (x=start; x<=lastchar; x++)
{
newstring[y++] = string[x];
}
newstring[lastchar + 1] = '\0';
newstring[lastchar + 2] = '\0';
return (newstring);
}
/*
* This frees a string if it is not null. This is a safety
* measure. Some compilers let you free a null string. I
* don't like that idea.
*/
void freeChar (char *string)
{
if (string != 0)
free (string);
}
void freeChtype (chtype *string)
{
if (string != 0)
free (string);
}
/*
* Corresponding list freeing
*/
void freeCharList (char **list, unsigned size)
{
while (size-- != 0) {
freeChar(list[size]);
list[size] = 0;
}
}
/*
* This performs a safe copy of a string. This means it adds the null
* terminator on the end of the string, like strdup().
*/
char *copyChar (char *original)
{
/* Declare local variables. */
char *newstring;
/* Make sure the string is not null. */
if (original == 0)
{
return 0;
}
newstring = (char *)malloc (strlen(original) + 1);
/* Copy from one to the other. */
strcpy (newstring, original);
/* Return the new string. */
return (newstring);
}
chtype *copyChtype (chtype *original)
{
/* Declare local variables. */
chtype *newstring;
int len, x;
/* Make sure the string is not null. */
if (original == 0)
{
return 0;
}
/* Create the new string. */
len = chlen (original);
newstring = (chtype *)malloc (sizeof(chtype) * (len + 4));
if (newstring == 0)
{
return (original);
}
/* Copy from one to the other. */
for (x=0; x < len; x++)
{
newstring[x] = original[x];
}
newstring[len] = '\0';
newstring[len + 1] = '\0';
/* Return the new string. */
return (newstring);
}
/*
* This reads a file and sticks it into the char ** provided.
*/
int readFile (char *filename, char **array, int maxlines)
{
FILE *fd;
char temp[BUFSIZ];
int lines = 0;
size_t len;
/* Can we open the file? */
if ((fd = fopen (filename, "r")) == 0)
{
return (-1);
}
/* Start reading the file in. */
while ((fgets (temp, sizeof(temp), fd) != 0) && lines < maxlines)
{
len = strlen (temp);
if (temp[len-1] == '\n')
{
temp[len-1] = '\0';
}
array[lines] = copyChar (temp);
lines++;
}
fclose (fd);
/* Clean up and return. */
return (lines);
}
#define DigitOf(c) ((c)-'0')
static int parseAttribute(char *string, int from, chtype *mask)
{
int pair = 0;
*mask = 0;
switch (string[from + 1])
{
case 'B': *mask = A_BOLD; break;
case 'D': *mask = A_DIM; break;
case 'K': *mask = A_BLINK; break;
case 'R': *mask = A_REVERSE; break;
case 'S': *mask = A_STANDOUT; break;
case 'U': *mask = A_UNDERLINE; break;
}
if (*mask != 0)
{
from++;
}
else if (isdigit((int)string[from + 1]) && isdigit((int)string[from + 2]))
{
#ifdef HAVE_START_COLOR
pair = DigitOf(string[from + 1]) * 10 + DigitOf(string[from + 2]);
*mask = COLOR_PAIR(pair);
#else
*mask = A_BOLD;
#endif
from += 2;
}
else if (isdigit((int)string[from + 1]))
{
#ifdef HAVE_START_COLOR
pair = DigitOf(string[from + 1]);
*mask = COLOR_PAIR(pair);
#else
*mask = A_BOLD;
#endif
from++;
}
return from;
}
/*
* This function takes a character string, full of format markers
* and translates them into a chtype * array. This is better suited
* to curses, because curses uses chtype almost exclusively
*/
chtype *char2Chtype (char *string, int *to, int *align)
{
chtype *result = 0;
chtype attrib;
chtype lastChar;
chtype mask;
int adjust;
int from;
int insideMarker;
int len;
int pass;
int start;
int used;
int x;
(*to) = 0;
*align = LEFT;
if (string != 0)
{
len = (int)strlen(string);
used = 0;
/*
* We make two passes because we may have indents and tabs to expand, and
* do not know in advance how large the result will be.
*/
for (pass = 0; pass < 2; pass++)
{
if (pass != 0)
{
if (result)
free(result);
if ((result = (chtype *)malloc((used+3) * sizeof(chtype))) == 0)
{
used = 0;
break;
}
}
adjust = 0;
attrib = A_NORMAL;
lastChar = 0;
start = 0;
used = 0;
x = 3;
/* Look for an alignment marker. */
if (!strncmp(string, "<C>", 3))
{
(*align) = CENTER;
start = 3;
}
else if (!strncmp(string, "<R>", 3))
{
(*align) = RIGHT;
start = 3;
}
else if (!strncmp(string, "<L>", 3))
{
start = 3;
}
else if (!strncmp(string, "<B=", 3))
{
/* Set the item index value in the string. */
if (result != 0)
{
result[0] = ' ';
result[1] = ' ';
result[2] = ' ';
}
/* Pull out the bullet marker. */
while (string[x] != '>' && string[x] != 0)
{
if (result != 0)
result[x] = string[x] | A_BOLD;
x++;
}
adjust = 1;
/* Set the alignment variables. */
start = x;
used = x;
}
else if (!strncmp(string, "<I=", 3))
{
from = 2;
x = 0;
while (string[++from] != '>' && string[from] != 0)
{
if (isdigit((int)string[from]))
{
adjust = (adjust * 10) + DigitOf(string[from]);
}
}
start = x + 4;
}
while (adjust-- > 0)
{
if (result != 0)
result[used] = ' ';
used++;
}
/* Set the format marker boolean to false. */
insideMarker = FALSE;
/* Start parsing the character string. */
for (from = start; from < len; from++)
{
/* Are we inside a format marker? */
if (! insideMarker)
{
if (string[from] == '<'
&& (string[from + 1] == '/'
|| string[from + 1] == '!'
|| string[from + 1] == '#'))
{
insideMarker = TRUE;
}
else if (string[from] == '\\' && string[from + 1] == '<')
{
from++;
if (result != 0)
result[used] = (A_CHARTEXT & string[from]) | attrib;
used++;
from++;
}
else if (string[from] == '\t')
{
int save = used;
for (x=0; x < 8 - (save % 8); x++)
{
if (result != 0)
result[used] = ' ';
used++;
}
}
else
{
if (result != 0)
result[used] = (A_CHARTEXT & string[from]) | attrib;
used++;
}
}
else
{
switch (string[from])
{
case '>':
insideMarker = 0;
break;
case '#':
{
lastChar = 0;
switch(string[from + 2])
{
case 'L':
switch (string[from + 1])
{
case 'L': lastChar = ACS_LLCORNER; break;
case 'U': lastChar = ACS_LRCORNER; break;
case 'H': lastChar = ACS_HLINE; break;
case 'V': lastChar = ACS_VLINE; break;
case 'P': lastChar = ACS_PLUS; break;
}
break;
case 'U':
switch (string[from + 1])
{
case 'L': lastChar = ACS_ULCORNER; break;
case 'U': lastChar = ACS_URCORNER; break;
}
break;
case 'T':
switch (string[from + 1])
{
case 'T': lastChar = ACS_TTEE; break;
case 'R': lastChar = ACS_RTEE; break;
case 'L': lastChar = ACS_LTEE; break;
case 'B': lastChar = ACS_BTEE; break;
}
break;
case 'A':
switch (string[from + 1])
{
case 'L': lastChar = ACS_LARROW; break;
case 'R': lastChar = ACS_RARROW; break;
case 'U': lastChar = ACS_UARROW; break;
case 'D': lastChar = ACS_DARROW; break;
}
break;
default:
if (string[from + 1] == 'D'
&& string[from + 2] == 'I')
lastChar = ACS_DIAMOND;
else
if (string[from + 1] == 'C'
&& string[from + 2] == 'B')
lastChar = ACS_CKBOARD;
else
if (string[from + 1] == 'D'
&& string[from + 2] == 'G')
lastChar = ACS_DEGREE;
else
if (string[from + 1] == 'P'
&& string[from + 2] == 'M')
lastChar = ACS_PLMINUS;
else
if (string[from + 1] == 'B'
&& string[from + 2] == 'U')
lastChar = ACS_BULLET;
else
if (string[from + 1] == 'S'
&& string[from + 2] == '1')
lastChar = ACS_S1;
else
if (string[from + 1] == 'S'
&& string[from + 2] == '9')
lastChar = ACS_S9;
}
if (lastChar != 0)
{
adjust = 1;
from += 2;
if (string[from + 1] == '(')
/* Check for a possible numeric modifier. */
{
from++;
adjust = 0;
while (string[++from] != ')' && string[from] != 0)
{
if (isdigit((int)string[from]))
{
adjust = (adjust * 10) + DigitOf(string[from]);
}
}
}
}
for (x=0; x < adjust; x++)
{
if (result != 0)
result[used] = lastChar | attrib;
used++;
}
break;
}
case '/':
from = parseAttribute(string, from, &mask);
attrib = attrib | mask;
break;
case '!':
from = parseAttribute(string, from, &mask);
attrib = attrib & ~mask;
break;
}
}
}
if (result != 0)
{
result[used] = 0;
result[used + 1] = 0;
}
/*
* If there are no characters, put the attribute into the
* the first character of the array.
*/
if (used == 0
&& result != 0)
{
result[0] = attrib;
}
}
*to = used;
}
return result;
}
/*
* This determines the length of a chtype string
*/
int chlen (chtype *string)
{
int result = 0;
if (string != 0)
{
while (string[result] != 0)
result++;
}
return (result);
}
/*
* This returns a pointer to char * of a chtype *
*/
char *chtype2Char (chtype *string)
{
/* Declare local variables. */
char *newstring;
int len = 0;
int x;
/* Is the string null? */
if (string == 0)
{
return (0);
}
/* Get the length of the string. */
len = chlen(string);
/* Make the new string. */
newstring = (char *)malloc (sizeof (char) * (len + 1));
/*cleanChar (newstring, len + 1, '\0');*/
/* Start translating. */
for (x=0; x < len; x++)
{
newstring[x] = (char)(string[x] & A_CHARTEXT);
}
/* Force a null character on the end of the string. */
newstring[len] = '\0';
/* Return it. */
return (newstring);
}
/*
* This takes a character pointer and returns the equivalent
* display type.
*/
EDisplayType char2DisplayType (char *string)
{
static const struct {
const char *name;
EDisplayType code;
} table[] = {
{ "CHAR", vCHAR },
{ "HCHAR", vHCHAR },
{ "INT", vINT },
{ "HINT", vHINT },
{ "UCHAR", vUCHAR },
{ "LCHAR", vLCHAR },
{ "UHCHAR", vUHCHAR },
{ "LHCHAR", vLHCHAR },
{ "MIXED", vMIXED },
{ "HMIXED", vHMIXED },
{ "UMIXED", vUMIXED },
{ "LMIXED", vLMIXED },
{ "UHMIXED", vUHMIXED },
{ "LHMIXED", vLHMIXED },
{ "VIEWONLY", vVIEWONLY },
{ 0, vINVALID },
};
/* Make sure we cover our bases... */
if (string != 0)
{
int n;
for (n = 0; table[n].name != 0; n++)
{
if (!strcmp(string, table[n].name))
return table[n].code;
}
}
return (EDisplayType)vINVALID;
}
/*
* This swaps two elements in an array.
*/
void swapIndex (char *list[], int i, int j)
{
char *temp;
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
/*
* This function is a quick sort alg which sort an array of
* char *. I wanted to use to stdlib qsort, but couldn't get the
* thing to work, so I wrote my own. I'll use qsort if I can get
* it to work.
*/
void quickSort (char *list[], int left, int right)
{
#ifdef HAVE_RADIXSORT
radixsort ((const u_char **)list, right-left+1, NULL, '\0');
#else
int i, last;
/* If there are fewer than 2 elements, return. */
if (left >= right)
{
return;
}
swapIndex (list, left, (left + right)/2);
last = left;
for (i=left + 1; i <= right; i++)
{
if (strcmp (list[i], list[left]) < 0)
{
swapIndex (list, ++last, i);
}
}
swapIndex (list, left, last);
quickSort (list, left, last-1);
quickSort (list, last + 1, right);
#endif
}
/*
* This strips white space off of the given string.
*/
void stripWhiteSpace (EStripType stripType, char *string)
{
/* Declare local variables. */
int stringLength = 0;
int alphaChar = 0;
int x = 0;
/* Make sure the string is not null. */
if (string == 0)
{
return;
}
/* Get the length of the string. */
stringLength = (int)strlen(string);
if (stringLength == 0)
{
return;
}
/* Strip the white space from the front. */
if (stripType == vFRONT || stripType == vBOTH)
{
/* Find the first non-whitespace character. */
while (string[alphaChar] == ' ' || string[alphaChar] == '\t')
{
alphaChar++;
}
/* Trim off the white space. */
if (alphaChar != stringLength)
{
for (x=0; x < (stringLength-alphaChar); x++)
{
string[x] = string[x + alphaChar];
}
string[stringLength-alphaChar] = '\0';
}
else
{
/* Set the string to zero. */
memset (string, 0, stringLength);
}
}
/* Get the length of the string. */
stringLength = (int)strlen(string)-1;
/* Strip the space from behind if it was asked for. */
if (stripType == vBACK || stripType == vBOTH)
{
/* Find the first non-whitespace character. */
while (string[stringLength] == ' ' || string[stringLength] == '\t')
{
string[stringLength--] = '\0';
}
}
}
static unsigned countChar(char *string, int separator)
{
unsigned result = 0;
int ch;
while ((ch = *string++) != 0)
{
if (ch == separator)
result++;
}
return result;
}
/*
* Split a string into a list of strings.
*/
char **CDKsplitString(char *string, int separator)
{
char **result = 0;
char *first;
char *temp;
unsigned item;
unsigned need;
if (string != 0)
{
need = countChar(string, separator) + 2;
if ((result = (char **)malloc(need * sizeof(char *))) != 0)
{
item = 0;
first = string;
for(;;)
{
while (*string != 0 && *string != separator)
string++;
need = string - first;
if ((temp = (char *)malloc(need+1)) == 0)
break;
memcpy(temp, first, need);
temp[need] = 0;
result[item++] = temp;
if (*string++ == 0)
break;
first = string;
}
result[item] = 0;
}
}
return result;
}
/*
* Count the number of items in a list of strings.
*/
unsigned CDKcountStrings(char **list)
{
unsigned result = 0;
if (list != 0)
{
while (*list++ != 0)
result++;
}
return result;
}
/*
* Free a list of strings
*/
void CDKfreeStrings(char **list)
{
if (list != 0)
{
void *base = (void *)list;
while (*list != 0)
free(*list++);
free(base);
}
}
int mode2Filetype (mode_t mode)
{
static const struct {
mode_t mode;
char code;
} table[] = {
#ifdef S_IFBLK
{ S_IFBLK, 'b' }, /* Block device */
#endif
{ S_IFCHR, 'c' }, /* Character device */
{ S_IFDIR, 'd' }, /* Directory */
{ S_IFREG, '-' }, /* Regular file */
#ifdef S_IFLNK
{ S_IFLNK, 'l' }, /* Socket */
#endif
{ S_IFSOCK, '@' }, /* Socket */
{ S_IFIFO, '&' }, /* Pipe */
};
int filetype = '?';
unsigned n;
for (n = 0; n < sizeof(table)/sizeof(table[0]); n++) {
if ((mode & S_IFMT) == table[n].mode) {
filetype = table[n].code;
break;
}
}
return filetype;
}
/*
* This function takes a mode_t type and creates a string represntation
* of the permission mode.
*/
int mode2Char (char *string, mode_t mode)
{
static struct {
mode_t mask;
unsigned col;
char flag;
} table[] = {
{ S_IRUSR, 1, 'r' },
{ S_IWUSR, 2, 'w' },
{ S_IXUSR, 3, 'x' },
{ S_IRGRP, 4, 'r' },
{ S_IWGRP, 5, 'w' },
{ S_IXGRP, 6, 'x' },
{ S_IROTH, 7, 'r' },
{ S_IWOTH, 8, 'w' },
{ S_IXOTH, 9, 'x' },
{ S_ISUID, 3, 's' },
{ S_ISGID, 6, 's' },
#ifdef S_ISVTX
{ S_ISVTX, 9, 't' },
#endif
};
/* Declare local variables. */
int permissions = 0;
int filetype = mode2Filetype(mode);
unsigned n;
/* Clean the string. */
cleanChar (string, 11, '-');
string[11] = '\0';
if (filetype == '?')
return -1;
for (n = 0; n < sizeof(table)/sizeof(table[0]); n++) {
if ((mode & table[n].mask) != 0) {
string[table[n].col] = table[n].flag;
permissions |= table[n].mask;
}
}
/* Check for unusual permissions. */
if (((mode & S_IXUSR) == 0) &&
((mode & S_IXGRP) == 0) &&
((mode & S_IXOTH) == 0) &&
(mode & S_ISUID) != 0)
{
string[3] = 'S';
}
return permissions;
}
/*
* This returns the length of the integer.
*/
int intlen (int value)
{
if (value < 0)
return 1 + intlen(-value);
else if (value >= 10)
return 1 + intlen(value/10);
return 1;
}
/*
* This opens the current directory and reads the contents.
*/
int getDirectoryContents (char *directory, char **list, int maxListSize)
{
/* Declare local variables. */
struct dirent *dirStruct;
int counter = 0;
DIR *dp;
/* Open the directory. */
dp = opendir (directory);
/* Could we open the directory? */
if (dp == 0)
{
return -1;
}
/* Read the directory. */
while ((dirStruct = readdir (dp)) != 0)
{
if (counter <= maxListSize)
{
list[counter++] = copyChar (dirStruct->d_name);
}
}
/* Close the directory. */
closedir (dp);
/* Sort the info. */
quickSort (list, 0, counter-1);
/* Return the number of files in the directory. */
return counter;
}
/*
* This looks for a subset of a word in the given list.
*/
int searchList (char **list, int listSize, char *pattern)
{
/* Declare local variables. */
int len = 0;
int Index = -1;
int x, ret;
/* Make sure the pattern isn't null. */
if (pattern == 0)
{
return Index;
}
len = (int)strlen (pattern);
/* Cycle through the list looking for the word. */
for (x=0; x < listSize; x++)
{
/* Do a string compare. */
ret = strncmp (list[x], pattern, len);
/*
* If 'ret' is less than 0, then the current word is
* alphabetically less than the provided word. At this
* point we will set the index to the current position.
* If 'ret' is greater than 0, then the current word is
* alphabettically greater than the given word. We should
* return with index, which might contain the last best
* match. If they are equal, then we've found it.
*/
if (ret < 0)
{
Index = ret;
}
else if (ret > 0)
{
return Index;
}
else
{
return x;
}
}
return -1;
}
/*
* This function checks to see if a link has been requested.
*/
int checkForLink (char *line, char *filename)
{
int len = 0;
int fPos = 0;
int x = 3;
/* Make sure the line isn't null. */
if (line == 0)
{
return -1;
}
len = (int)strlen (line);
/* Strip out the filename. */
if (line[0] == '<' && line[1] == 'F' && line[2] == '=')
{
/* Strip out the filename. */
while (x < len)
{
if (line[x] == '>')
{
break;
}
filename[fPos++] = line[x++];
}
filename[fPos] = '\0';
return 1;
}
return 0;
}
/*
* This strips out the filename from the pathname. I would have
* used rindex but it seems that not all the C libraries support
* it. :(
*/
char *baseName (char *pathname)
{
char *base = 0;
int pathLen = 0;
int pos = 0;
int Index = -1;
int x = 0;
/* Check if the string is null. */
if (pathname == 0)
{
return 0;
}
base = copyChar (pathname);
pathLen = (int)strlen (pathname);
/* Find the last '/' in the pathname. */
x = pathLen - 1;
while ((pathname[x] != '\0') && (Index == -1) && (x > 0))
{
if (pathname[x] == '/')
{
Index = x;
break;
}
x--;
}
/*
* If the index is -1, we never found one. Return a pointer
* to the string given to us.
*/
if (Index == -1)
{
return base;
}
/* Clean out the base pointer. */
memset (base, '\0', pathLen);
/*
* We have found an index. Copy from the index to the
* end of the string into a new string.
*/
for (x=Index + 1; x < pathLen; x++)
{
base[pos++] = pathname[x];
}
return base;
}
/*
* This strips out the directory from the pathname. I would have
* used rindex but it seems that not all the C libraries support
* it. :(
*/
char *dirName (char *pathname)
{
char *dir = 0;
int pathLen = 0;
int x = 0;
/* Check if the string is null. */
if (pathname == 0)
{
return 0;
}
dir = copyChar (pathname);
pathLen = (int)strlen (pathname);
/* Starting from the end, look for the first '/' character. */
x = pathLen;
while ((dir[x] != '/') && (x > 0))
{
dir[x--] = '\0';
}
/* Now dir either has nothing or the basename. */
if (dir[0] == '\0')
{
freeChar (dir);
/* If it has nothing, return nothing. */
return copyChar ("");
}
/* Otherwise, return the path. */
return dir;
}
/*
* If the dimension is a negative value, the dimension will
* be the full height/width of the parent window - the value
* of the dimension. Otherwise, the dimension will be the
* given value.
*/
int setWidgetDimension (int parentDim, int proposedDim, int adjustment)
{
int dimension = 0;
/* If the user passed in FULL, return the number of rows. */
if ((proposedDim == FULL) || (proposedDim == 0))
{
return parentDim;
}
/* If they gave a positive value, return it. */
if (proposedDim >= 0)
{
if (proposedDim >= parentDim)
{
return parentDim;
}
return (proposedDim + adjustment);
}
/*
* If they gave a negative value, then return the
* dimension of the parent minus the value given.
*/
dimension = parentDim + proposedDim;
/* Just to make sure. */
if (dimension < 0)
{
return parentDim;
}
return dimension;
}
/*
* This safely erases a given window.
*/
void eraseCursesWindow (WINDOW *window)
{
if (window != 0)
{
werase (window);
wnoutrefresh (window);
}
}
/*
* This safely deletes a given window.
*/
void deleteCursesWindow (WINDOW *window)
{
if (window != 0)
{
delwin (window);
}
}
/*
* This moves a given window
*/
void moveCursesWindow (WINDOW *window, int xpos, int ypos)
{
mvwin (window, ypos, xpos);
}
/*
* Return an integer like 'floor()', which returns a double.
*/
int floorCDK(double value)
{
int result = (int)value;
if (result > value) /* e.g., value < 0.0 and value is not an integer */
result--;
return result;
}
/*
* Return an integer like 'ceil()', which returns a double.
*/
int ceilCDK(double value)
{
return -floorCDK(-value);
}