Пример #1
0
void mereducemenucodes (bigstring bs, boolean *flenabled, boolean *flchecked) {

	/*
	4.1b8 dmb: common code for mebuildmenu, memenuitemchanged, and mecheckformulas
	
	handles item disabling with '(', and checkmark with '!'
	
	7.0b23 PBS: no longer static -- used in oppopup.c for right-click menus.
	*/
	
	*flenabled = (stringlength (bs) > 1) || (getstringcharacter (bs, 0) != '-');
		// !equalstrings (bs, (ptrstring) "\p-"); /*all dotted lines are disabled*/
	
	if (getstringcharacter (bs, 0) == '(' && lastchar (bs) != ')') { /*4.1b6 dmb*/
	
		deletestring (bs, 1, 1);
		
		*flenabled = false;
		}
	
	*flchecked = false;
	
	if ((stringlength (bs) > 1) && (getstringcharacter (bs, 0) == '!')) { /*4.1b8 dmb*/
	
		deletestring (bs, 1, 1);
		
		*flchecked = true;
		}
	} /*mereducemenucodes*/
Пример #2
0
/**
 * @relates texteditor
 * @brief Delete the character under the cursor.
 **/
void texteditDelete(texteditor * editor)
{
	int i;

	if (editor->selectflag) {
		texteditClearSelectedText(editor);
		return;
	}

	if (editor->pos < strlen(editor->curline->s)) {
		/* Slide everything after the cursor backward */
		for (i = editor->pos; i < strlen(editor->curline->s); i++)
			editor->curline->s[i] = editor->curline->s[i+1];
		editor->updateflags |= TUD_CENTER;
	}
	else if (strlen(editor->curline->s) == 0 && !(editor->text->first == editor->text->last)) {
		/* This string is empty: destroy */
		editor->text->cur = editor->curline;
		deletestring(editor->text);
		editor->curline = editor->text->cur;
		editor->pos = strlen(editor->curline->s);
		editor->updateflags |= TUD_EDITAREA;
	}
	else if (editor->curline->next != NULL) {
		if (strlen(editor->curline->next->s) == 0) {
			/* Next string is empty: destroy */
			editor->text->cur = editor->curline->next;
			deletestring(editor->text);
			editor->updateflags |= TUD_BOTTOM;
		}
		else if (strlen(editor->curline->s) + 1 < editor->wrapwidth) {
			char * nextline;

			/* merge lines; wordwrap */
			i = strlen(editor->curline->s);
			if (editor->curline->s[i-1] != ' ' && editor->curline->next->s[0] != ' ') {
				/* add a space at the end */
				editor->curline->s[i]   = ' ';
				editor->curline->s[++i] = 0;
			}

			/* Remove the next line */
			editor->text->cur = editor->curline->next;
			nextline = removestring(editor->text);
			editor->text->cur = editor->curline;

			/* Wordwrap the next line onto the end of the current line */
			editor->pos = wordwrap(editor->text, nextline, i, -1, editor->wrapwidth, editor->linewidth);
			editor->curline = editor->text->cur;

			free(nextline);
			editor->updateflags |= TUD_CENTER | TUD_BOTTOM | TUD_TOP;
		}
	}
}
Пример #3
0
void zlaunchcleanup(zlaunchinfo* zli)
{
	stringvector files = filetosvector(ZL_RMFILENAME, 0, 0);

	/* Start from the top */
	svmovetofirst(&files);

	while (files.cur != NULL) {
		/* Test for a displacement */
		char* dispfilename = strstr(files.cur->s, DISPLACE_SEPERATOR);
		if (dispfilename != NULL) {
			/* Restore original file */
			char* origfilename = str_duplen(files.cur->s,
																			dispfilename - files.cur->s);
			dispfilename += strlen(DISPLACE_SEPERATOR);

			rename(dispfilename, origfilename);

			free(origfilename);
		} else {
			/* Delete the file */
			remove(files.cur->s);
		}

		/* Delete the string */
		deletestring(&files);
	}
	
	remove(ZL_RMFILENAME);
}
Пример #4
0
/* deletestringvector - deletes entire vector and every s */
int deletestringvector(stringvector * v)
{
	if (v == NULL)
		return 1;

	v->cur = v->last;
	while (deletestring(v) != 1);

	return 0;
}
Пример #5
0
void MCParagraph::deleteselection(void)
{
	if (m_start_index != m_end_index)
	{
		m_focused_index = m_start_index;
		deletestring(m_start_index, m_end_index);
	}

	m_start_index = m_end_index = m_original_index = 0xffff;
	m_state &= ~kStateHilited;
}
Пример #6
0
/**
 * @relates texteditor
 * @brief Delete the current line.
 **/
