home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Shells / zsh-3.0.5-MIHS / src / Src / zle_utils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-25  |  7.3 KB  |  336 lines

  1. /*
  2.  * $Id: zle_utils.c,v 2.15 1996/10/15 21:07:03 hzoli Exp $
  3.  *
  4.  * zle_utils.c - miscellaneous line editor utilities
  5.  *
  6.  * This file is part of zsh, the Z shell.
  7.  *
  8.  * Copyright (c) 1992-1996 Paul Falstad
  9.  * All rights reserved.
  10.  *
  11.  * Permission is hereby granted, without written agreement and without
  12.  * license or royalty fees, to use, copy, modify, and distribute this
  13.  * software and to distribute modified versions of this software for any
  14.  * purpose, provided that the above copyright notice and the following
  15.  * two paragraphs appear in all copies of this software.
  16.  *
  17.  * In no event shall Paul Falstad or the Zsh Development Group be liable
  18.  * to any party for direct, indirect, special, incidental, or consequential
  19.  * damages arising out of the use of this software and its documentation,
  20.  * even if Paul Falstad and the Zsh Development Group have been advised of
  21.  * the possibility of such damage.
  22.  *
  23.  * Paul Falstad and the Zsh Development Group specifically disclaim any
  24.  * warranties, including, but not limited to, the implied warranties of
  25.  * merchantability and fitness for a particular purpose.  The software
  26.  * provided hereunder is on an "as is" basis, and Paul Falstad and the
  27.  * Zsh Development Group have no obligation to provide maintenance,
  28.  * support, updates, enhancements, or modifications.
  29.  *
  30.  */
  31.  
  32. #define ZLE
  33. #include "zsh.h"
  34.  
  35. /* make sure that the line buffer has at least sz chars */
  36.  
  37. /**/
  38. void
  39. sizeline(int sz)
  40. {
  41.     while (sz > linesz)
  42.     line = (unsigned char *)realloc(line, (linesz *= 4) + 2);
  43. }
  44.  
  45. /* insert space for ct chars at cursor position */
  46.  
  47. /**/
  48. void
  49. spaceinline(int ct)
  50. {
  51.     int i;
  52.  
  53.     sizeline(ct + ll);
  54.     for (i = ll; --i >= cs;)
  55.     line[i + ct] = line[i];
  56.     ll += ct;
  57.     line[ll] = '\0';
  58.  
  59.     if (mark >= cs)
  60.     mark += ct;
  61. }
  62.  
  63. /**/
  64. void
  65. shiftchars(int to, int cnt)
  66. {
  67.     if (mark >= to + cnt)
  68.     mark -= cnt;
  69.     else if (mark > to)
  70.     mark = to;
  71.  
  72.     while (to + cnt < ll) {
  73.     line[to] = line[to + cnt];
  74.     to++;
  75.     }
  76.     line[ll = to] = '\0';
  77. }
  78.  
  79. /**/
  80. void
  81. backkill(int ct, int dir)
  82. {
  83.     int i = (cs -= ct);
  84.  
  85.     cut(i, ct, dir);
  86.     shiftchars(i, ct);
  87. }
  88.  
  89. /**/
  90. void
  91. forekill(int ct, int dir)
  92. {
  93.     int i = cs;
  94.  
  95.     cut(i, ct, dir);
  96.     shiftchars(i, ct);
  97. }
  98.  
  99. /**/
  100. void
  101. cut(int i, int ct, int dir)
  102. {
  103.     if (gotvibufspec) {
  104.     if ((vibuf[vibufspec].flags & CUTBUFFER_LINE) && !vilinerange)
  105.         vibufappend = 0;
  106.     if (!vibufappend || !vibuf[vibufspec].buf) {
  107.         zfree(vibuf[vibufspec].buf, vibuf[vibufspec].len);
  108.         vibuf[vibufspec].buf = (char *)zalloc(ct);
  109.         memcpy(vibuf[vibufspec].buf, (char *) line + i, ct);
  110.         vibuf[vibufspec].len = ct;
  111.         vibuf[vibufspec].flags = 0;
  112.     } else {
  113.         int len = vibuf[vibufspec].len;
  114.  
  115.         vibuf[vibufspec].buf = realloc(vibuf[vibufspec].buf, ct + len + 1);
  116.         if (vilinerange)
  117.         vibuf[vibufspec].buf[len++] = '\n';
  118.         memcpy(vibuf[vibufspec].buf + len, (char *) line + i, ct);
  119.         vibuf[vibufspec].len = len + ct;
  120.     }
  121.     if(vilinerange)
  122.         vibuf[vibufspec].flags |= CUTBUFFER_LINE;
  123.     else
  124.         vibuf[vibufspec].flags &= ~CUTBUFFER_LINE;
  125.     return;
  126.     } else {
  127.     /* Save in "1, shifting "1-"8 along to "2-"9 */
  128.     int n;
  129.     zfree(vibuf[34].buf, vibuf[34].len);
  130.     for(n=34; n>26; n--)
  131.         vibuf[n] = vibuf[n-1];
  132.     vibuf[26].buf = (char *)zalloc(ct);
  133.     memcpy(vibuf[26].buf, (char *) line + i, ct);
  134.     vibuf[26].len = ct;
  135.     vibuf[26].flags = vilinerange ? CUTBUFFER_LINE : 0;
  136.     }
  137.     if (!cutbuf.buf) {
  138.     cutbuf.buf = ztrdup("");
  139.     cutbuf.len = cutbuf.flags = 0;
  140.     } else if (!(lastcmd & ZLE_KILL)) {
  141.     kringnum = (kringnum + 1) % KRINGCT;
  142.     if (kring[kringnum].buf)
  143.         free(kring[kringnum].buf);
  144.     kring[kringnum] = cutbuf;
  145.     cutbuf.buf = ztrdup("");
  146.     cutbuf.len = cutbuf.flags = 0;
  147.     }
  148.     if (dir) {
  149.     char *s = (char *)zalloc(cutbuf.len + ct);
  150.  
  151.     memcpy(s, (char *) line + i, ct);
  152.     memcpy(s + ct, cutbuf.buf, cutbuf.len);
  153.     free(cutbuf.buf);
  154.     cutbuf.buf = s;
  155.     cutbuf.len += ct;
  156.     } else {
  157.     cutbuf.buf = realloc(cutbuf.buf, cutbuf.len + ct);
  158.     memcpy(cutbuf.buf + cutbuf.len, (char *) line + i, ct);
  159.     cutbuf.len += ct;
  160.     }
  161.     if(vilinerange)
  162.     cutbuf.flags |= CUTBUFFER_LINE;
  163.     else
  164.     cutbuf.flags &= ~CUTBUFFER_LINE;
  165. }
  166.  
  167. /**/
  168. void
  169. backdel(int ct)
  170. {
  171.     shiftchars(cs -= ct, ct);
  172. }
  173.  
  174. /**/
  175. void
  176. foredel(int ct)
  177. {
  178.     shiftchars(cs, ct);
  179. }
  180.  
  181. /**/
  182. void
  183. setline(char const *s)
  184. {
  185.     sizeline(strlen(s));
  186.     strcpy((char *) line, s);
  187.     unmetafy((char *) line, &ll);
  188.     if ((cs = ll) && bindtab == altbindtab)
  189.     cs--;
  190. }
  191.  
  192. /**/
  193. int
  194. findbol(void)
  195. {
  196.     int x = cs;
  197.  
  198.     while (x > 0 && line[x - 1] != '\n')
  199.     x--;
  200.     return x;
  201. }
  202.  
  203. /**/
  204. int
  205. findeol(void)
  206. {
  207.     int x = cs;
  208.  
  209.     while (x != ll && line[x] != '\n')
  210.     x++;
  211.     return x;
  212. }
  213.  
  214. /**/
  215. void
  216. findline(int *a, int *b)
  217. {
  218.     *a = findbol();
  219.     *b = findeol();
  220. }
  221.  
  222. static int lastlinelen;
  223.  
  224. /**/
  225. void
  226. initundo(void)
  227. {
  228.     int t0;
  229.  
  230.     for (t0 = 0; t0 != UNDOCT; t0++)
  231.     undos[t0].change = NULL;
  232.     undoct = 0;
  233.     lastline = (unsigned char *)zalloc(lastlinelen = linesz + 1);
  234.     memcpy((char *)lastline, (char *)line, ll);
  235.     lastll = ll;
  236.     lastcs = cs;
  237. }
  238.  
  239. /**/
  240. void
  241. addundo(void)
  242. {
  243.     int pf, sf;
  244.     unsigned char *s, *s2, *t, *t2;
  245.     struct undoent *ue;
  246.  
  247.     for (s = line, t = lastline;
  248.     s < line+ll && t < lastline+lastll && *s == *t; s++, t++);
  249.     if (s == line+ll && t == lastline+lastll)
  250.     return;
  251.     pf = s - line;
  252.     for (s2 = (unsigned char *)line + ll, t2 = lastline + lastll;
  253.      s2 > s && t > t2 && s2[-1] == t2[-1]; s2--, t2--);
  254.     sf = line+ll - s2;
  255.     ue = undos + (undoct = (undoct + 1) % UNDOCT);
  256.     ue->pref = pf;
  257.     ue->suff = sf;
  258.     ue->len = t2 - t;
  259.     ue->cs = lastcs;
  260.     memcpy(ue->change = (char *)halloc(ue->len), (char *)t, ue->len);
  261.     if(linesz + 1 > lastlinelen) {
  262.     free(lastline);
  263.     lastline = (unsigned char *)zalloc(lastlinelen = linesz + 1);
  264.     }
  265.     memcpy((char *)lastline, (char *)line, ll);
  266.     lastll = ll;
  267.     lastcs = cs;
  268. }
  269.  
  270. /* Search for needle in haystack.  Haystack is a metafied string while *
  271.  * needle is unmetafied and len-long.  Start the search at position    *
  272.  * pos.  Search forward if dir > 0 otherwise search backward.          */
  273.  
  274. /**/
  275. char *
  276. hstrnstr(char *haystack, int pos, char *needle, int len, int dir, int sens)
  277. {
  278.     char *s = haystack + pos;
  279.  
  280.     if (dir > 0) {
  281.     while (*s) {
  282.         if (metadiffer(s, needle, len) < sens)
  283.         return s;
  284.         s += 1 + (*s == Meta);
  285.     }
  286.     } else {
  287.     for (;;) {
  288.         if (metadiffer(s, needle, len) < sens)
  289.         return s;
  290.         if (s == haystack)
  291.         break;
  292.         s -= 1 + (s != haystack+1 && s[-2] == Meta);
  293.     }
  294.     }
  295.     return NULL;
  296. }
  297.  
  298. /* Query the user, and return a single character response.  The *
  299.  * question is assumed to have been printed already, and the    *
  300.  * cursor is left immediately after the response echoed.        *
  301.  * (Might cause a problem if this takes it onto the next line.) *
  302.  * <Tab> is interpreted as 'y'; any other control character is  *
  303.  * interpreted as 'n'.  If there are any characters in the      *
  304.  * buffer, this is taken as a negative response, and no         *
  305.  * characters are read.  Case is folded.                        */
  306.  
  307. /**/
  308. int
  309. getzlequery(void)
  310. {
  311.     int c;
  312. #ifdef FIONREAD
  313.     int val;
  314.  
  315.     /* check for typeahead, which is treated as a negative response */
  316.     ioctl(SHTTY, FIONREAD, (char *)&val);
  317.     if (val) {
  318.     putc('n', shout);
  319.     return 'n';
  320.     }
  321. #endif
  322.  
  323.     /* get a character from the tty and interpret it */
  324.     c = getkey(0);
  325.     if (c == '\t')
  326.     c = 'y';
  327.     else if (icntrl(c) || c == EOF)
  328.     c = 'n';
  329.     else
  330.     c = tulower(c);
  331.  
  332.     /* echo response and return */
  333.     putc(c, shout);
  334.     return c;
  335. }
  336.