comparison src/ex_cmds.c @ 294:1c1cbdc42f75 v7.0077

updated for version 7.0077
author vimboss
date Tue, 31 May 2005 22:22:17 +0000
parents 9a10e4d195b3
children 006e9c8a6a8a
comparison
equal deleted inserted replaced
293:f811be6fa9b5 294:1c1cbdc42f75
264 /* Buffer for one line used during sorting. It's allocated to contain the 264 /* Buffer for one line used during sorting. It's allocated to contain the
265 * longest line being sorted. */ 265 * longest line being sorted. */
266 static char_u *sortbuf; 266 static char_u *sortbuf;
267 267
268 static int sort_ic; /* ignore case */ 268 static int sort_ic; /* ignore case */
269 static int sort_nr; /* sort on number */
270
271 /* Struct to store info to be sorted. */
272 typedef struct
273 {
274 linenr_T lnum; /* line number */
275 long col_nr; /* column number or number */
276 } sorti_T;
269 277
270 static int 278 static int
271 #ifdef __BORLANDC__ 279 #ifdef __BORLANDC__
272 _RTLENTRYF 280 _RTLENTRYF
273 #endif 281 #endif
279 #endif 287 #endif
280 sort_compare(s1, s2) 288 sort_compare(s1, s2)
281 const void *s1; 289 const void *s1;
282 const void *s2; 290 const void *s2;
283 { 291 {
284 lpos_T l1 = *(lpos_T *)s1; 292 sorti_T l1 = *(sorti_T *)s1;
285 lpos_T l2 = *(lpos_T *)s2; 293 sorti_T l2 = *(sorti_T *)s2;
286 char_u *s; 294 char_u *s;
295
296 /* When sorting numbers "col_nr" is the number, not the column number. */
297 if (sort_nr)
298 return l1.col_nr - l2.col_nr;
287 299
288 /* We need to copy one line into "sortbuf", because there is no guarantee 300 /* We need to copy one line into "sortbuf", because there is no guarantee
289 * that the first pointer becomes invalid when obtaining the second one. */ 301 * that the first pointer becomes invalid when obtaining the second one. */
290 STRCPY(sortbuf, ml_get(l1.lnum) + l1.col); 302 STRCPY(sortbuf, ml_get(l1.lnum) + l1.col_nr);
291 s = ml_get(l2.lnum) + l2.col; 303 s = ml_get(l2.lnum) + l2.col_nr;
304
292 return sort_ic ? STRICMP(sortbuf, s) : STRCMP(sortbuf, s); 305 return sort_ic ? STRICMP(sortbuf, s) : STRCMP(sortbuf, s);
293 } 306 }
294 307
295 /* 308 /*
296 * ":sort". 309 * ":sort".
301 { 314 {
302 regmatch_T regmatch; 315 regmatch_T regmatch;
303 int len; 316 int len;
304 linenr_T lnum; 317 linenr_T lnum;
305 long maxlen = 0; 318 long maxlen = 0;
306 lpos_T *nrs; 319 sorti_T *nrs;
307 size_t count = eap->line2 - eap->line1 + 1; 320 size_t count = eap->line2 - eap->line1 + 1;
308 int i; 321 size_t i;
309 char_u *p; 322 char_u *p;
310 char_u *s; 323 char_u *s;
311 int unique = FALSE; 324 int unique = FALSE;
312 long deleted; 325 long deleted;
326 colnr_T col;
327 int sort_oct; /* sort on octal number */
328 int sort_hex; /* sort on hex number */
313 329
314 if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL) 330 if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL)
315 return; 331 return;
316 sortbuf = NULL; 332 sortbuf = NULL;
317 regmatch.regprog = NULL; 333 regmatch.regprog = NULL;
318 nrs = (lpos_T *)lalloc((long_u)(count * sizeof(lpos_T)), TRUE); 334 nrs = (sorti_T *)lalloc((long_u)(count * sizeof(sorti_T)), TRUE);
319 if (nrs == NULL) 335 if (nrs == NULL)
320 goto theend; 336 goto theend;
337
338 sort_ic = sort_nr = sort_oct = sort_hex = 0;
321 339
322 for (p = eap->arg; *p != NUL; ++p) 340 for (p = eap->arg; *p != NUL; ++p)
323 { 341 {
324 if (vim_iswhite(*p)) 342 if (vim_iswhite(*p))
325 ; 343 ;
326 else if (*p == 'i') 344 else if (*p == 'i')
327 sort_ic = TRUE; 345 sort_ic = TRUE;
346 else if (*p == 'n')
347 sort_nr = 2;
348 else if (*p == 'o')
349 sort_oct = 2;
350 else if (*p == 'x')
351 sort_hex = 2;
328 else if (*p == 'u') 352 else if (*p == 'u')
329 unique = TRUE; 353 unique = TRUE;
330 else if (*p == '"') /* comment start */ 354 else if (*p == '"') /* comment start */
331 break; 355 break;
332 else if (check_nextcmd(p) != NULL) 356 else if (check_nextcmd(p) != NULL)
354 EMSG2(_(e_invarg2), p); 378 EMSG2(_(e_invarg2), p);
355 goto theend; 379 goto theend;
356 } 380 }
357 } 381 }
358 382
383 /* Can only have one of 'n', 'o' and 'x'. */
384 if (sort_nr + sort_oct + sort_hex > 2)
385 {
386 EMSG(_(e_invarg));
387 goto theend;
388 }
389
390 /* From here on "sort_nr" is used as a flag for any number sorting. */
391 sort_nr += sort_oct + sort_hex;
392
359 /* 393 /*
360 * Make an array with all line numbers, so that we don't have to copy all 394 * Make an array with all line numbers. This avoids having to copy all
361 * the lines into allocated memory. 395 * the lines into allocated memory.
362 * Also get the longest line length. 396 * When sorting on strings "col_nr" is de offset in the line, for numbers
397 * sorting it's the number to sort on. This means the pattern matching
398 * and number conversion only has to be done once per line.
399 * Also get the longest line length for allocating "sortbuf".
363 */ 400 */
364 for (lnum = eap->line1; lnum <= eap->line2; ++lnum) 401 for (lnum = eap->line1; lnum <= eap->line2; ++lnum)
365 { 402 {
366 nrs[lnum - eap->line1].lnum = lnum;
367 nrs[lnum - eap->line1].col = 0;
368
369 s = ml_get(lnum); 403 s = ml_get(lnum);
370 if (regmatch.regprog != NULL && vim_regexec(&regmatch, s, 0))
371 nrs[lnum - eap->line1].col = regmatch.endp[0] - s;
372
373 len = STRLEN(s); 404 len = STRLEN(s);
374 if (maxlen < len) 405 if (maxlen < len)
375 maxlen = len; 406 maxlen = len;
376 } 407
377 408 if (regmatch.regprog != NULL && vim_regexec(&regmatch, s, 0))
409 col = regmatch.endp[0] - s;
410 else
411 col = 0;
412
413 if (sort_nr)
414 {
415 /* Sorting on number: Store the number itself. */
416 if (sort_hex)
417 s = skiptohex(s + col);
418 else
419 s = skiptodigit(s + col);
420 vim_str2nr(s, NULL, NULL, sort_oct, sort_hex,
421 &nrs[lnum - eap->line1].col_nr, NULL);
422 }
423 else
424 /* Store the column to sort at. */
425 nrs[lnum - eap->line1].col_nr = col;
426
427 nrs[lnum - eap->line1].lnum = lnum;
428 }
429
430 /* Allocate a buffer that can hold the longest line. */
378 sortbuf = alloc((unsigned)maxlen + 1); 431 sortbuf = alloc((unsigned)maxlen + 1);
379 if (sortbuf == NULL) 432 if (sortbuf == NULL)
380 goto theend; 433 goto theend;
381 434
382 /* sort the array of line numbers */ 435 /* sort the array of line numbers */
383 qsort((void *)nrs, count, sizeof(lpos_T), sort_compare); 436 qsort((void *)nrs, count, sizeof(sorti_T), sort_compare);
384 437
385 /* Insert the lines in the sorted order below the last one. */ 438 /* Insert the lines in the sorted order below the last one. */
386 lnum = eap->line2; 439 lnum = eap->line2;
387 for (i = 0; i < count; ++i) 440 for (i = 0; i < count; ++i)
388 { 441 {
390 if (!unique || i == 0 443 if (!unique || i == 0
391 || (sort_ic ? STRICMP(s, sortbuf) : STRCMP(s, sortbuf)) != 0) 444 || (sort_ic ? STRICMP(s, sortbuf) : STRCMP(s, sortbuf)) != 0)
392 { 445 {
393 if (ml_append(lnum++, s, (colnr_T)0, FALSE) == FAIL) 446 if (ml_append(lnum++, s, (colnr_T)0, FALSE) == FAIL)
394 break; 447 break;
395 STRCPY(sortbuf, s); 448 if (unique)
449 STRCPY(sortbuf, s);
396 } 450 }
397 } 451 }
398 452
399 /* delete the original lines if appending worked */ 453 /* delete the original lines if appending worked */
400 if (i == count) 454 if (i == count)
401 for (i = 0; i < count; ++i) 455 for (i = 0; i < count; ++i)
402 ml_delete(eap->line1, FALSE); 456 ml_delete(eap->line1, FALSE);
403 else 457 else
404 count = 0; 458 count = 0;
405 459
460 /* Adjust marks for deleted (or added) lines and prepare for displaying. */
406 deleted = count - (lnum - eap->line2); 461 deleted = count - (lnum - eap->line2);
407 if (deleted > 0) 462 if (deleted > 0)
408 mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted); 463 mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted);
409 else if (deleted < 0) 464 else if (deleted < 0)
410 mark_adjust(eap->line2, MAXLNUM, -deleted, 0L); 465 mark_adjust(eap->line2, MAXLNUM, -deleted, 0L);
411 changed_lines(eap->line1, 0, eap->line2 + 1, -deleted); 466 changed_lines(eap->line1, 0, eap->line2 + 1, -deleted);
467
412 curwin->w_cursor.lnum = eap->line1; 468 curwin->w_cursor.lnum = eap->line1;
413 beginline(BL_WHITE | BL_FIX); 469 beginline(BL_WHITE | BL_FIX);
414 470
415 theend: 471 theend:
416 vim_free(nrs); 472 vim_free(nrs);
1530 if (fname == NULL) 1586 if (fname == NULL)
1531 return FAIL; 1587 return FAIL;
1532 fp = mch_fopen((char *)fname, READBIN); 1588 fp = mch_fopen((char *)fname, READBIN);
1533 1589
1534 if (p_verbose > 0) 1590 if (p_verbose > 0)
1591 {
1592 verbose_enter();
1535 smsg((char_u *)_("Reading viminfo file \"%s\"%s%s%s"), 1593 smsg((char_u *)_("Reading viminfo file \"%s\"%s%s%s"),
1536 fname, 1594 fname,
1537 want_info ? _(" info") : "", 1595 want_info ? _(" info") : "",
1538 want_marks ? _(" marks") : "", 1596 want_marks ? _(" marks") : "",
1539 fp == NULL ? _(" FAILED") : ""); 1597 fp == NULL ? _(" FAILED") : "");
1598 verbose_leave();
1599 }
1540 1600
1541 vim_free(fname); 1601 vim_free(fname);
1542 if (fp == NULL) 1602 if (fp == NULL)
1543 return FAIL; 1603 return FAIL;
1544 1604
1758 fclose(fp_in); 1818 fclose(fp_in);
1759 goto end; 1819 goto end;
1760 } 1820 }
1761 1821
1762 if (p_verbose > 0) 1822 if (p_verbose > 0)
1823 {
1824 verbose_enter();
1763 smsg((char_u *)_("Writing viminfo file \"%s\""), fname); 1825 smsg((char_u *)_("Writing viminfo file \"%s\""), fname);
1826 verbose_leave();
1827 }
1764 1828
1765 viminfo_errcnt = 0; 1829 viminfo_errcnt = 0;
1766 do_viminfo(fp_in, fp_out, !forceit, !forceit, FALSE); 1830 do_viminfo(fp_in, fp_out, !forceit, !forceit, FALSE);
1767 1831
1768 fclose(fp_out); /* errors are ignored !? */ 1832 fclose(fp_out); /* errors are ignored !? */