void texteditDeleteLine(texteditor * editor)
{
	/* Move cursor to the beginning of the line */
	editor->pos = 0;
	editor->text->cur = editor->curline;

	if (editor->curline->next != NULL) {
		/* Delete the current line, moving curline forward */
		editor->curline = editor->curline->next;
		deletestring(editor->text);
		editor->updateflags |= TUD_CENTER | TUD_BOTTOM;
	}
	else if (editor->curline->prev != NULL) {
		/* Delete the current line, moving curline backward */
		editor->curline = editor->curline->prev;
		deletestring(editor->text);
		editor->updateflags |= TUD_TOP | TUD_CENTER;
	}
	else {
		/* Clear the current (and only) line */
		editor->curline->s[0] = 0;
		editor->updateflags |= TUD_CENTER;
	}
}
Пример #7
0
int editbox(char *title, stringvector * sv, int editwidth, int flags, displaymethod * d)
{
	int key;                /* the key */
	int i, j;               /* general counters */
	int done = 0;           /* true when editing/viewing is done */
	int updateflags;        /* flags to determine what needs update */
	stringnode *centerstr;  /* str in center of dialog */
	stringnode *loopstr;    /* node pointer for use in looping */
	int selChar = 0;

	/* vars only relating to editing */
	int pos = 0;            /* position in sv->cur->s */
	char *tmpstr;           /* temporary string for pushing */
	char strbuf[80] = "";   /* general buffer */
	static char savefilename[SAVEFILENAME_LEN] = "temp.zoc";

	/* selection variables */
	int selectFlag = 0;     /* Status of the shift key */
	int selPos = -1;        /* Position of cursor when selection started; -1 when no selection */
	int selLineOffset = 0;  /* Offset of line where selection started;
	                           positive when below centerstr, negative when above */

	/* statics */
	static int insertflag = 1;   /* nonzero when in insert mode */
	static int wrapwidth = 42;   /* where to wrap */

	/* if there is no string, add one */
	if (sv->cur == NULL || sv->first == NULL || sv->last == NULL)
		pushstring(sv, strcpy((char *) malloc(editwidth + 2), ""));

	if (sv->cur == NULL)
		return 0;

	centerstr = sv->cur;

	if (editwidth == EDITBOX_NOEDIT) {
		d->cursorgo(9, 13);
		/* Look for @title on first line */
		if ((flags & EDITBOX_ZOCMODE) && sv->first != NULL && sv->first->s[0] == '@') {
			/* Display the first line as the title, not in the box itself */
			if (sv->first->s[1] != '\x0')
				title = sv->first->s + 1; /* What's the harm? We're only looking. */
			if (centerstr == sv->first)
				centerstr = centerstr->next;
		}
	}
	
	/* Check for NULL after advancing past @title, if we did so */
	if (centerstr == NULL)
		return 0;

	drawscrollbox(d, 0, 0, 1);
	updateflags = U_ALL;

	while (!done) {
		if (editwidth)
			d->cursorgo(9 + pos, 13);

		/* If in select mode, center line should be updated no matter what */
		if (selPos != -1)
			updateflags |= U_CENTER;

		if (updateflags & U_PANEL && editwidth)
			draweditpanel(insertflag, wrapwidth, flags & EDITBOX_ZOCMODE, d);

		sv->cur = centerstr;
		updateditbox(d, sv, updateflags, editwidth, flags, title, selPos == -1);
		updateflags = U_NONE;

		/* Draw highlighted text if applicable */
		if (selPos != -1) {
			int startPos = 0, endPos = 0;
			if (selLineOffset > 0) {
				startPos = pos;
				endPos = strlen(centerstr->s);
			} else if (selLineOffset < 0) {
				startPos = 0;
				endPos = pos;
			} else {
				if (selPos > pos) {
					startPos = pos;
					endPos = selPos;
				} else {
					startPos = selPos;
					endPos = pos;
				}
			}
			for (j = startPos; j < endPos; j++)
				d->putch(9 + j, 13, centerstr->s[j], ZOC_HIGHLIGHT_COLOUR);

			if (selLineOffset != 0) {
				/* Draw meat lines */
				if (selLineOffset > 0) {
					for (i = 1, loopstr = centerstr->next; i < selLineOffset && i < 8 && loopstr != NULL; i++, loopstr = loopstr->next)
						d->print_discrete(9, 13 + i, ZOC_HIGHLIGHT_COLOUR, loopstr->s);
				} else {
					for (i = -1, loopstr = centerstr->prev; i > selLineOffset && i > -8 && loopstr != NULL; i--, loopstr = loopstr->prev)
						d->print_discrete(9, 13 + i, ZOC_HIGHLIGHT_COLOUR, loopstr->s);
				}

				/* Draw farthest line from centerstr */
				if (i < 8 && i > -8 && loopstr != NULL) {
					if (selLineOffset < 0) {
						startPos = selPos;
						endPos = strlen(loopstr->s);
					} else if (selLineOffset > 0) {
						startPos = 0;
						endPos = selPos;
					}
					for (j = startPos; j < endPos; j++)
						d->putch_discrete(9 + j, 13 + i, loopstr->s[j], ZOC_HIGHLIGHT_COLOUR);
				}
			}

			/* Update the display */
			d->update(3, 4, 51, 19);
		}

		/* Get the key */
		key = d->getch();

		selectFlag = d->shift();

		/* If we just started selecting, remember where we started */
		if (selectFlag && selPos == -1)
			selPos = pos;

		/* Keys which work when editing and browsing */
		switch (key) {
			case DKEY_UP:  /* Up Arrow */
				if (centerstr->prev != NULL && !(!editwidth && centerstr->prev == sv->first && sv->first->s[0] == '@')) {
					centerstr = centerstr->prev;
					if (pos > strlen(centerstr->s))
						pos = strlen(centerstr->s);
					if (selectFlag)
						selLineOffset++;
					updateflags = U_EDITAREA;
				}
				break;

			case DKEY_DOWN:  /* Down Arrow */
				if (centerstr->next != NULL) {
					centerstr = centerstr->next;
					if (pos > strlen(centerstr->s))
						pos = strlen(centerstr->s);
					if (selectFlag)
						selLineOffset--;
					updateflags = U_EDITAREA;
				}
				break;

			case DKEY_PAGEUP:  /* Page Up */
				for (i = 0; i < 7 && centerstr->prev != NULL && !(!editwidth && centerstr->prev == sv->first && sv->first->s[0] == '@'); i++) {
					centerstr = centerstr->prev;
					if (selectFlag)
						selLineOffset++;
				}
				if (pos > strlen(centerstr->s))
					pos = strlen(centerstr->s);
				updateflags = U_EDITAREA;
				break;

			case DKEY_PAGEDOWN:  /* Page Down */
				for (i = 0; i < 7 && centerstr->next != NULL; i++) {
					centerstr = centerstr->next;
					if (selectFlag)
						selLineOffset--;
				}
				if (pos > strlen(centerstr->s))
					pos = strlen(centerstr->s);
				updateflags = U_EDITAREA;
				break;

			case DKEY_CTRL_C:
			case DKEY_CTRL_X:
				/* Copy to register */
				if (selPos != -1) {
					stringnode *selStart = centerstr, *selEnd = centerstr;
					int selStartPos, selEndPos;
					selectionBounds bounds;

					if (selLineOffset > 0) {
						/* Other end of selection is below current line, move end down to meet it. */
						selStartPos = pos;
						selEndPos = selPos;
						for (i = 0; i < selLineOffset; i++)
							if (selEnd->next != NULL)
								selEnd = selEnd->next;
					} else if (selLineOffset < 0) {
						/* Other end of selection is above current line, move end up to meet it. */
						selStartPos = selPos;
						selEndPos = pos;
						for (i = 0; i > selLineOffset; i--)
							if (selStart->prev != NULL)
								selStart = selStart->prev;
					} else {
						/* Selection is only on current line: selStartPos gets the lesser of selPos & pos */
						if (selPos > pos) {
							selStartPos = pos;
							selEndPos = selPos;
						} else {
							selStartPos = selPos;
							selEndPos = pos;
						}
					}

					bounds.startLine = selStart;
					bounds.endLine = selEnd;
					bounds.startPos = selStartPos;
					bounds.endPos = selEndPos;

					regyank('\"', bounds);
				}
				break;

			case DKEY_ESC:
				if (editwidth > EDITBOX_NOEDIT)
					done = EDITBOX_OK;
				else
					done = EDITBOX_CANCEL;
				break;
		}

		/* Keys pertaining to browsing only */
		if (editwidth == EDITBOX_NOEDIT) {
			switch (key) {
				case DKEY_ENTER:
					done = EDITBOX_OK;
					break;
			}

			/* If movement is enabled... */
			if (flags & EDITBOX_MOVEMENT) {
				switch (key) {
					case DKEY_BACKSPACE:
						done = EDITBOX_BACK;
						break;

					case DKEY_RIGHT:
						done = EDITBOX_FORWARD;
						break;

					case DKEY_LEFT:
						done = EDITBOX_BACKWARD;
						break;

					case DKEY_F1:
						done = EDITBOX_HELP;
						break;
				}
			}
		}

		/* Keys pertaining to editing only */
		if (editwidth > EDITBOX_NOEDIT) {
			/* We are edititing! Yea! Fun time! */

			switch (key) {
				case DKEY_NONE:
					break;

				/********** Movement ***********/

				case DKEY_LEFT:  /* Left Arrow */
					if (pos > 0)
						pos--;
					else {
						/* Move to end of previous line (or current line) */
						if (centerstr->prev != NULL) {
							centerstr = centerstr->prev;
							updateflags = U_EDITAREA;
						}
						pos = strlen(centerstr->s);
						if (selectFlag)
							selLineOffset++;
					}
					break;

				case DKEY_RIGHT:    /* Right Arrow */
					if (pos < strlen(centerstr->s))
						pos++;
					else {
						/* Move to begining of next line (or current line) */
						if (centerstr->next != NULL) {
							centerstr = centerstr->next;
							updateflags = U_EDITAREA;
						}
						pos = 0;
						if (selectFlag)
							selLineOffset--;
					}
					break;

				case DKEY_HOME: /* Home */
					pos = 0;
					break;

				case DKEY_END: /* End */
					pos = strlen(centerstr->s);
					break;

				case DKEY_UP:
				case DKEY_DOWN:
				case DKEY_PAGEUP:
				case DKEY_PAGEDOWN:
				case DKEY_CTRL_C:
					/* Avoid inserting these keys */
					break;

				/********** Insert & Delete ***********/

				case DKEY_INSERT:
					/* Insert */
					insertflag = !insertflag;
					updateflags = U_PANEL;
					break;

				case DKEY_DELETE:
					/* Delete */
					if (pos < strlen(centerstr->s)) {
						for (i = pos; i < strlen(centerstr->s); i++)
							centerstr->s[i] = centerstr->s[i+1];
						updateflags = U_CENTER;
					}
					else if (strlen(centerstr->s) == 0 && !(sv->first == sv->last)) {
						/* This string is empty: destroy */
						sv->cur = centerstr;
						deletestring(sv);
						centerstr = sv->cur;
						pos = strlen(centerstr->s);
						updateflags = U_EDITAREA;
					}
					else if (centerstr->next != NULL) {
						if (strlen(centerstr->next->s) == 0) {
							/* Next string is empty: destroy */
							sv->cur = centerstr->next;
							deletestring(sv);
							updateflags = U_BOTTOM;
						}
						else if (strlen(centerstr->s) + 1 < wrapwidth) {
							/* merge lines; wordwrap */
							i = strlen(centerstr->s);
							if (centerstr->s[i-1] != ' ' && centerstr->next->s[0] != ' ') {
								/* add a space at the end */
								centerstr->s[i]   = ' ';
								centerstr->s[++i] = 0;
							}
							sv->cur = centerstr->next;
							tmpstr = removestring(sv);
							sv->cur = centerstr;
							pos = wordwrap(sv, tmpstr, i, -1, wrapwidth, editwidth);
							centerstr = sv->cur;
							free(tmpstr);
							updateflags = U_CENTER | U_BOTTOM | U_TOP;
						}
					}
					break;

				/****** ZOC Mode & Wordwrap settings **********/

				case DKEY_ALT_Z: /* alt-z - toggle ZOC mode */
					flags ^= EDITBOX_ZOCMODE;
					updateflags = U_PANEL | U_EDITAREA;
					break;

				case DKEY_ALT_MINUS: /* alt - */
					if (wrapwidth > 10)
						wrapwidth--;
					else
						wrapwidth = editwidth;
					updateflags = U_PANEL;
					break;

				case DKEY_ALT_PLUS:    /* alt + */
					if (wrapwidth < editwidth)
						wrapwidth++;
					else
						wrapwidth = 10;
					updateflags = U_PANEL;
					break;

				/****** Help dialog ******/

				case DKEY_F1: /* F1: help dialog */
					/* Look for #command on current line for lookup in help */
					i = pos;
					while (i > 0 && centerstr->s[i] != '#')
						i--;

					if (centerstr->s[i] == '#') {
						/* Copy the command onto tmpstr */
						tmpstr = str_dup(centerstr->s + i + 1);
						for (i = 0; tmpstr[i] != ' ' && tmpstr[i] != '\0'; i++)
							;
						tmpstr[i] = '\0';

						if (zztoopFindCommand(tmpstr) == -1) {
							/* If it's not a valid command, don't bother looking for it */
							tmpstr[0] = '\0';
						}

						/* Display the help file with the command as the topic */
						helpsectiontopic("langref", tmpstr, d);
						
						free(tmpstr);
					} else {
						/* Display the oop help file */
						helpsectiontopic("langref", NULL, d);
					}

					updateflags = U_ALL;
					break;

				/********* ZZM Testing ********************/
				case DKEY_CTRL_T:
				case DKEY_ALT_T:
					sv->cur = centerstr;
					testMusic(sv, key == DKEY_CTRL_T, editwidth, flags, d);
					updateflags = U_EDITAREA;
					break;

				/********* File access operations *********/
				case DKEY_ALT_O: /* alt+o: open file */
				case DKEY_ALT_I:
					/* alt+i: insert file */
					{
						stringvector filetypelist;
						char* filename = NULL;
						
						initstringvector(&filetypelist);

						pushstring(&filetypelist, "*.zoc");
						pushstring(&filetypelist, "*.txt");
						pushstring(&filetypelist, "*.hlp");
						pushstring(&filetypelist, "*.zzm");
						pushstring(&filetypelist, "*.*");
						if (editbox("Select A File Type", &filetypelist, 0, 1, d) == 27) {
							updateflags = U_EDITAREA | U_TITLE;
							break;
						}

						if (filetypelist.cur != NULL)
							filename =
								filedialog(".", filetypelist.cur->s + 2,
													 (key == DKEY_ALT_O ?
													   "Open ZZT Object Code (ZOC) File" :
													   "Insert ZZT Object Code (ZOC) File"),
													 FTYPE_ALL, d);

						if (filename != NULL && strlen(filename) != 0) {
							stringvector newsvector;
							newsvector = filetosvector(filename, wrapwidth, editwidth);
							if (newsvector.first != NULL) {
								if (key == DKEY_ALT_O) {
									strcpy(savefilename, filename);
									/* erase & replace sv */
									deletestringvector(sv);
									*sv = newsvector;
									centerstr = sv->first;
								} else {
									/* insert newsvector before centerstr */
									sv->cur = centerstr;
									if (sv->cur == sv->first) {
										/* first node */
										sv->first = newsvector.first;
										sv->cur->prev = newsvector.last;
										newsvector.last->next = sv->cur;
										centerstr = newsvector.first;
									} else if (sv->cur->prev != NULL) {
										/* middle/end node */
										newsvector.first->prev = sv->cur->prev;
										sv->cur->prev->next = newsvector.first;
										newsvector.last->next = sv->cur;
										sv->cur->prev = newsvector.last;
										centerstr = newsvector.first;
									} else {
										/* this code should be unreachable */
										deletestringvector(&newsvector);
									}
								} /* esle alt-i */
							}	/* fi file selected */
						}		/* fi not empty */
						free(filename);
						removestringvector(&filetypelist);
					}			/* block */
					updateflags = U_EDITAREA | U_TITLE | U_PANEL;
					break;

				case DKEY_ALT_S: /* alt-s: save to file */
					{
						char* filename;
						filename = filenamedialog(savefilename, "", "Save Object Code As",
																			1, d);
						if (filename != NULL) {
							/* Save to the file */
							svectortofile(sv, filename);
							/* Remember the file name */
							strncpy(savefilename, filename, SAVEFILENAME_LEN - 1);
							savefilename[SAVEFILENAME_LEN - 1] = '\x0';

							free(filename);
						}
					}
					updateflags = U_EDITAREA | U_PANEL | U_PANEL;
					break;

				case DKEY_ALT_M: /* alt-m: load .zzm music */
					{
						char* filename;
						filename = filedialog(".", "zzm", "Choose ZZT Music (ZZM) File",
																	FTYPE_ALL, d);
						if (filename != NULL) {
							stringvector zzmv;
							zzmv = filetosvector(filename, 80, 80);
							if (zzmv.first != NULL) {
								stringvector song;
								song = zzmpullsong(&zzmv, zzmpicksong(&zzmv, d));
								if (song.first != NULL) {
									/* copy song into sv */
									sv->cur = centerstr;
									for (song.cur = song.first; song.cur != NULL; song.cur = song.cur->next) {
										tmpstr = (char*) malloc(editwidth + 2);

										if (flags & EDITBOX_ZOCMODE) {
											strcpy(tmpstr, "#play ");
											strncat(tmpstr, song.cur->s, editwidth - 6);
										} else {
											strncpy(tmpstr, song.cur->s, editwidth);
										}

										preinsertstring(sv, tmpstr);
									}
									deletestringvector(&song);
								}
								deletestringvector(&zzmv);
							}
						}
						free(filename);
					}
					updateflags = U_EDITAREA | U_TITLE | U_PANEL;
					break;

				case DKEY_CTRL_R: /* ctrl-r: rip music */
					{
						/* This is mostly worthless just now */
						stringvector ripped;
						sv->cur = centerstr;
						ripped = zzmripsong(sv, 4);
						scrolldialog("Ripped Music", &ripped, d);
						deletestringvector(&ripped);
						updateflags = U_ALL;
					}
					break;

				/******** Cut operation *********/

				case DKEY_CTRL_DELETE:    /* ctrl-delete: clear selected text */
				case DKEY_CTRL_X:         /* ctrl-x: cut selected text */
					sv->cur = centerstr;
					/* Destroy the meat of the selection */
					if (selPos != -1) {
						int selStartPos, selEndPos, offset = selLineOffset;
						if (offset < 0) {
							/* Other end is above centerstr */
							offset = -offset;
							selStartPos = selPos;
							selEndPos = pos;
							/* Move back to top of selection */
							for (i = 0; i < offset; i++) {
								if (sv->cur->prev != NULL)
									sv->cur = sv->cur->prev;
							}
							/* Change centerstr to reflect the top of the selection */
							centerstr = sv->cur;
						} else {
							selStartPos = pos;
							selEndPos = selPos;
						}
						if (offset == 0) {
							/* Only one line to work with */
							int deltaPos;

							/* Reverse selStartPos and selEndPos if start is bigger */
							if (selStartPos > selEndPos) {
								int swapPos = selStartPos;
								selStartPos = selEndPos;
								selEndPos = swapPos;
							}
							
							/* Remove everything between selStartPos and selEndPos */
							deltaPos = selEndPos - selStartPos;
							for (i = selEndPos; i < strlen(centerstr->s); i++) {
								centerstr->s[i - deltaPos] = centerstr->s[i];
							}
							centerstr->s[i - deltaPos] = '\0';
							
							/* Move the cursor to the starting position of the cut */
							pos = selStartPos;
						} else {
							/* Multiple lines were involved */

							/* Remove lines following the first line of the block */
							sv->cur = centerstr->next;
							for (i = 0; i + 1 < offset; i++) {
								deletestring(sv);
							}

							/* Remove the string at the end of the cut */
							sv->cur = centerstr->next;
							tmpstr = removestring(sv);
							/* Remove first selEndPos chars from end string */
							for (i = 0; i < (strlen(tmpstr) - selEndPos); i++)
								tmpstr[i] = tmpstr[i+selEndPos];
							tmpstr[i] = 0;

							/* Truncate the string at the start of the cut */
							sv->cur = centerstr;
							sv->cur->s[selStartPos] = '\0';
							/* Wordwrap the end string onto this one */
							/* The -1 tells wordwrap to track the cursor position at
							 * the beginning of tmpstr. Negative tracking values should
							 * be used only by wordwrap for internal purposes, but
							 * necessity warrents in this case.     vv    */
							pos = wordwrap(sv, tmpstr, selStartPos, -1, wrapwidth, editwidth);
							centerstr = sv->cur;  /* Follow cursor */
							/* tmpstr is our responsability */
							free(tmpstr);
						}
						updateflags = U_EDITAREA;
					}
					break;

				case DKEY_CTRL_V:     /* ctrl-v: paste register */
					sv->cur = centerstr;
					pos = regput('\"', sv, pos, wrapwidth, editwidth);
					centerstr = sv->cur;
					updateflags = U_EDITAREA;
					break;

				case DKEY_TAB: /* Tab */
					/* determine tab amount */
					j = 4 - (pos % 4);
					if (strlen(centerstr->s) + j < (wrapwidth?wrapwidth:editwidth)) {
						/* insert if there is room */
						for (i = strlen(centerstr->s) + j; i > pos; i--)
							centerstr->s[i] = centerstr->s[i-j];
						for (i = 0; i < j; i++)
							centerstr->s[pos++] = ' ';
						updateflags = U_CENTER;
					}
					else {
						/* no room; wordwrap */
						for (i = 0; i < j; i++)
							strbuf[i] = ' ';
						strbuf[i] = 0;
						sv->cur = centerstr;
						pos = wordwrap(sv, strbuf, pos, pos, wrapwidth, editwidth);
						centerstr = sv->cur;
						updateflags = U_EDITAREA;
					}
					break;

				case DKEY_ENTER:
					/* Enter */
					tmpstr = (char*) malloc(editwidth + 2);
					for (i = pos, j = 0; i < strlen(centerstr->s); i++, j++)
						tmpstr[j] = centerstr->s[i];
					centerstr->s[pos] = 0;

					tmpstr[j] = 0;
					sv->cur = centerstr;
					insertstring(sv, tmpstr);
					centerstr = centerstr->next;
					pos = 0;
					updateflags = U_EDITAREA;
					break;

				case DKEY_BACKSPACE:
					/* Backspace */
					if (pos > 0) {
						for (i = pos - 1; i < strlen(centerstr->s); i++)
							centerstr->s[i] = centerstr->s[i+1];
						pos--;
						updateflags = U_CENTER;
					}
					else if (centerstr->prev != NULL) {
						if (strlen(centerstr->s) == 0) {
							/* remove current line & move up & to eol */
							sv->cur = centerstr;
							centerstr = centerstr->prev;
							pos = strlen(centerstr->s);
							deletestring(sv);
							updateflags = U_TOP | U_CENTER;
						}
						else if (strlen(centerstr->prev->s) == 0) {
							/* remove previous line */
							sv->cur = centerstr->prev;
							deletestring(sv);
							/* update center too, in case @ line has moved to top now */
							updateflags = U_TOP | U_CENTER;
						}
						else if (strlen(centerstr->prev->s) + 1 < wrapwidth) {
							/* merge lines; wordwrap */
							i = strlen(centerstr->prev->s);
							if (centerstr->prev->s[i-1] != ' ' && centerstr->s[0] != ' ') {
								/* add a space at the end */
								centerstr->prev->s[i]     = ' ';
								centerstr->prev->s[i + 1] = 0;
							}
							sv->cur = centerstr->prev;
							tmpstr = removestring(sv);
							sv->cur = centerstr;
							pos = wordwrap(sv, tmpstr, 0, 0, wrapwidth, editwidth);
							centerstr = sv->cur;
							free(tmpstr);
							updateflags = U_EDITAREA;
						}
					}
					break;

				case DKEY_CTRL_Y: /* ctrl-y: delete line */
					pos = 0;
					sv->cur = centerstr;
					if (centerstr->next != NULL) {
						centerstr = centerstr->next;
						deletestring(sv);
						updateflags = U_CENTER | U_BOTTOM;
					}
					else if (centerstr->prev != NULL) {
						centerstr = centerstr->prev;
						deletestring(sv);
						updateflags = U_TOP | U_CENTER;
					}
					else {
						centerstr->s[0] = 0;
						updateflags = U_CENTER;
					}
					break;

				case DKEY_ESC: /* escape when done */
					done = EDITBOX_OK;
					break;

				case DKEY_CTRL_A: /* ctrl-a: insert ascii char/decimal-value */
					strcpy(strbuf, centerstr->s);
					updateflags = U_EDITAREA;

					if (str_equ(strbuf, "#char", STREQU_UNCASE | STREQU_RFRONT)) {
						/* append dec value for ascii char */

						sscanf(strbuf + 5, "%d", &selChar);
						key = charselect(d, selChar);
						if (key == -1)
							break;
						selChar = key;
						centerstr->s[5] = ' ';
						centerstr->s[6] = 0;

						/* change c to a string */
						sprintf(strbuf, "%d", selChar);
						strcat(centerstr->s, strbuf);
						pos = strlen(centerstr->s);
						updateflags = U_EDITAREA;
						break;
					}
					else {
						/* ctrl-a: insert ascii char */
						key = charselect(d, selChar);
						if (key == -1)
							break;
						else
							selChar = key;
					}
					/* no break; we just changed the key & want to insert it */

				default:
					key = key & 0xFF;  /* Clear all but the first 8 bits */
					/* Normal/weird char for insert/replace */
					if (insertflag) {
						/* insert */
						if (strlen(centerstr->s) < (wrapwidth?wrapwidth:editwidth)) {
							/* insert if there is room */
							for (i = strlen(centerstr->s) + 1; i > pos; i--)
								centerstr->s[i] = centerstr->s[i-1];
							centerstr->s[pos++] = key;
							updateflags |= U_CENTER;
						}
						else if (wrapwidth) {
							/* no room; wordwrap */
							strbuf[0] = key;
							strbuf[1] = 0;
							sv->cur = centerstr;
							pos = wordwrap(sv, strbuf, pos, pos, wrapwidth, editwidth);
							centerstr = sv->cur;
							updateflags = U_EDITAREA;
						}
					}
					else {
						/* easy replace */
						if (centerstr->s[pos] == 0) {
							if (strlen(centerstr->s) < (wrapwidth?wrapwidth:editwidth)) {
								centerstr->s[pos+1] = 0;
								centerstr->s[pos++] = key;
								updateflags |= U_CENTER;
							}
							else if (wrapwidth) {
								/* no room; wordwrap */
								strbuf[0] = key;
								strbuf[1] = 0;
								sv->cur = centerstr;
								pos = wordwrap(sv, strbuf, pos, pos, wrapwidth, editwidth);
								centerstr = sv->cur;
								updateflags = U_EDITAREA;
							}
						}
						else {
							centerstr->s[pos++] = key;
							updateflags |= U_CENTER;
						}
					} /* esle replace */
					break;
			}
		}		/* esle in editmode */

		/* if the shift key is not still held down and we are selecting,
		 * then stop select mode */
		/* also stop if true ASCII key was pressed and selection is active */
		if ((!selectFlag && selPos != -1) || (key < 0x7F && selPos != -1)) {
			selPos = -1;
			selLineOffset = 0;
			updateflags |= U_EDITAREA;
		}
	}			/* elihw */

	sv->cur = centerstr;

	return done;
}
Пример #8
0
/**
 * @relates texteditor
 * @brief Delete the character before the cursor.
 */
