Metropoli BBS
VIEWER: name.c MODE: TEXT (ASCII)
/***************************************************************************
 *		  Copyright (C) 1994  Charles P. Peterson                  *
 *	     4007 Enchanted Sun, San Antonio, Texas 78244-1254             *
 *              Email: Charles_P_Peterson@fcircus.sat.tx.us                *
 *                                                                         *
 *		  This is free software with NO WARRANTY.                  *
 *	      See gfft.c, or run program itself, for details.              *
 *		      Support is available for a fee.                      *
 ***************************************************************************
 *
 * Program:     gfft--General FFT analysis
 * File:        name.c
 * Purpose:     identify name and/or invoke method on it
 * Author:      Charles Peterson (CPP)
 * History:     30-May-1993 CPP; Created.
 *              13-January-1995 CPP (1.19) use <string.h> for ANSI compat
 *              20-Jan-1995 CPP; (1.23) Use GFFT Icon Tooltypes (here...
 *                allow '=' as separator)
 * Comments:    (1) Error display puts a (^) below first bad character
 */

#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "gfft.h"
#include "errcodes.h"

#define SEPARATOR(ch) (ch == ' ' || ch == '=' || ch == '\t')

static int cindex = 0;

Name_Info_St *invoke_method (char *command, 
			      Name_Info_St *command_name_list)
{
    Name_Info_St *this_command;
    char *argument_string;

    this_command = identify_name (command, command_name_list, TRUE);
    if (command[cindex] == '\0')
    {
	argument_string = &command[cindex];
    }
    else
    {
	argument_string = &command[ cindex + 1];
    }
    (*this_command->cfunction) (argument_string);
    return this_command;
}


/*
 * if report_error is TRUE,
 * there will be no direct return on error
 * only longjmp
 */
Name_Info_St *identify_name (char *command, 
				Name_Info_St *command_name_list, 
				BOOLEAN report_error)
{
    int i;
    int lastmatch = 0;
    int error_code = NO_SUCH_COMMAND;
    int command_offset;

    if (command[0] == '\0')
    {
	if (report_error)
	{
	    RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */
	}
	else
	{
	    return NULL;
	}
    }

    for (i = 0; strlen (command_name_list[i].full_string); i++)
    {
/*
 * First, find a minimum string that matches
 */
	cindex = 0;
	while (command[cindex] && command_name_list[i].min_string[cindex] &&
	       !SEPARATOR (command[cindex]) &&
	       toupper (command[cindex]) == toupper 
	       (command_name_list[i].min_string[cindex]))
	{
	    cindex++;
	    if (cindex > lastmatch)
	    {
		lastmatch = cindex;
	    }
	}
	if (command_name_list[i].min_string[cindex] != '\0')
        {
	    if (command[cindex] == '\0' || SEPARATOR (command[cindex]))
	    {
		error_code = AMBIGUOUS_COMMAND;
	    }
	    continue;
	}
/*
 * Then, insure that following characters don't mismatch
 */
	while (command[cindex] && command_name_list[i].full_string[cindex] &&
	       !SEPARATOR (command[cindex]) &&
	       toupper (command[cindex]) == toupper 
	       (command_name_list[i].full_string[cindex]))
	{
	    cindex++;
	    if (cindex > lastmatch)
	    {
		lastmatch = cindex;
	    }
	}
	if (command[cindex] == '\0' || SEPARATOR (command[cindex]))
	{
	    return &command_name_list[i];  /* SUCCESSFUL return */
	}
	continue;
    }
/*
 * No command has matched completely!
 */
    command_offset = command - Command;
    if (command_offset)
    {
	if (error_code == NO_SUCH_COMMAND)
	{
	    error_code = NO_SUCH_ARGUMENT;
	}
	else if (error_code == AMBIGUOUS_COMMAND)
	{
	    error_code = AMBIGUOUS_ARGUMENT;
	}
    }
    if (report_error)
    {
	command_error_message (error_code, command + lastmatch);
	RAISE_ERROR (NOTHING_SPECIAL); /* longjmp outa here! */
    }
    else
    {
	return NULL;
    }
/*
 * all returns or jumps above
 */
}
[ RETURN TO DIRECTORY ]