*/
static void unix_set_global_timeout(int timeout)
{
- if (!timeout) global_timeout.tv_sec = 0;
- else {
- gettimeofday(&global_timeout, NULL);
- global_timeout.tv_sec += (timeout/10);
- global_timeout.tv_usec += ((timeout%10)*100000);
- if (global_timeout.tv_usec > 999999) {
- global_timeout.tv_sec++;
- global_timeout.tv_usec -= 1000000;
- }
- }
- return;
-}
+ if (!timeout)
+ global_timeout.tv_sec = 0;
+ else {
+ gettimeofday(&global_timeout, NULL);
+ global_timeout.tv_sec += (timeout/10);
+ global_timeout.tv_usec += ((timeout%10)*100000);
+ if (global_timeout.tv_usec > 999999) {
+ global_timeout.tv_sec++;
+ global_timeout.tv_usec -= 1000000;
+ }
+ }
+ return;
+} /* unix_set_global_timeout */
/*
*/
static bool timeout_left(struct timeval *diff)
{
- struct timeval now;
-
- if (global_timeout.tv_sec == 0)
- return false;
- gettimeofday( &now, NULL);
- diff->tv_usec = global_timeout.tv_usec - now.tv_usec;
- if (diff->tv_usec < 0) {
- /* Carry */
- now.tv_sec++;
- diff->tv_usec += 1000000;
- }
- diff->tv_sec = global_timeout.tv_sec - now.tv_sec;
- if (diff->tv_sec < 0) {
- diff->tv_sec = diff->tv_usec = 0;
- }
- return true;
-}
-
-
-#if 0
-/*
- * Time left until input timeout. Return the number of milliseconds left
- * until the input timeout elapses, zero if it has already elapsed, -1 if
- * no timeout is in effect.
- */
-static int timeout_to_ms()
-{
- struct timeval diff;
- if (!timeout_left(&diff))
- return -1;
- if (diff.tv_sec >= INT_MAX / 1000 - 1) /* Paranoia... */
- return INT_MAX - 1000;
- return diff.tv_sec * 1000 + diff.tv_usec / 1000;
-}
-#endif
+ struct timeval now;
+
+ if (global_timeout.tv_sec == 0)
+ return false;
+ gettimeofday( &now, NULL);
+ diff->tv_usec = global_timeout.tv_usec - now.tv_usec;
+ if (diff->tv_usec < 0) { /* Carry */
+ now.tv_sec++;
+ diff->tv_usec += 1000000;
+ }
+ diff->tv_sec = global_timeout.tv_sec - now.tv_sec;
+ if (diff->tv_sec < 0)
+ diff->tv_sec = diff->tv_usec = 0;
+ return true;
+} /* timeout_left */
+/*
+ * os_tick
+ *
+ * This is something of a catch-all for things that need to be done
+ * perodically. Currently it turn off audio when a sound is finished.
+ * It will eventually rewrite the output when the terminal is resized.
+ */
void os_tick()
{
- while (terminal_resized) {
- terminal_resized = 0;
- unix_resize_display();
- }
+ while (terminal_resized) {
+ terminal_resized = 0;
+ unix_resize_display();
+ }
#ifndef NO_SOUND
- if (ux_sem_trywait(&sound_done) == 0)
- end_of_sound();
+ if (ux_sem_trywait(&sound_done) == 0)
+ end_of_sound();
#endif
-}
+} /* os_tick */
/*
* If unix_set_global_timeout has been used to set a global timeout
* this routine may also return ZC_TIME_OUT if input times out.
*/
-
static int unix_read_char(int extkeys)
{
#ifdef USE_UTF8
- wint_t c;
+ wint_t c;
#else
- int c;
+ int c;
#endif
- int sel, fd = fileno(stdin);
- fd_set rsel;
- struct timeval tval, *t_left, maxwait;
-
-
- while(1) {
- /* Wait with select so that we get interrupted on SIGWINCH. */
- FD_ZERO(&rsel);
- FD_SET(fd, &rsel);
- os_tick();
- refresh();
-
- /*
- * If the timeout is 0, we still want to call os_tick periodically
- *
- * Based on experimentation, 10 msec seems to strike a balance
- * between cpu usage and not having pauses between sounds
- */
- maxwait.tv_sec=0;
- maxwait.tv_usec=10000;
-
- t_left = timeout_left(&tval) ? &tval : NULL;
- /*
- * if the timeout is zero, we wait forever for input, but if
- * we are playing a sequence of sounds, we need to periodically
- * call os_tick(). So if the timeout is zero, wait up to maxwait
- * for input, but if we get no input continue the while loop.
- */
- if (t_left)
- sel = select(fd + 1, &rsel, NULL, NULL, t_left);
- else
- sel = select(fd + 1, &rsel, NULL, NULL, &maxwait);
-
- if (terminal_resized)
- continue;
- switch (sel) {
- case -1:
- if (errno != EINTR)
- os_fatal(strerror(errno));
- continue;
- case 0:
- if (t_left == NULL)
+ int sel, fd = fileno(stdin);
+ fd_set rsel;
+ struct timeval tval, *t_left, maxwait;
+
+
+ while(1) {
+ /* Wait with select so that we get interrupted on SIGWINCH. */
+ FD_ZERO(&rsel);
+ FD_SET(fd, &rsel);
+ os_tick();
+ refresh();
+
/*
- * The timeout was 0 (wait forever) but we need to call
- * call os_tick to handle sound sequences
+ * If the timeout is 0, we still want to call os_tick
+ * periodically.
+ *
+ * Based on experimentation, 10 msec seems to strike a balance
+ * between cpu usage and not having pauses between sounds
*/
- continue;
- return ZC_TIME_OUT;
- }
+ maxwait.tv_sec=0;
+ maxwait.tv_usec=10000;
- timeout(0);
+ t_left = timeout_left(&tval) ? &tval : NULL;
+ /*
+ * if the timeout is zero, we wait forever for input, but if
+ * we are playing a sequence of sounds, we need to periodically
+ * call os_tick(). So if the timeout is zero, wait up to
+ * maxwait for input, but if we get no input continue the
+ * while loop.
+ */
+ if (t_left)
+ sel = select(fd + 1, &rsel, NULL, NULL, t_left);
+ else
+ sel = select(fd + 1, &rsel, NULL, NULL, &maxwait);
+
+ if (terminal_resized)
+ continue;
+ switch (sel) {
+ case -1:
+ if (errno != EINTR)
+ os_fatal(strerror(errno));
+ continue;
+ case 0:
+ if (t_left == NULL)
+ /*
+ * The timeout was 0 (wait forever)
+ * but we need to call os_tick to handle
+ * sound sequences
+ */
+ continue;
+ return ZC_TIME_OUT;
+ }
+
+ timeout(0);
#ifdef USE_UTF8
- sel = get_wch(&c);
+ sel = get_wch(&c);
#else
- c = getch();
+ c = getch();
#endif
- /* Catch 98% of all input right here... */
- if ((c >= ZC_ASCII_MIN && c <= ZC_ASCII_MAX)
- || (!u_setup.plain_ascii
- && c >= ZC_LATIN1_MIN && c <= ZC_LATIN1_MAX))
- return c;
+ /* Catch 98% of all input right here... */
+ if ((c >= ZC_ASCII_MIN && c <= ZC_ASCII_MAX) || (!u_setup.plain_ascii
+ && c >= ZC_LATIN1_MIN && c <= ZC_LATIN1_MAX))
+ return c;
- /* ...and the other 2% makes up 98% of the code. :( */
+ /* ...and the other 2% makes up 98% of the code. :( */
#ifdef USE_UTF8
- if (sel != KEY_CODE_YES && c >= ZC_LATIN1_MIN) {
- if (c > 0xffff) continue;
- return c;
- }
+ if (sel != KEY_CODE_YES && c >= ZC_LATIN1_MIN) {
+ if (c > 0xffff) continue;
+ return c;
+ }
#endif
- /* On many terminals the backspace key returns DEL. */
- if (c == erasechar()) return ZC_BACKSPACE;;
-
- switch(c) {
- /* This should not happen because select said we have input. */
- case ERR:
- /* Ignore NUL (ctrl+space or ctrl+@ on many terminals) because it
- would be misinterpreted as timeout (ZC_TIME_OUT == 0). */
- case 0:
- /* Ncurses appears to produce KEY_RESIZE even if we handle SIGWINCH
- ourselves. */
+ /* On many terminals the backspace key returns DEL. */
+ if (c == erasechar()) return ZC_BACKSPACE;;
+
+ switch(c) {
+ /* This should not happen because select said we have input. */
+ case ERR:
+ /* Ignore NUL (ctrl+space or ctrl+@ on many terminals)
+ * because it would be misinterpreted as timeout
+ * (ZC_TIME_OUT == 0).
+ */
+ case 0:
+ /* Ncurses appears to produce KEY_RESIZE even if we handle
+ * SIGWINCH ourselves.
+ */
#ifdef KEY_RESIZE
case KEY_RESIZE:
#endif
- continue;
-
- /* Screen decluttering. */
- case MOD_CTRL ^ 'L': case MOD_CTRL ^ 'R':
- clearok( curscr, 1); refresh(); clearok( curscr, 0);
- continue;
- /* Lucian P. Smith reports KEY_ENTER on Irix 5.3. LF has never
- been reported, but I'm leaving it in just in case. */
- case '\n': case '\r': case KEY_ENTER: return ZC_RETURN;
- /* I've seen KEY_BACKSPACE returned on some terminals. */
- case KEY_BACKSPACE: case '\b': return ZC_BACKSPACE;
- /* On terminals with 8-bit character sets or 7-bit connections
- "Alt-Foo" may be returned as an escape followed by the ASCII
- value of the letter. We have to decide here whether to
- return a single escape or a frotz hot key. */
- case ZC_ESCAPE:
+ continue;
+
+ /* Screen decluttering. */
+ case MOD_CTRL ^ 'L':
+ case MOD_CTRL ^ 'R':
+ clearok(curscr, 1);
+ refresh();
+ clearok(curscr, 0);
+ continue;
+ /* Lucian P. Smith reports KEY_ENTER on Irix 5.3. LF has never
+ * been reported, but I'm leaving it in just in case.
+ */
+ case '\n':
+ case '\r':
+ case KEY_ENTER:
+ return ZC_RETURN;
+ /* I've seen KEY_BACKSPACE returned on some terminals. */
+ case KEY_BACKSPACE:
+ case '\b':
+ return ZC_BACKSPACE;
+ /* On terminals with 8-bit character sets or 7-bit connections
+ * "Alt-Foo" may be returned as an escape followed by the ASCII
+ * value of the letter. We have to decide here whether to
+ * return a single escape or a frotz hot key.
+ */
+ case ZC_ESCAPE:
#ifdef USE_UTF8
- nodelay(stdscr, TRUE); get_wch(&c); nodelay(stdscr, FALSE);
+ nodelay(stdscr, TRUE); get_wch(&c); nodelay(stdscr, FALSE);
#else
- nodelay(stdscr, TRUE); c = getch(); nodelay(stdscr, FALSE);
+ nodelay(stdscr, TRUE); c = getch(); nodelay(stdscr, FALSE);
#endif
- switch(c) {
- case ERR: return ZC_ESCAPE;
- case 'p': return ZC_HKEY_PLAYBACK;
- case 'r': return ZC_HKEY_RECORD;
- case 's': return ZC_HKEY_SEED;
- case 'u': return ZC_HKEY_UNDO;
- case 'n': return ZC_HKEY_RESTART;
- case 'x': return ZC_HKEY_QUIT;
- case 'd': return ZC_HKEY_DEBUG;
- case 'h': return ZC_HKEY_HELP;
- case 'f': return ZC_WORD_RIGHT;
- case 'b': return ZC_WORD_LEFT;
- default: continue; /* Ignore unknown combinations. */
- }
- /* The standard function key block. */
- case KEY_UP: return ZC_ARROW_UP;
- case KEY_DOWN: return ZC_ARROW_DOWN;
- case KEY_LEFT: return ZC_ARROW_LEFT;
- case KEY_RIGHT: return ZC_ARROW_RIGHT;
- case KEY_F(1): return ZC_FKEY_MIN;
- case KEY_F(2): return ZC_FKEY_MIN + 1;
- case KEY_F(3): return ZC_FKEY_MIN + 2;
- case KEY_F(4): return ZC_FKEY_MIN + 3;
- case KEY_F(5): return ZC_FKEY_MIN + 4;
- case KEY_F(6): return ZC_FKEY_MIN + 5;
- case KEY_F(7): return ZC_FKEY_MIN + 6;
- case KEY_F(8): return ZC_FKEY_MIN + 7;
- case KEY_F(9): return ZC_FKEY_MIN + 8;
- case KEY_F(10): return ZC_FKEY_MIN + 9;
- case KEY_F(11): return ZC_FKEY_MIN + 10;
- case KEY_F(12): return ZC_FKEY_MIN + 11;
- /* Curses can't differentiate keypad numbers from cursor keys,
- which is annoying, as cursor and keypad keys have
- nothing to do with each other on, say, a vt200.
- So we can only read 1, 3, 5, 7 and 9 from the keypad. This
- would be so silly that we choose not to provide keypad keys at all.
- */
- /* Catch the meta key on those plain old ASCII terminals where
- it sets the high bit. This only works in
- u_setup.plain_ascii mode: otherwise these character codes
- would have been interpreted according to ISO-Latin-1
- earlier. */
- case MOD_META | 'p': return ZC_HKEY_PLAYBACK;
- case MOD_META | 'r': return ZC_HKEY_RECORD;
- case MOD_META | 's': return ZC_HKEY_SEED;
- case MOD_META | 'u': return ZC_HKEY_UNDO;
- case MOD_META | 'n': return ZC_HKEY_RESTART;
- case MOD_META | 'x': return ZC_HKEY_QUIT;
- case MOD_META | 'd': return ZC_HKEY_DEBUG;
- case MOD_META | 'h': return ZC_HKEY_HELP;
- case MOD_META | 'f': return ZC_WORD_RIGHT;
- case MOD_META | 'b': return ZC_WORD_LEFT;
-
- /* these are the UNIX line-editing characters */
- case MOD_CTRL ^ 'B': return ZC_ARROW_LEFT;
- /* use ^C to clear line anywhere it doesn't send SIGINT */
- case MOD_CTRL ^ 'C': return ZC_ESCAPE;
- case MOD_CTRL ^ 'F': return ZC_ARROW_RIGHT;
- case MOD_CTRL ^ 'P': return ZC_ARROW_UP;
- case MOD_CTRL ^ 'N': return ZC_ARROW_DOWN;
-
- case MOD_CTRL ^ 'A': c = KEY_HOME; break;
- case MOD_CTRL ^ 'E': c = KEY_END; break;
- case MOD_CTRL ^ 'D': c = KEY_DC; break;
- case MOD_CTRL ^ 'K': c = KEY_EOL; break;
- case MOD_CTRL ^ 'U': c = ZC_DEL_TO_BOL; break;
- case MOD_CTRL ^ 'W': c = ZC_DEL_WORD; break;
-
- /* In raw mode we need to take care of this as well. */
- case MOD_CTRL ^ 'Z':
- unix_suspend_program();
- continue;
-
- /* use ^Q to immediately exit. */
- case MOD_CTRL ^ 'Q': os_quit();
-
- default: break; /* Who knows? */
+ switch(c) {
+ case ERR: return ZC_ESCAPE;
+ case 'p': return ZC_HKEY_PLAYBACK;
+ case 'r': return ZC_HKEY_RECORD;
+ case 's': return ZC_HKEY_SEED;
+ case 'u': return ZC_HKEY_UNDO;
+ case 'n': return ZC_HKEY_RESTART;
+ case 'x': return ZC_HKEY_QUIT;
+ case 'd': return ZC_HKEY_DEBUG;
+ case 'h': return ZC_HKEY_HELP;
+ case 'f': return ZC_WORD_RIGHT;
+ case 'b': return ZC_WORD_LEFT;
+ default: continue; /* Ignore unknown combinations. */
+ }
+ /* The standard function key block. */
+ case KEY_UP: return ZC_ARROW_UP;
+ case KEY_DOWN: return ZC_ARROW_DOWN;
+ case KEY_LEFT: return ZC_ARROW_LEFT;
+ case KEY_RIGHT: return ZC_ARROW_RIGHT;
+ case KEY_F(1): return ZC_FKEY_MIN;
+ case KEY_F(2): return ZC_FKEY_MIN + 1;
+ case KEY_F(3): return ZC_FKEY_MIN + 2;
+ case KEY_F(4): return ZC_FKEY_MIN + 3;
+ case KEY_F(5): return ZC_FKEY_MIN + 4;
+ case KEY_F(6): return ZC_FKEY_MIN + 5;
+ case KEY_F(7): return ZC_FKEY_MIN + 6;
+ case KEY_F(8): return ZC_FKEY_MIN + 7;
+ case KEY_F(9): return ZC_FKEY_MIN + 8;
+ case KEY_F(10): return ZC_FKEY_MIN + 9;
+ case KEY_F(11): return ZC_FKEY_MIN + 10;
+ case KEY_F(12): return ZC_FKEY_MIN + 11;
+ /* Curses can't differentiate keypad numbers from cursor keys,
+ * which is annoying, as cursor and keypad keys have
+ * nothing to do with each other on, say, a vt200.
+ * So we can only read 1, 3, 5, 7 and 9 from the keypad. This
+ * would be so silly that we choose not to provide keypad
+ * keys at all.
+ */
+
+ /* Catch the meta key on those plain old ASCII terminals where
+ * it sets the high bit. This only works in
+ * u_setup.plain_ascii mode: otherwise these character codes
+ * would have been interpreted according to ISO-Latin-1
+ * earlier.
+ */
+ case MOD_META | 'p': return ZC_HKEY_PLAYBACK;
+ case MOD_META | 'r': return ZC_HKEY_RECORD;
+ case MOD_META | 's': return ZC_HKEY_SEED;
+ case MOD_META | 'u': return ZC_HKEY_UNDO;
+ case MOD_META | 'n': return ZC_HKEY_RESTART;
+ case MOD_META | 'x': return ZC_HKEY_QUIT;
+ case MOD_META | 'd': return ZC_HKEY_DEBUG;
+ case MOD_META | 'h': return ZC_HKEY_HELP;
+ case MOD_META | 'f': return ZC_WORD_RIGHT;
+ case MOD_META | 'b': return ZC_WORD_LEFT;
+
+ /* these are the UNIX line-editing characters */
+ case MOD_CTRL ^ 'B': return ZC_ARROW_LEFT;
+ /* use ^C to clear line anywhere it doesn't send SIGINT */
+ case MOD_CTRL ^ 'C': return ZC_ESCAPE;
+ case MOD_CTRL ^ 'F': return ZC_ARROW_RIGHT;
+ case MOD_CTRL ^ 'P': return ZC_ARROW_UP;
+ case MOD_CTRL ^ 'N': return ZC_ARROW_DOWN;
+
+ case MOD_CTRL ^ 'A': c = KEY_HOME; break;
+ case MOD_CTRL ^ 'E': c = KEY_END; break;
+ case MOD_CTRL ^ 'D': c = KEY_DC; break;
+ case MOD_CTRL ^ 'K': c = KEY_EOL; break;
+ case MOD_CTRL ^ 'U': c = ZC_DEL_TO_BOL; break;
+ case MOD_CTRL ^ 'W': c = ZC_DEL_WORD; break;
+
+ /* In raw mode we need to take care of this as well. */
+ case MOD_CTRL ^ 'Z':
+ unix_suspend_program();
+ continue;
+
+ /* use ^Q to immediately exit. */
+ case MOD_CTRL ^ 'Q': os_quit();
+
+ default: break; /* Who knows? */
+ }
+
+ /* Control-N through Control-U happen to map to the frotz hot
+ * key codes, but not in any mnemonic manner. It annoys an
+ * emacs user (or this one anyway) when he tries out of habit
+ * to use one of the emacs keys that isn't implemented and he
+ * gets a random hot key function. It's less jarring to catch
+ * them and do nothing. [APP]
+ */
+ if ((c >= ZC_HKEY_MIN) && (c <= ZC_HKEY_MAX))
+ continue;
+
+ /* Finally, if we're in full line mode (os_read_line), we
+ * might return codes which aren't legal Z-machine keys but
+ * are used by the editor.
+ */
+ if (extkeys) return c;
}
+} /* unix_read_char */
- /* Control-N through Control-U happen to map to the frotz hot
- * key codes, but not in any mnemonic manner. It annoys an
- * emacs user (or this one anyway) when he tries out of habit
- * to use one of the emacs keys that isn't implemented and he
- * gets a random hot key function. It's less jarring to catch
- * them and do nothing. [APP] */
- if ((c >= ZC_HKEY_MIN) && (c <= ZC_HKEY_MAX)) continue;
-
- /* Finally, if we're in full line mode (os_read_line), we
- might return codes which aren't legal Z-machine keys but
- are used by the editor. */
- if (extkeys) return c;
- }
-}
+
+/*
+ * zcharstrlen
+ *
+ * A version of strlen() for dealing with ZSCII strings
+ */
size_t zcharstrlen(zchar *str)
{
- size_t ret = 0;
+ size_t ret = 0;
- while (str[ret] != 0)
- {
- ret++;
- }
- return ret;
-}
+ while (str[ret] != 0)
+ ret++;
+ return ret;
+} /* zcharstrlen */
+
+/* zcharstrncpy
+ *
+ * A version of strncpy() for dealing with ZSCII strings
+ */
zchar *zcharstrncpy(zchar *dest, zchar *src, size_t n)
{
- size_t i;
+ size_t i;
+
+ for (i = 0; i < n && src[i] != '\0'; i++)
+ dest[i] = src[i];
+ for ( ; i < n; i++)
+ dest[i] = 0;
- for (i = 0; i < n && src[i] != '\0'; i++)
- dest[i] = src[i];
- for ( ; i < n; i++)
- dest[i] = 0;
+ return dest;
+} /* zcharstrncpy */
- return dest;
-}
+
+/* zcharstrncmp
+ *
+ * A version of strncmp() for dealing with ZSCII strings
+ */
int zcharstrncmp(zchar *s1, zchar *s2, size_t n)
{
- zchar u1, u2;
- while (n-- > 0)
- {
- u1 = *s1++;
- u2 = *s2++;
- if (u1 != u2)
- return u1 - u2;
- if (u1 == 0)
- return 0;
- }
- return 0;
-}
+ zchar u1, u2;
+ while (n-- > 0) {
+ u1 = *s1++;
+ u2 = *s2++;
+ if (u1 != u2)
+ return u1 - u2;
+ if (u1 == 0)
+ return 0;
+ }
+ return 0;
+} /* zcharstrncmp */
+
/*
* unix_add_to_history
static void unix_add_to_history(zchar *str)
{
- if (*history_next != NULL)
- free( *history_next);
- *history_next = (zchar *)malloc((zcharstrlen(str) + 1) * sizeof(zchar));
- zcharstrncpy( *history_next, str, zcharstrlen(str) + 1);
- RING_INC( history_next, history_buffer, history_end);
- history_view = history_next; /* Reset user frame after each line */
+ if (*history_next != NULL)
+ free( *history_next);
+ *history_next = (zchar *)malloc((zcharstrlen(str) + 1) * sizeof(zchar));
+ zcharstrncpy( *history_next, str, zcharstrlen(str) + 1);
+ RING_INC( history_next, history_buffer, history_end);
+ history_view = history_next; /* Reset user frame after each line */
- return;
-}
+ return;
+} /* unix_add_to_history */
/*
*/
static int unix_history_back(zchar *str, int searchlen, int maxlen)
{
- zchar **prev = history_view;
-
- do {
- RING_DEC( history_view, history_buffer, history_end);
- if ((history_view == history_next)
- || (*history_view == NULL)) {
- os_beep(BEEP_HIGH);
- history_view = prev;
- return 0;
- }
- } while (zcharstrlen( *history_view) > (size_t) maxlen
- || (searchlen != 0 && zcharstrncmp(str, *history_view, searchlen)));
- zcharstrncpy(str + searchlen, *history_view + searchlen,
+ zchar **prev = history_view;
+
+ do {
+ RING_DEC( history_view, history_buffer, history_end);
+ if ((history_view == history_next) || (*history_view == NULL)) {
+ os_beep(BEEP_HIGH);
+ history_view = prev;
+ return 0;
+ }
+ } while (zcharstrlen( *history_view) > (size_t) maxlen
+ || (searchlen != 0 && zcharstrncmp(str, *history_view, searchlen)));
+ zcharstrncpy(str + searchlen, *history_view + searchlen,
(size_t) maxlen - (zcharstrlen(str) + searchlen));
- return 1;
-}
+ return 1;
+} /* unix_history_back */
/*
*/
static int unix_history_forward(zchar *str, int searchlen, int maxlen)
{
- zchar **prev = history_view;
-
- do {
- RING_INC( history_view, history_buffer, history_end);
- if ((history_view == history_next)
- || (*history_view == NULL)) {
-
- os_beep(BEEP_HIGH);
- history_view = prev;
- return 0;
- }
- } while (zcharstrlen( *history_view) > (size_t) maxlen
- || (searchlen != 0 && zcharstrncmp(str, *history_view, searchlen)));
- zcharstrncpy(str + searchlen, *history_view + searchlen,
+ zchar **prev = history_view;
+
+ do {
+ RING_INC( history_view, history_buffer, history_end);
+ if ((history_view == history_next) || (*history_view == NULL)) {
+ os_beep(BEEP_HIGH);
+ history_view = prev;
+ return 0;
+ }
+ } while (zcharstrlen( *history_view) > (size_t) maxlen
+ || (searchlen != 0 && zcharstrncmp(str, *history_view, searchlen)));
+ zcharstrncpy(str + searchlen, *history_view + searchlen,
(size_t) maxlen - (zcharstrlen(str) + searchlen));
- return 1;
-}
+ return 1;
+} /* unix_history_forward */
/*
*/
static void scrnmove(int dest, int src, int n)
{
- int col, x, y;
-
- getyx(stdscr, y, x);
- if (src > dest) {
- for (col = src; col < src + n; col++) {
- chtype ch = mvinch(y, col);
- mvaddch(y, col - src + dest, ch);
- }
- } else if (src < dest) {
- for (col = src + n - 1; col >= src; col--) {
- chtype ch = mvinch(y, col);
- mvaddch(y, col - src + dest, ch);
- }
- }
- move(y, x);
-
- return;
-}
+ int col, x, y;
+
+ getyx(stdscr, y, x);
+ if (src > dest) {
+ for (col = src; col < src + n; col++) {
+ chtype ch = mvinch(y, col);
+ mvaddch(y, col - src + dest, ch);
+ }
+ } else if (src < dest) {
+ for (col = src + n - 1; col >= src; col--) {
+ chtype ch = mvinch(y, col);
+ mvaddch(y, col - src + dest, ch);
+ }
+ }
+ move(y, x);
+ return;
+} /* scrnmove */
/*
*/
static void scrnset(int start, int c, int n)
{
- int y, x;
- getyx(stdscr, y, x);
- while (n--)
- mvaddch(y, start + n, c);
- move(y, x);
+ int y, x;
+ getyx(stdscr, y, x);
+ while (n--)
+ mvaddch(y, start + n, c);
+ move(y, x);
+ return;
+} /* scrnset */
- return;
-}
#ifdef USE_UTF8
+/*
+ * utf8_mvaddnstr
+ *
+ * Like mvaddnstr except modified to deal with UTF-8 and ZSCII
+ *
+ */
static void utf8_mvaddnstr(int y, int x, zchar * buf, int n)
{
- zchar *bp = buf;
+ zchar *bp = buf;
- move(y,x);
- while(*bp && (n > 0)) {
- if(*bp < ZC_LATIN1_MIN) {
- addch(*bp);
- } else {
- if(*bp > 0x7ff) {
- addch(0xe0 | ((*bp >> 12) & 0xf));
- addch(0x80 | ((*bp >> 6) & 0x3f));
- addch(0x80 | (*bp & 0x3f));
- } else {
- addch(0xc0 | ((*bp >> 6) & 0x1f));
- addch(0x80 | (*bp & 0x3f));
- }
+ move(y,x);
+ while(*bp && (n > 0)) {
+ if(*bp < ZC_LATIN1_MIN) {
+ addch(*bp);
+ } else {
+ if(*bp > 0x7ff) {
+ addch(0xe0 | ((*bp >> 12) & 0xf));
+ addch(0x80 | ((*bp >> 6) & 0x3f));
+ addch(0x80 | (*bp & 0x3f));
+ } else {
+ addch(0xc0 | ((*bp >> 6) & 0x1f));
+ addch(0x80 | (*bp & 0x3f));
+ }
+ }
+ bp++;
+ n--;
}
- bp++;
- n--;
- }
-}
+} /* utf8_mvaddnstr */
+
+/*
+ * utf8_mvaddstr
+ *
+ * Like mvaddstr except modified to deal with UTF-8 and ZSCII
+ *
+ */
static void utf8_mvaddstr(int y, int x, zchar * buf)
{
- utf8_mvaddnstr(y,x,buf,zcharstrlen(buf));
-}
+ utf8_mvaddnstr(y,x,buf,zcharstrlen(buf));
+} /* utf8_mvaddstr */
#endif /* USE_UTF8 */
zchar os_read_line (int bufmax, zchar *buf, int timeout, int width,
int continued)
{
- int ch, y, x, len = zcharstrlen(buf);
- int res;
- const int margin = MAX(h_screen_width - width, 0);
-
- /* These are static to allow input continuation to work smoothly. */
- static int scrpos = 0, searchpos = -1, insert_flag = 1;
-
- /* Set x and y to be at the start of the input area. */
- getyx(stdscr, y, x);
- x -= len;
-
- /* Better be careful here or it might segv. I wonder if we should just
- ignore 'continued' and check for len > 0 instead? Might work better
- with Beyond Zork. */
- if (!continued || scrpos > len || searchpos > len) {
- scrpos = len;
- history_view = history_next; /* Reset user's history view. */
- searchpos = -1; /* -1 means initialize from len. */
- insert_flag = 1; /* Insert mode is now default. */
- }
-
- unix_set_global_timeout(timeout);
- for (;;) {
- int x2, max;
- if (scrpos >= width)
- scrpos = width - 1;
- move(y, x + scrpos);
- /* Maybe there's a cleaner way to do this, but refresh() is */
- /* still needed here to print spaces. --DG */
- refresh();
- ch = unix_read_char(1);
- getyx(stdscr, y, x2);
- x2++; /*XXX Eliminate compiler warning. */
- width = h_screen_width - margin;
- max = MIN(width, bufmax);
- /* The screen has shrunk and input no longer fits. Chop. */
- if (len > max) {
- len = max;
- if (scrpos > len)
- scrpos = len;
- if (searchpos > len)
- searchpos = len;
+ int ch, y, x, len = zcharstrlen(buf);
+ int res;
+ const int margin = MAX(h_screen_width - width, 0);
+
+ /* These are static to allow input continuation to work smoothly. */
+ static int scrpos = 0, searchpos = -1, insert_flag = 1;
+
+ /* Set x and y to be at the start of the input area. */
+ getyx(stdscr, y, x);
+ x -= len;
+
+ /* Better be careful here or it might segv. I wonder if we should just
+ * ignore 'continued' and check for len > 0 instead? Might work better
+ * with Beyond Zork.
+ */
+ if (!continued || scrpos > len || searchpos > len) {
+ scrpos = len;
+ history_view = history_next; /* Reset user's history view. */
+ searchpos = -1; /* -1 means initialize from len. */
+ insert_flag = 1; /* Insert mode is now default. */
}
- switch (ch) {
- case ZC_BACKSPACE: /* Delete preceding character */
- if (scrpos != 0) {
- len--; scrpos--; searchpos = -1;
- scrnmove(x + scrpos, x + scrpos + 1, len - scrpos);
- mvaddch(y, x + len, ' ');
- memmove(buf + scrpos, buf + scrpos + 1, (len - scrpos)*sizeof(zchar));
- }
- break;
- case ZC_DEL_WORD:
- if (scrpos != 0) {
- int newoffset = start_of_prev_word(scrpos, buf);
- searchpos = -1;
- int delta = scrpos - newoffset;
- int oldlen = len;
- int oldscrpos = scrpos;
- len -= delta;
- scrpos -= delta;
- scrnmove(x + scrpos, x + oldscrpos, len - scrpos);
- memmove(buf + scrpos, buf + oldscrpos, (len - scrpos)*sizeof(zchar));
- int i = newoffset;
- for (i = len; i <= oldlen ; i++) {
- mvaddch(y, x + i, ' ');
- }
+
+ unix_set_global_timeout(timeout);
+ for (;;) {
+ int x2, max;
+ if (scrpos >= width)
+ scrpos = width - 1;
+ move(y, x + scrpos);
+ /* Maybe there's a cleaner way to do this,
+ * but refresh() is still needed here to
+ * print spaces. --DG
+ */
+ refresh();
+ ch = unix_read_char(1);
+ getyx(stdscr, y, x2);
+ x2++;
+ width = h_screen_width - margin;
+ max = MIN(width, bufmax);
+ /* The screen has shrunk and input no longer fits. Chop. */
+ if (len > max) {
+ len = max;
+ if (scrpos > len)
+ scrpos = len;
+ if (searchpos > len)
+ searchpos = len;
}
- break;
- case ZC_DEL_TO_BOL:
- if (scrpos != 0) {
- searchpos = -1;
- len -= scrpos;
- scrnmove(x, x + scrpos, len);
- memmove(buf, buf + scrpos, len*sizeof(zchar));
- for (int i = len; i <= len + scrpos; i++) {
- mvaddch(y, x + i, ' ');
+ switch (ch) {
+ case ZC_BACKSPACE: /* Delete preceding character */
+ if (scrpos != 0) {
+ len--;
+ scrpos--;
+ searchpos = -1;
+ scrnmove(x + scrpos,
+ x + scrpos + 1, len - scrpos);
+ mvaddch(y, x + len, ' ');
+ memmove(buf + scrpos, buf + scrpos + 1,
+ (len - scrpos)*sizeof(zchar));
+ }
+ break;
+ case ZC_DEL_WORD:
+ if (scrpos != 0) {
+ int newoffset =
+ start_of_prev_word(scrpos, buf);
+ searchpos = -1;
+ int delta = scrpos - newoffset;
+ int oldlen = len;
+ int oldscrpos = scrpos;
+ len -= delta;
+ scrpos -= delta;
+ scrnmove(x + scrpos, x + oldscrpos,
+ len - scrpos);
+ memmove(buf + scrpos, buf + oldscrpos,
+ (len - scrpos)*sizeof(zchar));
+ int i = newoffset;
+ for (i = len; i <= oldlen ; i++)
+ mvaddch(y, x + i, ' ');
+ }
+ break;
+ case ZC_DEL_TO_BOL:
+ if (scrpos != 0) {
+ searchpos = -1;
+ len -= scrpos;
+ scrnmove(x, x + scrpos, len);
+ memmove(buf, buf + scrpos,
+ len*sizeof(zchar));
+ for (int i = len; i <= len + scrpos; i++)
+ mvaddch(y, x + i, ' ');
+ scrpos = 0;
}
+ break;
+ case CHR_DEL:
+ case KEY_DC: /* Delete following character */
+ if (scrpos < len) {
+ len--; searchpos = -1;
+ scrnmove(x + scrpos, x + scrpos + 1,
+ len - scrpos);
+ mvaddch(y, x + len, ' ');
+ memmove(buf + scrpos, buf + scrpos + 1,
+ (len - scrpos)*sizeof(zchar));
+ }
+ continue; /* Don't feed is_terminator bad zchars. */
+
+ case KEY_EOL: /* Delete from cursor to end of line. */
+ scrnset(x + scrpos, ' ', len - scrpos);
+ len = scrpos;
+ continue;
+ case ZC_ESCAPE: /* Delete whole line */
+ scrnset(x, ' ', len);
+ len = scrpos = 0;
+ searchpos = -1;
+ history_view = history_next;
+ continue;
+
+ /* Cursor motion */
+ case ZC_ARROW_LEFT:
+ if (scrpos)
+ scrpos--;
+ continue;
+ case ZC_ARROW_RIGHT:
+ if (scrpos < len)
+ scrpos++;
+ continue;
+ case KEY_HOME:
scrpos = 0;
- }
- break;
- case CHR_DEL:
- case KEY_DC: /* Delete following character */
- if (scrpos < len) {
- len--; searchpos = -1;
- scrnmove(x + scrpos, x + scrpos + 1, len - scrpos);
- mvaddch(y, x + len, ' ');
- memmove(buf + scrpos, buf + scrpos + 1, (len - scrpos)*sizeof(zchar));
- }
- continue; /* Don't feed is_terminator bad zchars. */
-
- case KEY_EOL: /* Delete from cursor to end of line. */
- scrnset(x + scrpos, ' ', len - scrpos);
- len = scrpos;
- continue;
- case ZC_ESCAPE: /* Delete whole line */
- scrnset(x, ' ', len);
- len = scrpos = 0;
- searchpos = -1;
- history_view = history_next;
- continue;
-
- /* Cursor motion */
- case ZC_ARROW_LEFT: if (scrpos) scrpos--; continue;
- case ZC_ARROW_RIGHT: if (scrpos < len) scrpos++; continue;
- case KEY_HOME: scrpos = 0; continue;
- case KEY_END: scrpos = len; continue;
- case ZC_WORD_RIGHT:
- if (scrpos < len) {
- scrpos = end_of_next_word(scrpos, buf, len);
- }
- continue;
- case ZC_WORD_LEFT:
- if (scrpos > 0) {
- scrpos = start_of_prev_word(scrpos, buf);
- }
- continue;
- case KEY_IC: /* Insert Character */
- insert_flag = !insert_flag;
- continue;
-
- case ZC_ARROW_UP: case ZC_ARROW_DOWN:
- if (searchpos < 0)
- searchpos = len;
- if (ch == ZC_ARROW_UP)
- res = unix_history_back(buf, searchpos, max);
- else
- res = unix_history_forward(buf, searchpos, max);
-
- if (res) {
- scrnset(x, ' ', len);
+ continue;
+ case KEY_END:
+ scrpos = len;
+ continue;
+ case ZC_WORD_RIGHT:
+ if (scrpos < len)
+ scrpos = end_of_next_word(scrpos, buf, len);
+ continue;
+ case ZC_WORD_LEFT:
+ if (scrpos > 0)
+ scrpos = start_of_prev_word(scrpos, buf);
+ continue;
+ case KEY_IC: /* Insert Character */
+ insert_flag = !insert_flag;
+ continue;
+ case ZC_ARROW_UP:
+ case ZC_ARROW_DOWN:
+ if (searchpos < 0)
+ searchpos = len;
+ if (ch == ZC_ARROW_UP)
+ res = unix_history_back(buf, searchpos, max);
+ else
+ res = unix_history_forward(buf, searchpos, max);
+
+ if (res) {
+ scrnset(x, ' ', len);
#ifdef USE_UTF8
- utf8_mvaddstr(y, x, buf);
+ utf8_mvaddstr(y, x, buf);
#else
- mvaddstr(y, x, (char *) buf);
+ mvaddstr(y, x, (char *) buf);
#endif
- scrpos = len = zcharstrlen(buf);
- }
- continue;
-
- /* Passthrough as up/down arrows for Beyond Zork. */
- case KEY_PPAGE: ch = ZC_ARROW_UP; break;
- case KEY_NPAGE: ch = ZC_ARROW_DOWN; break;
- case '\t':
+ scrpos = len = zcharstrlen(buf);
+ }
+ continue;
+ /* Passthrough as up/down arrows for Beyond Zork. */
+ case KEY_PPAGE: ch = ZC_ARROW_UP; break;
+ case KEY_NPAGE: ch = ZC_ARROW_DOWN; break;
+ case '\t':
/* This really should be fixed to work also in the middle of a
sentence. */
- {
- int status;
- zchar extension[10], saved_char;
-
- saved_char = buf[scrpos];
- buf[scrpos] = '\0';
- status = completion( buf, extension);
- buf[scrpos] = saved_char;
-
- if (status != 2) {
- int ext_len = zcharstrlen(extension);
- if (ext_len > max - len) {
- ext_len = max - len;
- status = 1;
- }
- memmove(buf + scrpos + ext_len, buf + scrpos,
- (len - scrpos)*sizeof(zchar));
- memmove(buf + scrpos, extension, ext_len*sizeof(zchar));
- scrnmove(x + scrpos + ext_len, x + scrpos, len - scrpos);
+ {
+ int status;
+ zchar extension[10], saved_char;
+
+ saved_char = buf[scrpos];
+ buf[scrpos] = '\0';
+ status = completion( buf, extension);
+ buf[scrpos] = saved_char;
+
+ if (status != 2) {
+ int ext_len = zcharstrlen(extension);
+ if (ext_len > max - len) {
+ ext_len = max - len;
+ status = 1;
+ }
+ memmove(buf + scrpos + ext_len, buf + scrpos,
+ (len - scrpos)*sizeof(zchar));
+ memmove(buf + scrpos, extension,
+ ext_len*sizeof(zchar));
+ scrnmove(x + scrpos + ext_len, x + scrpos, len - scrpos);
#ifdef USE_UTF8
- utf8_mvaddnstr(y, x + scrpos, extension, ext_len);
+ utf8_mvaddnstr(y, x + scrpos, extension,
+ ext_len);
#else
- mvaddnstr(y, x + scrpos, (char *)extension, ext_len);
+ mvaddnstr(y, x + scrpos, (char *)extension,
+ ext_len);
#endif
- scrpos += ext_len;
- len += ext_len;
- searchpos = -1;
- }
- if (status) os_beep(BEEP_HIGH);
- }
- continue; /* TAB is invalid as an input character. */
- default:
- /* ASCII or ISO-Latin-1 */
- if ((ch >= ZC_ASCII_MIN && ch <= ZC_ASCII_MAX)
- || (!u_setup.plain_ascii
- && ch >= ZC_LATIN1_MIN /*&& ch <= ZC_LATIN1_MAX*/)) {
- searchpos = -1;
- if ((scrpos == max) || (insert_flag && (len == max))) {
- os_beep(BEEP_HIGH);
- continue;
- }
- if (insert_flag && (scrpos < len)) {
- /* move what's there to the right */
- scrnmove(x + scrpos + 1, x + scrpos, len - scrpos);
- memmove(buf + scrpos + 1, buf + scrpos, (len - scrpos)*sizeof(zchar));
- }
- if (insert_flag || scrpos == len)
- len++;
+ scrpos += ext_len;
+ len += ext_len;
+ searchpos = -1;
+ }
+ if (status) os_beep(BEEP_HIGH);
+ }
+ continue; /* TAB is invalid as an input character. */
+ default:
+ /* ASCII or ISO-Latin-1 */
+ if ((ch >= ZC_ASCII_MIN && ch <= ZC_ASCII_MAX)
+ || (!u_setup.plain_ascii
+ && ch >= ZC_LATIN1_MIN /*&& ch <= ZC_LATIN1_MAX*/)) {
+ searchpos = -1;
+ if ((scrpos == max) || (insert_flag && (len == max))) {
+ os_beep(BEEP_HIGH);
+ continue;
+ }
+ if (insert_flag && (scrpos < len)) {
+ /* move what's there to the right */
+ scrnmove(x + scrpos + 1, x + scrpos,
+ len - scrpos);
+ memmove(buf + scrpos + 1, buf + scrpos,
+ (len - scrpos)*sizeof(zchar));
+ }
+ if (insert_flag || scrpos == len)
+ len++;
#ifdef USE_UTF8
- if (ch < ZC_LATIN1_MIN) {
- mvaddch(y, x + scrpos, ch);
- } else if(ch > 0x7ff) {
- mvaddch(y, x + scrpos, 0xe0 | ((ch >> 12) & 0xf));
- addch(0x80 | ((ch >> 6) & 0x3f));
- addch(0x80 | (ch & 0x3f));
- } else {
- mvaddch(y, x + scrpos, 0xc0 | ((ch >> 6) & 0x1f));
- addch(0x80 | (ch & 0x3f));
- }
+ if (ch < ZC_LATIN1_MIN) {
+ mvaddch(y, x + scrpos, ch);
+ } else if(ch > 0x7ff) {
+ mvaddch(y, x + scrpos, 0xe0 |
+ ((ch >> 12) & 0xf));
+ addch(0x80 | ((ch >> 6) & 0x3f));
+ addch(0x80 | (ch & 0x3f));
+ } else {
+ mvaddch(y, x + scrpos, 0xc0 |
+ ((ch >> 6) & 0x1f));
+ addch(0x80 | (ch & 0x3f));
+ }
#else
- mvaddch(y, x + scrpos, ch);
+ mvaddch(y, x + scrpos, ch);
#endif
- buf[scrpos++] = ch;
- continue;
- }
- }
- if (is_terminator(ch)) {
- buf[len] = '\0';
- if (ch == ZC_RETURN)
- unix_add_to_history(buf);
- /* Games don't know about line editing and might get
- confused if the cursor is not at the end of the input
- line. */
- move(y, x + len);
- return ch;
+ buf[scrpos++] = ch;
+ continue;
+ }
+ }
+ if (is_terminator(ch)) {
+ buf[len] = '\0';
+ if (ch == ZC_RETURN)
+ unix_add_to_history(buf);
+ /* Games don't know about line editing and might
+ * get confused if the cursor is not at the end
+ * of the input line. */
+ move(y, x + len);
+ return ch;
+ }
}
- }
-}/* os_read_line */
+} /* os_read_line */
/*
*/
zchar os_read_key (int timeout, int cursor)
{
- zchar c;
-
- refresh();
- if (!cursor) curs_set(0);
+ zchar c;
- unix_set_global_timeout(timeout);
- c = (zchar) unix_read_char(0);
+ refresh();
+ if (!cursor)
+ curs_set(0);
- if (!cursor) curs_set(1);
- return c;
+ unix_set_global_timeout(timeout);
+ c = (zchar) unix_read_char(0);
-}/* os_read_key */
+ if (!cursor)
+ curs_set(1);
+ return c;
+} /* os_read_key */
/*
*
* Return value is NULL if there was a problem.
*/
-
char *os_read_file_name (const char *default_name, int flag)
{
- FILE *fp;
- int saved_replay = istream_replay;
- int saved_record = ostream_record;
- int i;
- char *tempname;
- zchar answer[4];
- char path_separator[2];
- char file_name[FILENAME_MAX + 1];
-
- path_separator[0] = PATH_SEPARATOR;
- path_separator[1] = 0;
-
- /* Turn off playback and recording temporarily */
- istream_replay = 0;
- ostream_record = 0;
-
- /* If we're restoring a game before the interpreter starts,
- * our filename is already provided. Just go ahead silently.
- */
- if (f_setup.restore_mode) {
- file_name[0]=0;
- } else {
- print_string ("Enter a file name.\nDefault is \"");
-
- /* After successfully reading or writing a file, the default
- * name gets saved and used again the next time something is
- * to be read or written. In restricted mode, we don't want
- * to show any path prepended to the actual file name. Here,
- * we strip out that path and display only the filename.
+ FILE *fp;
+ int saved_replay = istream_replay;
+ int saved_record = ostream_record;
+ int i;
+ char *tempname;
+ zchar answer[4];
+ char path_separator[2];
+ char file_name[FILENAME_MAX + 1];
+
+ path_separator[0] = PATH_SEPARATOR;
+ path_separator[1] = 0;
+
+ /* Turn off playback and recording temporarily */
+ istream_replay = 0;
+ ostream_record = 0;
+
+ /* If we're restoring a game before the interpreter starts,
+ * our filename is already provided. Just go ahead silently.
*/
- if (f_setup.restricted_path != NULL) {
- tempname = basename((char *)default_name);
- print_string(tempname);
- } else
+ if (f_setup.restore_mode) {
+ file_name[0]=0;
+ } else {
+ print_string ("Enter a file name.\nDefault is \"");
+
+ /* After successfully reading or writing a file, the default
+ * name gets saved and used again the next time something is
+ * to be read or written. In restricted mode, we don't want
+ * to show any path prepended to the actual file name. Here,
+ * we strip out that path and display only the filename.
+ */
+ if (f_setup.restricted_path != NULL) {
+ tempname = basename((char *)default_name);
+ print_string(tempname);
+ } else
#ifdef USE_UTF8
- {
- zchar z;
- i = 0;
- while (default_name[i])
- {
- if((default_name[i] & 0x80) == 0) {
- print_char(default_name[i++]);
- } else if((default_name[i] & 0xe0) == 0xc0 ) {
- z = default_name[i++] & 0x1f;
- z = (z << 6) | (default_name[i++] & 0x3f);
- print_char(z);
- } else if((default_name[i] & 0xf0) == 0xe0 ) {
- z = default_name[i++] & 0xf;
- z = (z << 6) | (default_name[i++] & 0x3f);
- z = (z << 6) | (default_name[i++] & 0x3f);
- print_char(z);
- } else {
- i+=4;
- print_char('?');
+ {
+ zchar z;
+ i = 0;
+ while (default_name[i]) {
+ if((default_name[i] & 0x80) == 0) {
+ print_char(default_name[i++]);
+ } else if((default_name[i] & 0xe0) == 0xc0 ) {
+ z = default_name[i++] & 0x1f;
+ z = (z << 6) | (default_name[i++] & 0x3f);
+ print_char(z);
+ } else if((default_name[i] & 0xf0) == 0xe0 ) {
+ z = default_name[i++] & 0xf;
+ z = (z << 6) | (default_name[i++] & 0x3f);
+ z = (z << 6) | (default_name[i++] & 0x3f);
+ print_char(z);
+ } else {
+ i+=4;
+ print_char('?');
+ }
+ }
}
- }
- }
#else
- print_string (default_name);
+ print_string (default_name);
#endif
- print_string ("\": ");
+ print_string ("\": ");
#ifdef USE_UTF8
- {
- zchar z_name[FILENAME_MAX + 1];
- zchar *zp;
- read_string (FILENAME_MAX, z_name);
- i = 0;
- zp = z_name;
- while (*zp)
- {
- if(*zp <= 0x7f) {
- if (i > FILENAME_MAX) break;
- file_name[i++] = *zp;
- } else if(*zp > 0x7ff) {
- if (i > FILENAME_MAX - 2) break;
- file_name[i++] = 0xe0 | ((*zp >> 12) & 0xf);
- file_name[i++] = 0x80 | ((*zp >> 6) & 0x3f);
- file_name[i++] = 0x80 | (*zp & 0x3f);
- } else {
- if (i > FILENAME_MAX - 1) break;
- file_name[i++] = 0xc0 | ((*zp >> 6) & 0x1f);
- file_name[i++] = 0x80 | (*zp & 0x3f);
+ {
+ zchar z_name[FILENAME_MAX + 1];
+ zchar *zp;
+ read_string (FILENAME_MAX, z_name);
+ i = 0;
+ zp = z_name;
+ while (*zp) {
+ if(*zp <= 0x7f) {
+ if (i > FILENAME_MAX)
+ break;
+ file_name[i++] = *zp;
+ } else if(*zp > 0x7ff) {
+ if (i > FILENAME_MAX - 2)
+ break;
+ file_name[i++] = 0xe0 | ((*zp >> 12) & 0xf);
+ file_name[i++] = 0x80 | ((*zp >> 6) & 0x3f);
+ file_name[i++] = 0x80 | (*zp & 0x3f);
+ } else {
+ if (i > FILENAME_MAX - 1)
+ break;
+ file_name[i++] = 0xc0 | ((*zp >> 6) & 0x1f);
+ file_name[i++] = 0x80 | (*zp & 0x3f);
+ }
+ zp++;
+ }
+ file_name[i] = 0;
}
- zp++;
- }
- file_name[i] = 0;
- }
#else
- read_string (FILENAME_MAX, (zchar *)file_name);
+ read_string (FILENAME_MAX, (zchar *)file_name);
#endif
- }
-
- /* Return failure if path provided when in restricted mode.
- * I think this is better than accepting a path/filename
- * and stripping off the path.
- */
- if (f_setup.restricted_path) {
- tempname = dirname(file_name);
- if (strlen(tempname) > 1)
- return NULL;
- }
-
- /* Use the default name if nothing was typed */
- if (file_name[0] == 0)
- strncpy (file_name, default_name, FILENAME_MAX);
-
- /* If we're restricted to one directory, strip any leading path left
- * over from a previous call to os_read_file_name(), then prepend
- * the prescribed path to the filename. Hostile leading paths won't
- * get this far. Instead we return failure a few lines above here if
- * someone tries it.
- */
- if (f_setup.restricted_path != NULL) {
- for (i = strlen(file_name); i > 0; i--) {
- if (file_name[i] == PATH_SEPARATOR) {
- i++;
- break;
- }
}
- tempname = strdup(file_name + i);
- strncpy(file_name, f_setup.restricted_path, FILENAME_MAX);
- /* Make sure the final character is the path separator. */
- if (file_name[strlen(file_name)-1] != PATH_SEPARATOR) {
- strncat(file_name, path_separator, FILENAME_MAX - strlen(file_name) - 2);
+ /* Return failure if path provided when in restricted mode.
+ * I think this is better than accepting a path/filename
+ * and stripping off the path.
+ */
+ if (f_setup.restricted_path) {
+ tempname = dirname(file_name);
+ if (strlen(tempname) > 1)
+ return NULL;
}
- strncat(file_name, tempname, strlen(file_name) - strlen(tempname) - 1);
- }
- /* Warn if overwriting a file. */
- if ((flag == FILE_SAVE || flag == FILE_SAVE_AUX || flag == FILE_RECORD || flag == FILE_SCRIPT)
- && ((fp = fopen(file_name, "rb")) != NULL)) {
- fclose (fp);
- print_string("Overwrite existing file? ");
- read_string(4, answer);
- if (tolower(answer[0] != 'y'))
- return NULL;
- }
+ /* Use the default name if nothing was typed */
+ if (file_name[0] == 0)
+ strncpy (file_name, default_name, FILENAME_MAX);
- /* Restore state of playback and recording */
- istream_replay = saved_replay;
- ostream_record = saved_record;
+ /* If we're restricted to one directory, strip any leading path left
+ * over from a previous call to os_read_file_name(), then prepend
+ * the prescribed path to the filename. Hostile leading paths won't
+ * get this far. Instead we return failure a few lines above here if
+ * someone tries it.
+ */
+ if (f_setup.restricted_path != NULL) {
+ for (i = strlen(file_name); i > 0; i--) {
+ if (file_name[i] == PATH_SEPARATOR) {
+ i++;
+ break;
+ }
+ }
+ tempname = strdup(file_name + i);
+ strncpy(file_name, f_setup.restricted_path, FILENAME_MAX);
+
+ /* Make sure the final character is the path separator. */
+ if (file_name[strlen(file_name)-1] != PATH_SEPARATOR) {
+ strncat(file_name, path_separator, FILENAME_MAX - strlen(file_name) - 2);
+ }
+ strncat(file_name, tempname, strlen(file_name) - strlen(tempname) - 1);
+ }
+
+ /* Warn if overwriting a file. */
+ if ((flag == FILE_SAVE || flag == FILE_SAVE_AUX ||
+ flag == FILE_RECORD || flag == FILE_SCRIPT)
+ && ((fp = fopen(file_name, "rb")) != NULL)) {
+ fclose (fp);
+ print_string("Overwrite existing file? ");
+ read_string(4, answer);
+ if (tolower(answer[0] != 'y'))
+ return NULL;
+ }
- return strdup(file_name);
+ /* Restore state of playback and recording */
+ istream_replay = saved_replay;
+ ostream_record = saved_record;
+ return strdup(file_name);
} /* os_read_file_name */
zword os_read_mouse (void)
{
/* INCOMPLETE */
- return 0;
+ return 0;
} /* os_read_mouse */
-
-
-/* What's this? */
-/*
- * Local Variables:
- * c-basic-offset: 4
- * End:
- */
-
-
/*
* Search for start of preceding word
* param currpos marker position
for (i = currpos - 1; i > 0 && buf[i] == ' '; i--) {}
j = i;
for (; i > 0 && buf[i] != ' '; i--) {}
- if (i < j && i != 0) {
+ if (i < j && i != 0)
i += 1;
- }
return i;
-}
+} /* start_of_prev_word */
+
/*
* Search for end of next word
for (i = currpos; i < len && buf[i] == ' '; i++) {}
for (; i < len && buf[i] != ' '; i++) {}
return i;
-}
+} /* end_of_next_word */