void texteditBackspace(texteditor * editor)
{
	int i;

	if (editor->selectflag) {
		texteditClearSelectedText(editor);
		return;
	}

	if (editor->pos > 0) {
		/* Slide everything at or after the cursor back */
		for (i = editor->pos - 1; i < strlen(editor->curline->s); i++)
			editor->curline->s[i] = editor->curline->s[i+1];

		/* Cursor moves back too */
		editor->pos--;
		editor->updateflags |= TUD_CENTER;
	}
	else if (editor->curline->prev != NULL) {
		if (strlen(editor->curline->s) == 0) {
			/* remove current line & move up & to eol */
			editor->text->cur = editor->curline;
			editor->curline = editor->curline->prev;
			editor->pos = strlen(editor->curline->s);

			deletestring(editor->text);

			editor->updateflags |= TUD_TOP | TUD_CENTER;
		}
		else if (strlen(editor->curline->prev->s) == 0) {
			/* remove previous line */
			editor->text->cur = editor->curline->prev;
			deletestring(editor->text);

			/* update center too, in case @ line has moved to top now */
			editor->updateflags |= TUD_TOP | TUD_CENTER;
		}
		else if (strlen(editor->curline->prev->s) + 1 < editor->wrapwidth) {
			/* merge lines; wordwrap */
			char * prevline;

			i = strlen(editor->curline->prev->s);

			/* Previous line must have a space at the end */
			if (editor->curline->prev->s[i-1] != ' ' && editor->curline->s[0] != ' ') {
				/* add a space at the end */
				editor->curline->prev->s[i]     = ' ';
				editor->curline->prev->s[i + 1] = 0;
			}

			/* Grab the previous line */
			editor->text->cur = editor->curline->prev;
			prevline = removestring(editor->text);
			editor->text->cur = editor->curline;

			/* Wrap the previous line onto the beginning of the current line */
			editor->pos = wordwrap(editor->text, prevline, 0, 0, editor->wrapwidth, editor->linewidth);
			editor->curline = editor->text->cur;

			free(prevline);
			editor->updateflags |= TUD_EDITAREA;
		}
	}
}
Пример #9
0
void xcmdcallback (void) {
	
	/*
	5/4/92 dmb: HyperCard 1.0 XCMD callback emulation
	
	7/8/92 dmb: set return code; use xresNotImp for unknown request
	
	9/25/92 dmb: added SendHCEvent callback support. also spotted & fixed 
	a bug in ExtToStr handler.
	
	10/3/92 dmb: it turns out that the protocol requires that the caller 
	of the xcmd put the xcmdptr into a global for us; the xcmd code 
	doesn't pass it to us consistently.
	
	11/6/92 dmb: use new truncatecstringhandle instead of just popping last char.
	also, fixed NumToHex, NumToStr
	*/
	
	register XCmdPtr pxcb;
	register long *args;
	register long *out;
	tyvaluerecord val;
	bigstring bs;
	hdlhashtable htable;
	hdlhashnode hnode;
	
	pxcb = plangxcmdrec; /*copy global into register*/
	
	args = (*pxcb).inArgs;
	out = (long *) &(*pxcb).outArgs;
	
	(*pxcb).result = xresSucc;
	
	switch ((*pxcb).request) {
		
		/*  HyperTalk Utilities  */
		case 0x02: /*Handle EvalExpr (StringPtr expr)*/
			
			if (!langrunstringnoerror ((ptrstring) args [0], bs))
				(*pxcb).result = xresFail;
			
			else {
				
				pushchar (chnul, bs);
				
				newtexthandle (bs, (Handle *) out);
				}
			
			break;
		
		case 0x01: /*void SendCardMessage (StringPtr msg)*/
		case 0x05: /*void SendHCMessage (StringPtr msg)*/
			
			if (!langrunstringnoerror ((ptrstring) args [0], bs))
				(*pxcb).result = xresFail;
			
			break;
		
		/*
		case 0x26: /*void RunHandler (Handle handler)%/
			
			break;
		*/
		
		
		/*  Memory Utilities  */
		case 0x12: /*Handle GetGlobal (StringPtr globName)*/
			
			resolvexcmdglobal ((ptrstring) args [0], &htable, bs);
			
			if (hashtablelookup (htable, bs, &val, &hnode)
				&& copyvaluerecord (val, &val)
				&& coercetostring (&val)
				&& enlargehandle (val.data.stringvalue, 1, zerostring)) {
				
				exemptfromtmpstack (&val);
				
				*out = (long) val.data.stringvalue;
				}
			else
				*out = 0L;
			
			break;
		
		case 0x13: /*void SetGlobal (StringPtr globName, Handle globValue)*/
			
			resolvexcmdglobal ((ptrstring) args [0], &htable, bs);
			
			initvalue (&val, stringvaluetype);
			
			if (!copyhandle ((Handle) args [1], &val.data.stringvalue))
				(*pxcb).result = xresFail;
			
			else {
				
				truncatecstringhandle (val.data.stringvalue); /*strip zero terminator*/
				
				if (!hashtableassign (htable, bs, val))
					disposevaluerecord (val, false);
				}
			
			break;
		
		case 0x06: /*void ZeroBytes (Ptr dstPtr, long longCount)*/
			clearbytes ((byte *) args [0], args [1]);
			
			break;
		
		
		/*  String Utilities  */
		case 0x1c: /*void ScanToReturn (Ptr *scanPtr)*/
			
			scantext (chreturn, (ptrbyte *) args [0]);
			
			/*** test: ++*(ptrbyte *) args [0]; /*point past return*/
			
			break;
		
		case 0x27: /*void ScanToZero (Ptr *scanPtr)*/
			
			scantext (chnul, (ptrbyte *) args [0]);
			
			break;
		
		case 0x1a: /*Boolean StringEqual (StringPtr str1, StringPtr str2)*/
			*out = (long) equalstrings ((ptrstring) args [0], (ptrstring) args [1]);
			
			break;
		
		case 0x03: { /*long StringLength (Ptr strPtr)*/
			
			*out = scanlength (chnul, (ptrbyte) args [0]);
			
			break;
			}
		
		case 0x04: { /*Ptr StringMatch (StringPtr pattern, Ptr target)*/
			
			tysearchparameters saveparams = searchparams;
			long ix = 0;
			long len;
			
			searchparams.flunicase = false;
			searchparams.flwholewords = false;
			searchparams.flregexp = false;
			copystring ((ptrstring) args [0], searchparams.bsfind);
			
			textsearch ((ptrbyte) args [1], infinity, &ix, &len);
			
			*out = (long) ((ptrbyte) args [1] + ix);
			
			searchparams = saveparams;
			
			break;
			}
		
		case 0x20: /*void ZeroTermHandle (Handle hndl)*/
			
			enlargehandle ((Handle) args [0], 1, zerostring);
			
			break;
		
		
		/*  String Conversions  */
		case 0x10: /*void BoolToStr (Boolean bool, StringPtr str)*/
			setbooleanvalue ((Boolean) args [0], &val);
			
			valtostring (&val, (ptrstring) args [1]);
			
			break;
		
		case 0x11: { /*void ExtToStr (extended num, StringPtr str)*/
			
			#if __powerc
			
				long double x;
				
				safex80told ((extended80 *) args [0], &x);
				
				setdoublevalue (x, &val);
			#else
			
				setdoublevalue (* (long double *) args [0], &val);
			
			#endif
			
			valtostring (&val, (ptrstring) args [1]);
				
			break;
			}
		
		case 0x0d: /*void LongToStr (long posNum, StringPtr str)*/
			setlongvalue ((unsigned long) args [0], &val); /*11/6/92 dmb*/
			
			valtostring (&val, (ptrstring) args [1]);
			
			break;
		
		case 0x0f: { /*void NumToHex (long num, short nDigits, StringPtr str)*/
			
			long n = args [0];
			byte hex [16];
			
			if (args [1] <= 4)
				n = (short) n;
			
			numbertohexstring (n, hex); /*11/6/92 dmb*/
			
			deletestring (hex, 1, 2); /*remove the "0x"*/
			
			copystring (hex, (ptrstring) args [2]);
			
			break;
			}
		
		case 0x0e: /*void NumToStr (long num, StringPtr str)*/
			setlongvalue ((long) args [0], &val); /*11/6/92 dmb*/
			
			valtostring (&val, (ptrstring) args [1]);
			
			break;
		
		case 0x07: /*Handle PasToZero (StringPtr str)*/
			copystring ((ptrstring) args [0], bs);
			
			pushchar (chnul, bs);
			
			newtexthandle (bs, (Handle *) out);
			
			break;
		
		case 0x2b: /*void PointToStr (Point pt, StringPtr str)*/
			setpointvalue (*(Point *) args [0], &val);
			
			valtostring (&val, (ptrstring) args [1]);
			
			break;
		
		case 0x2c: /*void RectToStr (Rect *rct, StringPtr str)*/
			newheapvalue ((Rect *) args [0], longsizeof (Rect), rectvaluetype, &val);
			
			valtostring (&val, (ptrstring) args [1]);
			
			break;
		
		case 0x1b: /*void ReturnToPas (Ptr zeroStr, StringPtr pasStr)*/
			texttostring ((ptrbyte) args [0], scanlength (chreturn, (ptrbyte) args [0]), (ptrstring) args [1]);
			
			break;
		
		case 0x0b: /*Boolean StrToBool (StringPtr str)*/
			stringtoval ((ptrstring) args [0], booleanvaluetype, &val);
			
			*out = (long) val.data.flvalue;
			
			break;
		
		case 0x0c: { /*extended StrToExt (StringPtr str)*/
			#if __powerc
			
				long double x;
				
				stringtoval ((ptrstring) args [0], doublevaluetype, &val);
				
				x = **val.data.doublevalue;
				
				safeldtox80 (&x, (extended80 *) args [1]);
				
			#else
				
				stringtoval ((ptrstring) args [0], doublevaluetype, &val);
				
				*(double *) args [1] = **val.data.doublevalue;
				
			#endif
			
			break;
			}
		
		case 0x09: /*long StrToLong (StringPtr str)*/
			stringtoval ((ptrstring) args [0], longvaluetype, &val);
			
			*out = abs (val.data.longvalue);
			
			break;
		
		case 0x0a: /*long StrToNum (StringPtr str)*/
			stringtoval ((ptrstring) args [0], longvaluetype, &val);
			
			*out = (long) val.data.longvalue;
			
			break;
		
		case 0x2d: /*void StrToPoint (StringPtr str, Point *pt)*/
			stringtoval ((ptrstring) args [0], pointvaluetype, &val);
			
			*(Point *) args [1] = val.data.pointvalue;
			
			break;
		
		case 0x2e: /*void StrToRect (StringPtr str, Rect *rct)*/
			stringtoval ((ptrstring) args [0], rectvaluetype, &val);
			
			*(Rect *) args [1] = **val.data.rectvalue;
			
			break;
		
		case 0x08: /*void ZeroToPas (Ptr zeroStr, StringPtr pasStr)*/
			texttostring ((ptrbyte) args [0], scanlength (chnul, (ptrbyte) args [0]), (ptrstring) args [1]);
			
			break;
		
		#if 0
		
		/*  Field Utilities  */
		case 0x16: /*Handle GetFieldByID (Boolean cardFieldFlag, short fieldID)*/
			newfilledhandle (zerostring, 1L, (Handle *) out);
			
			break;
		
		case 0x14: /*Handle GetFieldByName (Boolean cardFieldFlag, StringPtr fieldName)*/
			newfilledhandle (zerostring, 1L, (Handle *) out);
			
			break;
		
		case 0x15: /*Handle GetFieldByNum (Boolean cardFieldFlag, short fieldNum)*/
			newfilledhandle (zerostring, 1L, (Handle *) out);
			
			break;
		
		case 0x19: /*void SetFieldByID (Boolean cardFieldFlag, short fieldID, Handle fieldVal)*/
			break;
		
		case 0x17: /*void SetFieldByName (Boolean cardFieldFlag, StringPtr fieldName, Handle fieldVal)*/
			break;
		
		case 0x18: /*void SetFieldByNum (Boolean cardFieldFlag, short fieldNum, Handle fieldVal)*/
			break;
		
		case 0x2f: /*TEHandle GetFieldTE (Boolean cardFieldFlag, short fieldID, short fieldNum, StringPtr fieldNamePtr)*/
			*out = 0;
			
			break;
															
		case 0x30: /*void SetFieldTE (Boolean cardFieldFlag, short fieldID, short fieldNum, StringPtr fieldNamePtr, TEHandle fieldTE)*/
			break;
		
		#endif
		
		case 0x22: /*void SendHCEvent(EventRecord *event)*/
			
			/****component***/
			
			shellpostevent ((EventRecord *) &args [0]); /*yes, the event itself is in args*/
			
			shellforcebackgroundtask (); /*come back as soon as possible*/
			
			if (!processyield ()) /*we've been killed*/
				(*pxcb).result = xresFail;
			
			break;
		
		default:
			*out = 0L;
			
			(*pxcb).result = xresNotImp;
			
			break;
		}
	
	plangxcmdrec = pxcb; /*reset in case another xcmd ran in the background*/
	} /*xcmdcallback*/
