00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "config.h"
00014 #include "vi.h"
00015 #if TURBOC
00016 #include <process.h>
00017 #endif
00018 #if TOS
00019 #include <osbind.h>
00020 #define rename(a,b) Frename(0,a,b)
00021 #endif
00022
00023 # define NANONS 9
00024
00025 static struct cutbuf
00026 {
00027 short *phys;
00028 int nblks;
00029 int start;
00030 int end;
00031 int tmpnum;
00032 char lnmode;
00033 }
00034 named[27],
00035 anon[NANONS];
00036
00037 static char cbname;
00038 static char dotcb;
00039
00040
00041 #ifndef NO_RECYCLE
00042
00043
00044
00045
00046
00047
00048 int cutneeds(need)
00049 BLK *need;
00050 {
00051 struct cutbuf *cb;
00052 int i;
00053 int n;
00054
00055 n = 0;
00056
00057
00058 for (cb = named; cb < &named[27]; cb++)
00059 {
00060 if (cb->tmpnum != tmpnum)
00061 continue;
00062
00063 for (i = cb->nblks; i-- > 0; )
00064 {
00065 need->n[n++] = cb->phys[i];
00066 }
00067 }
00068
00069
00070 for (cb = anon; cb < &anon[NANONS]; cb++)
00071 {
00072 if (cb->tmpnum != tmpnum)
00073 continue;
00074
00075 for (i = cb->nblks; i-- > 0; )
00076 {
00077 need->n[n++] = cb->phys[i];
00078 }
00079 }
00080
00081
00082 return n;
00083 }
00084 #endif
00085
00086 static void maybezap(num)
00087 int num;
00088 {
00089 char cutfname[80];
00090 int i;
00091
00092
00093 if (tmpfd >= 0 && num == tmpnum)
00094 {
00095 return;
00096 }
00097
00098
00099 for (i = 27; --i >= 0; )
00100 {
00101 if (named[i].nblks > 0 && named[i].tmpnum == num)
00102 {
00103 break;
00104 }
00105 }
00106 if (i < 0)
00107 {
00108 for (i = NANONS; --i >= 0 ; )
00109 {
00110 if (anon[i].nblks > 0 && anon[i].tmpnum == num)
00111 {
00112 break;
00113 }
00114 }
00115 }
00116
00117
00118 if (i < 0)
00119 {
00120 #if MSDOS || TOS
00121 strcpy(cutfname, o_directory);
00122 if ((i = strlen(cutfname)) && !strchr(":/\\", cutfname[i - 1]))
00123 cutfname[i++] = SLASH;
00124 sprintf(cutfname + i, TMPNAME + 3, getpid(), num);
00125 #else
00126 sprintf(cutfname, TMPNAME, o_directory, getpid(), num);
00127 #endif
00128 unlink(cutfname);
00129 }
00130 }
00131
00132
00133
00134 static void cutfree(buf)
00135 struct cutbuf *buf;
00136 {
00137 int num;
00138
00139
00140 if (buf->nblks <= 0)
00141 {
00142 return;
00143 }
00144
00145
00146 num = buf->tmpnum;
00147 buf->nblks = 0;
00148 #ifdef DEBUG
00149 if (!buf->phys)
00150 msg("cutfree() tried to free a NULL buf->phys pointer.");
00151 else
00152 #endif
00153 free((char *)buf->phys);
00154
00155
00156 maybezap(num);
00157 }
00158
00159
00160
00161
00162
00163
00164 void cutswitch()
00165 {
00166 int i;
00167
00168
00169 storename((char *)0);
00170 close(tmpfd);
00171 tmpfd = -1;
00172
00173
00174 for (i = 0; i < NANONS; i++)
00175 {
00176 cutfree(&anon[i]);
00177 }
00178
00179
00180 maybezap(tmpnum);
00181 }
00182
00183
00184 void cutend()
00185 {
00186 int i;
00187
00188
00189 cutswitch();
00190
00191
00192
00193
00194 for (i = 0; i < 27; i++)
00195 {
00196 cutfree(&named[i]);
00197 }
00198
00199
00200 maybezap(tmpnum);
00201 }
00202
00203
00204
00205 void cutname(name)
00206 int name;
00207 {
00208 cbname = name;
00209 }
00210
00211
00212
00213
00214
00215 void cut(from, to)
00216 MARK from;
00217 MARK to;
00218 {
00219 int first;
00220 int last;
00221 long line;
00222 int lnmode;
00223 MARK delthru;
00224 REG struct cutbuf *cb;
00225 REG long l;
00226 REG int i;
00227 REG char *scan;
00228 char *blkc;
00229
00230
00231 if (markidx(from) == 0 && markidx(to) == 0)
00232 lnmode = TRUE;
00233 else
00234 lnmode = FALSE;
00235
00236
00237 delthru = MARK_UNSET;
00238
00239
00240 if (doingdot)
00241 {
00242 if (!cbname)
00243 {
00244 cbname = dotcb;
00245 }
00246 }
00247 else if (cbname != '.')
00248 {
00249 dotcb = cbname;
00250 }
00251
00252
00253 if (!cbname)
00254 {
00255
00256 cutfree(&anon[NANONS - 1]);
00257
00258
00259 for (i = NANONS - 1; i > 0; i--)
00260 {
00261 anon[i] = anon[i - 1];
00262 }
00263
00264
00265 cb = anon;
00266 cb->nblks = 0;
00267 }
00268 else if (cbname >= 'a' && cbname <= 'z')
00269 {
00270 cb = &named[cbname - 'a'];
00271 cutfree(cb);
00272 }
00273 #ifndef CRUNCH
00274 else if (cbname >= 'A' && cbname <= 'Z')
00275 {
00276 cb = &named[cbname - 'A'];
00277 if (cb->nblks > 0)
00278 {
00279
00280 if (!lnmode && cb->lnmode)
00281 {
00282 from &= ~(BLKSIZE - 1);
00283 if (markidx(to) != 0 || to == from)
00284 {
00285 to = to + BLKSIZE - markidx(to);
00286 }
00287 lnmode = TRUE;
00288 }
00289
00290
00291 mark[28] = to;
00292 delthru = paste(from, FALSE, TRUE);
00293 if (delthru == MARK_UNSET)
00294 {
00295 return;
00296 }
00297 delthru++;
00298 to = mark[28];
00299 }
00300 cutfree(cb);
00301 }
00302 #endif
00303 else if (cbname == '.')
00304 {
00305 cb = &named[26];
00306 cutfree(cb);
00307 }
00308 else
00309 {
00310 msg("Invalid cut buffer name: \"%c", cbname);
00311 dotcb = cbname = '\0';
00312 return;
00313 }
00314 cbname = '\0';
00315 cb->tmpnum = tmpnum;
00316
00317
00318 cb->lnmode = lnmode;
00319
00320
00321
00322
00323 if (markidx(from) == 0 && markidx(to) == 0)
00324 {
00325 rptlines = markline(to) - markline(from);
00326 rptlabel = "yanked";
00327 }
00328
00329
00330
00331
00332 blksync();
00333
00334
00335 line = markline(from);
00336 for (first = 1; line > lnum[first]; first++)
00337 {
00338 }
00339
00340
00341 blkc = scan = blkget(first)->c;
00342
00343
00344 for (l = lnum[first - 1]; ++l < line; )
00345 {
00346 while (*scan++ != '\n')
00347 {
00348 }
00349 }
00350 scan += markidx(from);
00351
00352
00353 cb->start = scan - blkc;
00354
00355
00356
00357
00358 line = markline(to);
00359 for (last = first; line > lnum[last]; last++)
00360 {
00361 }
00362
00363
00364 if (last != first)
00365 {
00366 blkc = scan = blkget(last)->c;
00367 }
00368 else
00369 {
00370 scan = blkc;
00371 }
00372
00373
00374 for (l = lnum[last - 1]; ++l < line; )
00375 {
00376 while (*scan++ != '\n')
00377 {
00378 }
00379 }
00380 if (markline(to) <= nlines)
00381 {
00382 scan += markidx(to);
00383 }
00384
00385
00386 cb->end = scan - blkc;
00387
00388
00389
00390
00391 cb->nblks = last - first;
00392 if (cb->end > 0)
00393 {
00394 cb->nblks++;
00395 }
00396 #ifdef lint
00397 cb->phys = (short *)0;
00398 #else
00399 cb->phys = (short *)malloc((unsigned)(cb->nblks * sizeof(short)));
00400 #endif
00401 for (i = 0; i < cb->nblks; i++)
00402 {
00403 cb->phys[i] = hdr.n[first++];
00404 }
00405
00406 #ifndef CRUNCH
00407
00408
00409
00410 if (delthru)
00411 {
00412 line = rptlines;
00413 delete(from, delthru);
00414 rptlines = line;
00415 rptlabel = "yanked";
00416 }
00417 #endif
00418 }
00419
00420
00421 static void readcutblk(cb, blkno)
00422 struct cutbuf *cb;
00423 int blkno;
00424 {
00425 char cutfname[50];
00426 int fd;
00427 #if MSDOS || TOS
00428 int i;
00429 #endif
00430
00431
00432 if (cb->tmpnum == tmpnum)
00433 {
00434 fd = tmpfd;
00435 }
00436 else
00437 {
00438 #if MSDOS || TOS
00439 strcpy(cutfname, o_directory);
00440 if ((i = strlen(cutfname)) && !strchr(":/\\", cutfname[i-1]))
00441 cutfname[i++]=SLASH;
00442 sprintf(cutfname+i, TMPNAME+3, getpid(), cb->tmpnum);
00443 #else
00444 sprintf(cutfname, TMPNAME, o_directory, getpid(), cb->tmpnum);
00445 #endif
00446 fd = open(cutfname, O_RDONLY);
00447 }
00448
00449
00450 lseek(fd, (long)cb->phys[blkno] * (long)BLKSIZE, 0);
00451 if (read(fd, tmpblk.c, (unsigned)BLKSIZE) != BLKSIZE)
00452 {
00453 msg("Error reading back from tmp file for pasting!");
00454 }
00455
00456
00457 if (fd != tmpfd)
00458 {
00459 close(fd);
00460 }
00461 }
00462
00463
00464
00465
00466
00467 MARK paste(at, after, retend)
00468 MARK at;
00469 int after;
00470 int retend;
00471 {
00472 REG struct cutbuf *cb;
00473 REG int i;
00474
00475
00476 if (doingdot)
00477 {
00478 if (!cbname)
00479 {
00480 if (dotcb >= '1' && dotcb < '1' + NANONS - 1)
00481 {
00482 dotcb++;
00483 }
00484 cbname = dotcb;
00485 }
00486 }
00487 else if (cbname != '.')
00488 {
00489 dotcb = cbname;
00490 }
00491
00492
00493 if (cbname >= 'A' && cbname <= 'Z')
00494 {
00495 cb = &named[cbname - 'A'];
00496 }
00497 else if (cbname >= 'a' && cbname <= 'z')
00498 {
00499 cb = &named[cbname - 'a'];
00500 }
00501 else if (cbname >= '1' && cbname <= '9')
00502 {
00503 cb = &anon[cbname - '1'];
00504 }
00505 else if (cbname == '.')
00506 {
00507 cb = &named[26];
00508 }
00509 else if (!cbname)
00510 {
00511 cb = anon;
00512 }
00513 else
00514 {
00515 msg("Invalid cut buffer name: \"%c", cbname);
00516 cbname = '\0';
00517 return MARK_UNSET;
00518 }
00519
00520
00521 if (cb->nblks == 0)
00522 {
00523 if (cbname)
00524 msg("Cut buffer \"%c is empty", cbname);
00525 else
00526 msg("Cut buffer is empty");
00527 cbname = '\0';
00528 return MARK_UNSET;
00529 }
00530 cbname = '\0';
00531
00532
00533 if (cb->lnmode)
00534 {
00535 at &= ~(BLKSIZE - 1);
00536 if (after)
00537 {
00538 at += BLKSIZE;
00539 }
00540 }
00541 else if (after)
00542 {
00543
00544
00545
00546 if (markidx(at) == 0)
00547 {
00548 pfetch(markline(at));
00549 if (plen != 0)
00550 {
00551 at++;
00552 }
00553 }
00554 else
00555 {
00556 at++;
00557 }
00558 }
00559
00560
00561
00562
00563 mark[27] = at;
00564
00565
00566 if (cb->nblks == 1)
00567 {
00568
00569 readcutblk(cb, 0);
00570
00571
00572 if (cb->end)
00573 {
00574 tmpblk.c[cb->end] = '\0';
00575 }
00576
00577
00578 ChangeText
00579 {
00580 add(at, &tmpblk.c[cb->start]);
00581 }
00582 }
00583 else
00584 {
00585
00586
00587 ChangeText
00588 {
00589 i = cb->nblks - 1;
00590
00591
00592 if (cb->end > 0)
00593 {
00594 readcutblk(cb, i);
00595 tmpblk.c[cb->end] = '\0';
00596 add(at, tmpblk.c);
00597 i--;
00598 }
00599
00600
00601 while (i > 0)
00602 {
00603 readcutblk(cb, i);
00604 add(at, tmpblk.c);
00605 i--;
00606 }
00607
00608
00609 readcutblk(cb, 0);
00610 add(at, &tmpblk.c[cb->start]);
00611 }
00612 }
00613
00614
00615 rptlines = markline(mark[27]) - markline(at);
00616 rptlabel = "pasted";
00617
00618
00619 if (retend)
00620 {
00621 return mark[27] - 1L;
00622 }
00623 return at;
00624 }
00625
00626
00627
00628
00629 #ifndef NO_AT
00630
00631
00632
00633
00634
00635
00636
00637 int cb2str(name, buf, size)
00638 int name;
00639 char *buf;
00640 unsigned size;
00641 {
00642 REG struct cutbuf *cb;
00643 REG char *src;
00644 REG char *dest;
00645
00646
00647 if (name >= 'a' && name <= 'z')
00648 {
00649 cb = &named[name - 'a'];
00650 }
00651 else
00652 {
00653 return -1;
00654 }
00655
00656
00657 if (cb->nblks == 0)
00658 {
00659 return 0;
00660 }
00661
00662
00663 if (cb->nblks != 1)
00664 {
00665 return size;
00666 }
00667
00668
00669 if (cb->end - cb->start >= size)
00670 {
00671 return cb->end - cb->start;
00672 }
00673
00674
00675 readcutblk(cb, 0);
00676
00677
00678 if (cb->start == 0)
00679 {
00680 tmpblk.c[cb->end] = '\0';
00681 }
00682 else
00683 {
00684 for (dest = tmpblk.c, src = dest + cb->start; src < tmpblk.c + cb->end; )
00685 {
00686 *dest++ = *src++;
00687 }
00688 *dest = '\0';
00689 }
00690
00691
00692 if (buf != tmpblk.c)
00693 {
00694 strcpy(buf, tmpblk.c);
00695 }
00696
00697
00698 return cb->end - cb->start;
00699 }
00700 #endif