void showhelp(const char *filename) { char nc,nr,ph; char *title,*text; union { char *buffer; void *vbuf; } buf; // This is to avoild type-punning issues char line[512]; size_t size; char scan; int rv,numlines,curr_line; nc = getnumcols(); nr = getnumrows(); ph = nr - HELP_BOTTOM_MARGIN - HELP_BODY_ROW - 1; cls(); drawbox(0,0,nr,nc-1,HELPPAGE,0x07,HELPBOX); drawhorizline(2,0,nc-1,HELPPAGE,0x07,HELPBOX,0); // dumb==0 if (filename == NULL) { // print file contents gotoxy(HELP_BODY_ROW,HELP_LEFT_MARGIN,HELPPAGE); cswprint("Filename not given",0x07,HELP_LEFT_MARGIN); while (1) { inputc(&scan); if (scan == ESCAPE) break; } cls(); return; } rv = loadfile(filename,(void **)&buf.vbuf, &size); // load entire file into memory if (rv < 0) { // Error reading file or no such file sprintf(line, "Error reading file or file not found\n file=%s",filename); gotoxy(HELP_BODY_ROW,HELP_LEFT_MARGIN,HELPPAGE); cswprint(line,0x07,HELP_LEFT_MARGIN); while (1) { inputc(&scan); if (scan == ESCAPE) break; } cls(); return; } title = buf.buffer; text = findline(title,1); // end of first line *text++='\0'; // end the title string and increment text // Now we have a file just print it. gotoxy(1,(nc-strlen(title))/2,HELPPAGE); csprint(title,0x07); numlines = countlines(text); curr_line = 0; scan = ESCAPE+1; // anything except ESCAPE while(scan != ESCAPE) { printtext(text,curr_line); gotoxy(HELP_BODY_ROW-1,nc-HELP_RIGHT_MARGIN,HELPPAGE); if (curr_line > 0) putch(HELP_MORE_ABOVE,0x07,HELPPAGE); else putch(' ',0x07,HELPPAGE); gotoxy(nr-HELP_BOTTOM_MARGIN+1,nc-HELP_RIGHT_MARGIN,HELPPAGE); if (curr_line < numlines - ph) putch(HELP_MORE_BELOW,0x07,HELPPAGE); else putch(' ',0x07,HELPPAGE); inputc(&scan); // wait for user keypress switch(scan) { case HOMEKEY: curr_line = 0; break; case ENDKEY: curr_line = numlines; break; case UPARROW: curr_line--; break; case DNARROW: curr_line++; break; case PAGEUP: curr_line -= ph; break; case PAGEDN: curr_line += ph; break; default: break; } if (curr_line > numlines - ph) curr_line = numlines-ph; if (curr_line < 0) curr_line = 0; } cls(); return; }
ps_output &ps_output::put_string(const char *s, int n) { int len = 0; int i; for (i = 0; i < n; i++) { char c = s[i]; if (is_ascii(c) && csprint(c)) { if (c == '(' || c == ')' || c == '\\') len += 2; else len += 1; } else len += 4; } if (len > n*2) { if (col + n*2 + 2 > max_line_length && n*2 + 2 <= max_line_length) { putc('\n', fp); col = 0; } if (col + 1 > max_line_length) { putc('\n', fp); col = 0; } putc('<', fp); col++; for (i = 0; i < n; i++) { if (col + 2 > max_line_length) { putc('\n', fp); col = 0; } fprintf(fp, "%02x", s[i] & 0377); col += 2; } putc('>', fp); col++; } else { if (col + len + 2 > max_line_length && len + 2 <= max_line_length) { putc('\n', fp); col = 0; } if (col + 2 > max_line_length) { putc('\n', fp); col = 0; } putc('(', fp); col++; for (i = 0; i < n; i++) { char c = s[i]; if (is_ascii(c) && csprint(c)) { if (c == '(' || c == ')' || c == '\\') len = 2; else len = 1; } else len = 4; if (col + len + 1 > max_line_length) { putc('\\', fp); putc('\n', fp); col = 0; } switch (len) { case 1: putc(c, fp); break; case 2: putc('\\', fp); putc(c, fp); break; case 4: fprintf(fp, "\\%03o", c & 0377); break; default: assert(0); } col += len; } putc(')', fp); col++; } need_space = 0; return *this; }
// Reads a line of input from stdin. Replace CR with NUL byte // password <> 0 implies not echoed on screen // showoldvalue <> 0 implies currentvalue displayed first // If showoldvalue <> 0 then caller responsibility to ensure that // str is NULL terminated. void getuserinput(char *stra, unsigned int size, unsigned int password, unsigned int showoldvalue) { unsigned char c, scan; char *p, *q; // p = current char of string, q = tmp char *last; // The current last char of string char *str; // pointer to string which is going to be allocated char page; char row, col; char start, end; // Cursor shape char fudge; // How many chars should be removed from output char insmode; // Are we in insert or overwrite page = getdisppage(); getpos(&row, &col, page); // Get current position getcursorshape(&start, &end); insmode = 1; str = (char *)malloc(size + 1); // Allocate memory to store user input memset(str, 0, size + 1); // Zero it out if (password != 0) showoldvalue = 0; // Password's never displayed if (showoldvalue != 0) strcpy(str, stra); // If show old value copy current value last = str; while (*last) { last++; } // Find the terminating null byte p = str + strlen(str); if (insmode == 0) setcursorshape(1, 7); // Block cursor else setcursorshape(6, 7); // Normal cursor // Invariants: p is the current char // col is the corresponding column on the screen if (password == 0) // Not a password, print initial value { gotoxy(row, col, page); csprint(str, GETSTRATTR); } while (1) { // Do forever c = inputc(&scan); if (c == '\r') break; // User hit Enter getout of loop if (scan == ESCAPE) // User hit escape getout and nullify string { *str = 0; break; } fudge = 0; // if scan code is regognized do something // else if char code is recognized do something // else ignore switch (scan) { case HOMEKEY: p = str; break; case ENDKEY: p = last; break; case LTARROW: if (p > str) p--; break; case CTRLLT: if (p == str) break; if (*p == ' ') while ((p > str) && (*p == ' ')) p--; else { if (*(p - 1) == ' ') { p--; while ((p > str) && (*p == ' ')) p--; } } while ((p > str) && ((*p == ' ') || (*(p - 1) != ' '))) p--; break; case RTARROW: if (p < last) p++; break; case CTRLRT: if (*p == 0) break; // At end of string if (*p != ' ') while ((*p != 0) && (*p != ' ')) p++; while ((*p != 0) && ((*p == ' ') && (*(p + 1) != ' '))) p++; if (*p == ' ') p++; break; case DELETE: q = p; while (*(q + 1)) { *q = *(q + 1); q++; } if (last > str) last--; fudge = 1; break; case INSERT: insmode = 1 - insmode; // Switch mode if (insmode == 0) setcursorshape(1, 7); // Block cursor else setcursorshape(6, 7); // Normal cursor break; default: // Unrecognized scan code, look at the ascii value switch (c) { case '\b': // Move over by one q = p; while (q <= last) { *(q - 1) = *q; q++; } if (last > str) last--; if (p > str) p--; fudge = 1; break; case '\x15': /* Ctrl-U: kill input */ fudge = last - str; while (p > str) *p-- = 0; p = str; *p = 0; last = str; break; default: // Handle insert and overwrite mode if ((c >= ' ') && (c < 128) && ((unsigned int)(p - str) < size - 1)) { if (insmode == 0) { // Overwrite mode if (p == last) last++; *last = 0; *p++ = c; } else { // Insert mode if (p == last) { // last char last++; *last = 0; *p++ = c; } else { // Non-last char q = last++; while (q >= p) { *q = *(q - 1); q--; } *p++ = c; } } } else beep(); } break; } // Now the string has been modified, print it if (password == 0) { gotoxy(row, col, page); csprint(str, GETSTRATTR); if (fudge > 0) cprint(' ', GETSTRATTR, fudge, page); gotoxy(row, col + (p - str), page); } } *p = '\0'; if (password == 0) csprint("\r\n", GETSTRATTR); setcursorshape(start, end); // Block cursor // If user hit ESCAPE so return without any changes if (scan != ESCAPE) strcpy(stra, str); free(str); }