Пример #10
0
/** 
 * Write a File to disk
 * 
 * @param lsdd 
 *    Set the Output to be a SDD file
 * @param nerr 
 *    Error Return Flag 
 *    - 0 on Success
 *
 * @date   970702:  Changed lckey and lkchar to lckeyExact and lkcharExact
 *                  throughout xw.c.  This will allow files to begin with 
 *                  the same string as the various options (eg. sacxz.021.z)
 *                  maf.
 * @date   910731:  Bug fixed in options PREPEND, DELETE, CHANGE.
 * @date   900904:  Added SDD as a format for write.
 * @date   881228:  Added four new options for generating write file list
 *                  from data file list: APPEND, PREPEND, CHANGE, DELETE.
 * @date   880204:  Fixed logic involving use of DIR option in READ and WRITE
 *                  by adding an ON/OFF flag as well as a directory name.
 * @date   880115:  Deleted call that forced default directory to lowercase.
 * @date   870626:  Added default directory option.
 * @date   860917:  Changed to character lists for storing data file names.
 * @date   850730:  Deleted SOCKITTOME  format.
 * @date   830120:  Added SOCK and CI output formats.
 * @date   820721:  Changed to newest set of parsing and checking functions.
 * @date   810120:  Changed to output message retrieval from disk.
 * @date   810203:  Fixed bug in file overwrite option.
 *
 */
