/** * Put a coloured string at a location in the char_attr line dump_ptr */ void dump_put_str(byte attr, const char *str, int col) { int i = 0; char *s; char buf[1024]; bool finished = FALSE; /* Find the start point */ while ((i != col) && (i < MAX_C_A_LEN)) { if (dump_ptr[i].pchar == '\0') finished = TRUE; if (finished) { dump_ptr[i].pchar = ' '; dump_ptr[i].pattr = TERM_WHITE; } i++; } /* Copy to a rewriteable string */ my_strcpy(buf, str, 1024); /* Hack - translate if we do that */ if (Term->xchar_hook) xstr_trans(buf, (Term->xchar_hook(128) == 128)); /* Current location within "buf" */ s = buf; /* Write the characters */ while ((*s != '\0') && (i < MAX_C_A_LEN)) { dump_ptr[i].pattr = attr; dump_ptr[i++].pchar = *s++; } /* Paranoia */ if (i >= MAX_C_A_LEN) i--; /* Terminate */ dump_ptr[i].pchar = '\0'; }
/** * Format and translate a string, then print it out to file. */ void x_fprintf(ang_file *f, int encoding, const char *fmt, ...) { va_list vp; char buf[1024]; /* Begin the Varargs Stuff */ va_start(vp, fmt); /* Format the args, save the length */ (void)vstrnfmt(buf, sizeof(buf), fmt, vp); /* End the Varargs Stuff */ va_end(vp); /* Translate */ xstr_trans(buf, encoding); file_put(f, buf); }
/* * Prompt for a string from the user. * * The "prompt" should take the form "Prompt: ". * * See "askfor_aux" for some notes about "buf" and "len", and about * the return value of this function. */ bool get_string(const char *prompt, char *buf, size_t len) { bool res; /* Paranoia XXX XXX XXX */ message_flush(); /* Display prompt */ prt(prompt, 0, 0); /* Ask the user for a string */ res = askfor_aux(buf, len, NULL); /* Translate it to 8-bit (Latin-1) */ xstr_trans(buf, LATIN1); /* Clear prompt */ prt("", 0, 0); /* Result */ return (res); }
/* * Write text to the given file and apply line-wrapping. * * Hook function for text_out(). Make sure that text_out_file points * to an open text-file. * * Long lines will be wrapped at text_out_wrap, or at column 75 if that * is not set; or at a newline character. Note that punctuation can * sometimes be placed one column beyond the wrap limit. * * You must be careful to end all file output with a newline character * to "flush" the stored line position. */ void text_out_to_file(byte a, const char *str) { const char *s; char buf[1024]; /* Current position on the line */ static int pos = 0; /* Wrap width */ int wrap = (text_out_wrap ? text_out_wrap : 75); /* We use either ascii or system-specific encoding */ int encoding = OPT(xchars_to_file) ? SYSTEM_SPECIFIC : ASCII; /* Unused parameter */ (void)a; /* Copy to a rewriteable string */ my_strcpy(buf, str, 1024); /* Translate it to 7-bit ASCII or system-specific format */ xstr_trans(buf, encoding); /* Current location within "buf" */ s = buf; /* Process the string */ while (*s) { char ch; int n = 0; int len = wrap - pos; int l_space = -1; /* If we are at the start of the line... */ if (pos == 0) { int i; /* Output the indent */ for (i = 0; i < text_out_indent; i++) { file_writec(text_out_file, ' '); pos++; } } /* Find length of line up to next newline or end-of-string */ while ((n < len) && !((s[n] == '\n') || (s[n] == '\0'))) { /* Mark the most recent space in the string */ if (s[n] == ' ') l_space = n; /* Increment */ n++; } /* If we have encountered no spaces */ if ((l_space == -1) && (n == len)) { /* If we are at the start of a new line */ if (pos == text_out_indent) { len = n; } /* HACK - Output punctuation at the end of the line */ else if ((s[0] == ' ') || (s[0] == ',') || (s[0] == '.')) { len = 1; } else { /* Begin a new line */ file_writec(text_out_file, '\n'); /* Reset */ pos = 0; continue; } } else { /* Wrap at the newline */ if ((s[n] == '\n') || (s[n] == '\0')) len = n; /* Wrap at the last space */ else len = l_space; } /* Write that line to file */ for (n = 0; n < len; n++) { /* Ensure the character is printable */ ch = (my_isprint((unsigned char) s[n]) ? s[n] : ' '); /* Write out the character */ file_writec(text_out_file, ch); /* Increment */ pos++; } /* Move 's' past the stuff we've written */ s += len; /* If we are at the end of the string, end */ if (*s == '\0') return; /* Skip newlines */ if (*s == '\n') s++; /* Begin a new line */ file_writec(text_out_file, '\n'); /* Reset */ pos = 0; /* Skip whitespace */ while (*s == ' ') s++; } /* We are done */ return; }
/* * Print some (colored) text to the screen at the current cursor position, * automatically "wrapping" existing text (at spaces) when necessary to * avoid placing any text into the last column, and clearing every line * before placing any text in that line. Also, allow "newline" to force * a "wrap" to the next line. Advance the cursor as needed so sequential * calls to this function will work correctly. * * Once this function has been called, the cursor should not be moved * until all the related "text_out()" calls to the window are complete. * * This function will correctly handle any width up to the maximum legal * value of 256, though it works best for a standard 80 character width. */ void text_out_to_screen(byte a, const char *str) { int x, y; int wid, h; int wrap; const char *s; char buf[1024]; /* We use either ascii or system-specific encoding */ int encoding = (OPT(xchars_to_file)) ? SYSTEM_SPECIFIC : ASCII; /* Obtain the size */ (void)Term_get_size(&wid, &h); /* Obtain the cursor */ (void)Term_locate(&x, &y); /* Copy to a rewriteable string */ my_strcpy(buf, str, 1024); /* Translate it to 7-bit ASCII or system-specific format */ xstr_trans(buf, encoding); /* Use special wrapping boundary? */ if ((text_out_wrap > 0) && (text_out_wrap < wid)) wrap = text_out_wrap; else wrap = wid; /* Process the string */ for (s = buf; *s; s++) { char ch; /* Force wrap */ if (*s == '\n') { /* Wrap */ x = text_out_indent; y++; /* Clear line, move cursor */ Term_erase(x, y, 255); x += text_out_pad; Term_gotoxy(x, y); continue; } /* Clean up the char */ ch = (my_isprint((unsigned char)*s) ? *s : ' '); /* Wrap words as needed */ if ((x >= wrap - 1) && (ch != ' ')) { int i, n = 0; byte av[256]; char cv[256]; /* Wrap word */ if (x < wrap) { /* Scan existing text */ for (i = wrap - 2; i >= 0; i--) { /* Grab existing attr/char */ Term_what(i, y, &av[i], &cv[i]); /* Break on space */ if (cv[i] == ' ') break; /* Track current word */ n = i; } } /* Special case */ if (n == 0) n = wrap; /* Clear line */ Term_erase(n, y, 255); /* Wrap */ x = text_out_indent; y++; /* Clear line, move cursor */ Term_erase(x, y, 255); x += text_out_pad; Term_gotoxy(x, y); /* Wrap the word (if any) */ for (i = n; i < wrap - 1; i++) { /* Dump */ Term_addch(av[i], cv[i]); /* Advance (no wrap) */ if (++x > wrap) x = wrap; } } /* Dump */ Term_addch(a, ch); /* Advance */ if (++x > wrap) x = wrap; } }
/* * Write text to the given file and apply line-wrapping. * * Hook function for text_out(). Make sure that text_out_file points * to an open text-file. * * Long lines will be wrapped at text_out_wrap, or at column 75 if that * is not set; or at a newline character. Note that punctuation can * sometimes be placed one column beyond the wrap limit. * * You must be careful to end all file output with a newline character * to "flush" the stored line position. */ void text_out_dump(byte a, char *str, char_attr_line **line, int *current_line, int indent, int wrap) { const char *s; char buf[1024]; /* Current position on the line */ int pos = 0; /* We use either ascii or system-specific encoding */ int encoding = OPT(xchars_to_file) ? SYSTEM_SPECIFIC : ASCII; char_attr_line *lline = *line; /* Copy to a rewriteable string */ my_strcpy(buf, str, 1024); /* Translate it to 7-bit ASCII or system-specific format */ xstr_trans(buf, encoding); /* Current location within "buf" */ s = buf; /* Process the string */ while (*s) { char ch; int n = 0; int len = wrap - pos; int l_space = -1; /* If we are at the start of the line... */ if (pos == 0) { int i; /* Output the indent */ for (i = 0; i < indent; i++) { dump_put_str(TERM_WHITE, " ", pos); pos++; } } /* Find length of line up to next newline or end-of-string */ while ((n < len) && !((s[n] == '\n') || (s[n] == '\0'))) { /* Mark the most recent space in the string */ if (s[n] == ' ') l_space = n; /* Increment */ n++; } /* If we have encountered no spaces */ if ((l_space == -1) && (n == len)) { /* If we are at the start of a new line */ if (pos == indent) { len = n; } /* HACK - Output punctuation at the end of the line */ else if ((s[0] == ' ') || (s[0] == ',') || (s[0] == '.')) { len = 1; } else { /* Begin a new line */ (*current_line)++; dump_ptr = (char_attr *) &lline[*current_line]; /* Reset */ pos = 0; continue; } } else { /* Wrap at the newline */ if ((s[n] == '\n') || (s[n] == '\0')) len = n; /* Wrap at the last space */ else len = l_space; } /* Write that line to dump */ for (n = 0; n < len; n++) { /* Ensure the character is printable */ ch = (my_isprint((unsigned char) s[n]) ? s[n] : ' '); /* Write out the character */ dump_put_str(a, format("%c",ch), pos); /* Increment */ pos++; } /* Move 's' past the stuff we've written */ s += len; /* Begin a new line */ (*current_line)++; dump_ptr = (char_attr *) &lline[*current_line]; /* If we are at the end of the string, end */ if (*s == '\0') return; /* Begin a new line */ if (*s == '\n') { (*current_line)++; dump_ptr = (char_attr *) &lline[*current_line]; } /* Reset */ pos = 0; /* Skip whitespace */ while (*s == ' ') s++; } /* We are done */ return; }
bool file_getl(ang_file *f, char *buf, size_t len) { bool seen_cr = FALSE; byte b; size_t i = 0; bool check_encodes = FALSE; /* Leave a byte for the terminating 0 */ size_t max_len = len - 1; while (i < max_len) { char c; if (!file_readc(f, &b)) { buf[i] = '\0'; return (i == 0) ? FALSE : TRUE; } c = (char) b; if (c == '\r') { seen_cr = TRUE; continue; } if (seen_cr && c != '\n') { fseek(f->fh, -1, SEEK_CUR); buf[i] = '\0'; return TRUE; } if (c == '\n') { buf[i] = '\0'; return TRUE; } /* Expand tabs */ if (c == '\t') { /* Next tab stop */ size_t tabstop = ((i + TAB_COLUMNS) / TAB_COLUMNS) * TAB_COLUMNS; if (tabstop >= len) break; /* Convert to spaces */ while (i < tabstop) buf[i++] = ' '; continue; } /* Ignore non-printables */ else if (my_isprint((unsigned char)c)) { buf[i++] = c; /* Notice possible encode */ if (c == '[') check_encodes = TRUE; continue; } else { buf[i++] = '?'; continue; } } /* Translate encodes if necessary */ if (check_encodes) xstr_trans(buf, LATIN1); buf[i] = '\0'; return TRUE; }