scummvm/engines/glk/jacl/encapsulate.cpp
2019-10-07 19:01:52 -07:00

280 lines
6.9 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "glk/jacl/jacl.h"
#include "glk/jacl/types.h"
#include "glk/jacl/prototypes.h"
namespace Glk {
namespace JACL {
extern struct synonym_type *synonym_table;
extern struct filter_type *filter_table;
char text_buffer[1024];
/* THIS IS A STRING CONSTANT TO POINT TO WHENEVER A COMMA IS
* USED IN THE PLAYER'S INPUT */
const char *comma = "comma\0";
const char *then = "then\0";
const char *word[MAX_WORDS];
int quoted[MAX_WORDS];
int percented[MAX_WORDS];
int wp;
void
encapsulate() {
int index,
length;
int position = 0;
int new_word = TRUE;
length = strlen(text_buffer);
/* QUOTED IS USED TO STORE WHETHER EACH WORD WAS ENCLOSED IN QUOTES
* IN THE PLAYERS COMMAND - RESET EACH WORD TO NO */
for (index = 0; index < MAX_WORDS; index++) {
quoted[index] = 0;
percented[index] = 0;
}
for (index = 0; index < length; index++) {
switch (text_buffer[index]) {
case ':':
case '\t':
case ' ':
case ',':
text_buffer[index] = 0;
new_word = TRUE;
break;
case ';':
case '#':
case '\r':
case '\n':
/* TERMINATE THE WHOLE COMMAND ON HITTING A NEWLINE CHARACTER, A
* SEMICOLON OR A HASH */
text_buffer[index] = 0;
index = length;
break;
case '"':
index++;
/* NEED TO REMEMBER THAT THIS WORD WAS ENCLOSED IN QUOTES FOR
* THE COMMAND 'write'*/
quoted[position] = 1;
word[position] = &text_buffer[index];
if (position < MAX_WORDS)
position++;
/* IF A WORD IS ENCLOSED IN QUOTES, KEEP GOING UNTIL THE END
* OF THE LINE OR A CLOSING QUOTE IS FOUND, NOT BREAKING AT
* WHITESPACE AS USUAL */
for (; index < length; index++) {
if (text_buffer[index] == '"') {
text_buffer[index] = 0;
new_word = TRUE;
break;
} else if (text_buffer[index] == '\r' || text_buffer[index] == '\n') {
text_buffer[index] = 0;
index = length;
break;
}
}
break;
default:
if (new_word) {
if (text_buffer[index] == '%' && text_buffer[index + 1] != ' ' && text_buffer[index + 1] != '\t') {
percented[position]++;
break;
}
word[position] = &text_buffer[index];
new_word = FALSE;
if (position < MAX_WORDS)
position++;
}
break;
}
}
/* NULL OUT ALL THE WORD POINTERS BEYOND THE LAST WORD */
for (index = position; index < MAX_WORDS; index++)
word[index] = NULL;
wp = 0;
}
// THIS VERSION OF ENCAPSULATE DOESN'T LOOK FOR CERTAIN SPECIAL CHARACTERS
void
command_encapsulate() {
int index,
length;
int position = 0;
int new_word = TRUE;
length = strlen(text_buffer);
// QUOTED IS USED TO STORE WHETHER EACH WORD WAS ENCLOSED IN QUOTES
// IN THE PLAYERS COMMAND - RESET EACH WORD TO NO
for (index = 0; index < MAX_WORDS; index++) {
quoted[index] = 0;
}
for (index = 0; index < length; index++) {
// REDUSE EVERYTHING TO LOWER CASE EXCEPT TEXT ENCLOSED IN QUOTES
text_buffer[index] = tolower((int) text_buffer[index]);
switch (text_buffer[index]) {
case ':':
case '\t':
case ' ':
text_buffer[index] = 0;
new_word = TRUE;
break;
case ',':
text_buffer[index] = 0;
// SET THIS WORD TO POINT TO A STRING CONSTANT OF 'comma' AS THE
// COMMA ITSELF WILL BE NULLED OUT TO TERMINATE THE PRECEEDING
// WORD IN THE COMMAND.
word[position] = comma;
if (position < MAX_WORDS)
position++;
new_word = TRUE;
break;
case '.':
text_buffer[index] = 0;
// SET THIS WORD TO POINT TO A STRING CONSTANT OF 'comma' AS THE
// COMMA ITSELF WILL BE NULLED OUT TO TERMINATE THE PRECEEDING
// WORD IN THE COMMAND
word[position] = then;
if (position < MAX_WORDS)
position++;
new_word = TRUE;
break;
case ';':
case '\r':
case '\n':
// TERMINATE THE WHOLE COMMAND ON HITTING A NEWLINE CHARACTER, A
// SEMICOLON OR A HASH
text_buffer[index] = 0;
index = length;
break;
case '"':
index++;
// NEED TO REMEMBER THAT THIS WORD WAS ENCLOSED IN QUOTES FOR
// THE COMMAND 'write'
quoted[position] = 1;
word[position] = &text_buffer[index];
if (position < MAX_WORDS)
position++;
// IF A WORD IS ENCLOSED IN QUOTES, KEEP GOING UNTIL THE END
// OF THE LINE OR A CLOSING QUOTE IS FOUND, NOT BREAKING AT
// WHITESPACE AS USUAL
for (; index < length; index++) {
if (text_buffer[index] == '"') {
text_buffer[index] = 0;
new_word = TRUE;
break;
} else if (text_buffer[index] == '\r' || text_buffer[index] == '\n') {
text_buffer[index] = 0;
index = length;
break;
}
}
break;
default:
if (new_word) {
word[position] = &text_buffer[index];
new_word = FALSE;
if (position < MAX_WORDS)
position++;
}
break;
}
}
// NULL OUT ALL THE WORD POINTERS BEYOND THE LAST WORD
for (index = position; index < MAX_WORDS; index++) {
word[index] = NULL;
}
wp = 0;
}
void
jacl_truncate() {
int index,
counter,
match;
int position = 0;
struct synonym_type *synonym;
struct filter_type *filter = filter_table;
// REMOVE ALL THE DEFINED 'filter's FROM THE PLAYER'S COMMAND
if (filter != NULL) {
while (word[position] != NULL) {
match = FALSE;
do {
if (!strcmp(word[position], filter->word)) {
for (index = position; word[index + 1] != NULL;
index++)
word[index] = word[index + 1];
word[index] = NULL;
match = TRUE;
}
filter = filter->next_filter;
} while (filter != NULL && !match);
filter = filter_table;
if (!match)
position++;
};
}
// SUBTITUTE ALL THE DEFINED 'synonym's IN THE PLAYER'S COMMAND
if (synonym_table != NULL) {
for (counter = 0; word[counter] != NULL; counter++) {
synonym = synonym_table;
do {
if (!strcmp(word[counter], synonym->original)) {
word[counter] = synonym->standard;
break;
}
if (synonym->next_synonym != NULL)
synonym = synonym->next_synonym;
else
break;
} while (TRUE);
}
}
}
} // End of namespace JACL
} // End of namespace Glk