/*
* word_split.c -- split a string into words (or lines)
*
* PMF -- Padrone's MudFrontend, a frontend for (maybe mostly LP-)mud
* Thomas Padron-McCarthy (Email: padrone@lysator.liu.se), 1990, 1991
* Share and enjoy, but be nice: don't steal my program! Hugo is watching!
* This file latest updated: Sept 21, 1991
*
*/
#include <ctype.h>
#include "pmf.h"
/*---------------------------------------------------------------------------*/
/* This function splits the string the_line into words OR LINES.
* The string the_line is supposed to end with '\0' and contain no newlines.
* If the string contains an un-quoted $n (i. e. outside a double-quoted
* string and not quoted as $$n), the string is split into lines.
* If there is no un-quoted $n in the string linecp, it is split into words.
*
* The words or lines themselves are put in the buffer pointed to by
* the_buffer, and the_array will contain pointers into that buffer.
*
* The contents of the orignal line is not changed.
*
* If the string the_line was split into words, the number of words extracted
* from the string is returned. If it was split into lines, the NEGATIVE
* number of lines is returned.
* If there was an error, or there the line was blank, 0 is returned.
*
*/
int word_split(the_line, the_array, the_buffer)
char *the_line, *the_buffer;
char **the_array;
{
int wordnr, inside_quotes;
register char *line_cp, *buffer_cp;
line_cp = the_line;
buffer_cp = the_buffer;
wordnr = 0;
inside_quotes = 0;
while (*line_cp) {
/* Skip Botha */
while (*line_cp && isspace(*line_cp))
++line_cp;
/* Start reading a word, if there is one. */
if (!*line_cp)
return wordnr; /* End of string. Finished. */
else if (inside_quotes)
error("This cannot happen: a word started inside a string: %s", line_cp);
else if (*line_cp == '$') {
/* A character quoted by a $ character. Check next character. */
++line_cp;
if (*line_cp == 'n') {
/* Found an un-quoted $n. Split by lines instead of words! */
return -line_split(the_line, the_array, the_buffer);
}
else if (*line_cp == '\0') {
/* Last character in the line was a dollar. */
message("Malformed line: Tried to quote newline (last char on line was $).");
return 0;
}
else {
/* A $-quoted character, except for 'n' and '\0'. Just copy it. */
the_array[wordnr++] = buffer_cp; /* A word has started. */
*buffer_cp++ = *line_cp++; /* First character of that word. */
}
}
else if (*line_cp == '"') {
/* Found an un-quoted double quote. This means that a string starts here. */
inside_quotes = 1;
++line_cp;
the_array[wordnr++] = buffer_cp; /* A word has started. */
}
else {
/* Found a character other than dollar or double quote. */
the_array[wordnr++] = buffer_cp; /* A word has started. */
}
/* Read the word. If it started with " or $-something, those are already copied. */
while (*line_cp && *line_cp != '"' && (inside_quotes || !isspace(*line_cp))) {
if (*line_cp == '$') {
/* A character quoted by a $ character. Check next character. */
++line_cp;
if (*line_cp == 'n' && !inside_quotes) {
/* Found an un-quoted $n. Split by lines instead of words! */
return line_split(the_line, the_array, the_buffer);
}
else if (*line_cp == '\0') {
/* Last character in the line was a dollar. */
message("Malformed line: Tried to quote newline (last char on line was $).");
return 0;
}
else if (*line_cp == '"') {
/* A $ plus a ". */
*buffer_cp++ = *line_cp++;
}
else {
/* A $ plus a character. */
if (inside_quotes) {
*buffer_cp++ = '$';
*buffer_cp++ = *line_cp++;
}
else
*buffer_cp++ = *line_cp++;
}
}
else {
/* Found a character other than dollar or double quote. */
*buffer_cp++ = *line_cp++;
}
} /* Loop until end of line, end of this word, or end of this double-quoted string. */
if (!*line_cp && inside_quotes) {
message("Malformed line: String does not end (mismatched \" on input line: %s).", the_line);
return 0;
}
else if (*line_cp == '"') {
/* Found an un-quoted double quote. This means that this string ends here. */
inside_quotes = 0;
++line_cp;
}
/* Put the '\0' at the end of this word. */
*buffer_cp++ = '\0';
} /* while not end of line */
if (inside_quotes)
error("Ooops: Take care of this, Padrone!");
return wordnr;
} /* word_split */
syntax highlighted by Code2HTML, v. 0.9.1