home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume35 / ee / part03 < prev    next >
Encoding:
Text File  |  1993-02-21  |  53.7 KB  |  2,212 lines

  1. Newsgroups: comp.sources.misc
  2. From: hugh@nsmdserv.cnd.hp.com (Hugh F. Mahon)
  3. Subject: v35i082:  ee - Easy Editor, a simple editor for UNIX, Part03/05
  4. Message-ID: <1993Feb22.041355.15332@sparky.imd.sterling.com>
  5. X-Md4-Signature: 3693c0f88d4971eb39e4a4006830449a
  6. Date: Mon, 22 Feb 1993 04:13:55 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: hugh@nsmdserv.cnd.hp.com (Hugh F. Mahon)
  10. Posting-number: Volume 35, Issue 82
  11. Archive-name: ee/part03
  12. Environment: SYSV, SunOS, Curses
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # Contents:  ee.c.A ee.msg
  19. # Wrapped by kent@sparky on Sat Feb 20 21:31:18 1993
  20. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  21. echo If this archive is complete, you will see the following message:
  22. echo '          "shar: End of archive 3 (of 5)."'
  23. if test -f 'ee.c.A' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'ee.c.A'\"
  25. else
  26.   echo shar: Extracting \"'ee.c.A'\" \(45319 characters\)
  27.   sed "s/^X//" >'ee.c.A' <<'END_OF_FILE'
  28. X/*
  29. X |    ee (easy editor)
  30. X |
  31. X |    An easy to use, simple screen oriented editor.
  32. X |
  33. X |    written by Hugh Mahon
  34. X |
  35. X |    THIS MATERIAL IS PROVIDED "AS IS".  THERE ARE
  36. X |    NO WARRANTIES OF ANY KIND WITH REGARD TO THIS
  37. X |    MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE
  38. X |    IMPLIED WARRANTIES OF MERCHANTABILITY AND
  39. X |    FITNESS FOR A PARTICULAR PURPOSE.  Neither
  40. X |    Hewlett-Packard nor Hugh Mahon shall be liable
  41. X |    for errors contained herein, nor for
  42. X |    incidental or consequential damages in
  43. X |    connection with the furnishing, performance or
  44. X |    use of this material.  Neither Hewlett-Packard
  45. X |    nor Hugh Mahon assumes any responsibility for
  46. X |    the use or reliability of this software or
  47. X |    documentation.  This software and
  48. X |    documentation is totally UNSUPPORTED.  There
  49. X |    is no support contract available.  Hewlett-
  50. X |    Packard has done NO Quality Assurance on ANY
  51. X |    of the program or documentation.  You may find
  52. X |    the quality of the materials inferior to
  53. X |    supported materials.
  54. X |
  55. X |    This software is not a product of Hewlett-Packard, Co., or any 
  56. X |    other company.  No support is implied or offered with this software.
  57. X |    You've got the source, and you're on your own.
  58. X |
  59. X |    This software is for free distribution, and is not to be sold, or 
  60. X |    otherwise traded for value without the expressed, written consent of 
  61. X |    the author.  Likewise, any derivatives of this software cannot be 
  62. X |    sold or traded without the consent of the author.  
  63. X |
  64. X |    This notice must be included with this software and any derivatives.
  65. X |
  66. X |    This editor was purposely developed to be simple, both in 
  67. X |    interface and implementation.  This editor was developed to 
  68. X |    address a specific audience: the user who is new to computers 
  69. X |    (especially UNIX).
  70. X |    
  71. X |    ee is not aimed at technical users; for that reason more 
  72. X |    complex features were intentionally left out.  In addition, 
  73. X |    ee is intended to be compiled by people with little computer 
  74. X |    experience, which means that it needs to be small, relatively 
  75. X |    simple in implementation, and portable.
  76. X |
  77. X |    This software and documentation contains
  78. X |    proprietary information which is protected by
  79. X |    copyright.  All rights are reserved.
  80. X |
  81. X |    $Header: /users/hugh/tmp/old_ae/ee.c,v 1.65 1993/02/19 05:00:07 hugh Exp $
  82. X |
  83. X */
  84. X
  85. Xchar *ee_copyright_message = 
  86. X"Copyright (c) 1986, 1990, 1991, 1992, 1993 Hugh Mahon ";
  87. X
  88. Xchar *ee_long_notice[] = {
  89. X    "This software and documentation contains", 
  90. X    "proprietary information which is protected by", 
  91. X    "copyright.  All rights are reserved."
  92. X    };
  93. X
  94. Xchar *version = "@(#) ee, version 1.2.2 $Revision: 1.65 $";
  95. X
  96. X#ifdef NCURSE
  97. X#include "new_curse.h"
  98. X#else
  99. X#include <curses.h>
  100. X#endif
  101. X
  102. X#include <signal.h>
  103. X#include <fcntl.h>
  104. X#include <sys/types.h>
  105. X#include <sys/stat.h>
  106. X#include <errno.h>
  107. X#include <string.h>
  108. X#include <pwd.h>
  109. X
  110. X#ifndef NO_CATGETS
  111. X#include <locale.h>
  112. X#include <nl_types.h>
  113. X
  114. Xnl_catd catalog;
  115. X#else
  116. X#define catgetlocal(a, b) (b)
  117. X#endif /* NO_CATGETS */
  118. X
  119. X#ifndef SIGCHLD
  120. X#define SIGCHLD SIGCLD
  121. X#endif
  122. X
  123. X#define TAB 9
  124. X#define max(a, b)    (a > b ? a : b)
  125. X#define min(a, b)    (a < b ? a : b)
  126. X
  127. X/*
  128. X |    defines for type of data to show in info window
  129. X */
  130. X
  131. X#define CONTROL_KEYS 1
  132. X#define COMMANDS     2
  133. X
  134. Xextern char *malloc();
  135. Xextern char *realloc();
  136. Xextern char *getenv();
  137. X
  138. Xchar *get_string();
  139. Xchar *resolve_name();
  140. X
  141. Xstruct text {
  142. X    char *line;            /* line of characters        */
  143. X    int line_number;        /* line number            */
  144. X    int line_length;    /* actual number of characters in the line */
  145. X    int max_length;    /* maximum number of characters the line handles */
  146. X    struct text *next_line;        /* next line of text        */
  147. X    struct text *prev_line;        /* previous line of text    */
  148. X    };
  149. X
  150. Xstruct text *first_line;    /* first line of current buffer        */
  151. Xstruct text *dlt_line;        /* structure for info on deleted line    */
  152. Xstruct text *curr_line;        /* current line cursor is on        */
  153. Xstruct text *tmp_line;        /* temporary line pointer        */
  154. Xstruct text *srch_line;        /* temporary pointer for search routine */
  155. X
  156. Xstruct text *txtalloc();    /* procedure to allocate space for each line */
  157. X
  158. Xstruct files {        /* structure to store names of files to be edited*/
  159. X    char *name;        /* name of file                */
  160. X    struct files *next_name;
  161. X    };
  162. X
  163. Xstruct files *name_alloc();
  164. Xstruct files *top_of_stack = NULL;
  165. X
  166. Xint d_wrd_len;            /* length of deleted word        */
  167. Xint position;            /* offset in bytes from begin of line    */
  168. Xint scr_pos;            /* horizontal position            */
  169. Xint scr_vert;            /* vertical position on screen        */
  170. Xint scr_horz;            /* horizontal position on screen    */
  171. Xint tmp_vert, tmp_horz;
  172. Xint input_file;            /* indicate to read input file        */
  173. Xint recv_file;            /* indicate reading a file        */
  174. Xint edit;            /* continue executing while true    */
  175. Xint gold;            /* 'gold' function key pressed        */
  176. Xint fildes;            /* file descriptor            */
  177. Xint case_sen;            /* case sensitive search flag        */
  178. Xint last_line;            /* last line for text display        */
  179. Xint last_col;            /* last column for text display        */
  180. Xint horiz_offset = 0;        /* offset from left edge of text    */
  181. Xint clear_com_win;        /* flag to indicate com_win needs clearing */
  182. Xint text_changes = FALSE;    /* indicate changes have been made to text */
  183. Xint get_fd;            /* file descriptor for reading a file    */
  184. Xint info_window = TRUE;        /* flag to indicate if help window visible */
  185. Xint info_type = CONTROL_KEYS;    /* flag to indicate type of info to display */
  186. Xint expand_tabs = TRUE;        /* flag for expanding tabs        */
  187. Xint right_margin = 0;        /* the right margin             */
  188. Xint observ_margins = TRUE;    /* flag for whether margins are observed */
  189. Xint shell_fork;
  190. Xint temp_stdin;            /* temporary storage for stdin        */
  191. Xint temp_stdout;        /* temp storage for stdout descriptor    */
  192. Xint temp_stderr;        /* temp storage for stderr descriptor    */
  193. Xint pipe_out[2];        /* pipe file desc for output        */
  194. Xint pipe_in[2];            /* pipe file descriptors for input    */
  195. Xint out_pipe;            /* flag that info is piped out        */
  196. Xint in_pipe;            /* flag that info is piped in        */
  197. Xint formatted = FALSE;        /* flag indicating paragraph formatted    */
  198. Xint auto_format = FALSE;    /* flag for auto_format mode        */
  199. Xint restricted = FALSE;        /* flag to indicate restricted mode    */
  200. Xint nohighlight = FALSE;    /* turns off highlighting        */
  201. Xint eightbit = TRUE;        /* eight bit character flag        */
  202. X
  203. Xchar *point;            /* points to current position in line    */
  204. Xchar *srch_str;            /* pointer for search string        */
  205. Xchar *u_srch_str;        /* pointer to non-case sensitive search    */
  206. Xchar *srch_1;            /* pointer to start of suspect string    */
  207. Xchar *srch_2;            /* pointer to next character of string    */
  208. Xchar *srch_3;
  209. Xchar *in_file_name = NULL;    /* name of input file            */
  210. Xchar *tmp_file;            /* temporary file name            */
  211. Xchar d_char;            /* deleted character            */
  212. Xchar *d_word;            /* deleted word                */
  213. Xchar *d_line;            /* deleted line                */
  214. Xchar in_string[513];        /* buffer for reading a file        */
  215. Xchar *print_command = "lp";    /* string to use for the print command     */
  216. Xint in;                /* input character            */
  217. X
  218. XFILE *temp_fp;            /* temporary file pointer        */
  219. XFILE *bit_bucket;        /* file pointer to /dev/null        */
  220. XFILE *fopen();            /* declaration for open function    */
  221. X
  222. Xchar *table[] = { 
  223. X    "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H", "\t", "^J", 
  224. X    "^K", "^L", "^M", "^N", "^O", "^P", "^Q", "^R", "^S", "^T", "^U", 
  225. X    "^V", "^W", "^X", "^Y", "^Z", "^[", "^\\", "^]", "^^", "^_"
  226. X    };
  227. X
  228. XWINDOW *com_win;
  229. XWINDOW *text_win;
  230. XWINDOW *help_win;
  231. XWINDOW *info_win;
  232. X
  233. X/*
  234. X |    Declare addresses for routines referenced in menus below.
  235. X */
  236. X
  237. Xint help();
  238. Xint menu_op();
  239. Xint file_op();
  240. Xint search_prompt();
  241. Xint search();
  242. Xint finish();
  243. Xint quit();
  244. Xint shell_op();
  245. Xint leave_op();
  246. Xint no_info_window();
  247. Xint create_info_window();
  248. Xint redraw();
  249. Xint Format();
  250. Xint modes_op();
  251. Xint spell_op();
  252. Xint ispell_op();
  253. Xint print_buffer();
  254. X
  255. X/*
  256. X |    The following structure allows menu items to be flexibly declared.
  257. X |    The first item is the string describing the selection, the second 
  258. X |    is the address of the procedure to call when the item is selected,
  259. X |    and the third is the argument for the procedure.
  260. X |
  261. X |    For those systems with i18n, the string should be accompanied by a
  262. X |    catalog number.  The 'int *' should be replaced with 'void *' on 
  263. X |    systems with that type.
  264. X |
  265. X |    The first menu item will be the title of the menu, with NULL 
  266. X |    parameters for the procedure and argument, followed by the menu items.
  267. X |
  268. X |    If the procedure value is NULL, the menu item is displayed, but no 
  269. X |    procedure is called when the item is selected.  The number of the 
  270. X |    item will be returned.  If the third (argument) parameter is -1, no 
  271. X |    argument is given to the procedure when it is called.
  272. X */
  273. X
  274. Xstruct menu_entries {
  275. X    char *item_string;
  276. X    int (*procedure)();
  277. X    unsigned int argument;
  278. X    };
  279. X
  280. X/*
  281. X |    allocate space here for the strings that will be in the menu
  282. X */
  283. X
  284. Xstruct menu_entries modes_menu[] = {
  285. X    {"", NULL, NULL}, 
  286. X    {"                                                                      ", NULL, -1}, 
  287. X    {"                                                                      ", NULL, -1}, 
  288. X    {"                                                                      ", NULL, -1}, 
  289. X    {"                                                                      ", NULL, -1}, 
  290. X    {"                                                                      ", NULL, -1}, 
  291. X    {"                                                                      ", NULL, -1}, 
  292. X    {"                                                                      ", NULL, -1}, 
  293. X    {NULL, NULL, -1}
  294. X    };
  295. X
  296. Xint modes_initialized = FALSE;
  297. X
  298. Xchar *mode_strings[8]; 
  299. X
  300. Xstruct menu_entries leave_menu[] = {
  301. X    {"", NULL, -1}, 
  302. X    {"", finish, -1}, 
  303. X    {"", quit, TRUE}, 
  304. X    {NULL, NULL, -1}
  305. X    };
  306. X
  307. X#define READ_FILE 1
  308. X#define WRITE_FILE 2
  309. X#define SAVE_FILE 3
  310. X
  311. Xstruct menu_entries file_menu[] = {
  312. X    {"", NULL, -1},
  313. X    {"", file_op, READ_FILE},
  314. X    {"", file_op, WRITE_FILE},
  315. X    {"", file_op, SAVE_FILE},
  316. X    {"", print_buffer, -1},
  317. X    {NULL, NULL, -1}
  318. X    };
  319. X
  320. Xstruct menu_entries search_menu[] = {
  321. X    {"", NULL, NULL}, 
  322. X    {"", search_prompt, -1},
  323. X    {"", search, TRUE},
  324. X    {NULL, NULL, -1}
  325. X    };
  326. X
  327. Xstruct menu_entries spell_menu[] = {
  328. X    {"", NULL, -1}, 
  329. X    {"", spell_op, -1},
  330. X    {"", ispell_op, -1},
  331. X    {NULL, NULL, -1}
  332. X    };
  333. X
  334. Xstruct menu_entries misc_menu[] = {
  335. X    {"", NULL, -1}, 
  336. X    {"", Format, -1},
  337. X    {"", shell_op, -1}, 
  338. X    {"", menu_op, (int)spell_menu}, 
  339. X    {NULL, NULL, -1}
  340. X    };
  341. X
  342. Xstruct menu_entries main_menu[] = {
  343. X    {"", NULL, -1}, 
  344. X    {"", leave_op, -1}, 
  345. X    {"", help, -1},
  346. X    {"", menu_op, (int)file_menu}, 
  347. X    {"", redraw, -1}, 
  348. X    {"", modes_op, -1}, 
  349. X    {"", menu_op, (int)search_menu}, 
  350. X    {"", menu_op, (int)misc_menu}, 
  351. X    {NULL, NULL, -1}
  352. X    };
  353. X
  354. Xchar *help_text[22];
  355. X
  356. Xchar *control_keys[5];
  357. X
  358. Xchar *command_strings[5];
  359. Xchar *commands[30];
  360. Xchar *init_strings[18];
  361. X
  362. Xint abort();
  363. X
  364. X/*
  365. X |    Declarations for strings for localization
  366. X */
  367. X
  368. Xchar *com_win_message;        /* to be shown in com_win if no info window */
  369. Xchar *no_file_string;
  370. Xchar *ascii_code_str;
  371. Xchar *printer_msg_str;
  372. Xchar *command_str;
  373. Xchar *file_write_prompt_str;
  374. Xchar *file_read_prompt_str;
  375. Xchar *char_str;
  376. Xchar *unkn_cmd_str;
  377. Xchar *non_unique_cmd_msg;
  378. Xchar *line_num_str;
  379. Xchar *line_len_str;
  380. Xchar *current_file_str;
  381. Xchar *usage0;
  382. Xchar *usage1;
  383. Xchar *usage2;
  384. Xchar *usage3;
  385. Xchar *file_is_dir_msg;
  386. Xchar *new_file_msg;
  387. Xchar *cant_open_msg;
  388. Xchar *open_file_msg;
  389. Xchar *file_read_fin_msg;
  390. Xchar *reading_file_msg;
  391. Xchar *read_only_msg;
  392. Xchar *file_read_lines_msg;
  393. Xchar *save_file_name_prompt;
  394. Xchar *file_not_saved_msg;
  395. Xchar *changes_made_prompt;
  396. Xchar *yes_char;
  397. Xchar *file_exists_prompt;
  398. Xchar *create_file_fail_msg;
  399. Xchar *writing_file_msg;
  400. Xchar *file_written_msg;
  401. Xchar *searching_msg;
  402. Xchar *str_not_found_msg;
  403. Xchar *search_prompt_str;
  404. Xchar *exec_err_msg;
  405. Xchar *continue_msg;
  406. Xchar *menu_cancel_msg;
  407. Xchar *menu_size_err_msg;
  408. Xchar *press_any_key_msg;
  409. Xchar *shell_prompt;
  410. Xchar *formatting_msg;
  411. Xchar *shell_echo_msg;
  412. Xchar *spell_in_prog_msg;
  413. Xchar *margin_prompt;
  414. Xchar *restricted_msg;
  415. Xchar *ON;
  416. Xchar *OFF;
  417. Xchar *HELP;
  418. Xchar *WRITE;
  419. Xchar *READ;
  420. Xchar *LINE;
  421. Xchar *FILE_str;
  422. Xchar *CHARACTER;
  423. Xchar *REDRAW;
  424. Xchar *RESEQUENCE;
  425. Xchar *AUTHOR;
  426. Xchar *VERSION;
  427. Xchar *CASE;
  428. Xchar *NOCASE;
  429. Xchar *EXPAND;
  430. Xchar *NOEXPAND;
  431. Xchar *Exit_string;
  432. Xchar *QUIT_string;
  433. Xchar *INFO;
  434. Xchar *NOINFO;
  435. Xchar *MARGINS;
  436. Xchar *NOMARGINS;
  437. Xchar *AUTOFORMAT;
  438. Xchar *NOAUTOFORMAT;
  439. Xchar *Echo;
  440. Xchar *PRINTCOMMAND;
  441. Xchar *RIGHTMARGIN;
  442. Xchar *HIGHLIGHT;
  443. Xchar *NOHIGHLIGHT;
  444. Xchar *EIGHTBIT;
  445. Xchar *NOEIGHTBIT;
  446. X
  447. Xmain(argc, argv)        /* beginning of main program        */
  448. Xint argc;
  449. Xchar *argv[];
  450. X{
  451. X    int counter;
  452. X
  453. X    for (counter = 1; counter < 24; counter++)
  454. X        signal(counter, SIG_IGN);
  455. X
  456. X    signal(SIGCHLD, SIG_DFL);
  457. X    signal(SIGSEGV, SIG_DFL);
  458. X    signal(SIGINT, abort);
  459. X
  460. X    d_char = 0;
  461. X    d_word = malloc(150);
  462. X    *d_word = NULL;
  463. X    d_line = NULL;
  464. X    dlt_line = txtalloc();
  465. X    dlt_line->line = d_line;
  466. X    curr_line = first_line = txtalloc();
  467. X    curr_line->line = point = malloc(10);
  468. X    curr_line->line_length = 1;
  469. X    curr_line->max_length = 10;
  470. X    curr_line->prev_line = NULL;
  471. X    curr_line->next_line = NULL;
  472. X    curr_line->line_number  = 1;
  473. X    srch_str = NULL;
  474. X    u_srch_str = NULL;
  475. X    position = 1;
  476. X    scr_pos =0;
  477. X    scr_vert = 0;
  478. X    scr_horz = 0;
  479. X    bit_bucket = fopen("/dev/null", "w");
  480. X    edit = TRUE;
  481. X    gold = case_sen = FALSE;
  482. X    shell_fork = TRUE;
  483. X    strings_init();
  484. X    ee_init();
  485. X    if (argc > 0 )
  486. X        get_options(argc, argv);
  487. X    set_up_term();
  488. X    if (right_margin == 0)
  489. X        right_margin = COLS - 1;
  490. X    if (top_of_stack == NULL)
  491. X    {
  492. X        wprintw(com_win, no_file_string);
  493. X        wrefresh(com_win);
  494. X    }
  495. X    else
  496. X        check_fp();
  497. X
  498. X    clear_com_win = TRUE;
  499. X
  500. X    while(edit) 
  501. X    {
  502. X        wrefresh(text_win);
  503. X        in = wgetch(text_win);
  504. X        if (in == -1)
  505. X            exit(0);
  506. X
  507. X        if (clear_com_win)
  508. X        {
  509. X            clear_com_win = FALSE;
  510. X            wmove(com_win, 0, 0);
  511. X            werase(com_win);
  512. X            if (!info_window)
  513. X            {
  514. X                wprintw(com_win, "%s", com_win_message);
  515. X            }
  516. X            wrefresh(com_win);
  517. X        }
  518. X
  519. X        if (in > 255)
  520. X            function_key();
  521. X        else if ((in == '\10') || (in == 127))
  522. X            delete(TRUE);
  523. X        else if ((in > 31) || (in == 9))
  524. X            insert(in);
  525. X        else if ((in >= 0) && (in <= 31))
  526. X            control();
  527. X    }
  528. X}
  529. X
  530. Xchar *resiz_line(factor, rline, rpos)    /* resize the line to length + factor*/
  531. Xint factor;        /* resize factor                */
  532. Xstruct text *rline;    /* position in line                */
  533. Xint rpos;
  534. X{
  535. X    char *rpoint;
  536. X    int resiz_var;
  537. X    rline->max_length += factor;
  538. X    rpoint = rline->line = realloc(rline->line, rline->max_length );
  539. X    for (resiz_var = 1 ; (resiz_var < rpos) ; resiz_var++)
  540. X        rpoint++;
  541. X    return(rpoint);
  542. X}
  543. X
  544. Xinsert(character)        /* insert character into line        */
  545. Xint character;            /* new character            */
  546. X{
  547. X    int counter;
  548. X    int value;
  549. X    char *temp;        /* temporary pointer            */
  550. X    char *temp2;        /* temporary pointer            */
  551. X
  552. X    if ((character == '\011') && (expand_tabs))
  553. X    {
  554. X        counter = len_char('\011', scr_horz);
  555. X        for (; counter > 0; counter--)
  556. X            insert(' ');
  557. X        if (auto_format)
  558. X            Auto_Format();
  559. X        return;
  560. X    }
  561. X    text_changes = TRUE;
  562. X    if ((curr_line->max_length - curr_line->line_length) < 5)
  563. X        point = resiz_line(10, curr_line, position);
  564. X    curr_line->line_length++;
  565. X    temp = point;
  566. X    counter = position;
  567. X    while (counter < curr_line->line_length)    /* find end of line */
  568. X    {
  569. X        counter++;
  570. X        temp++;
  571. X    }
  572. X    temp++;            /* increase length of line by one    */
  573. X    while (point < temp)
  574. X    {
  575. X        temp2=temp - 1;
  576. X        *temp= *temp2;    /* shift characters over by one        */
  577. X        temp--;
  578. X    }
  579. X    *point = character;    /* insert new character            */
  580. X    wclrtoeol(text_win);
  581. X    if (((character >= 0) && (character < ' ')) || (character >= 127)) /* check for TAB character*/
  582. X    {
  583. X        scr_pos = scr_horz += out_char(text_win, character, scr_horz);
  584. X        point++;
  585. X        position++;
  586. X    }
  587. X    else
  588. X    {
  589. X        waddch(text_win, character);
  590. X        scr_pos = ++scr_horz;
  591. X        point++;
  592. X        position ++;
  593. X    }
  594. X
  595. X    if ((observ_margins) && (right_margin < scr_pos))
  596. X    {
  597. X        counter = position;
  598. X        while (scr_pos > right_margin)
  599. X            prev_word();
  600. X        if (scr_pos == 0)
  601. X        {
  602. X            while (position < counter)
  603. X                right(TRUE);
  604. X        }
  605. X        else
  606. X        {
  607. X            counter -= position;
  608. X            insert_line(TRUE);
  609. X            for (value = 0; value < counter; value++)
  610. X                right(TRUE);
  611. X        }
  612. X    }
  613. X
  614. X    if ((scr_horz - horiz_offset) > last_col)
  615. X    {
  616. X        horiz_offset += 8;
  617. X        midscreen(scr_vert, point);
  618. X    }
  619. X
  620. X    if ((auto_format) && (character == ' ') && (!formatted))
  621. X        Auto_Format();
  622. X    else if ((character != ' ') && (character != '\t'))
  623. X        formatted = FALSE;
  624. X
  625. X    draw_line(scr_vert, scr_horz, point, position, curr_line->line_length);
  626. X}
  627. X
  628. Xdelete(disp)            /* delete character        */
  629. Xint disp;
  630. X{
  631. X    char *tp;
  632. X    char *temp2;
  633. X    struct text *temp_buff;
  634. X    int temp_vert;
  635. X    int temp_pos;
  636. X
  637. X    if (point != curr_line->line)    /* if not at beginning of line    */
  638. X    {
  639. X        text_changes = TRUE;
  640. X        temp2 = tp = point;
  641. X        tp--;
  642. X        point--;
  643. X        if ((*tp >= '\000') && (*tp < ' '))    /* check for TAB    */
  644. X            scanline(tp);
  645. X        else
  646. X            --scr_horz;
  647. X        scr_pos = scr_horz;
  648. X        if (in == 8)
  649. X            d_char = *point;    /* save deleted character  */
  650. X        temp_pos = --position;
  651. X        curr_line->line_length--;
  652. X        while (temp_pos <= curr_line->line_length)
  653. X        {
  654. X            temp_pos++;
  655. X            *tp= *temp2;
  656. X            tp++;
  657. X            temp2++;
  658. X        }
  659. X        if (scr_horz < horiz_offset)
  660. X        {
  661. X            horiz_offset -= 8;
  662. X            midscreen(scr_vert, point);
  663. X        }
  664. X    }
  665. X    else if (curr_line->prev_line != NULL)
  666. X    {
  667. X        text_changes = TRUE;
  668. X        left(disp);            /* go to previous line    */
  669. X        temp_buff = curr_line->next_line;
  670. X        point = resiz_line(temp_buff->line_length, curr_line, position);
  671. X        if (temp_buff->next_line != NULL)
  672. X            temp_buff->next_line->prev_line = curr_line;
  673. X        curr_line->next_line = temp_buff->next_line;
  674. X        temp2 = temp_buff->line;
  675. X        if (in == 8)
  676. X            d_char = '\n';
  677. X        tp = point;
  678. X        temp_pos = 1;
  679. X        while (temp_pos < temp_buff->line_length)
  680. X        {
  681. X            curr_line->line_length++;
  682. X            temp_pos++;
  683. X            *tp = *temp2;
  684. X            tp++;
  685. X            temp2++;
  686. X        }
  687. X        *tp = NULL;
  688. X        free(temp_buff->line);
  689. X        free(temp_buff);
  690. X        temp_buff = curr_line;
  691. X        temp_vert = scr_vert;
  692. X        scr_pos = scr_horz;
  693. X        if (scr_vert < last_line)
  694. X        {
  695. X            wmove(text_win, scr_vert + 1, 0);
  696. X            wdeleteln(text_win);
  697. X        }
  698. X        while ((temp_buff != NULL) && (temp_vert < last_line))
  699. X        {
  700. X            temp_buff = temp_buff->next_line;
  701. X            temp_vert++;
  702. X        }
  703. X        if ((temp_vert == last_line) && (temp_buff != NULL))
  704. X        {
  705. X            tp = temp_buff->line;
  706. X            wmove(text_win, last_line,0);
  707. X            wclrtobot(text_win);
  708. X            draw_line(last_line, 0, tp, 1, temp_buff->line_length);
  709. X            wmove(text_win, scr_vert, (scr_horz - horiz_offset));
  710. X        }
  711. X    }
  712. X    draw_line(scr_vert, scr_horz, point, position, curr_line->line_length);
  713. X    formatted = FALSE;
  714. X}
  715. X
  716. Xscanline(pos)    /* find the proper horizontal position for the pointer    */
  717. Xchar *pos;
  718. X{
  719. X    int temp;
  720. X    char *ptr;
  721. X
  722. X    ptr = curr_line->line;
  723. X    temp = 0;
  724. X    while (ptr < pos)
  725. X    {
  726. X        if ((*ptr >= 0) && (*ptr <= 8))
  727. X            temp += 2;
  728. X        else if (*ptr == 9)
  729. X            temp += tabshift(temp);
  730. X        else if ((*ptr >= 10) && (*ptr <= 31))
  731. X            temp += 2;
  732. X        else if ((*ptr >= 32) && (*ptr < 127))
  733. X            temp++;
  734. X        else if (*ptr == 127)
  735. X            temp += 2;
  736. X        else if (!eightbit)
  737. X            temp += 5;
  738. X        else
  739. X            temp++;
  740. X        ptr++;
  741. X    }
  742. X    scr_horz = temp;
  743. X    if ((scr_horz - horiz_offset) > last_col)
  744. X    {
  745. X        horiz_offset = (scr_horz - (scr_horz % 8)) - (COLS - 8);
  746. X        midscreen(scr_vert, point);
  747. X    }
  748. X    else if (scr_horz < horiz_offset)
  749. X    {
  750. X        horiz_offset = max(0, (scr_horz - (scr_horz % 8)));
  751. X        midscreen(scr_vert, point);
  752. X    }
  753. X}
  754. X
  755. Xint tabshift(temp_int)        /* give the number of spaces to shift    */
  756. Xint temp_int;
  757. X{
  758. X    int leftover;
  759. X
  760. X    leftover = ((temp_int + 1) % 8);
  761. X    if (leftover == 0)
  762. X        return (1);
  763. X    else
  764. X        return (9 - leftover);
  765. X}
  766. X
  767. Xout_char(window, character, column)    /* output non-printing character */
  768. XWINDOW *window;
  769. Xchar character;
  770. Xint column;
  771. X{
  772. X    int i1, i2;
  773. X    char *string;
  774. X    char string2[8];
  775. X
  776. X    if (character == TAB)
  777. X    {
  778. X        i1 = tabshift(column);
  779. X        for (i2 = 0; 
  780. X          (i2 < i1) && (((column+i2+1)-horiz_offset) < last_col); i2++)
  781. X        {
  782. X            waddch(window, ' ');
  783. X        }
  784. X        return(i1);
  785. X    }
  786. X    else if ((character >= '\0') && (character < ' '))
  787. X    {
  788. X        string = table[character];
  789. X    }
  790. X    else if ((character < 0) || (character >= 127))
  791. X    {
  792. X        if (character == 127)
  793. X            string = "^?";
  794. X        else if (!eightbit)
  795. X        {
  796. X            sprintf(string2, "<%d>", (character < 0) ? (character + 256) : character);
  797. X            string = string2;
  798. X        }
  799. X        else
  800. X        {
  801. X            waddch(window, character);
  802. X            return(1);
  803. X        }
  804. X    }
  805. X    else
  806. X    {
  807. X        waddch(window, character);
  808. X        return(1);
  809. X    }
  810. X    for (i2 = 0; (string[i2] != NULL) && (((column+i2+1)-horiz_offset) < last_col); i2++)
  811. X        waddch(window, string[i2]);
  812. X    return(strlen(string));
  813. X}
  814. X
  815. Xlen_char(character, column)    /* return the length of the character    */
  816. Xchar character;
  817. Xint column;    /* the column must be known to provide spacing for tabs    */
  818. X{
  819. X    int length;
  820. X
  821. X    if (character == '\t')
  822. X        length = tabshift(column);
  823. X    else if ((character >= 0) && (character < 32))
  824. X        length = 2;
  825. X    else if ((character >= 32) && (character <= 126))
  826. X        length = 1;
  827. X    else if (character == 127)
  828. X        length = 2;
  829. X    else if (((character > 126) || (character < 0)) && (!eightbit))
  830. X        length = 5;
  831. X    else
  832. X        length = 1;
  833. X
  834. X    return(length);
  835. X}
  836. X
  837. Xdraw_line(vertical, horiz, ptr, t_pos, length)    /* redraw line from current position */
  838. Xint vertical;    /* current vertical position on screen        */
  839. Xint horiz;    /* current horizontal position on screen    */
  840. Xchar *ptr;    /* pointer to line                */
  841. Xint t_pos;    /* current position (offset in bytes) from bol    */
  842. Xint length;    /* length (in bytes) of line            */
  843. X{
  844. X    int d;        /* partial length of special or tab char to display  */
  845. X    char *temp;    /* temporary pointer to position in line         */
  846. X    int abs_column;    /* offset in screen units from begin of line         */
  847. X    int column;    /* horizontal position on screen             */
  848. X    int row;    /* vertical position on screen                 */
  849. X    int posit;    /* temporary position indicator within line         */
  850. X
  851. X    abs_column = horiz;
  852. X    column = horiz - horiz_offset;
  853. X    row = vertical;
  854. X    temp = ptr;
  855. X    d = 0;
  856. X    posit = t_pos;
  857. X    if (column < 0)
  858. X    {
  859. X        wmove(text_win, row, 0);
  860. X        wclrtoeol(text_win);
  861. X    }
  862. X    while (column < 0)
  863. X    {
  864. X        d = len_char(*temp, abs_column);
  865. X        abs_column += d;
  866. X        column += d;
  867. X        posit++;
  868. X        temp++;
  869. X    }
  870. X    wmove(text_win, row, column);
  871. X    wclrtoeol(text_win);
  872. X    while ((posit < length) && (column <= last_col))
  873. X    {
  874. X        if ((*temp < 32) || (*temp == 127))
  875. X        {
  876. X            column += len_char(*temp, abs_column);
  877. X            abs_column += out_char(text_win, *temp, abs_column);
  878. X        }
  879. X        else
  880. X        {
  881. X            abs_column++;
  882. X            column++;
  883. X            waddch(text_win, *temp);
  884. X        }
  885. X        posit++;
  886. X        temp++;
  887. X    }
  888. X    if (column < last_col)
  889. X        wclrtoeol(text_win);
  890. X    wmove(text_win, vertical, (horiz - horiz_offset));
  891. X}
  892. X
  893. Xinsert_line(disp)            /* insert new line        */
  894. Xint disp;
  895. X{
  896. X    int temp_pos;
  897. X    int temp_pos2;
  898. X    char *temp;
  899. X    char *extra;
  900. X    struct text *temp_nod;
  901. X
  902. X    text_changes = TRUE;
  903. X    wmove(text_win, scr_vert, (scr_horz - horiz_offset));
  904. X    wclrtoeol(text_win);
  905. X    temp_nod= txtalloc();
  906. X    temp_nod->line = extra= malloc(10);
  907. X    temp_nod->line_length = 1;
  908. X    temp_nod->max_length = 10;
  909. X    temp_nod->line_number = curr_line->line_number + 1;
  910. X    temp_nod->next_line = curr_line->next_line;
  911. X    if (temp_nod->next_line != NULL)
  912. X        temp_nod->next_line->prev_line = temp_nod;
  913. X    temp_nod->prev_line = curr_line;
  914. X    curr_line->next_line = temp_nod;
  915. X    temp_pos2 = position;
  916. X    temp = point;
  917. X    if (temp_pos2 < curr_line->line_length)
  918. X    {
  919. X        temp_pos = 1;
  920. X        while (temp_pos2 < curr_line->line_length)
  921. X        {
  922. X            if ((temp_nod->max_length - temp_nod->line_length)< 5)
  923. X                extra = resiz_line(10, temp_nod, temp_pos);
  924. X            temp_nod->line_length++;
  925. X            temp_pos++;
  926. X            temp_pos2++;
  927. X            *extra= *temp;
  928. X            extra++;
  929. X            temp++;
  930. X        }
  931. X        temp=point;
  932. X        *temp= NULL;
  933. X        temp = resiz_line((1 - temp_nod->line_length), curr_line, position);
  934. X        curr_line->line_length = 1 + temp - curr_line->line;
  935. X    }
  936. X    curr_line->line_length = position;
  937. X    curr_line = temp_nod;
  938. X    *extra = NULL;
  939. X    position = 1;
  940. X    point= curr_line->line;
  941. X    if (disp)
  942. X    {
  943. X        if (scr_vert < last_line)
  944. X        {
  945. X            scr_vert++;
  946. X            wclrtoeol(text_win);
  947. X            wmove(text_win, scr_vert, 0);
  948. X            winsertln(text_win);
  949. X        }
  950. X        else
  951. X        {
  952. X            wmove(text_win, 0,0);
  953. X            wdeleteln(text_win);
  954. X            wmove(text_win, last_line,0);
  955. X            wclrtobot(text_win);
  956. X        }
  957. X        scr_pos = scr_horz = 0;
  958. X        if (horiz_offset)
  959. X        {
  960. X            horiz_offset = 0;
  961. X            midscreen(scr_vert, point);
  962. X        }
  963. X        draw_line(scr_vert, scr_horz, point, position,
  964. X            curr_line->line_length);
  965. X    }
  966. X}
  967. X
  968. Xstruct text *txtalloc()        /* allocate space for line structure    */
  969. X{
  970. X    return((struct text *) malloc(sizeof( struct text)));
  971. X}
  972. X
  973. Xstruct files *name_alloc()    /* allocate space for file name list node */
  974. X{
  975. X    return((struct files *) malloc(sizeof( struct files)));
  976. X}
  977. X
  978. Xchar *next_word(string)        /* move to next word in string        */
  979. Xchar *string;
  980. X{
  981. X    while ((*string != NULL) && ((*string != 32) && (*string != 9)))
  982. X        string++;
  983. X    while ((*string != NULL) && ((*string == 32) || (*string == 9)))
  984. X        string++;
  985. X    return(string);
  986. X}
  987. X
  988. Xprev_word()    /* move to start of previous word in text    */
  989. X{
  990. X    if (position != 1)
  991. X    {
  992. X        if ((position != 1) && ((point[-1] == ' ') || (point[-1] == '\t')))
  993. X        {    /* if at the start of a word    */
  994. X            while ((position != 1) && ((*point != ' ') && (*point != '\t')))
  995. X                left(TRUE);
  996. X        }
  997. X        while ((position != 1) && ((*point == ' ') || (*point == '\t')))
  998. X            left(TRUE);
  999. X        while ((position != 1) && ((*point != ' ') && (*point != '\t')))
  1000. X            left(TRUE);
  1001. X        if ((position != 1) && ((*point == ' ') || (*point == '\t')))
  1002. X            right(TRUE);
  1003. X    }
  1004. X    else
  1005. X        left(TRUE);
  1006. X}
  1007. X
  1008. Xcontrol()            /* use control for commands        */
  1009. X{
  1010. X    char *string;
  1011. X
  1012. X    if (in == 1)        /* control a    */
  1013. X    {
  1014. X        string = get_string(ascii_code_str, TRUE);
  1015. X        if (*string != NULL)
  1016. X        {
  1017. X            in = atoi(string);
  1018. X            wmove(text_win, scr_vert, (scr_horz - horiz_offset));
  1019. X            insert(in);
  1020. X        }
  1021. X        free(string);
  1022. X    }
  1023. X    else if (in == 2)    /* control b    */
  1024. X        bottom();
  1025. X    else if (in == 3)    /* control c    */
  1026. X    {
  1027. X        command_prompt();
  1028. X    }
  1029. X    else if (in == 4)    /* control d    */
  1030. X        down();
  1031. X    else if (in == 5)    /* control e    */
  1032. X        search_prompt();
  1033. X    else if (in == 6)    /* control f    */
  1034. X        undel_char();
  1035. X    else if (in == 7)    /* control g    */
  1036. X        bol();
  1037. X    else if (in == 8)    /* control h    */
  1038. X        delete(TRUE);
  1039. X    else if (in == 9)    /* control i    */
  1040. X        ;
  1041. X    else if (in == 10)    /* control j    */
  1042. X        insert_line(TRUE);
  1043. X    else if (in == 11)    /* control k    */
  1044. X        del_char();
  1045. X    else if (in == 12)    /* control l    */
  1046. X        left(TRUE);
  1047. X    else if (in == 13)    /* control m    */
  1048. X        insert_line(TRUE);
  1049. X    else if (in == 14)    /* control n    */
  1050. X        move_rel("d", max(5, (last_line - 5)));
  1051. X    else if (in == 15)    /* control o    */
  1052. X        eol();
  1053. X    else if (in == 16)    /* control p    */
  1054. X        move_rel("u", max(5, (last_line - 5)));
  1055. X    else if (in == 17)    /* control q    */
  1056. X        ;
  1057. X    else if (in == 18)    /* control r    */
  1058. X        right(TRUE);
  1059. X    else if (in == 19)    /* control s    */
  1060. X        ;
  1061. X    else if (in == 20)    /* control t    */
  1062. X        top();
  1063. X    else if (in == 21)    /* control u    */
  1064. X        up();
  1065. X    else if (in == 22)    /* control v    */
  1066. X        undel_word();
  1067. X    else if (in == 23)    /* control w    */
  1068. X        del_word();
  1069. X    else if (in == 24)    /* control x    */
  1070. X        search(TRUE);
  1071. X    else if (in == 25)    /* control y    */
  1072. X        del_line();
  1073. X    else if (in == 26)    /* control z    */
  1074. X        undel_line();
  1075. X    else if (in == 27)    /* control [ (escape)    */
  1076. X    {
  1077. X        menu_op(main_menu);
  1078. X    }    
  1079. X}
  1080. X
  1081. Xbottom()            /* go to bottom of file            */
  1082. X{
  1083. X    while (curr_line->next_line != NULL)
  1084. X        curr_line = curr_line->next_line;
  1085. X    point = curr_line->line;
  1086. X    if (horiz_offset)
  1087. X        horiz_offset = 0;
  1088. X    position = 1;
  1089. X    midscreen(last_line, point);
  1090. X    scr_pos = scr_horz;
  1091. X}
  1092. X
  1093. Xtop()                /* go to top of file            */
  1094. X{
  1095. X    while (curr_line->prev_line != NULL)
  1096. X        curr_line = curr_line->prev_line;
  1097. X    point = curr_line->line;
  1098. X    if (horiz_offset)
  1099. X        horiz_offset = 0;
  1100. X    position = 1;
  1101. X    midscreen(0, point);
  1102. X    scr_pos = scr_horz;
  1103. X}
  1104. X
  1105. Xnextline()            /* move pointers to start of next line    */
  1106. X{
  1107. X    curr_line = curr_line->next_line;
  1108. X    point = curr_line->line;
  1109. X    position = 1;
  1110. X    if (scr_vert == last_line)
  1111. X    {
  1112. X        wmove(text_win, 0,0);
  1113. X        wdeleteln(text_win);
  1114. X        wmove(text_win, last_line,0);
  1115. X        wclrtobot(text_win);
  1116. X        draw_line(last_line,0,point,1,curr_line->line_length);
  1117. X    }
  1118. X    else
  1119. X        scr_vert++;
  1120. X}
  1121. X
  1122. Xprevline()            /* move pointers to start of previous line*/
  1123. X{
  1124. X    curr_line = curr_line->prev_line;
  1125. X    point = curr_line->line;
  1126. X    position = 1;
  1127. X    if (scr_vert == 0)
  1128. X    {
  1129. X        winsertln(text_win);
  1130. X        draw_line(0,0,point,1,curr_line->line_length);
  1131. X    }
  1132. X    else
  1133. X        scr_vert--;
  1134. X    while (position < curr_line->line_length)
  1135. X    {
  1136. X        position++;
  1137. X        point++;
  1138. X    }
  1139. X}
  1140. X
  1141. Xleft(disp)                /* move left one character    */
  1142. Xint disp;
  1143. X{
  1144. X    if (point != curr_line->line)    /* if not at begin of line    */
  1145. X    {
  1146. X        point--;
  1147. X        position--;
  1148. X        scanline(point);
  1149. X        wmove(text_win, scr_vert, (scr_horz - horiz_offset));
  1150. X        scr_pos = scr_horz;
  1151. X    }
  1152. X    else if (curr_line->prev_line != NULL)
  1153. X    {
  1154. X        if (!disp)
  1155. X        {
  1156. X            curr_line = curr_line->prev_line;
  1157. X            point = curr_line->line + curr_line->line_length;
  1158. X            position = curr_line->line_length;
  1159. X            return;
  1160. X        }
  1161. X        position = 1;
  1162. X        prevline();
  1163. X        scanline(point);
  1164. X        scr_pos = scr_horz;
  1165. X        wmove(text_win, scr_vert, (scr_horz - horiz_offset));
  1166. X    }
  1167. X}
  1168. X
  1169. Xright(disp)                /* move right one character    */
  1170. Xint disp;
  1171. X{
  1172. X    if (position < curr_line->line_length)
  1173. X    {
  1174. X        point++;
  1175. X        position++;
  1176. X        scanline(point);
  1177. X        wmove(text_win, scr_vert, (scr_horz - horiz_offset));
  1178. X        scr_pos = scr_horz;
  1179. X    }
  1180. X    else if (curr_line->next_line != NULL)
  1181. X    {
  1182. X        if (!disp)
  1183. X        {
  1184. X            curr_line = curr_line->next_line;
  1185. X            point = curr_line->line;
  1186. X            position = 1;
  1187. X            return;
  1188. X        }
  1189. X        nextline();
  1190. X        scr_pos = scr_horz = 0;
  1191. X        if (horiz_offset)
  1192. X        {
  1193. X            horiz_offset = 0;
  1194. X            midscreen(scr_vert, point);
  1195. X        }
  1196. X        wmove(text_win, scr_vert, (scr_horz - horiz_offset));
  1197. X        position = 1;    
  1198. X    }
  1199. X}
  1200. X
  1201. Xfind_pos()        /* move to the same column as on other line    */
  1202. X{
  1203. X    scr_horz = 0;
  1204. X    position = 1;
  1205. X    while ((scr_horz < scr_pos) && (position < curr_line->line_length))
  1206. X    {
  1207. X        if (*point == 9)
  1208. X            scr_horz += tabshift(scr_horz);
  1209. X        else if ((*point >= '\0') && (*point < ' '))
  1210. X            scr_horz += 2;
  1211. X        else
  1212. X            scr_horz++;
  1213. X        position++;
  1214. X        point++;
  1215. X    }
  1216. X    if ((scr_horz - horiz_offset) > last_col)
  1217. X    {
  1218. X        horiz_offset = (scr_horz - (scr_horz % 8)) - (COLS - 8);
  1219. X        midscreen(scr_vert, point);
  1220. X    }
  1221. X    else if (scr_horz < horiz_offset)
  1222. X    {
  1223. X        horiz_offset = max(0, (scr_horz - (scr_horz % 8)));
  1224. X        midscreen(scr_vert, point);
  1225. X    }
  1226. X    wmove(text_win, scr_vert, (scr_horz - horiz_offset));
  1227. X}
  1228. X
  1229. Xup()                    /* move up one line        */
  1230. X{
  1231. X    if (curr_line->prev_line != NULL)
  1232. X    {
  1233. X        prevline();
  1234. X        point = curr_line->line;
  1235. X        find_pos();
  1236. X    }
  1237. X}
  1238. X
  1239. Xdown()                    /* move down one line        */
  1240. X{
  1241. X    if (curr_line->next_line != NULL)
  1242. X    {
  1243. X        nextline();
  1244. X        find_pos();
  1245. X    }
  1246. X}
  1247. X
  1248. Xfunction_key()                /* process function key        */
  1249. X{
  1250. X    if (in == KEY_LEFT)
  1251. X        left(TRUE);
  1252. X    else if (in == KEY_RIGHT)
  1253. X        right(TRUE);
  1254. X    else if ( in == KEY_HOME)
  1255. X        top();
  1256. X    else if ( in == KEY_UP)
  1257. X        up();
  1258. X    else if (in == KEY_DOWN)
  1259. X        down();
  1260. X    else if (in == KEY_NPAGE)
  1261. X        move_rel("d", max( 5, (last_line - 5)));
  1262. X    else if (in == KEY_PPAGE)
  1263. X        move_rel("u", max(5, (last_line - 5)));
  1264. X    else if (in == KEY_DL)
  1265. X        del_line();
  1266. X    else if (in == KEY_DC)
  1267. X        del_char();
  1268. X    else if (in == KEY_BACKSPACE)
  1269. X        delete(TRUE);
  1270. X    else if (in == KEY_IL)
  1271. X    {        /* insert a line before current line    */
  1272. X        insert_line(TRUE);
  1273. X        left(TRUE);
  1274. X    }
  1275. X    else if (in == KEY_F(1))
  1276. X        gold = !gold;
  1277. X    else if (in == KEY_F(2))
  1278. X    {
  1279. X        if (gold)
  1280. X        {
  1281. X            gold = FALSE;
  1282. X            undel_line();
  1283. X        }
  1284. X        else
  1285. X            undel_char();
  1286. X    }
  1287. X    else if (in == KEY_F(3))
  1288. X    {
  1289. X        if (gold)
  1290. X        {
  1291. X            gold = FALSE;
  1292. X            undel_word();
  1293. X        }
  1294. X        else
  1295. X            del_word();
  1296. X    }
  1297. X    else if (in == KEY_F(4))
  1298. X    {
  1299. X        if (gold)
  1300. X        {
  1301. X            gold = FALSE;
  1302. X            paint_info_win();
  1303. X            midscreen(scr_vert, point);
  1304. X        }
  1305. X        else
  1306. X            adv_word();
  1307. X    }
  1308. X    else if (in == KEY_F(5))
  1309. X    {
  1310. X        if (gold)
  1311. X        {
  1312. X            gold = FALSE;
  1313. X            search_prompt();
  1314. X        }
  1315. X        else
  1316. X            search(TRUE);
  1317. X    }
  1318. X    else if (in == KEY_F(6))
  1319. X    {
  1320. X        if (gold)
  1321. X        {
  1322. X            gold = FALSE;
  1323. X            bottom();
  1324. X        }
  1325. X        else
  1326. X            top();
  1327. X    }
  1328. X    else if (in == KEY_F(7))
  1329. X    {
  1330. X        if (gold)
  1331. X        {
  1332. X            gold = FALSE;
  1333. X            eol();
  1334. X        }
  1335. X        else
  1336. X            bol();
  1337. X    }
  1338. X    else if (in == KEY_F(8))
  1339. X    {
  1340. X        if (gold)
  1341. X        {
  1342. X            gold = FALSE;
  1343. X            command_prompt();
  1344. X        } 
  1345. X        else
  1346. X            adv_line();
  1347. X    }
  1348. X}
  1349. X
  1350. Xprint_buffer()
  1351. X{
  1352. X    char buffer[256];
  1353. X
  1354. X    sprintf(buffer, ">!%s", print_command);
  1355. X    wmove(com_win, 0, 0);
  1356. X    wclrtoeol(com_win);
  1357. X    wprintw(com_win, printer_msg_str, print_command);
  1358. X    wrefresh(com_win);
  1359. X    command(buffer);
  1360. X}
  1361. X
  1362. Xcommand_prompt()
  1363. X{
  1364. X    char *cmd_str;
  1365. X    int result;
  1366. X
  1367. X    info_type = COMMANDS;
  1368. X    paint_info_win();
  1369. X    cmd_str = get_string(command_str, TRUE);
  1370. X    if ((result = unique_test(cmd_str, commands)) != 1)
  1371. X    {
  1372. X        werase(com_win);
  1373. X        wmove(com_win, 0, 0);
  1374. X        if (result == 0)
  1375. X            wprintw(com_win, unkn_cmd_str, cmd_str);
  1376. X        else
  1377. X            wprintw(com_win, non_unique_cmd_msg);
  1378. X
  1379. X        wrefresh(com_win);
  1380. X
  1381. X        info_type = CONTROL_KEYS;
  1382. X        paint_info_win();
  1383. X
  1384. X        if (cmd_str != NULL)
  1385. X            free(cmd_str);
  1386. X        return;
  1387. X    }
  1388. X    command(cmd_str);
  1389. X    wrefresh(com_win);
  1390. X    wmove(text_win, scr_vert, (scr_horz - horiz_offset));
  1391. X    info_type = CONTROL_KEYS;
  1392. X    paint_info_win();
  1393. X    if (cmd_str != NULL)
  1394. X        free(cmd_str);
  1395. X}
  1396. X
  1397. Xcommand(cmd_str1)        /* process commands from keyboard    */
  1398. Xchar *cmd_str1;
  1399. X{
  1400. X    char *cmd_str2 = NULL;
  1401. X    char *cmd_str = cmd_str1;
  1402. X
  1403. X    clear_com_win = TRUE;
  1404. X    if (compare(cmd_str, HELP, FALSE))
  1405. X        help();
  1406. X    else if (compare(cmd_str, WRITE, FALSE))
  1407. X    {
  1408. X        if (restrict_mode())
  1409. X        {
  1410. X            return;
  1411. X        }
  1412. X        cmd_str = next_word(cmd_str);
  1413. X        if (*cmd_str == NULL)
  1414. X        {
  1415. X            cmd_str = cmd_str2 = get_string(file_write_prompt_str, TRUE);
  1416. X        }
  1417. X        tmp_file = resolve_name(cmd_str);
  1418. X        if (write_file(tmp_file))
  1419. X            ;
  1420. X        if (tmp_file != cmd_str)
  1421. X            free(tmp_file);
  1422. X    }
  1423. X    else if (compare(cmd_str, READ, FALSE))
  1424. X    {
  1425. X        if (restrict_mode())
  1426. X        {
  1427. X            return;
  1428. X        }
  1429. X        cmd_str = next_word(cmd_str);
  1430. X        if (*cmd_str == NULL)
  1431. X        {
  1432. X            cmd_str = cmd_str2 = get_string(file_read_prompt_str, TRUE);
  1433. X        }
  1434. X        tmp_file = cmd_str;
  1435. X        recv_file = TRUE;
  1436. X        tmp_file = resolve_name(cmd_str);
  1437. X        check_fp();
  1438. X        if (tmp_file != cmd_str)
  1439. X            free(tmp_file);
  1440. X    }
  1441. X    else if (compare(cmd_str, LINE, FALSE))
  1442. X    {
  1443. X        wmove(com_win, 0, 0);
  1444. X        wclrtoeol(com_win);
  1445. X        wprintw(com_win, line_num_str, curr_line->line_number);
  1446. X        wprintw(com_win, line_len_str, curr_line->line_length);
  1447. X    }
  1448. X    else if (compare(cmd_str, FILE_str, FALSE))
  1449. X    {
  1450. X        wmove(com_win, 0, 0);
  1451. X        wclrtoeol(com_win);
  1452. X        wprintw(com_win, current_file_str, in_file_name);
  1453. X    }
  1454. X    else if ((*cmd_str >= '0') && (*cmd_str <= '9'))
  1455. X        goto_line(cmd_str);
  1456. X    else if (compare(cmd_str, CHARACTER, FALSE))
  1457. X    {
  1458. X        wmove(com_win, 0, 0);
  1459. X        wclrtoeol(com_win);
  1460. X        if (*point >= '\0')
  1461. X            wprintw(com_win, char_str, *point);
  1462. X        else
  1463. X            wprintw(com_win, char_str, (*point + 256));
  1464. X    }
  1465. X    else if (compare(cmd_str, REDRAW, FALSE))
  1466. X        redraw();
  1467. X    else if (compare(cmd_str, RESEQUENCE, FALSE))
  1468. X    {
  1469. X        tmp_line = first_line->next_line;
  1470. X        while (tmp_line != NULL)
  1471. X        {
  1472. X        tmp_line->line_number = tmp_line->prev_line->line_number + 1;
  1473. X            tmp_line = tmp_line->next_line;
  1474. X        }
  1475. X    }
  1476. X    else if (compare(cmd_str, AUTHOR, FALSE))
  1477. X    {
  1478. X        wmove(com_win, 0, 0);
  1479. X        wclrtoeol(com_win);
  1480. X        wprintw(com_win, "written by Hugh Mahon");
  1481. X    }
  1482. X    else if (compare(cmd_str, VERSION, FALSE))
  1483. X    {
  1484. X        wmove(com_win, 0, 0);
  1485. X        wclrtoeol(com_win);
  1486. X        wprintw(com_win, "%s", version);
  1487. X    }
  1488. X    else if (compare(cmd_str, CASE, FALSE))
  1489. X        case_sen = TRUE;
  1490. X    else if (compare(cmd_str, NOCASE, FALSE))
  1491. X        case_sen = FALSE;
  1492. X    else if (compare(cmd_str, EXPAND, FALSE))
  1493. X        expand_tabs = TRUE;
  1494. X    else if (compare(cmd_str, NOEXPAND, FALSE))
  1495. X        expand_tabs = FALSE;
  1496. X    else if (compare(cmd_str, Exit_string, FALSE))
  1497. X        finish();
  1498. X    else if (compare(cmd_str, QUIT_string, FALSE))
  1499. X        quit(0);
  1500. X    else if (*cmd_str == '!')
  1501. X    {
  1502. X        cmd_str++;
  1503. X        if ((*cmd_str == ' ') || (*cmd_str == 9))
  1504. X            cmd_str = next_word(cmd_str);
  1505. X        sh_command(cmd_str);
  1506. X    }
  1507. X    else if ((*cmd_str == '<') && (!in_pipe))
  1508. X    {
  1509. X        in_pipe = TRUE;
  1510. X        shell_fork = FALSE;
  1511. X        cmd_str++;
  1512. X        if ((*cmd_str == ' ') || (*cmd_str == '\t'))
  1513. X            cmd_str = next_word(cmd_str);
  1514. X        command(cmd_str);
  1515. X        in_pipe = FALSE;
  1516. X        shell_fork = TRUE;
  1517. X    }
  1518. X    else if ((*cmd_str == '>') && (!out_pipe))
  1519. X    {
  1520. X        out_pipe = TRUE;
  1521. X        cmd_str++;
  1522. X        if ((*cmd_str == ' ') || (*cmd_str == '\t'))
  1523. X            cmd_str = next_word(cmd_str);
  1524. X        command(cmd_str);
  1525. X        out_pipe = FALSE;
  1526. X    }
  1527. X    else
  1528. X    {
  1529. X        wmove(com_win, 0, 0);
  1530. X        wclrtoeol(com_win);
  1531. X        wprintw(com_win, unkn_cmd_str, cmd_str);
  1532. X    }
  1533. X    if (cmd_str2 != NULL)
  1534. X        free(cmd_str2);
  1535. X}
  1536. X
  1537. Xscan(line, offset, column)    /* determine horizontal position for get_string    */
  1538. Xchar *line;
  1539. Xint offset;
  1540. Xint column;
  1541. X{
  1542. X    char *stemp;
  1543. X    int i;
  1544. X    int j;
  1545. X
  1546. X    stemp = line;
  1547. X    i = 0;
  1548. X    j = column;
  1549. X    while (i < offset)
  1550. X    {
  1551. X        i++;
  1552. X        j += len_char(*stemp, j);
  1553. X        stemp++;
  1554. X    }
  1555. X    return(j);
  1556. X}
  1557. X
  1558. Xchar *get_string(prompt, advance)    /* read string from input on command line */
  1559. Xchar *prompt;        /* string containing user prompt message    */
  1560. Xint advance;        /* if true, skip leading spaces and tabs    */
  1561. X{
  1562. X    char *string;
  1563. X    char *tmp_string;
  1564. X    char *nam_str;
  1565. X    char *g_point;
  1566. X    int tmp_int;
  1567. X    int g_horz, g_position, g_pos;
  1568. X    int esc_flag;
  1569. X
  1570. X    g_point = tmp_string = malloc(512);
  1571. X    wmove(com_win,0,0);
  1572. X    wclrtoeol(com_win);
  1573. X    waddstr(com_win, prompt);
  1574. X    wrefresh(com_win);
  1575. X    nam_str = tmp_string;
  1576. X    clear_com_win = TRUE;
  1577. X    g_horz = g_position = scan(prompt, strlen(prompt), 0);
  1578. X    g_pos = 0;
  1579. X    do
  1580. X    {
  1581. X        esc_flag = FALSE;
  1582. X        in = wgetch(com_win);
  1583. X        if (in == -1)
  1584. X            exit(0);
  1585. X        if (((in == 8) || (in == 127)) && (g_pos > 0))
  1586. X        {
  1587. X            tmp_int = g_horz;
  1588. X            g_pos--;
  1589. X            g_horz = scan(g_point, g_pos, g_position);
  1590. X            tmp_int = tmp_int - g_horz;
  1591. X            for (; 0 < tmp_int; tmp_int--)
  1592. X            {
  1593. X                if ((g_horz+tmp_int) < (last_col - 1))
  1594. X                {
  1595. X                    waddch(com_win, '\010');
  1596. X                    waddch(com_win, ' ');
  1597. X                    waddch(com_win, '\010');
  1598. X                }
  1599. X            }
  1600. X            nam_str--;
  1601. X        }
  1602. X        else if ((in != 8) && (in != 127) && (in != '\n') && (in != '\r'))
  1603. X        {
  1604. X            if (in == '\026')    /* control-v, accept next character verbatim    */
  1605. X            {            /* allows entry of ^m, ^j, and ^h    */
  1606. X                esc_flag = TRUE;
  1607. X                in = wgetch(com_win);
  1608. X                if (in == -1)
  1609. X                    exit(0);
  1610. X            }
  1611. X            *nam_str = in;
  1612. X            g_pos++;
  1613. X            if (((in < ' ') || (in > 126)) && (g_horz < (last_col - 1)))
  1614. X                g_horz += out_char(com_win, in, g_horz);
  1615. X            else
  1616. X            {
  1617. X                g_horz++;
  1618. X                if (g_horz < (last_col - 1))
  1619. X                    waddch(com_win, in);
  1620. X            }
  1621. X            nam_str++;
  1622. X        }
  1623. X        wrefresh(com_win);
  1624. X        if (esc_flag)
  1625. X            in = NULL;
  1626. X    } while ((in != '\n') && (in != '\r'));
  1627. X    *nam_str = NULL;
  1628. X    nam_str = tmp_string;
  1629. X    if (((*nam_str == ' ') || (*nam_str == 9)) && (advance))
  1630. X        nam_str = next_word(nam_str);
  1631. X    string = malloc(strlen(nam_str) + 1);
  1632. X    strcpy(string, nam_str);
  1633. X    free(tmp_string);
  1634. X    wrefresh(com_win);
  1635. X    return(string);
  1636. X}
  1637. X
  1638. Xcompare(string1, string2, sensitive)    /* compare two strings    */
  1639. Xchar *string1;
  1640. Xchar *string2;
  1641. Xint sensitive;
  1642. X{
  1643. X    char *strng1;
  1644. X    char *strng2;
  1645. X    int tmp;
  1646. X    int equal;
  1647. X
  1648. X    strng1 = string1;
  1649. X    strng2 = string2;
  1650. X    tmp = 0;
  1651. X    if ((strng1 == NULL) || (strng2 == NULL) || (*strng1 == NULL) || (*strng2 == NULL))
  1652. X        return(FALSE);
  1653. X    equal = TRUE;
  1654. X    while (equal)
  1655. X    {
  1656. X        if (sensitive)
  1657. X        {
  1658. X            if (*strng1 != *strng2)
  1659. X                equal = FALSE;
  1660. X        }
  1661. X        else
  1662. X        {
  1663. X            if (toupper(*strng1) != toupper(*strng2))
  1664. X                equal = FALSE;
  1665. X        }
  1666. X        strng1++;
  1667. X        strng2++;
  1668. X        if ((*strng1 == NULL) || (*strng2 == NULL) || (*strng1 == ' ') || (*strng2 == ' '))
  1669. X            break;
  1670. X        tmp++;
  1671. X    }
  1672. X    return(equal);
  1673. X}
  1674. X
  1675. Xgoto_line(cmd_str)
  1676. Xchar *cmd_str;
  1677. X{
  1678. X    int number;
  1679. X    int i;
  1680. X    char *ptr;
  1681. X    char *direction;
  1682. X    struct text *t_line;
  1683. X
  1684. X    ptr = cmd_str;
  1685. X    i= 0;
  1686. X    while ((*ptr >='0') && (*ptr <= '9'))
  1687. X    {
  1688. X        i= i * 10 + (*ptr - '0');
  1689. X        ptr++;
  1690. X    }
  1691. X    number = i;
  1692. X    i = 0;
  1693. X    t_line = curr_line;
  1694. X    while ((t_line->line_number > number) && (t_line->prev_line != NULL))
  1695. X    {
  1696. X        i++;
  1697. X        t_line = t_line->prev_line;
  1698. X        direction = "u";
  1699. X    }
  1700. X    while ((t_line->line_number < number) && (t_line->next_line != NULL))
  1701. X    {
  1702. X        i++;
  1703. X        direction = "d";
  1704. X        t_line = t_line->next_line;
  1705. X    }
  1706. X    if ((i < 30) && (i > 0))
  1707. X    {
  1708. X        move_rel(direction, i);
  1709. X    }
  1710. X    else
  1711. X    {
  1712. X        curr_line = t_line;
  1713. X        point = curr_line->line;
  1714. X        position = 1;
  1715. X        midscreen((last_line / 2), point);
  1716. X        scr_pos = scr_horz;
  1717. X    }
  1718. X    wmove(com_win, 0, 0);
  1719. X    wclrtoeol(com_win);
  1720. X    wprintw(com_win, line_num_str, curr_line->line_number);
  1721. X    wmove(text_win, scr_vert, (scr_horz - horiz_offset));
  1722. X}
  1723. X
  1724. Xmidscreen(line, pnt)    /* put current line in middle of screen    */
  1725. Xint line;
  1726. Xchar *pnt;
  1727. X{
  1728. X    struct text *mid_line;
  1729. X    int i;
  1730. X
  1731. X    mid_line = curr_line;
  1732. X    for (i = 0; ((i < line) && (curr_line->prev_line != NULL)); i++)
  1733. X        curr_line = curr_line->prev_line;
  1734. X    scr_vert = scr_horz = 0;
  1735. X    wmove(text_win, 0, 0);
  1736. X    draw_screen();
  1737. X    scr_vert = i;
  1738. X    curr_line = mid_line;
  1739. X    scanline(pnt);
  1740. X    wmove(text_win, scr_vert, (scr_horz - horiz_offset));
  1741. X}
  1742. X
  1743. Xget_options(numargs, arguments)    /* get arguments from command line    */
  1744. Xint numargs;
  1745. Xchar *arguments[];
  1746. X{
  1747. X    char *buff;
  1748. X    int count;
  1749. X    struct files *temp_names;
  1750. X    char *name;
  1751. X    char *ptr;
  1752. X
  1753. X    /*
  1754. X     |    see if editor was invoked as 'ree' (restricted mode)
  1755. X     */
  1756. X
  1757. X    if (!(name = strrchr(arguments[0], '/')))
  1758. X        name = arguments[0];
  1759. X    else
  1760. X        name++;
  1761. X    if (!strcmp(name, "ree"))
  1762. X        restricted = TRUE;
  1763. X
  1764. X    top_of_stack = NULL;
  1765. X    input_file = FALSE;
  1766. X    recv_file = FALSE;
  1767. X    count = 1;
  1768. X    while (count < numargs)
  1769. X    {
  1770. X        buff = arguments[count];
  1771. X        if (!strcmp("-i", buff))
  1772. X        {
  1773. X            info_window = FALSE;
  1774. X        }
  1775. X        else if (!strcmp("-e", buff))
  1776. X        {
  1777. X            expand_tabs = FALSE;
  1778. X        }
  1779. X        else if (!strcmp("-h", buff))
  1780. X        {
  1781. X            nohighlight = TRUE;
  1782. X        }
  1783. X        else if (!strcmp("-?", buff))
  1784. X        {
  1785. X            fprintf(stderr, usage0, arguments[0]);
  1786. X            fprintf(stderr, usage1);
  1787. X            fprintf(stderr, usage2);
  1788. X            fprintf(stderr, usage3);
  1789. X            exit(1);
  1790. X        }
  1791. X        else
  1792. X        {
  1793. X            if (top_of_stack == NULL)
  1794. X            {
  1795. X                temp_names = top_of_stack = name_alloc();
  1796. X            }
  1797. X            else
  1798. X            {
  1799. X                temp_names->next_name = name_alloc();
  1800. X                temp_names = temp_names->next_name;
  1801. X            }
  1802. X            ptr = temp_names->name = malloc(strlen(buff) + 1);
  1803. X            while (*buff != NULL)
  1804. X            {
  1805. X                *ptr = *buff;
  1806. X                buff++;
  1807. X                ptr++;
  1808. X            }
  1809. X            *ptr = NULL;
  1810. X            temp_names->next_name = NULL;
  1811. X            input_file = TRUE;
  1812. X            recv_file = TRUE;
  1813. X        }
  1814. X        count++;
  1815. X    }
  1816. X}
  1817. X
  1818. Xcheck_fp()        /* open or close files according to flags */
  1819. X{
  1820. X    int line_num;
  1821. X    int temp;
  1822. X    struct stat buf;
  1823. X
  1824. X    clear_com_win = TRUE;
  1825. X    tmp_vert = scr_vert;
  1826. X    tmp_horz = scr_horz;
  1827. X    tmp_line = curr_line;
  1828. X    if (input_file)
  1829. X    {
  1830. X        in_file_name = tmp_file = top_of_stack->name;
  1831. X        top_of_stack = top_of_stack->next_name;
  1832. X    }
  1833. X    temp = stat(tmp_file, &buf);
  1834. X    buf.st_mode &= ~07777;
  1835. X    if ((temp != -1) && (buf.st_mode != 0100000) && (buf.st_mode != 0))
  1836. X    {
  1837. X        wprintw(com_win, file_is_dir_msg, tmp_file);
  1838. X        wrefresh(com_win);
  1839. X        if (input_file)
  1840. X            quit(0);
  1841. X        else
  1842. X            return;
  1843. X    }
  1844. X    if ((get_fd = open(tmp_file, O_RDONLY)) == -1)
  1845. X    {
  1846. X        wmove(com_win, 0, 0);
  1847. X        wclrtoeol(com_win);
  1848. X        if (input_file)
  1849. X            wprintw(com_win, new_file_msg, tmp_file);
  1850. X        else
  1851. X            wprintw(com_win, cant_open_msg, tmp_file);
  1852. X        wrefresh(com_win);
  1853. X        wmove(text_win, scr_vert, (scr_horz - horiz_offset));
  1854. X        wrefresh(text_win);
  1855. X        recv_file = FALSE;
  1856. X        input_file = FALSE;
  1857. X        return;
  1858. X    }
  1859. X    else
  1860. X        get_file(tmp_file);
  1861. X
  1862. X    recv_file = FALSE;
  1863. X    line_num = curr_line->line_number;
  1864. X    scr_vert = tmp_vert;
  1865. X    scr_horz = tmp_horz;
  1866. X    if (input_file)
  1867. X        curr_line= first_line;
  1868. X    else
  1869. X        curr_line = tmp_line;
  1870. X    point = curr_line->line;
  1871. X    draw_screen();
  1872. X    wmove(com_win, 0, 0);
  1873. X    wclrtoeol(com_win);
  1874. X    if (input_file)
  1875. X    {
  1876. X        wprintw(com_win, open_file_msg, in_file_name, line_num);
  1877. X        input_file = FALSE;
  1878. X    }
  1879. X    else
  1880. X    {
  1881. X        text_changes = TRUE;
  1882. X        if ((tmp_file != NULL) && (*tmp_file != NULL))
  1883. X            wprintw(com_win, file_read_fin_msg, tmp_file);
  1884. X    }
  1885. X    wrefresh(com_win);
  1886. X    wmove(text_win, scr_vert, (scr_horz - horiz_offset));
  1887. X    wrefresh(text_win);
  1888. X}
  1889. X
  1890. Xget_file(file_name)    /* read specified file into current buffer    */
  1891. Xchar *file_name;
  1892. X{
  1893. X    int can_read;        /* file has at least one character    */
  1894. X    int length;        /* length of line read by read        */
  1895. X    int append;        /* should text be appended to current line */
  1896. X    struct text *temp_line;
  1897. X
  1898. X    if (recv_file)        /* if reading a file            */
  1899. X    {
  1900. X        wmove(com_win, 0, 0);
  1901. X        wclrtoeol(com_win);
  1902. X        wprintw(com_win, reading_file_msg, file_name);
  1903. X        if (access(file_name, 2))    /* check permission to write */
  1904. X        {
  1905. X            if ((errno == ENOTDIR) || (errno == EACCES) || (errno == EROFS) || (errno == ETXTBSY) || (errno == EFAULT))
  1906. X                wprintw(com_win, read_only_msg);
  1907. X        }
  1908. X        wrefresh(com_win);
  1909. X    }
  1910. X    if (curr_line->line_length > 1)    /* if current line is not blank    */
  1911. X    {
  1912. X        insert_line(FALSE);
  1913. X        left(FALSE);
  1914. X        append = FALSE;
  1915. X    }
  1916. X    else
  1917. X        append = TRUE;
  1918. X    can_read = FALSE;        /* test if file has any characters  */
  1919. X    while (((length = read(get_fd, in_string, 512)) != 0) && (length != -1))
  1920. X    {
  1921. X        can_read = TRUE;  /* if set file has at least 1 character   */
  1922. X        get_line(length, in_string, &append);
  1923. X    }
  1924. X    if ((can_read) && (curr_line->line_length == 1))
  1925. X    {
  1926. X        temp_line = curr_line->prev_line;
  1927. X        temp_line->next_line = curr_line->next_line;
  1928. X        if (temp_line->next_line != NULL)
  1929. X            temp_line->next_line->prev_line = temp_line;
  1930. X        if (curr_line->line != NULL)
  1931. X            free(curr_line->line);
  1932. X        free(curr_line);
  1933. X        curr_line = temp_line;
  1934. X    }
  1935. X    if (input_file)    /* if this is the file to be edited display number of lines    */
  1936. X    {
  1937. X        wmove(com_win, 0, 0);
  1938. X        wclrtoeol(com_win);
  1939. X        wprintw(com_win, file_read_lines_msg, in_file_name, curr_line->line_number);
  1940. X        wrefresh(com_win);
  1941. X    }
  1942. X    else if (can_read)    /* not input_file and file is non-zero size */
  1943. X        text_changes = TRUE;
  1944. X
  1945. X    if (recv_file)        /* if reading a file            */
  1946. X    {
  1947. X        in = EOF;
  1948. X    }
  1949. X}
  1950. X
  1951. Xget_line(length, in_string, append)    /* read string and split into lines */
  1952. Xint length;        /* length of string read by read        */
  1953. Xchar *in_string;    /* string read by read                */
  1954. Xint *append;    /* TRUE if must append more text to end of current line    */
  1955. X{
  1956. X    char *str1;
  1957. X    char *str2;
  1958. X    int num;        /* offset from start of string        */
  1959. X    int char_count;        /* length of new line (or added portion    */
  1960. X    int temp_counter;    /* temporary counter value        */
  1961. X    struct text *tline;    /* temporary pointer to new line    */
  1962. X    int first_time;        /* if TRUE, the first time through the loop */
  1963. X
  1964. X    str2 = in_string;
  1965. X    num = 0;
  1966. X    first_time = TRUE;
  1967. X    while (num < length)
  1968. X    {
  1969. X        if (!first_time)
  1970. X        {
  1971. X            if (num < length)
  1972. X            {
  1973. X                str2++;
  1974. X                num++;
  1975. X            }
  1976. X        }
  1977. X        else
  1978. X            first_time = FALSE;
  1979. X        str1 = str2;
  1980. X        char_count = 1;
  1981. X        /* find end of line    */
  1982. X        while ((*str2 != '\n') && (num < length))
  1983. X        {
  1984. X            str2++;
  1985. X            num++;
  1986. X            char_count++;
  1987. X        }
  1988. X        if (!(*append))    /* if not append to current line, insert new one */
  1989. X        {
  1990. X            tline = txtalloc();    /* allocate data structure for next line */
  1991. X            tline->line_number = curr_line->line_number + 1;
  1992. X            tline->next_line = curr_line->next_line;
  1993. X            tline->prev_line = curr_line;
  1994. X            curr_line->next_line = tline;
  1995. X            if (tline->next_line != NULL)
  1996. X                tline->next_line->prev_line = tline;
  1997. X            curr_line = tline;
  1998. X            curr_line->line = point = (char *) malloc(char_count);
  1999. X            curr_line->line_length = char_count;
  2000. X            curr_line->max_length = char_count;
  2001. X        }
  2002. X        else
  2003. X        {
  2004. X            point = resiz_line(char_count, curr_line, curr_line->line_length); 
  2005. X            curr_line->line_length += (char_count - 1);
  2006. X        }
  2007. X        for (temp_counter = 1; temp_counter < char_count; temp_counter++)
  2008. X        {
  2009. X            *point = *str1;
  2010. X            point++;
  2011. X            str1++;
  2012. X        }
  2013. X        *point = NULL;
  2014. X        *append = FALSE;
  2015. X        if ((num == length) && (*str2 != '\n'))
  2016. X            *append = TRUE;
  2017. X    }
  2018. X}
  2019. X
  2020. END_OF_FILE
  2021.   if test 45319 -ne `wc -c <'ee.c.A'`; then
  2022.     echo shar: \"'ee.c.A'\" unpacked with wrong size!
  2023.   elif test -f 'ee.c.B'; then
  2024.     echo shar: Combining  \"'ee.c'\" \(97591 characters\)
  2025.     cat 'ee.c.A' 'ee.c.B' > 'ee.c'
  2026.     if test 97591 -ne `wc -c <'ee.c'`; then
  2027.       echo shar: \"'ee.c'\" combined with wrong size!
  2028.     else
  2029.       rm ee.c.A ee.c.B
  2030.     fi
  2031.   fi
  2032.   # end of 'ee.c.A'
  2033. fi
  2034. if test -f 'ee.msg' -a "${1}" != "-c" ; then 
  2035.   echo shar: Will not clobber existing file \"'ee.msg'\"
  2036. else
  2037.   echo shar: Extracting \"'ee.msg'\" \(5288 characters\)
  2038.   sed "s/^X//" >'ee.msg' <<'END_OF_FILE'
  2039. X$ This file contains the messages for ee ("easy editor).  See the file 
  2040. X$ ee.i18n.guide for more information
  2041. X$ 
  2042. X$set 1
  2043. X$quote "
  2044. X1 "modes menu"
  2045. X2 "tabs to spaces       "
  2046. X3 "case sensitive search"
  2047. X4 "margins observed     "
  2048. X5 "auto-paragraph format"
  2049. X6 "eightbit characters  "
  2050. X7 "info window          "
  2051. X8 "right margin         "
  2052. X9 "leave menu"
  2053. X10 "save changes"
  2054. X11 "no save"
  2055. X12 "file menu"
  2056. X13 "read a file"
  2057. X14 "write a file"
  2058. X15 "save file"
  2059. X16 "print editor contents"
  2060. X17 "search menu"
  2061. X18 "search for ..."
  2062. X19 "search"
  2063. X20 "spell menu"
  2064. X21 "use 'spell'"
  2065. X22 "use 'ispell'"
  2066. X23 "miscellaneous menu"
  2067. X24 "format paragraph"
  2068. X25 "shell command"
  2069. X26 "check spelling"
  2070. X27 "main menu"
  2071. X28 "leave editor"
  2072. X29 "help"
  2073. X30 "file operations"
  2074. X31 "redraw screen"
  2075. X32 "settings"
  2076. X33 "search"
  2077. X34 "miscellaneous"
  2078. X35 "Control keys:                                                              "
  2079. X36 "^a ascii code           ^i tab                  ^r right                   "
  2080. X37 "^b bottom of text       ^j newline              ^t top of text             "
  2081. X38 "^c command              ^k delete char          ^u up                      "
  2082. X39 "^d down                 ^l left                 ^v undelete word           "
  2083. X40 "^e search prompt        ^m newline              ^w delete word             "
  2084. X41 "^f undelete char        ^n next page            ^x search                  "
  2085. X42 "^g begin of line        ^o end of line          ^y delete line             "
  2086. X43 "^h backspace            ^p prev page            ^z undelete line           "
  2087. X44 "^[ (escape) menu                                                           "
  2088. X45 "                                                                           "
  2089. X46 "Commands:                                                                  "
  2090. X47 "help    : get this info                 file    : print file name          "
  2091. X48 "read    : read a file                   char    : ascii code of char       "
  2092. X49 "write   : write a file                  case    : case sensitive search    "
  2093. X50 "exit    : leave and save                nocase  : case insensitive search  "
  2094. X51 "quit    : leave, no save                !cmd    : execute \"cmd\" in shell   "
  2095. X52 "line    : display line #                0-9     : go to line \"#\"           "
  2096. X53 "expand  : expand tabs                   noexpand: do not expand tabs         "
  2097. X54 "                                                                             "
  2098. X55 "  ee [-i] [-e] [-h] [file(s)]                                                 "
  2099. X56 "   -i : no information window  -e : do not expand tabs   -h : no highlight "
  2100. X57 "^[ (escape) menu  ^e search prompt  ^y delete line    ^u up     ^p prev page  "
  2101. X58 "^a ascii code     ^x search         ^z undelete line  ^d down   ^n next page  "
  2102. X59 "^b bottom of text ^g begin of line  ^w delete word    ^l left                 "
  2103. X60 "^t top of text    ^o end of line    ^v undelete word  ^r right                "
  2104. X61 "^c command        ^k delete char    ^f undelete char                          "
  2105. X62 "help : get help info  |file  : print file name         |line : print line # "
  2106. X63 "read : read a file    |char  : ascii code of char      |0-9 : go to line \"#\""
  2107. X64 "write: write a file   |case  : case sensitive search   |exit : leave and save "
  2108. X65 "!cmd : shell \"cmd\"    |nocase: ignore case in search   |quit : leave, no save"
  2109. X66 "expand: expand tabs   |noexpand: do not expand tabs                           "
  2110. X67 "    press Escape (^[) for menu"
  2111. X68 "no file"
  2112. X69 "ascii code: "
  2113. X70 "sending contents of buffer to \"%s\" "
  2114. X71 "command: "
  2115. X72 "name of file to write: "
  2116. X73 "name of file to read: "
  2117. X74 "character = %d"
  2118. X75 "unknown command \"%s\""
  2119. X76 "entered command is not unique"
  2120. X77 "line %d  "
  2121. X78 "length = %d"
  2122. X79 "current file is \"%s\" "
  2123. X80 "usage: %s [-i] [-e] [-h] [file(s)]\n"
  2124. X81 "       -i   turn off info window\n"
  2125. X82 "       -e   do not convert tabs to spaces\n"
  2126. X83 "       -h   do not use highlighting\n"
  2127. X84 "file \"%s\" is a directory"
  2128. X85 "new file \"%s\""
  2129. X86 "can't open \"%s\""
  2130. X87 "file \"%s\", %d lines"
  2131. X88 "finished reading file \"%s\""
  2132. X89 "reading file \"%s\""
  2133. X90 ", read only"
  2134. X91 "file \"%s\", %d lines"
  2135. X92 "enter name of file: "
  2136. X93 "no filename entered: file not saved"
  2137. X94 "changes have been made, are you sure? (y/n [n]) "
  2138. X95 "y"
  2139. X96 "file already exists, overwrite? (y/n) [n] "
  2140. X97 "unable to create file \"%s\""
  2141. X98 "writing file \"%s\""
  2142. X99 "\"%s\" %d lines, %d characters"
  2143. X100 "           ...searching"
  2144. X101 "string \"%s\" not found"
  2145. X102 "search for: "
  2146. X103 "could not exec %s\n"
  2147. X104 "press return to continue "
  2148. X105 "press Esc to cancel"
  2149. X106 "menu too large for window"
  2150. X107 "press any key to continue "
  2151. X108 "shell command: "
  2152. X109 "...formatting paragraph..."
  2153. X110 "<!echo 'list of unrecognized words'; echo -=-=-=-=-=-"
  2154. X111 "sending contents of edit buffer to 'spell'"
  2155. X112 "right margin is: "
  2156. X113 "restricted mode: unable to perform requested operation"
  2157. X114 "ON"
  2158. X115 "OFF"
  2159. X116 "HELP"
  2160. X117 "WRITE"
  2161. X118 "READ"
  2162. X119 "LINE"
  2163. X120 "FILE"
  2164. X121 "CHARACTER"
  2165. X122 "REDRAW"
  2166. X123 "RESEQUENCE"
  2167. X124 "AUTHOR"
  2168. X125 "VERSION"
  2169. X126 "CASE"
  2170. X127 "NOCASE"
  2171. X128 "EXPAND"
  2172. X129 "NOEXPAND"
  2173. X130 "EXIT"
  2174. X131 "QUIT"
  2175. X132 "INFO"
  2176. X133 "NOINFO"
  2177. X134 "MARGINS"
  2178. X135 "NOMARGINS"
  2179. X136 "AUTOFORMAT"
  2180. X137 "NOAUTOFORMAT"
  2181. X138 "ECHO"
  2182. X139 "PRINTCOMMAND"
  2183. X140 "RIGHTMARGIN"
  2184. X141 "HIGHLIGHT"
  2185. X142 "NOHIGHLIGHT"
  2186. X143 "EIGHTBIT"
  2187. X144 "NOEIGHTBIT"
  2188. END_OF_FILE
  2189.   if test 5288 -ne `wc -c <'ee.msg'`; then
  2190.     echo shar: \"'ee.msg'\" unpacked with wrong size!
  2191.   fi
  2192.   # end of 'ee.msg'
  2193. fi
  2194. echo shar: End of archive 3 \(of 5\).
  2195. cp /dev/null ark3isdone
  2196. MISSING=""
  2197. for I in 1 2 3 4 5 ; do
  2198.     if test ! -f ark${I}isdone ; then
  2199.     MISSING="${MISSING} ${I}"
  2200.     fi
  2201. done
  2202. if test "${MISSING}" = "" ; then
  2203.     echo You have unpacked all 5 archives.
  2204.     rm -f ark[1-9]isdone
  2205. else
  2206.     echo You still must unpack the following archives:
  2207.     echo "        " ${MISSING}
  2208. fi
  2209. exit 0
  2210. exit 0 # Just in case...
  2211.