📄 commline.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 06/05/06 */
/* */
/* COMMAND LINE MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Provides a set of routines for processing */
/* commands entered at the top level prompt. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* Brian L. Donnell */
/* */
/* Revision History: */
/* */
/* 6.24: Renamed BOOLEAN macro type to intBool. */
/* */
/* Refactored several functions and added */
/* additional functions for use by an interface */
/* layered on top of CLIPS. */
/* */
/*************************************************************/
#define _COMMLINE_SOURCE_
#include <stdio.h>
#define _STDIO_INCLUDED_
#include <string.h>
#include <ctype.h>
#include "setup.h"
#include "constant.h"
#include "argacces.h"
#include "constrct.h"
#include "cstrcpsr.h"
#include "envrnmnt.h"
#include "exprnpsr.h"
#include "filecom.h"
#include "memalloc.h"
#include "prcdrfun.h"
#include "prcdrpsr.h"
#include "router.h"
#include "scanner.h"
#include "strngrtr.h"
#include "symbol.h"
#include "utility.h"
#include "commline.h"
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
#if ! RUN_TIME
static int DoString(char *,int,int *);
static int DoComment(char *,int);
static int DoWhiteSpace(char *,int);
static int DefaultGetNextEvent(void *);
#endif
static void DeallocateCommandLineData(void *);
/****************************************************/
/* InitializeCommandLineData: Allocates environment */
/* data for command line functionality. */
/****************************************************/
globle void InitializeCommandLineData(
void *theEnv)
{
AllocateEnvironmentData(theEnv,COMMANDLINE_DATA,sizeof(struct commandLineData),DeallocateCommandLineData);
#if ! RUN_TIME
CommandLineData(theEnv)->BannerString = BANNER_STRING;
CommandLineData(theEnv)->EventFunction = DefaultGetNextEvent;
#endif
}
/*******************************************************/
/* DeallocateCommandLineData: Deallocates environment */
/* data for the command line functionality. */
/******************************************************/
static void DeallocateCommandLineData(
void *theEnv)
{
#if ! RUN_TIME
if (CommandLineData(theEnv)->CommandString != NULL)
{ rm(theEnv,CommandLineData(theEnv)->CommandString,CommandLineData(theEnv)->MaximumCharacters); }
#else
#if MAC_MCW || IBM_MCW || MAC_XCD
#pragma unused(theEnv)
#endif
#endif
}
#if ! RUN_TIME
/***************************************************/
/* ExpandCommandString: Appends a character to the */
/* command string. Returns TRUE if the command */
/* string was successfully expanded, otherwise */
/* FALSE. Expanding the string also includes */
/* adding a backspace character which reduces */
/* string's length. */
/***************************************************/
globle int ExpandCommandString(
void *theEnv,
int inchar)
{
register int k;
k = RouterData(theEnv)->CommandBufferInputCount;
CommandLineData(theEnv)->CommandString = ExpandStringWithChar(theEnv,inchar,CommandLineData(theEnv)->CommandString,&RouterData(theEnv)->CommandBufferInputCount,
&CommandLineData(theEnv)->MaximumCharacters,CommandLineData(theEnv)->MaximumCharacters+80);
return((RouterData(theEnv)->CommandBufferInputCount != k) ? TRUE : FALSE);
}
/******************************************************************/
/* FlushCommandString: Empties the contents of the CommandString. */
/******************************************************************/
globle void FlushCommandString(
void *theEnv)
{
if (CommandLineData(theEnv)->CommandString != NULL) rm(theEnv,CommandLineData(theEnv)->CommandString,CommandLineData(theEnv)->MaximumCharacters);
CommandLineData(theEnv)->CommandString = NULL;
CommandLineData(theEnv)->MaximumCharacters = 0;
RouterData(theEnv)->CommandBufferInputCount = 0;
}
/*********************************************************************************/
/* SetCommandString: Sets the contents of the CommandString to a specific value. */
/*********************************************************************************/
globle void SetCommandString(
void *theEnv,
char *str)
{
unsigned length;
FlushCommandString(theEnv);
length = strlen(str);
CommandLineData(theEnv)->CommandString = (char *)
genrealloc(theEnv,CommandLineData(theEnv)->CommandString,(unsigned) CommandLineData(theEnv)->MaximumCharacters,
(unsigned) CommandLineData(theEnv)->MaximumCharacters + length + 1);
strcpy(CommandLineData(theEnv)->CommandString,str);
CommandLineData(theEnv)->MaximumCharacters += (length + 1);
RouterData(theEnv)->CommandBufferInputCount += (int) length;
}
/*************************************************************/
/* SetNCommandString: Sets the contents of the CommandString */
/* to a specific value up to N characters. */
/*************************************************************/
globle void SetNCommandString(
void *theEnv,
char *str,
unsigned length)
{
FlushCommandString(theEnv);
CommandLineData(theEnv)->CommandString = (char *)
genrealloc(theEnv,CommandLineData(theEnv)->CommandString,(unsigned) CommandLineData(theEnv)->MaximumCharacters,
(unsigned) CommandLineData(theEnv)->MaximumCharacters + length + 1);
strncpy(CommandLineData(theEnv)->CommandString,str,length);
CommandLineData(theEnv)->CommandString[CommandLineData(theEnv)->MaximumCharacters + length] = 0;
CommandLineData(theEnv)->MaximumCharacters += (length + 1);
RouterData(theEnv)->CommandBufferInputCount += (int) length;
}
/******************************************************************************/
/* AppendCommandString: Appends a value to the contents of the CommandString. */
/******************************************************************************/
globle void AppendCommandString(
void *theEnv,
char *str)
{
CommandLineData(theEnv)->CommandString = AppendToString(theEnv,str,CommandLineData(theEnv)->CommandString,&RouterData(theEnv)->CommandBufferInputCount,&CommandLineData(theEnv)->MaximumCharacters);
}
/************************************************************/
/* AppendNCommandString: Appends a value up to N characters */
/* to the contents of the CommandString. */
/************************************************************/
globle void AppendNCommandString(
void *theEnv,
char *str,
unsigned length)
{
CommandLineData(theEnv)->CommandString = AppendNToString(theEnv,str,CommandLineData(theEnv)->CommandString,length,&RouterData(theEnv)->CommandBufferInputCount,&CommandLineData(theEnv)->MaximumCharacters);
}
/*****************************************************************************/
/* GetCommandString: Returns a pointer to the contents of the CommandString. */
/*****************************************************************************/
globle char *GetCommandString(
void *theEnv)
{
return(CommandLineData(theEnv)->CommandString);
}
/**************************************************************************/
/* CompleteCommand: Determines whether a string forms a complete command. */
/* A complete command is either a constant, a variable, or a function */
/* call which is followed (at some point) by a carriage return. Once a */
/* complete command is found (not including the parenthesis), */
/* extraneous parenthesis and other tokens are ignored. If a complete */
/* command exists, then 1 is returned. 0 is returned if the command was */
/* not complete and without errors. -1 is returned if the command */
/* contains an error. */
/**************************************************************************/
globle int CompleteCommand(
char *mstring)
{
int i;
char inchar;
int depth = 0;
int moreThanZero = 0;
int complete;
int error = 0;
if (mstring == NULL) return(0);
/*===================================================*/
/* Loop through each character of the command string */
/* to determine if there is a complete command. */
/*===================================================*/
i = 0;
while ((inchar = mstring[i++]) != EOS)
{
switch(inchar)
{
/*======================================================*/
/* If a carriage return or line feed is found, there is */
/* at least one completed token in the command buffer, */
/* and parentheses are balanced, then a complete */
/* command has been found. Otherwise, remove all white */
/* space beginning with the current character. */
/*======================================================*/
case '\n' :
case '\r' :
if (error) return(-1);
if (moreThanZero && (depth == 0)) return(1);
i = DoWhiteSpace(mstring,i);
break;
/*=====================*/
/* Remove white space. */
/*=====================*/
case ' ' :
case '\f' :
case '\t' :
i = DoWhiteSpace(mstring,i);
break;
/*======================================================*/
/* If the opening quotation of a string is encountered, */
/* determine if the closing quotation of the string is */
/* in the command buffer. Until the closing quotation */
/* is found, a complete command can not be made. */
/*======================================================*/
case '"' :
i = DoString(mstring,i,&complete);
if ((depth == 0) && complete) moreThanZero = TRUE;
break;
/*====================*/
/* Process a comment. */
/*====================*/
case ';' :
i = DoComment(mstring,i);
if (moreThanZero && (depth == 0) && (mstring[i] != EOS))
{
if (error) return(-1);
else return(1);
}
else if (mstring[i] != EOS) i++;
break;
/*====================================================*/
/* A left parenthesis increases the nesting depth of */
/* the current command by 1. Don't bother to increase */
/* the depth if the first token encountered was not */
/* a parenthesis (e.g. for the command string */
/* "red (+ 3 4", the symbol red already forms a */
/* complete command, so the next carriage return will */
/* cause evaluation of red--the closing parenthesis */
/* for "(+ 3 4" does not have to be found). */
/*====================================================*/
case '(' :
if ((depth > 0) || (moreThanZero == FALSE))
{
depth++;
moreThanZero = TRUE;
}
break;
/*====================================================*/
/* A right parenthesis decreases the nesting depth of */
/* the current command by 1. If the parenthesis is */
/* the first token of the command, then an error is */
/* generated. */
/*====================================================*/
case ')' :
if (depth > 0) depth--;
else if (moreThanZero == FALSE) error = TRUE;
break;
/*=====================================================*/
/* If the command begins with any other character and */
/* an opening parenthesis hasn't yet been found, then */
/* skip all characters on the same line. If a carriage */
/* return or line feed is found, then a complete */
/* command exists. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -