From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3359 invoked from network); 25 Jan 2005 14:47:51 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 25 Jan 2005 14:47:51 -0000 Received: (qmail 4459 invoked from network); 25 Jan 2005 14:47:45 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 25 Jan 2005 14:47:45 -0000 Received: (qmail 24122 invoked by alias); 25 Jan 2005 14:47:37 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 20742 Received: (qmail 24103 invoked from network); 25 Jan 2005 14:47:36 -0000 Received: from unknown (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 25 Jan 2005 14:47:36 -0000 Received: (qmail 3770 invoked from network); 25 Jan 2005 14:46:58 -0000 Received: from mailhost1.csr.com (HELO MAILSWEEPER01.csr.com) (81.105.217.43) by a.mx.sunsite.dk with SMTP; 25 Jan 2005 14:46:52 -0000 Received: from exchange03.csr.com (unverified [10.100.137.60]) by MAILSWEEPER01.csr.com (Content Technologies SMTPRS 4.3.12) with ESMTP id for ; Tue, 25 Jan 2005 14:45:29 +0000 Received: from news01.csr.com ([10.103.143.38]) by exchange03.csr.com with Microsoft SMTPSVC(5.0.2195.6713); Tue, 25 Jan 2005 14:46:34 +0000 Received: from news01.csr.com (localhost.localdomain [127.0.0.1]) by news01.csr.com (8.13.1/8.12.11) with ESMTP id j0PEkpim024139 for ; Tue, 25 Jan 2005 14:46:51 GMT Received: from csr.com (pws@localhost) by news01.csr.com (8.13.1/8.13.1/Submit) with ESMTP id j0PEkoFJ024136 for ; Tue, 25 Jan 2005 14:46:51 GMT Message-Id: <200501251446.j0PEkoFJ024136@news01.csr.com> X-Authentication-Warning: news01.csr.com: pws owned process doing -bs To: zsh-workers@sunsite.dk (Zsh hackers list) Subject: PATCH: Unicode additions, next phase. Date: Tue, 25 Jan 2005 14:46:50 +0000 From: Peter Stephenson X-OriginalArrivalTime: 25 Jan 2005 14:46:34.0438 (UTC) FILETIME=[AA679660:01C502EC] X-Spam-Checker-Version: SpamAssassin 3.0.2 on a.mx.sunsite.dk X-Spam-Level: X-Spam-Status: No, score=-2.3 required=6.0 tests=AWL,BAYES_00 autolearn=ham version=3.0.2 X-Spam-Hits: -2.3 Here are some more changes. ZLE_UNICODE_SUPPORT is still not complete enough to be turned on, so it hasn't even been compiled with that in effect, hence there may be arbitrarily many arbitrarily glaring bugs. I've only tested it in the old-fashioned case so far by compiling and trying some simple editing. - Added a few extra definitions: characters and sizes. Quite possibly '\0' will convert smoothly to L'\0' without a definition, but (since we are currently testing for full Unicode compiler support) I don't see any point in risking it. - Modified zlegetline to get general zlelineasstring and stringaszleline functions. Use zlegetline to return value from zlereadline; this already returns allocated memory so the callers don't need changing. Careful freeing: as an optimisation the functions don't bother resizing down to the minimum needed size, so you can't use zfree with the length of the array. - Undo/redo should now use the right format for command line chunks. - The cutbuffer and the kill ring should use the right format for killed text, including the zle variables. - Went through zle_main.c and zle_utils.c fixing things up (hence the previous two items). They still may need changing if more things need to be passed as ZLE_STRING_T instead of char */unsigned char *. (I don't like all the casts between char * and unsigned char * but it's about a dozen years too late for that.) The key missing bits are screen output from zle_refresh.c and key input, but there will be lots of little things in the other files I haven't yet looked at. For example, we need multibyte/wide-character support for word separator characters, as well as extending use of ctype macros to iswupper etc. Those are interesting projects for anyone who wants a relatively self-contained chunk. We may need to widen some uses of wchar_t to wint_t (which is defined to be able to hold a WEOF, which replaces EOF). We probably need more configure tests for such things eventually. Index: Src/system.h =================================================================== RCS file: /cvsroot/zsh/zsh/Src/system.h,v retrieving revision 1.22 diff -u -r1.22 system.h --- Src/system.h 14 Jan 2005 13:05:22 -0000 1.22 +++ Src/system.h 25 Jan 2005 14:40:56 -0000 @@ -709,6 +709,7 @@ #ifdef ZLE_UNICODE_SUPPORT typedef wchar_t ZLE_CHAR_T; typedef wchar_t *ZLE_STRING_T; +#define ZLE_CHAR_SIZE sizeof(wchar_t) /* * MB_CUR_MAX is the maximum number of bytes that a single wide @@ -720,7 +721,14 @@ #ifndef MB_CUR_MAX #define MB_CUR_MAX 6 #endif + +#define ZLENL L'\n' +#define ZLENUL L'\0' #else typedef int ZLE_CHAR_T; typedef unsigned char *ZLE_STRING_T; +#define ZLE_CHAR_SIZE sizeof(unsigned char) + +#define ZLENL '\n' +#define ZLENUL '\0' #endif Index: Src/Zle/zle.h =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle.h,v retrieving revision 1.4 diff -u -r1.4 zle.h --- Src/Zle/zle.h 14 Jan 2005 13:05:23 -0000 1.4 +++ Src/Zle/zle.h 25 Jan 2005 14:40:57 -0000 @@ -99,8 +99,10 @@ int flags; /* see below */ int hist; /* history line being changed */ int off; /* offset of the text changes */ - char *del; /* characters to delete (metafied) */ - char *ins; /* characters to insert (metafied) */ + ZLE_STRING_T del; /* characters to delete */ + int dell; /* no. of characters in del */ + ZLE_STRING_T ins; /* characters to insert */ + int insl; /* no. of characters in ins */ int old_cs, new_cs; /* old and new cursor positions */ }; @@ -123,12 +125,15 @@ #define removesuffix() iremovesuffix(256, 0) -/* Cut/kill buffer type. The buffer itself is purely binary data, * - * not NUL-terminated. len is a length count. flags uses the * - * CUTBUFFER_* constants defined below. */ +/* + * Cut/kill buffer type. The buffer itself is purely binary data, not + * NUL-terminated. len is a length count (N.B. number of characters, + * not size in bytes). flags uses the CUTBUFFER_* constants defined + * below. + */ struct cutbuffer { - char *buf; + ZLE_STRING_T buf; size_t len; char flags; }; Index: Src/Zle/zle_main.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_main.c,v retrieving revision 1.56 diff -u -r1.56 zle_main.c --- Src/Zle/zle_main.c 14 Jan 2005 13:05:23 -0000 1.56 +++ Src/Zle/zle_main.c 25 Jan 2005 14:40:57 -0000 @@ -719,7 +719,7 @@ handleprefixes(); /* for vi mode, make sure the cursor isn't somewhere illegal */ if (invicmdmode() && zlecs > findbol() && - (zlecs == zlell || zleline[zlecs] == '\n')) + (zlecs == zlell || zleline[zlecs] == ZLENL)) zlecs--; if (undoing) handleundo(); @@ -819,8 +819,8 @@ zlecontext = context; histline = curhist; undoing = 1; - zleline = (unsigned char *)zalloc((linesz = 256) + 2); - *zleline = '\0'; + zleline = (unsigned char *)zalloc(((linesz = 256) + 2) * ZLE_CHAR_SIZE); + *zleline = ZLENUL; virangeflag = lastcmd = done = zlecs = zlell = mark = 0; vichgflag = 0; viinsbegin = 0; @@ -877,15 +877,16 @@ freeundo(); if (eofsent) { - free(zleline); - zleline = NULL; + s = NULL; } else { - zleline[zlell++] = '\n'; - zleline = (unsigned char *) metafy((char *) zleline, zlell, META_REALLOC); + zleline[zlell++] = ZLENL; + s = zlegetline(NULL, NULL); } + free(zleline); + zleline = NULL; forget_edits(); errno = old_errno; - return zleline; + return s; } /* execute a widget */ @@ -1512,10 +1513,10 @@ free_isrch_spots(); if (rdstrs) freelinklist(rdstrs, freestr); - zfree(cutbuf.buf, cutbuf.len); + free(cutbuf.buf); if (kring) { for(i = kringsize; i--; ) - zfree(kring[i].buf, kring[i].len); + free(kring[i].buf); zfree(kring, kringsize * sizeof(struct cutbuffer)); } for(i = 35; i--; ) Index: Src/Zle/zle_misc.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_misc.c,v retrieving revision 1.13 diff -u -r1.13 zle_misc.c --- Src/Zle/zle_misc.c 14 Jan 2005 13:05:23 -0000 1.13 +++ Src/Zle/zle_misc.c 25 Jan 2005 14:40:57 -0000 @@ -358,7 +358,8 @@ while (n--) { kct = -1; spaceinline(kctbuf->len); - memcpy((char *)zleline + zlecs, kctbuf->buf, kctbuf->len); + memcpy((char *)(zleline + zlecs), (char *)kctbuf->buf, + kctbuf->len * ZLE_CHAR_SIZE); zlecs += kctbuf->len; yanke = zlecs; } @@ -412,13 +413,13 @@ * was full, we could loop round and round it, otherwise * we just stopped when we hit the first empty buffer. */ - } while (!buf->buf || !*buf->buf); + } while (!buf->buf || *buf->buf == ZLENUL); zlecs = yankb; foredel(yanke - yankb); cc = buf->len; spaceinline(cc); - memcpy((char *)zleline + zlecs, buf->buf, cc); + memcpy((char *)(zleline + zlecs), (char *)buf->buf, cc * ZLE_CHAR_SIZE); zlecs += cc; yanke = zlecs; return 0; Index: Src/Zle/zle_params.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_params.c,v retrieving revision 1.20 diff -u -r1.20 zle_params.c --- Src/Zle/zle_params.c 14 Jan 2005 13:05:24 -0000 1.20 +++ Src/Zle/zle_params.c 25 Jan 2005 14:40:57 -0000 @@ -418,7 +418,8 @@ get_cutbuffer(UNUSED(Param pm)) { if (cutbuf.buf) - return metafy(cutbuf.buf, cutbuf.len, META_HEAPDUP); + return (char *) + zlelineasstring(cutbuf.buf, cutbuf.len, 0, NULL, NULL, 1); else return ""; } @@ -433,10 +434,8 @@ cutbuf.flags = 0; if (x) { int n; - unmetafy(x, &n); + cutbuf.buf = stringaszleline((unsigned char *)x, &n, NULL); cutbuf.len = n; - cutbuf.buf = zalloc(cutbuf.len); - memcpy((char *)cutbuf.buf, x, cutbuf.len); free(x); } else { cutbuf.buf = NULL; @@ -469,7 +468,7 @@ if (kring) { for (kptr = kring, kcnt = 0; kcnt < kringsize; kcnt++, kptr++) if (kptr->buf) - zfree(kptr->buf, kptr->len); + free(kptr->buf); zfree(kring, kringsize * sizeof(struct cutbuffer)); kring = NULL; kringsize = kringnum = 0; @@ -489,10 +488,10 @@ for (p = x; *p; p++) { int n, len = strlen(*p); kptr = kring + kpos; - unmetafy(*p, &n); + + kptr->buf = stringaszleline((unsigned char *)*p, &n, NULL); kptr->len = n; - kptr->buf = (char *)zalloc(kptr->len); - memcpy(kptr->buf, *p, kptr->len); + zfree(*p, len+1); kpos = (kpos + kringsize -1 ) % kringsize; } @@ -524,11 +523,9 @@ Cutbuffer kptr = kring + kpos; if (kptr->buf) { - /* - * Need to use HEAPDUP to make sure there's room for the - * terminating NULL. - */ - *p++ = metafy((char *)kptr->buf, kptr->len, META_HEAPDUP); + /* Allocate on heap. */ + *p++ = (char *)zlelineasstring(kptr->buf, kptr->len, + 0, NULL, NULL, 1); } else *p++ = dupstring(""); Index: Src/Zle/zle_utils.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_utils.c,v retrieving revision 1.14 diff -u -r1.14 zle_utils.c --- Src/Zle/zle_utils.c 22 Jan 2005 16:26:43 -0000 1.14 +++ Src/Zle/zle_utils.c 25 Jan 2005 14:40:57 -0000 @@ -51,7 +51,7 @@ /* the line before last mod (for undo purposes) */ /**/ -char *lastline; +ZLE_STRING_T lastline; /**/ int lastlinesz, lastll, lastcs; @@ -67,7 +67,9 @@ sizeline(int sz) { while (sz > linesz) - zleline = (ZLE_STRING_T)realloc(zleline, (linesz *= 4) + 2); + zleline = + (ZLE_STRING_T)realloc(zleline, + ((linesz *= 4) + 2) * ZLE_CHAR_SIZE); } /* @@ -82,22 +84,36 @@ zleline[zlecs++] = chr; } +/* + * Input a line in internal zle format, possibly using wide characters, + * possibly not, together with its length and the cursor position. + * Output an ordinary string, using multibyte characters instead of wide + * characters where appropriate and with the contents metafied. + * + * If outll is non-NULL, assign the new length. If outcs is non-NULL, + * assign the new character position. + * + * If useheap is 1, memory is returned from the heap, else is allocated + * for later freeing. + */ + /**/ mod_export unsigned char * -zlegetline(int *ll, int *cs) +zlelineasstring(ZLE_STRING_T instr, int inll, int incs, int *outll, + int *outcs, int useheap) { - char *s; #ifdef ZLE_UNICODE_SUPPORT + char *s; char *mb_cursor; int i, j; size_t mb_len = 0; - mb_cursor = s = zalloc(zlell * MB_CUR_MAX); + mb_cursor = s = zalloc(inll * MB_CUR_MAX); - for(i=0;i<=zlell;i++) { - if (i == zlecs) - *cs = mb_len; - j = wctomb(mb_cursor, zleline[i]); + for(i=0;i<=inll;i++) { + if (outcs != NULL && i == incs) + *outcs = mb_len; + j = wctomb(mb_cursor, instr[i]); if (j == -1) { /* invalid char; what to do? */ } else { @@ -105,14 +121,130 @@ } } - *ll = mb_len; + if (outll != NULL) + *outll = mb_len; + if (useheap) + { + unsigned char *ret = + (unsigned char *) metafy((char *) s, mb_len, META_HEAPDUP); + + zfree((char *)s, inll * MB_CUR_MAX); + + return ret; + } + else + { + return (unsigned char *) metafy((char *) s, mb_len, META_REALLOC); + } #else - *ll = zlell; - *cs = zlecs; + if (outll != NULL) + *outll = inll; + if (outcs != NULL) + *outcs = incs; + + return (unsigned char *) metafy((char *) instr, inll, + useheap ? META_HEAPDUP : META_DUP); +#endif +} + + +/* + * Input a NULL-terminated metafied string instr. + * Output a line in internal zle format, together with its length + * in the appropriate character units. Note that outll may not be NULL. + * + * If outsz is non-NULL, the number of allocated characters in the + * string is written there. For compatibility with use of the linesz + * variable (allocate size of zleline), at least two characters are + * allocated more than needed for immediate use. (The extra characters + * may take a newline and a null at a later stage.) These are not + * included in *outsz. + * + * Note that instr is modified in place, hence should be copied + * first if necessary; + * + * Memory for the returned string is permanently allocated. *outsz may + * be longer than the *outll returned. Hence it should be freed with + * zfree(outstr, *outsz) or free(outstr), not zfree(outstr, *outll). + */ + +/**/ +mod_export ZLE_STRING_T +stringaszleline(unsigned char *instr, int *outll, int *outsz) +{ + ZLE_STRING_T outstr; + int ll, sz; +#ifdef ZLE_UNICODE_SUPPORT + int cll; + mbstate_t ps; +#endif + + unmetafy(instr, &ll); + + /* + * ll is the maximum number of characters there can be in + * the output string; the closer to ASCII the string, the + * better the guess. For the 2 see above. + */ + sz = (ll + 2) * ZLE_CHAR_SIZE; + if (outsz) + *outsz = ll; + outstr = (ZLE_STRING_T)zalloc(sz); + +#ifdef ZLE_UNICODE_SUPPORT + if (ll) { + /* reset shift state by converting null. */ + char cnull = '\0'; + char *inptr = (char *)instr; + wchar_t *outptr = outstr; + + mbrtowc(outstr, &cnull, 1, &ps); + + while (ll) { + size_t ret = mbrtowc(outptr, inptr, ll, &ps); + + /* + * At this point we don't handle either incomplete (-2) or + * invalid (-1) multibyte sequences. Use the current length + * and return. + */ + if (ret == (size_t)-1 || ret == (size_t)-2) + break; - s = ztrdup(zleline); + /* + * Careful: converting a wide NUL returns zero, but we + * want to treat NULs as regular characters. + * The NUL does get converted, however, so test that. + * Assume it was represented by a single ASCII NUL; + * certainly true for Unicode and unlikely to be false + * in any non-pathological multibyte representation. + */ + if (*outptr == L'\0' && ret == 0) + ret = 1; + + inptr += ret; + outptr++; + ll -= ret; + } + *outll = outptr - outstr; + } + else + *outll = 0; +#else + memcpy((char *)outstr, (char *)instr, ll); + *outll = ll; #endif - return (unsigned char *) metafy((char *) s, zlell, META_REALLOC); + + return outstr; +} + + + +/**/ +mod_export unsigned char * +zlegetline(int *ll, int *cs) +{ + return zlelineasstring(zleline, zlell, zlecs, ll, cs, 0); } @@ -128,7 +260,7 @@ for (i = zlell; --i >= zlecs;) zleline[i + ct] = zleline[i]; zlell += ct; - zleline[zlell] = '\0'; + zleline[zlell] = ZLENUL; if (mark > zlecs) mark += ct; @@ -147,7 +279,7 @@ zleline[to] = zleline[to + cnt]; to++; } - zleline[zlell = to] = '\0'; + zleline[zlell = to] = ZLENUL; } /**/ @@ -181,9 +313,9 @@ struct cutbuffer *b = &vibuf[zmod.vibuf]; if (!(zmod.flags & MOD_VIAPP) || !b->buf) { - zfree(b->buf, b->len); - b->buf = (char *)zalloc(ct); - memcpy(b->buf, (char *) zleline + i, ct); + free(b->buf); + b->buf = (ZLE_STRING_T)zalloc(ct * ZLE_CHAR_SIZE); + memcpy((char *)b->buf, (char *)(zleline + i), ct * ZLE_CHAR_SIZE); b->len = ct; b->flags = vilinerange ? CUTBUFFER_LINE : 0; } else { @@ -191,26 +323,32 @@ if(vilinerange) b->flags |= CUTBUFFER_LINE; - b->buf = realloc(b->buf, ct + len + !!(b->flags & CUTBUFFER_LINE)); + b->buf = (ZLE_STRING_T) + realloc((char *)b->buf, + (ct + len + !!(b->flags & CUTBUFFER_LINE)) + * ZLE_CHAR_SIZE); if (b->flags & CUTBUFFER_LINE) - b->buf[len++] = '\n'; - memcpy(b->buf + len, (char *) zleline + i, ct); + b->buf[len++] = ZLENL; + memcpy((char *)(b->buf + len), (char *)(zleline + i), + ct * ZLE_CHAR_SIZE); b->len = len + ct; } return; } else { /* Save in "1, shifting "1-"8 along to "2-"9 */ int n; - zfree(vibuf[34].buf, vibuf[34].len); + free(vibuf[34].buf); for(n=34; n>26; n--) vibuf[n] = vibuf[n-1]; - vibuf[26].buf = (char *)zalloc(ct); - memcpy(vibuf[26].buf, (char *) zleline + i, ct); + vibuf[26].buf = (ZLE_STRING_T)zalloc(ct * ZLE_CHAR_SIZE); + memcpy((char *)vibuf[26].buf, (char *)(zleline + i), + ct * ZLE_CHAR_SIZE); vibuf[26].len = ct; vibuf[26].flags = vilinerange ? CUTBUFFER_LINE : 0; } if (!cutbuf.buf) { - cutbuf.buf = ztrdup(""); + cutbuf.buf = (ZLE_STRING_T)zalloc(ZLE_CHAR_SIZE); + cutbuf.buf[0] = ZLENUL; cutbuf.len = cutbuf.flags = 0; } else if (!(lastcmd & ZLE_KILL)) { Cutbuffer kptr; @@ -221,22 +359,26 @@ kringnum = (kringnum + 1) % kringsize; kptr = kring + kringnum; if (kptr->buf) - zfree(kptr->buf, kptr->len); + free(kptr->buf); *kptr = cutbuf; - cutbuf.buf = ztrdup(""); + cutbuf.buf = (ZLE_STRING_T)zalloc(ZLE_CHAR_SIZE); + cutbuf.buf[0] = ZLENUL; cutbuf.len = cutbuf.flags = 0; } if (dir) { - char *s = (char *)zalloc(cutbuf.len + ct); + ZLE_STRING_T s = (ZLE_STRING_T)zalloc((cutbuf.len + ct)*ZLE_CHAR_SIZE); - memcpy(s, (char *) zleline + i, ct); - memcpy(s + ct, cutbuf.buf, cutbuf.len); + memcpy(s, (char *) (zleline + i), ct * ZLE_CHAR_SIZE); + memcpy((char *)(s + ct), (char *)cutbuf.buf, + cutbuf.len * ZLE_CHAR_SIZE); free(cutbuf.buf); cutbuf.buf = s; cutbuf.len += ct; } else { - cutbuf.buf = realloc(cutbuf.buf, cutbuf.len + ct); - memcpy(cutbuf.buf + cutbuf.len, (char *) zleline + i, ct); + cutbuf.buf = realloc((char *)cutbuf.buf, + (cutbuf.len + ct) * ZLE_CHAR_SIZE); + memcpy((char *)(cutbuf.buf + cutbuf.len), (char *) (zleline + i), + ct * ZLE_CHAR_SIZE); cutbuf.len += ct; } if(vilinerange) @@ -263,11 +405,19 @@ void setline(char const *s) { - sizeline(strlen(s)); - strcpy((char *) zleline, s); - unmetafy((char *) zleline, &zlell); + char *scp = ztrdup(s); + /* + * TBD: we could make this more efficient by passing the existing + * allocated line to stringaszleline. + */ + free(zleline); + + zleline = stringaszleline(scp, &zlell, &linesz); + if ((zlecs = zlell) && invicmdmode()) zlecs--; + + free(scp); } /**/ @@ -276,7 +426,7 @@ { int x = zlecs; - while (x > 0 && zleline[x - 1] != '\n') + while (x > 0 && zleline[x - 1] != ZLENL) x--; return x; } @@ -287,7 +437,7 @@ { int x = zlecs; - while (x != zlell && zleline[x] != '\n') + while (x != zlell && zleline[x] != ZLENL) x++; return x; } @@ -328,15 +478,18 @@ return NULL; } -/* Query the user, and return a single character response. The * - * question is assumed to have been printed already, and the * - * cursor is left immediately after the response echoed. * - * (Might cause a problem if this takes it onto the next line.) * - * If yesno is non-zero: * - * is interpreted as 'y'; any other control character is * - * interpreted as 'n'. If there are any characters in the * - * buffer, this is taken as a negative response, and no * - * characters are read. Case is folded. */ +/* + * Query the user, and return a single character response. The question + * is assumed to have been printed already, and the cursor is left + * immediately after the response echoed. (Might cause a problem if + * this takes it onto the next line.) If yesno is non-zero: is + * interpreted as 'y'; any other control character is interpreted as + * 'n'. If there are any characters in the buffer, this is taken as a + * negative response, and no characters are read. Case is folded. + * + * TBD: this may need extending to return a wchar_t or possibly + * a wint_t. + */ /**/ mod_export int @@ -496,8 +649,9 @@ changes = curchange = zalloc(sizeof(*curchange)); curchange->prev = curchange->next = NULL; curchange->del = curchange->ins = NULL; - lastline = zalloc(lastlinesz = linesz); - memcpy(lastline, zleline, lastll = zlell); + curchange->dell = curchange->insl = 0; + lastline = zalloc((lastlinesz = linesz) * ZLE_CHAR_SIZE); + memcpy(lastline, zleline, (lastll = zlell) * ZLE_CHAR_SIZE); lastcs = zlecs; } @@ -518,8 +672,8 @@ for(; p; p = n) { n = p->next; - zsfree(p->del); - zsfree(p->ins); + free(p->del); + free(p->ins); zfree(p, sizeof(*p)); } } @@ -537,9 +691,10 @@ if(curchange->next) { freechanges(curchange->next); curchange->next = NULL; - zsfree(curchange->del); - zsfree(curchange->ins); + free(curchange->del); + free(curchange->ins); curchange->del = curchange->ins = NULL; + curchange->dell = curchange->insl = 0; } nextchanges->prev = curchange->prev; if(curchange->prev) @@ -561,7 +716,7 @@ int sh = zlell < lastll ? zlell : lastll; struct change *ch; - if(lastll == zlell && !memcmp(lastline, zleline, zlell)) + if(lastll == zlell && !memcmp(lastline, zleline, zlell * ZLE_CHAR_SIZE)) return; for(pre = 0; pre < sh && zleline[pre] == lastline[pre]; ) pre++; @@ -574,14 +729,24 @@ ch->off = pre; ch->old_cs = lastcs; ch->new_cs = zlecs; - if(suf + pre == lastll) + if(suf + pre == lastll) { ch->del = NULL; - else - ch->del = metafy(lastline + pre, lastll - pre - suf, META_DUP); - if(suf + pre == zlell) + ch->dell = 0; + } else { + ch->dell = lastll - pre - suf; + ch->del = (ZLE_STRING_T)zalloc(ch->dell * ZLE_CHAR_SIZE); + memcpy((char *)ch->del, (char *)(lastline + pre), + ch->dell * ZLE_CHAR_SIZE); + } + if(suf + pre == zlell) { ch->ins = NULL; - else - ch->ins = metafy((char *)zleline + pre, zlell - pre - suf, META_DUP); + ch->insl = 0; + } else { + ch->insl = zlell - pre - suf; + ch->ins = (ZLE_STRING_T)zalloc(ch->insl * ZLE_CHAR_SIZE); + memcpy((char *)ch->ins, (char *)(zleline + pre), + ch->insl * ZLE_CHAR_SIZE); + } if(nextchanges) { ch->flags = CH_PREV; ch->prev = endnextchanges; @@ -602,8 +767,8 @@ setlastline(void) { if(lastlinesz != linesz) - lastline = realloc(lastline, lastlinesz = linesz); - memcpy(lastline, zleline, lastll = zlell); + lastline = realloc(lastline, (lastlinesz = linesz) * ZLE_CHAR_SIZE); + memcpy(lastline, zleline, (lastll = zlell) * ZLE_CHAR_SIZE); lastcs = zlecs; } @@ -637,16 +802,12 @@ } zlecs = ch->off; if(ch->ins) - foredel(ztrlen(ch->ins)); + foredel(ch->insl); if(ch->del) { - char *c = ch->del; - - spaceinline(ztrlen(c)); - for(; *c; c++) - if(*c == Meta) - zleline[zlecs++] = STOUC(*++c) ^ 32; - else - zleline[zlecs++] = STOUC(*c); + spaceinline(ch->dell); + memcpy((char *)(zleline + zlecs), (char *)ch->del, + ch->dell * ZLE_CHAR_SIZE); + zlecs += ch->dell; } zlecs = ch->old_cs; return 1; @@ -682,16 +843,12 @@ } zlecs = ch->off; if(ch->del) - foredel(ztrlen(ch->del)); + foredel(ch->dell); if(ch->ins) { - char *c = ch->ins; - - spaceinline(ztrlen(c)); - for(; *c; c++) - if(*c == Meta) - zleline[zlecs++] = STOUC(*++c) ^ 32; - else - zleline[zlecs++] = STOUC(*c); + spaceinline(ch->insl); + memcpy((char *)(zleline + zlecs), (char *)ch->ins, + ch->insl * ZLE_CHAR_SIZE); + zlecs += ch->insl; } zlecs = ch->new_cs; return 1; -- Peter Stephenson Software Engineer CSR PLC, Churchill House, Cambridge Business Park, Cowley Road Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070 ********************************************************************** This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed. If you have received this email in error please notify the system manager. This footnote also confirms that this email message has been swept by MIMEsweeper for the presence of computer viruses. www.mimesweeper.com **********************************************************************