This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
magicka/deps/cdk-5.0-20161210/demos/command.c
2017-03-20 21:40:32 +10:00

447 lines
11 KiB
C

/* $Id: command.c,v 1.22 2016/12/04 15:22:16 tom Exp $ */
#include <cdk_test.h>
#ifdef HAVE_XCURSES
char *XCursesProgramName = "command";
#endif
/* Define some global variables. */
#define MAXHISTORY 5000
static const char *introductionMessage[] =
{
"<C></B/16>Little Command Interface", "",
"<C>Written by Mike Glover", "",
"<C>Type </B>help<!B> to get help."};
/* This structure is used for keeping command history. */
struct history_st
{
int count;
int current;
char *command[MAXHISTORY];
};
/* Define some local prototypes. */
char *uc (char *word);
void help (CDKENTRY *entry);
static BINDFN_PROTO (historyUpCB);
static BINDFN_PROTO (historyDownCB);
static BINDFN_PROTO (viewHistoryCB);
static BINDFN_PROTO (listHistoryCB);
static BINDFN_PROTO (jumpWindowCB);
/*
* Written by: Mike Glover
* Purpose:
* This creates a very simple command interface.
*/
int main (int argc, char **argv)
{
/* *INDENT-EQLS* */
CDKSCREEN *cdkscreen = 0;
CDKSWINDOW *commandOutput = 0;
CDKENTRY *commandEntry = 0;
chtype *convert = 0;
const char *prompt = "</B/24>Command >";
const char *title = "<C></B/5>Command Output Window";
int promptLen = 0;
int commandFieldWidth = 0;
struct history_st history;
char temp[600];
int junk;
/* Set up the history. */
history.current = 0;
history.count = 0;
/* Check the command line for options. */
while (1)
{
int ret;
/* Are there any more command line options to parse. */
if ((ret = getopt (argc, argv, "t:p:")) == -1)
{
break;
}
switch (ret)
{
case 'p':
prompt = copyChar (optarg);
break;
case 't':
title = copyChar (optarg);
break;
default:
break;
}
}
cdkscreen = initCDKScreen (NULL);
/* Start color. */
initCDKColor ();
/* Create the scrolling window. */
commandOutput = newCDKSwindow (cdkscreen, CENTER, TOP, -8, -2,
title, 1000, TRUE, FALSE);
/* Convert the prompt to a chtype and determine its length. */
convert = char2Chtype (prompt, &promptLen, &junk);
commandFieldWidth = COLS - promptLen - 4;
freeChtype (convert);
/* Create the entry field. */
commandEntry = newCDKEntry (cdkscreen, CENTER, BOTTOM,
0, prompt,
A_BOLD | COLOR_PAIR (8),
COLOR_PAIR (24) | '_',
vMIXED, commandFieldWidth, 1, 512, FALSE, FALSE);
/* Create the key bindings. */
bindCDKObject (vENTRY, commandEntry, KEY_UP, historyUpCB, &history);
bindCDKObject (vENTRY, commandEntry, KEY_DOWN, historyDownCB, &history);
bindCDKObject (vENTRY, commandEntry, KEY_TAB, viewHistoryCB, commandOutput);
bindCDKObject (vENTRY, commandEntry, CTRL ('^'), listHistoryCB, &history);
bindCDKObject (vENTRY, commandEntry, CTRL ('G'), jumpWindowCB, commandOutput);
/* Draw the screen. */
refreshCDKScreen (cdkscreen);
/* Show them who wrote this and how to get help. */
popupLabel (cdkscreen, (CDK_CSTRING2)introductionMessage, 5);
eraseCDKEntry (commandEntry);
/* Do this forever. */
for (;;)
{
char *command = 0;
char *upper;
/* Get the command. */
drawCDKEntry (commandEntry, ObjOf (commandEntry)->box);
command = activateCDKEntry (commandEntry, 0);
upper = uc (command);
/* Check the output of the command. */
if (strcmp (upper, "QUIT") == 0 ||
strcmp (upper, "EXIT") == 0 ||
strcmp (upper, "Q") == 0 ||
strcmp (upper, "E") == 0 ||
commandEntry->exitType == vESCAPE_HIT)
{
/* All done. */
freeChar (upper);
while (history.count-- > 0)
free (history.command[history.count]);
destroyCDKEntry (commandEntry);
destroyCDKSwindow (commandOutput);
destroyCDKScreen (cdkscreen);
endCDK ();
ExitProgram (EXIT_SUCCESS);
}
else if (strcmp (command, "clear") == 0)
{
/* Keep the history. */
history.command[history.count] = copyChar (command);
history.count++;
history.current = history.count;
cleanCDKSwindow (commandOutput);
cleanCDKEntry (commandEntry);
}
else if (strcmp (command, "history") == 0)
{
/* Display the history list. */
listHistoryCB (vENTRY, commandEntry, &history, 0);
/* Keep the history. */
history.command[history.count] = copyChar (command);
history.count++;
history.current = history.count;
}
else if (strcmp (command, "help") == 0)
{
/* Keep the history. */
history.command[history.count] = copyChar (command);
history.count++;
history.current = history.count;
/* Display the help. */
help (commandEntry);
/* Clean the entry field. */
cleanCDKEntry (commandEntry);
eraseCDKEntry (commandEntry);
}
else
{
/* Keep the history. */
history.command[history.count] = copyChar (command);
history.count++;
history.current = history.count;
/* Jump to the bottom of the scrolling window. */
jumpToLineCDKSwindow (commandOutput, BOTTOM);
/* Insert a line providing the command. */
sprintf (temp, "Command: </R>%s", command);
addCDKSwindow (commandOutput, temp, BOTTOM);
/* Run the command. */
execCDKSwindow (commandOutput, command, BOTTOM);
/* Clean out the entry field. */
cleanCDKEntry (commandEntry);
}
/* Clean up a little. */
freeChar (upper);
}
}
/*
* This is the callback for the down arrow.
*/
static int historyUpCB (EObjectType cdktype GCC_UNUSED, void *object,
void *clientData,
chtype key GCC_UNUSED)
{
CDKENTRY *entry = (CDKENTRY *)object;
struct history_st *history = (struct history_st *)clientData;
/* Make sure we don't go out of bounds. */
if (history->current == 0)
{
Beep ();
return (FALSE);
}
/* Decrement the counter. */
history->current--;
/* Display the command. */
setCDKEntryValue (entry, history->command[history->current]);
drawCDKEntry (entry, ObjOf (entry)->box);
return (FALSE);
}
/*
* This is the callback for the down arrow.
*/
static int historyDownCB (EObjectType cdktype GCC_UNUSED, void *object,
void *clientData,
chtype key GCC_UNUSED)
{
CDKENTRY *entry = (CDKENTRY *)object;
struct history_st *history = (struct history_st *)clientData;
/* Make sure we don't go out of bounds. */
if (history->current == history->count)
{
Beep ();
return (FALSE);
}
/* Increment the counter... */
history->current++;
/* If we are at the end, clear the entry field. */
if (history->current == history->count)
{
cleanCDKEntry (entry);
drawCDKEntry (entry, ObjOf (entry)->box);
return (FALSE);
}
/* Display the command. */
setCDKEntryValue (entry, history->command[history->current]);
drawCDKEntry (entry, ObjOf (entry)->box);
return (FALSE);
}
/*
* This callback allows the user to play with the scrolling window.
*/
static int viewHistoryCB (EObjectType cdktype GCC_UNUSED, void *object,
void *clientData,
chtype key GCC_UNUSED)
{
CDKSWINDOW *swindow = (CDKSWINDOW *)clientData;
CDKENTRY *entry = (CDKENTRY *)object;
/* Let them play... */
activateCDKSwindow (swindow, 0);
/* Redraw the entry field. */
drawCDKEntry (entry, ObjOf (entry)->box);
return (FALSE);
}
/*
* This callback jumps to a line in the scrolling window.
*/
static int jumpWindowCB (EObjectType cdktype GCC_UNUSED, void *object,
void *clientData,
chtype key GCC_UNUSED)
{
CDKENTRY *entry = (CDKENTRY *)object;
CDKSWINDOW *swindow = (CDKSWINDOW *)clientData;
CDKSCALE *scale = 0;
int line;
/* Ask them which line they want to jump to. */
scale = newCDKScale (ScreenOf (entry), CENTER, CENTER,
"<C>Jump To Which Line",
"Line",
A_NORMAL, 5,
0, 0, swindow->listSize, 1, 2, TRUE, FALSE);
/* Get the line. */
line = activateCDKScale (scale, 0);
/* Clean up. */
destroyCDKScale (scale);
/* Jump to the line. */
jumpToLineCDKSwindow (swindow, line);
/* Redraw the widgets. */
drawCDKEntry (entry, ObjOf (entry)->box);
return (FALSE);
}
/*
* This callback allows the user to pick from the history list from a
* scrolling list.
*/
static int listHistoryCB (EObjectType cdktype GCC_UNUSED, void *object,
void *clientData,
chtype key GCC_UNUSED)
{
CDKENTRY *entry = (CDKENTRY *)object;
struct history_st *history = (struct history_st *)clientData;
CDKSCROLL *scrollList;
int height = (history->count < 10 ? history->count + 3 : 13);
int selection;
/* No history, no list. */
if (history->count == 0)
{
/* Popup a little window telling the user there are no commands. */
const char *mesg[] =
{
"<C></B/16>No Commands Entered",
"<C>No History"
};
popupLabel (ScreenOf (entry), (CDK_CSTRING2)mesg, 2);
/* Redraw the screen. */
eraseCDKEntry (entry);
drawCDKScreen (ScreenOf (entry));
/* And leave... */
return (FALSE);
}
/* Create the scrolling list of previous commands. */
scrollList = newCDKScroll (ScreenOf (entry), CENTER, CENTER, RIGHT,
height, 20, "<C></B/29>Command History",
(CDK_CSTRING2)history->command,
history->count,
NUMBERS, A_REVERSE, TRUE, FALSE);
/* Get the command to execute. */
selection = activateCDKScroll (scrollList, 0);
destroyCDKScroll (scrollList);
/* Check the results of the selection. */
if (selection >= 0)
{
/* Get the command and stick it back in the entry field. */
setCDKEntryValue (entry, history->command[selection]);
}
/* Redraw the screen. */
eraseCDKEntry (entry);
drawCDKScreen (ScreenOf (entry));
return (FALSE);
}
/*
* This function displays help.
*/
void help (CDKENTRY *entry)
{
const char *mesg[25];
/* Create the help message. */
mesg[0] = "<C></B/29>Help";
mesg[1] = "";
mesg[2] = "</B/24>When in the command line.";
mesg[3] = "<B=history > Displays the command history.";
mesg[4] = "<B=Ctrl-^ > Displays the command history.";
mesg[5] = "<B=Up Arrow > Scrolls back one command.";
mesg[6] = "<B=Down Arrow> Scrolls forward one command.";
mesg[7] = "<B=Tab > Activates the scrolling window.";
mesg[8] = "<B=help > Displays this help window.";
mesg[9] = "";
mesg[10] = "</B/24>When in the scrolling window.";
mesg[11] = "<B=l or L > Loads a file into the window.";
mesg[12] = "<B=s or S > Saves the contents of the window to a file.";
mesg[13] = "<B=Up Arrow > Scrolls up one line.";
mesg[14] = "<B=Down Arrow> Scrolls down one line.";
mesg[15] = "<B=Page Up > Scrolls back one page.";
mesg[16] = "<B=Page Down > Scrolls forward one page.";
mesg[17] = "<B=Tab/Escape> Returns to the command line.";
mesg[18] = "";
mesg[19] = "<C> (</B/24>Refer to the scrolling window online manual for more help<!B!24>.)";
popupLabel (ScreenOf (entry), (CDK_CSTRING2)mesg, 20);
}
/*
* This converts a word to upper case.
*/
char *uc (char *word)
{
char *upper = 0;
int length = 0;
int x;
/* Make sure the word is not null. */
if (word == 0)
{
return 0;
}
length = (int)strlen (word);
/* Get the memory for the new word. */
upper = (char *)malloc (sizeof (char) * (size_t) (length + 2));
if (upper == 0)
{
return (word);
}
/* Start converting the case. */
for (x = 0; x < length; x++)
{
int ch = (unsigned char)(word[x]);
if (isalpha (ch))
{
upper[x] = (char)toupper (ch);
}
else
{
upper[x] = word[x];
}
}
upper[length] = '\0';
return upper;
}