void 
xw(int  lsdd, 
   int *nerr) {

    int i;
        char delimiter[2], kcdir[9], kchange[MCPFN+1], kdirpart[MCPFN+1];
	char kfile[MCPFN+1], kpdir[9], kstring[MCPFN+1], ktemp[9];
	int lexpnd;
	int jdfl, nchange, nchar, nchg, ndx1, ndx2;
	int nlen, nstr, nstring, nwrdir;
	static int lwrdir = FALSE;
    char *cattemp;
    char *strtemp1, *strtemp2, *strtemp3;
    
    char *file;
    string_list *list, *files;

	kschan[12]='\0';
	kschdr[80]='\0';
	ksclas[4]='\0';
	kscom[40]='\0';
	ksevnm[8]='\0';
	ksfrmt[8]='\0';
	ksstnm[8]='\0';
    memset(kfile, 0, sizeof(kfile));
    memset(kdirpart, 0, sizeof(kdirpart));
    memset(kchange, 0, sizeof(kchange));
    memset(ktemp, 0, sizeof(ktemp));
    memset(kstring, 0, sizeof(kstring));
    memset(kpdir, 0, sizeof(kpdir));
    memset(kcdir, 0, sizeof(kcdir));
    memset(delimiter, 0, sizeof(delimiter));

        lexpnd = FALSE;

	*nerr = 0;

    files = string_list_init();
    list  = NULL;

	if( lsdd )
	    cmdfm.iwfmt = 3;

	/* PARSING PHASE: */
	/* - Loop on each token in command: */
	while ( lcmore( nerr ) ){

	    /* -- "SAC|ALPHA":  set format to be used in writing files. */
	    if( lckeyExact( "SAC#$",6 ) )
		cmdfm.iwfmt = 1;

	    else if( lckeyExact( "ALPHA#$",8 ) )
		cmdfm.iwfmt = 2;

	    else if( lckeyExact( "CI#$",5 ) )
		cmdfm.iwfmt = 2;

	    else if( lckeyExact( "SDD#$",6 ) )
		cmdfm.iwfmt = 3;

	    else if( lckeyExact( "XDR#$",6 ) ) {
		cmdfm.iwfmt = 4;
            }
            else if( lckeyExact( "SEGY#$", 7 ) )
                cmdfm.iwfmt = 5;

	    /* -- "OVER":  overwrite files from previous READ command. */
	    else if( lckeyExact( "OVER#$",7 ) ){
		cmdfm.lovrrq = TRUE;
		lexpnd = FALSE;
        string_list_extend(files, datafiles);
	    }

	    /* generate names from the KSTCMP header field */
	    else if( lckeyExact( "KSTCMP#$",9 ) ){
		lexpnd = FALSE;
		gennames("KSTCMP ",7,files,string_list_length(datafiles),nerr);
		if(*nerr != 0)
		    goto L_8888;
	    }

	    /* -- "APPEND string": append string to filenames from READ command. */
	    else if( lkcharExact( "APPEND#$",9, MCPFN, kstring,MCPFN+1, &nstring ) ){
        for(i = 0; i < cmdfm.ndfl; i++) {
            strtemp1 = string_list_get(datafiles, i);
		    appendstring( kstring,MCPFN+1, strtemp1, strlen(strtemp1)+2, kfile,MCPFN+1 );

            string_list_put(files, kfile, MCPFN+1);
		    if( *nerr != 0 )
                goto L_8888;
		}
		cmdfm.lovrrq = FALSE;
		lexpnd = TRUE;
	    }

	    /* -- "PREPEND string": prepend string to filenames from READ command. */
	    else if( lkcharExact( "PREPEND#$",10, MCPFN, kstring,MCPFN+1, &nstring ) ){
        for(i = 0; i < cmdfm.ndfl; i++) {
		    strtemp1 = malloc(nstring+1);
		    strncpy(strtemp1,kstring,nstring);
		    strtemp1[nstring] = '\0';
            strtemp2 = string_list_get(datafiles, i);
		    prependstring( strtemp1, nstring+1, strtemp2, strlen(strtemp2)+2, kfile,MCPFN+1);

		    free(strtemp1);
            string_list_put(files, kfile, MCPFN+1);
		    if( *nerr != 0 )
			goto L_8888;
		}
		cmdfm.lovrrq = FALSE;
		lexpnd = TRUE;
	    }

	    /* -- "DELETE string": delete string from filenames from READ command. */
	    else if( lkcharExact( "DELETE#$",9, MCPFN, kstring,MCPFN+1, &nstring ) ){
        for(i = 0; i < cmdfm.ndfl; i++) {
		    strtemp1 = malloc(nstring+1);
		    strncpy(strtemp1,kstring,nstring);
		    strtemp1[nstring] = '\0';
            strtemp2 = string_list_get(datafiles, i);

		    deletestring( strtemp1, nstring+1, strtemp2, strlen(strtemp2)+2, kfile,MCPFN+1);

		    free(strtemp1);
            string_list_put(files, kfile, MCPFN+1);
		    if( *nerr != 0 )
			goto L_8888;
		}
		cmdfm.lovrrq = FALSE;
		lexpnd = TRUE;
	    }

	    /* -- "CHANGE string1 string2": change string1 to string2 in READ filenames. */
	    else if( lkcharExact( "CHANGE#$",9, MCPFN, kstring,MCPFN+1, &nstring ) ){
		lcchar( MCPFN, kchange,MCPFN+1, &nchange );
        for(i = 0; i < cmdfm.ndfl; i++) {
		    nstr = indexb( kstring,MCPFN+1 );
		    nchg = indexb( kchange,MCPFN+1 );

		    strtemp1 = malloc(nstr+1);
		    strtemp2 = malloc(nchg+1);
		    strncpy(strtemp1,kstring,nstr);
		    strncpy(strtemp2,kchange,nchg);
		    strtemp1[nstr] = '\0';
		    strtemp2[nchg] = '\0';
            strtemp3 = string_list_get(datafiles, i);
		    changestring( strtemp1, nstr+1, strtemp2, nchg+1,
                          strtemp3, strlen(strtemp3)+2, kfile,MCPFN+1 );

		    free(strtemp1);            
		    free(strtemp2);

            string_list_put(files, kfile, MCPFN+1);
		    if( *nerr != 0 )
			goto L_8888;
		}
		cmdfm.lovrrq = FALSE;
		lexpnd = TRUE;
	    }

	    /* -- "DIR ON|OFF|CURRENT|name":  set the name of the default subdirectory. */
	    else if( lkcharExact( "DIR#$",6, MCPFN, kmdfm.kwrdir,MCPFN+1, &nchar ) ){
		modcase( TRUE, kmdfm.kwrdir, MCPW, ktemp );

		if( strncmp(ktemp,"OFF     ",8) == 0 ) {
          lwrdir = FALSE;
        } else if( strncmp(ktemp,"CURRENT ",8) == 0 ){
          lwrdir = TRUE;
          fstrncpy( kmdfm.kwrdir, MCPFN, " ", 1);
		} else if( kmdfm.kwrdir[nchar - 1] != KDIRDL ){ 
          /* If the string is mising the "/" path separator */
          lwrdir = TRUE;
          delimiter[0] = KDIRDL;
          delimiter[1] = '\0';
          subscpy( kmdfm.kwrdir, nchar, -1, MCPFN, delimiter );
		} else {
          /* Path is not OFF, CURRENT and has the "/" at the end */
          lwrdir = TRUE;
	    }
        }
	    /* -- "COMMIT|RECALLTRACE|ROLLBACK": 
	          how to treat existing data */
	    else if ( lckeyExact ( "COMMIT" , 7 ) )
		cmdfm.icomORroll = COMMIT ;
	    else if (lckeyExact ( "RECALLTRACE" , 12 ) )
		cmdfm.icomORroll = RECALL ;
	    else if ( lckeyExact ( "RECALL" , 7 ) )
		cmdfm.icomORroll = RECALL ;
	    else if ( lckeyExact ( "ROLLBACK" , 9 ) ) 
		cmdfm.icomORroll = ROLLBACK ;


	    /* -- "filelist":  write files using names in new filelist. */
	    else if( ( list = lcdfl() ) ){
		cmdfm.lovrrq = FALSE;
		lexpnd = FALSE;
	    }

	    /* -- Bad syntax. */
	    else{
		cfmt( "ILLEGAL OPTION:",17 );
		cresp();
	    }
	} /* end while ( lcmore( nerr ) ) */

	/* - The above loop is over when one of two conditions has been met:
	 *   (1) An error in parsing has occurred.  In this case NERR is > 0 .
	 *   (2) All the tokens in the command have been successfully parsed. */

	if( *nerr != 0 )
	    goto L_8888;

	/* CHECKING PHASE: */
    if(!list) {
        list = files;
    } else {
        /* List + Modifiers :: Use List */
        string_list_free(files);
        files = NULL;
    }

	/* - Check for null write filelist. */
	if( string_list_length(list) <= 0 ){
	    *nerr = 1311;
	    setmsg( "ERROR", *nerr );
	    goto L_8888;
	}

	/* - Make sure the write filelist has as many entries as read filelist. */

	if( string_list_length(list) != cmdfm.ndfl ){
	    *nerr = 1312;
        error(1312, "%d %d", string_list_length(list), cmdfm.ndfl);
	    goto L_8888;
	}

	/* EXECUTION PHASE: */

        /* - Commit or rollback data according to cmdfm.icomORroll */
	alignFiles ( nerr ) ;
	if ( *nerr )
	    return ;


	/* - Echo expanded filelist if requested. */

	if( cmdfm.lechof && lexpnd ){
	    setmsg( "OUTPUT", 0 );

        for(i = 0; i < string_list_length(list); i++) {
            file = string_list_get(list, i);

            getdir( file, strlen(file)+1, kcdir,9, kfile,MCPFN+1 );

		/* -- Echo the filename part if there is no directory part. */
            if( strcmp(kcdir,"        ") == 0 )
                apcmsg( kfile,MCPFN+1 );

		/* -- Prepend the filename part with some special characters if
         *    directory part is same as that of the previous file. */
            else if( memcmp(kcdir,kpdir,min(strlen(kcdir),strlen(kpdir)))
                     == 0 ){
                cattemp = malloc(3+strlen(kfile)+1);
                strcpy(cattemp, "...");
                strcat(cattemp,kfile);
                apcmsg( cattemp, 3+strlen(kfile)+1 );
                free(cattemp);
            }
		/* -- Echo complete pathname if directory part is different. */
            else{
                apcmsg2(file, strlen(file)+1);
                strcpy( kpdir, kcdir );
            }
	    }
	    wrtmsg( MUNOUT );
	}

	/* - Write each file in memory to disk. */

	nwrdir = indexb( kmdfm.kwrdir,MCPFN+1 );
	for( jdfl = 1; jdfl <= cmdfm.ndfl; jdfl++ ){
	    /* -- Get file from memory manager. */
        file = string_list_get(list, jdfl-1);
	    getfil( jdfl, TRUE, &nlen, &ndx1, &ndx2, nerr );
	    if( *nerr != 0 )
		goto L_8888;

	    /* isolate file name */
        file = string_list_get(list, jdfl-1);

	    /* -- Check overwrite-protect flag in header record. */
	    if( cmdfm.lovrrq && !*lovrok ){
		*nerr = 1303;
		setmsg( "ERROR", *nerr );
		apcmsg2(file, strlen(file)+1);
		outmsg () ;
		clrmsg () ;
		goto L_8888;
	    }

	    /* -- Prepare output file name:
	     * --- If directory option is ON (lwrdir=.TRUE. and nwrdir>0), 
	     *     concatenate directory name with file name part of write file list.
	     * --- If directory option is CURRENT (lwrdir=.TRUE. and nwrdir=0), 
	     *     use file name part of write file list.
	     * --- If directory option is OFF, use write file list. */
	    if( lwrdir ){
		if( nwrdir > 0 ){
		    fstrncpy( kfile, MCPFN, kmdfm.kwrdir,min(nwrdir,MCPFN));

            strtemp1 = file;
		    strtemp2 = malloc(130-(nwrdir+1));
		    strncpy(strtemp2,kfile+nwrdir,MCPFN+1-(nwrdir + 1));
		    strtemp2[MCPFN+1-(nwrdir+1)] = '\0';
		    getdir( strtemp1, strlen(strtemp1)+1, 
                    kdirpart, MCPFN+1, strtemp2,-(nwrdir+1)+130);
		    subscpy(kfile,nwrdir,-1,MCPFN,strtemp2);
		    free(strtemp2);
		}
		else{
		    fstrncpy( kfile, MCPFN, " ", 1);
		    getdir( file, strlen(file)+1, kdirpart,MCPFN+1, kfile,MCPFN+1 );
		}
	    }
	    else {
            fstrncpy( kfile, MCPFN, file, strlen(file));
        }
	    /* -- Write file in appropriate format. */
	    if( cmdfm.iwfmt == 2 )
		wrci( jdfl, kfile,MCPFN+1, "%#15.7g", nerr );

	    else if( cmdfm.iwfmt == 3 )
		wrsdd( jdfl, kfile,MCPFN+1, TRUE, nerr );

	    else if( cmdfm.iwfmt == 4 )
		wrxdr( jdfl, kfile,MCPFN+1, TRUE, nerr );

	    else if( cmdfm.iwfmt == 5 )
		wrsegy( jdfl , kfile , nerr ) ;

	    else
		wrsac( jdfl, kfile,MCPFN+1, TRUE, nerr );

	    if( *nerr != 0 )
		goto L_8888;

	} /* end for ( jdfl ) */

L_8888:
	return;
}