sort.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <bio.h>
  12. /*
  13. bugs:
  14. 00/ff for end of file can conflict with 00/ff characters
  15. */
  16. static Rune ljan[] = {'J','A','N'};
  17. static Rune lfeb[] = {'F','E','B'};
  18. static Rune lmar[] = {'M','A','R'};
  19. static Rune lapr[] = {'A','P','R'};
  20. static Rune lmay[] = {'M','A','Y'};
  21. static Rune ljun[] = {'J','U','N'};
  22. static Rune ljul[] = {'J','U','L'};
  23. static Rune laug[] = {'A','U','G'};
  24. static Rune lsep[] = {'S','E','P'};
  25. static Rune loct[] = {'O','C','T'};
  26. static Rune lnov[] = {'N','O','V'};
  27. static Rune ldec[] = {'D','E','C'};
  28. enum
  29. {
  30. Nline = 100000, /* default max number of lines saved in memory */
  31. Nmerge = 10, /* max number of temporary files merged */
  32. Nfield = 20, /* max number of argument fields */
  33. Bflag = 1<<0, /* flags per field */
  34. B1flag = 1<<1,
  35. Dflag = 1<<2,
  36. Fflag = 1<<3,
  37. Gflag = 1<<4,
  38. Iflag = 1<<5,
  39. Mflag = 1<<6,
  40. Nflag = 1<<7,
  41. Rflag = 1<<8,
  42. Wflag = 1<<9,
  43. NSstart = 0, /* states for number to key decoding */
  44. NSsign,
  45. NSzero,
  46. NSdigit,
  47. NSpoint,
  48. NSfract,
  49. NSzerofract,
  50. NSexp,
  51. NSexpsign,
  52. NSexpdigit,
  53. };
  54. typedef struct Line Line;
  55. typedef struct Key Key;
  56. typedef struct Merge Merge;
  57. typedef struct Field Field;
  58. struct Line
  59. {
  60. Key* key;
  61. int llen; /* always >= 1 */
  62. uint8_t line[1]; /* always ends in '\n' */
  63. };
  64. struct Merge
  65. {
  66. Key* key; /* copy of line->key so (Line*) looks like (Merge*) */
  67. Line* line; /* line at the head of a merged temp file */
  68. int fd; /* file descriptor */
  69. Biobuf b; /* iobuf for reading a temp file */
  70. };
  71. struct Key
  72. {
  73. int klen;
  74. uint8_t key[1];
  75. };
  76. struct Field
  77. {
  78. int beg1;
  79. int beg2;
  80. int end1;
  81. int end2;
  82. int32_t flags;
  83. uint8_t mapto[1+255];
  84. void (*dokey)(Key*, uint8_t*, uint8_t*, Field*);
  85. };
  86. struct args
  87. {
  88. char* ofile;
  89. char* tname;
  90. Rune tabchar;
  91. char cflag;
  92. char uflag;
  93. char vflag;
  94. int nfield;
  95. int nfile;
  96. Field field[Nfield];
  97. Line** linep;
  98. int32_t nline; /* number of lines in this temp file */
  99. int32_t lineno; /* overall ordinal for -s option */
  100. int ntemp;
  101. int32_t mline; /* max lines per file */
  102. } args;
  103. extern Rune* month[12];
  104. void buildkey(Line*);
  105. void doargs(int, char*[]);
  106. void dofield(char*, int*, int*, int, int);
  107. void dofile(Biobuf*);
  108. void dokey_(Key*, uint8_t*, uint8_t*, Field*);
  109. void dokey_dfi(Key*, uint8_t*, uint8_t*, Field*);
  110. void dokey_gn(Key*, uint8_t*, uint8_t*, Field*);
  111. void dokey_m(Key*, uint8_t*, uint8_t*, Field*);
  112. void dokey_r(Key*, uint8_t*, uint8_t*, Field*);
  113. void done(char*);
  114. int kcmp(Key*, Key*);
  115. void makemapd(Field*);
  116. void makemapm(Field*);
  117. void mergefiles(int, int, Biobuf*);
  118. void mergeout(Biobuf*);
  119. void newfield(void);
  120. Line* newline(Biobuf*);
  121. void nomem(void);
  122. void notifyf(void *c, char*);
  123. void printargs(void);
  124. void printout(Biobuf*);
  125. void setfield(int, int);
  126. uint8_t* skip(uint8_t*, int, int, int, int);
  127. void sort4(void *c, uint32_t);
  128. char* tempfile(int);
  129. void tempout(void);
  130. void lineout(Biobuf*, Line*);
  131. void
  132. main(int argc, char *argv[])
  133. {
  134. int i, f;
  135. char *s;
  136. Biobuf bbuf;
  137. notify(notifyf); /**/
  138. doargs(argc, argv);
  139. if(args.vflag)
  140. printargs();
  141. for(i=1; i<argc; i++) {
  142. s = argv[i];
  143. if(s == 0)
  144. continue;
  145. if(strcmp(s, "-") == 0) {
  146. Binit(&bbuf, 0, OREAD);
  147. dofile(&bbuf);
  148. Bterm(&bbuf);
  149. continue;
  150. }
  151. f = open(s, OREAD);
  152. if(f < 0) {
  153. fprint(2, "sort: open %s: %r\n", s);
  154. done("open");
  155. }
  156. Binit(&bbuf, f, OREAD);
  157. dofile(&bbuf);
  158. Bterm(&bbuf);
  159. close(f);
  160. }
  161. if(args.nfile == 0) {
  162. Binit(&bbuf, 0, OREAD);
  163. dofile(&bbuf);
  164. Bterm(&bbuf);
  165. }
  166. if(args.cflag)
  167. done(0);
  168. if(args.vflag)
  169. fprint(2, "=========\n");
  170. f = 1;
  171. if(args.ofile) {
  172. f = create(args.ofile, OWRITE, 0666);
  173. if(f < 0) {
  174. fprint(2, "sort: create %s: %r\n", args.ofile);
  175. done("create");
  176. }
  177. }
  178. Binit(&bbuf, f, OWRITE);
  179. if(args.ntemp) {
  180. tempout();
  181. mergeout(&bbuf);
  182. } else {
  183. printout(&bbuf);
  184. }
  185. Bterm(&bbuf);
  186. done(0);
  187. }
  188. void
  189. dofile(Biobuf *b)
  190. {
  191. Line *l, *ol;
  192. int n;
  193. if(args.cflag) {
  194. ol = newline(b);
  195. if(ol == 0)
  196. return;
  197. for(;;) {
  198. l = newline(b);
  199. if(l == 0)
  200. break;
  201. n = kcmp(ol->key, l->key);
  202. if(n > 0 || (n == 0 && args.uflag)) {
  203. fprint(2, "sort: -c file not in sort\n"); /**/
  204. done("order");
  205. }
  206. free(ol->key);
  207. free(ol);
  208. ol = l;
  209. }
  210. return;
  211. }
  212. if(args.linep == 0) {
  213. args.linep = malloc(args.mline * sizeof(args.linep));
  214. if(args.linep == 0)
  215. nomem();
  216. }
  217. for(;;) {
  218. l = newline(b);
  219. if(l == 0)
  220. break;
  221. if(args.nline >= args.mline)
  222. tempout();
  223. args.linep[args.nline] = l;
  224. args.nline++;
  225. args.lineno++;
  226. }
  227. }
  228. void
  229. notifyf(void *c, char *s)
  230. {
  231. if(strcmp(s, "interrupt") == 0)
  232. done(0);
  233. if(strcmp(s, "hangup") == 0)
  234. done(0);
  235. if(strcmp(s, "kill") == 0)
  236. done(0);
  237. if(strncmp(s, "sys: write on closed pipe", 25) == 0)
  238. done(0);
  239. fprint(2, "sort: note: %s\n", s);
  240. abort();
  241. }
  242. Line*
  243. newline(Biobuf *b)
  244. {
  245. Line *l;
  246. char *p;
  247. int n, c;
  248. p = Brdline(b, '\n');
  249. n = Blinelen(b);
  250. if(p == 0) {
  251. if(n == 0)
  252. return 0;
  253. l = 0;
  254. for(n=0;;) {
  255. if((n & 31) == 0) {
  256. l = realloc(l, sizeof(Line) +
  257. (n+31)*sizeof(l->line[0]));
  258. if(l == 0)
  259. nomem();
  260. }
  261. c = Bgetc(b);
  262. if(c < 0) {
  263. fprint(2, "sort: newline added\n");
  264. c = '\n';
  265. }
  266. l->line[n++] = c;
  267. if(c == '\n')
  268. break;
  269. }
  270. l->llen = n;
  271. buildkey(l);
  272. return l;
  273. }
  274. l = malloc(sizeof(Line) +
  275. (n-1)*sizeof(l->line[0]));
  276. if(l == 0)
  277. nomem();
  278. l->llen = n;
  279. memmove(l->line, p, n);
  280. buildkey(l);
  281. return l;
  282. }
  283. void
  284. lineout(Biobuf *b, Line *l)
  285. {
  286. int n, m;
  287. n = l->llen;
  288. m = Bwrite(b, l->line, n);
  289. if(n != m)
  290. exits("write");
  291. }
  292. void
  293. tempout(void)
  294. {
  295. int32_t n;
  296. Line **lp, *l;
  297. char *tf;
  298. int f;
  299. Biobuf tb;
  300. sort4(args.linep, args.nline);
  301. tf = tempfile(args.ntemp);
  302. args.ntemp++;
  303. f = create(tf, OWRITE, 0666);
  304. if(f < 0) {
  305. fprint(2, "sort: create %s: %r\n", tf);
  306. done("create");
  307. }
  308. Binit(&tb, f, OWRITE);
  309. lp = args.linep;
  310. for(n=args.nline; n>0; n--) {
  311. l = *lp++;
  312. lineout(&tb, l);
  313. free(l->key);
  314. free(l);
  315. }
  316. args.nline = 0;
  317. Bterm(&tb);
  318. close(f);
  319. }
  320. void
  321. done(char *xs)
  322. {
  323. int i;
  324. for(i=0; i<args.ntemp; i++)
  325. remove(tempfile(i));
  326. exits(xs);
  327. }
  328. void
  329. nomem(void)
  330. {
  331. fprint(2, "sort: out of memory\n");
  332. done("mem");
  333. }
  334. char*
  335. tempfile(int n)
  336. {
  337. static char file[100];
  338. static uint pid;
  339. char *dir;
  340. dir = "/tmp";
  341. if(args.tname)
  342. dir = args.tname;
  343. if(strlen(dir) >= nelem(file)-20) {
  344. fprint(2, "temp file directory name is too int32_t: %s\n", dir);
  345. done("tdir");
  346. }
  347. if(pid == 0) {
  348. pid = getpid();
  349. if(pid == 0) {
  350. pid = time(0);
  351. if(pid == 0)
  352. pid = 1;
  353. }
  354. }
  355. sprint(file, "%s/sort.%.4d.%.4d", dir, pid%10000, n);
  356. return file;
  357. }
  358. void
  359. mergeout(Biobuf *b)
  360. {
  361. int n, i, f;
  362. char *tf;
  363. Biobuf tb;
  364. for(i=0; i<args.ntemp; i+=n) {
  365. n = args.ntemp - i;
  366. if(n > Nmerge) {
  367. tf = tempfile(args.ntemp);
  368. args.ntemp++;
  369. f = create(tf, OWRITE, 0666);
  370. if(f < 0) {
  371. fprint(2, "sort: create %s: %r\n", tf);
  372. done("create");
  373. }
  374. Binit(&tb, f, OWRITE);
  375. n = Nmerge;
  376. mergefiles(i, n, &tb);
  377. Bterm(&tb);
  378. close(f);
  379. } else
  380. mergefiles(i, n, b);
  381. }
  382. }
  383. void
  384. mergefiles(int t, int n, Biobuf *b)
  385. {
  386. Merge *m, *mp, **mmp;
  387. Key *ok;
  388. Line *l;
  389. char *tf;
  390. int i, f, nn;
  391. mmp = malloc(n*sizeof(*mmp));
  392. mp = malloc(n*sizeof(*mp));
  393. if(mmp == 0 || mp == 0)
  394. nomem();
  395. nn = 0;
  396. m = mp;
  397. for(i=0; i<n; i++,m++) {
  398. tf = tempfile(t+i);
  399. f = open(tf, OREAD);
  400. if(f < 0) {
  401. fprint(2, "sort: reopen %s: %r\n", tf);
  402. done("open");
  403. }
  404. m->fd = f;
  405. Binit(&m->b, f, OREAD);
  406. mmp[nn] = m;
  407. l = newline(&m->b);
  408. if(l == 0)
  409. continue;
  410. nn++;
  411. m->line = l;
  412. m->key = l->key;
  413. }
  414. ok = 0;
  415. for(;;) {
  416. sort4(mmp, nn);
  417. m = *mmp;
  418. if(nn == 0)
  419. break;
  420. for(;;) {
  421. l = m->line;
  422. if(args.uflag && ok && kcmp(ok, l->key) == 0) {
  423. free(l->key);
  424. free(l);
  425. } else {
  426. lineout(b, l);
  427. if(ok)
  428. free(ok);
  429. ok = l->key;
  430. free(l);
  431. }
  432. l = newline(&m->b);
  433. if(l == 0) {
  434. nn--;
  435. mmp[0] = mmp[nn];
  436. break;
  437. }
  438. m->line = l;
  439. m->key = l->key;
  440. if(nn > 1 && kcmp(mmp[0]->key, mmp[1]->key) > 0)
  441. break;
  442. }
  443. }
  444. if(ok)
  445. free(ok);
  446. m = mp;
  447. for(i=0; i<n; i++,m++) {
  448. Bterm(&m->b);
  449. close(m->fd);
  450. }
  451. free(mp);
  452. free(mmp);
  453. }
  454. int
  455. kcmp(Key *ka, Key *kb)
  456. {
  457. int n, m;
  458. /*
  459. * set n to length of smaller key
  460. */
  461. n = ka->klen;
  462. m = kb->klen;
  463. if(n > m)
  464. n = m;
  465. return memcmp(ka->key, kb->key, n);
  466. }
  467. void
  468. printout(Biobuf *b)
  469. {
  470. int32_t n;
  471. Line **lp, *l;
  472. Key *ok;
  473. sort4(args.linep, args.nline);
  474. lp = args.linep;
  475. ok = 0;
  476. for(n=args.nline; n>0; n--) {
  477. l = *lp++;
  478. if(args.uflag && ok && kcmp(ok, l->key) == 0)
  479. continue;
  480. lineout(b, l);
  481. ok = l->key;
  482. }
  483. }
  484. void
  485. setfield(int n, int c)
  486. {
  487. Field *f;
  488. f = &args.field[n];
  489. switch(c) {
  490. default:
  491. fprint(2, "sort: unknown option: field.%C\n", c);
  492. done("option");
  493. case 'b': /* skip blanks */
  494. f->flags |= Bflag;
  495. break;
  496. case 'd': /* directory order */
  497. f->flags |= Dflag;
  498. break;
  499. case 'f': /* fold case */
  500. f->flags |= Fflag;
  501. break;
  502. case 'g': /* floating point -n case */
  503. f->flags |= Gflag;
  504. break;
  505. case 'i': /* ignore non-ascii */
  506. f->flags |= Iflag;
  507. break;
  508. case 'M': /* month */
  509. f->flags |= Mflag;
  510. break;
  511. case 'n': /* numbers */
  512. f->flags |= Nflag;
  513. break;
  514. case 'r': /* reverse */
  515. f->flags |= Rflag;
  516. break;
  517. case 'w': /* ignore white */
  518. f->flags |= Wflag;
  519. break;
  520. }
  521. }
  522. void
  523. dofield(char *s, int *n1, int *n2, int off1, int off2)
  524. {
  525. int c, n;
  526. c = *s++;
  527. if(c >= '0' && c <= '9') {
  528. n = 0;
  529. while(c >= '0' && c <= '9') {
  530. n = n*10 + (c-'0');
  531. c = *s++;
  532. }
  533. n -= off1; /* posix committee: rot in hell */
  534. if(n < 0) {
  535. fprint(2, "sort: field offset must be positive\n");
  536. done("option");
  537. }
  538. *n1 = n;
  539. }
  540. if(c == '.') {
  541. c = *s++;
  542. if(c >= '0' && c <= '9') {
  543. n = 0;
  544. while(c >= '0' && c <= '9') {
  545. n = n*10 + (c-'0');
  546. c = *s++;
  547. }
  548. n -= off2;
  549. if(n < 0) {
  550. fprint(2, "sort: character offset must be positive\n");
  551. done("option");
  552. }
  553. *n2 = n;
  554. }
  555. }
  556. while(c != 0) {
  557. setfield(args.nfield, c);
  558. c = *s++;
  559. }
  560. }
  561. void
  562. printargs(void)
  563. {
  564. int i, n;
  565. Field *f;
  566. char *prefix;
  567. fprint(2, "sort");
  568. for(i=0; i<=args.nfield; i++) {
  569. f = &args.field[i];
  570. prefix = " -";
  571. if(i) {
  572. n = f->beg1;
  573. if(n >= 0)
  574. fprint(2, " +%d", n);
  575. else
  576. fprint(2, " +*");
  577. n = f->beg2;
  578. if(n >= 0)
  579. fprint(2, ".%d", n);
  580. else
  581. fprint(2, ".*");
  582. if(f->flags & B1flag)
  583. fprint(2, "b");
  584. n = f->end1;
  585. if(n >= 0)
  586. fprint(2, " -%d", n);
  587. else
  588. fprint(2, " -*");
  589. n = f->end2;
  590. if(n >= 0)
  591. fprint(2, ".%d", n);
  592. else
  593. fprint(2, ".*");
  594. prefix = "";
  595. }
  596. if(f->flags & Bflag)
  597. fprint(2, "%sb", prefix);
  598. if(f->flags & Dflag)
  599. fprint(2, "%sd", prefix);
  600. if(f->flags & Fflag)
  601. fprint(2, "%sf", prefix);
  602. if(f->flags & Gflag)
  603. fprint(2, "%sg", prefix);
  604. if(f->flags & Iflag)
  605. fprint(2, "%si", prefix);
  606. if(f->flags & Mflag)
  607. fprint(2, "%sM", prefix);
  608. if(f->flags & Nflag)
  609. fprint(2, "%sn", prefix);
  610. if(f->flags & Rflag)
  611. fprint(2, "%sr", prefix);
  612. if(f->flags & Wflag)
  613. fprint(2, "%sw", prefix);
  614. }
  615. if(args.cflag)
  616. fprint(2, " -c");
  617. if(args.uflag)
  618. fprint(2, " -u");
  619. if(args.ofile)
  620. fprint(2, " -o %s", args.ofile);
  621. if(args.mline != Nline)
  622. fprint(2, " -l %ld", args.mline);
  623. fprint(2, "\n");
  624. }
  625. void
  626. newfield(void)
  627. {
  628. int n;
  629. Field *f;
  630. n = args.nfield + 1;
  631. if(n >= Nfield) {
  632. fprint(2, "sort: too many fields specified\n");
  633. done("option");
  634. }
  635. args.nfield = n;
  636. f = &args.field[n];
  637. f->beg1 = -1;
  638. f->beg2 = -1;
  639. f->end1 = -1;
  640. f->end2 = -1;
  641. }
  642. void
  643. doargs(int argc, char *argv[])
  644. {
  645. int i, c, hadplus;
  646. char *s, *p, *q;
  647. Field *f;
  648. hadplus = 0;
  649. args.mline = Nline;
  650. for(i=1; i<argc; i++) {
  651. s = argv[i];
  652. c = *s++;
  653. if(c == '-') {
  654. c = *s;
  655. if(c == 0) /* forced end of arg marker */
  656. break;
  657. argv[i] = 0; /* clobber args processed */
  658. if(c == '.' || (c >= '0' && c <= '9')) {
  659. if(!hadplus)
  660. newfield();
  661. f = &args.field[args.nfield];
  662. dofield(s, &f->end1, &f->end2, 0, 0);
  663. hadplus = 0;
  664. continue;
  665. }
  666. while((c = *s++) != '\0')
  667. switch(c) {
  668. case '-': /* end of options */
  669. i = argc;
  670. continue;
  671. case 'T': /* temp directory */
  672. if(*s == 0) {
  673. i++;
  674. if(i < argc) {
  675. args.tname = argv[i];
  676. argv[i] = 0;
  677. }
  678. } else
  679. args.tname = s;
  680. s = strchr(s, 0);
  681. break;
  682. case 'o': /* output file */
  683. if(*s == 0) {
  684. i++;
  685. if(i < argc) {
  686. args.ofile = argv[i];
  687. argv[i] = 0;
  688. }
  689. } else
  690. args.ofile = s;
  691. s = strchr(s, 0);
  692. break;
  693. case 'k': /* posix key (what were they thinking?) */
  694. p = 0;
  695. if(*s == 0) {
  696. i++;
  697. if(i < argc) {
  698. p = argv[i];
  699. argv[i] = 0;
  700. }
  701. } else
  702. p = s;
  703. s = strchr(s, 0);
  704. if(p == 0)
  705. break;
  706. newfield();
  707. q = strchr(p, ',');
  708. if(q)
  709. *q++ = 0;
  710. f = &args.field[args.nfield];
  711. dofield(p, &f->beg1, &f->beg2, 1, 1);
  712. if(f->flags & Bflag) {
  713. f->flags |= B1flag;
  714. f->flags &= ~Bflag;
  715. }
  716. if(q) {
  717. dofield(q, &f->end1, &f->end2, 1, 0);
  718. if(f->end2 <= 0)
  719. f->end1++;
  720. }
  721. hadplus = 0;
  722. break;
  723. case 't': /* tab character */
  724. if(*s == 0) {
  725. i++;
  726. if(i < argc) {
  727. chartorune(&args.tabchar, argv[i]);
  728. argv[i] = 0;
  729. }
  730. } else
  731. s += chartorune(&args.tabchar, s);
  732. if(args.tabchar == '\n') {
  733. fprint(2, "aw come on, rob\n");
  734. done("rob");
  735. }
  736. break;
  737. case 'c': /* check order */
  738. args.cflag = 1;
  739. break;
  740. case 'u': /* unique */
  741. args.uflag = 1;
  742. break;
  743. case 'v': /* debugging noise */
  744. args.vflag = 1;
  745. break;
  746. case 'l':
  747. if(*s == 0) {
  748. i++;
  749. if(i < argc) {
  750. args.mline = atol(argv[i]);
  751. argv[i] = 0;
  752. }
  753. } else
  754. args.mline = atol(s);
  755. s = strchr(s, 0);
  756. break;
  757. case 'M': /* month */
  758. case 'b': /* skip blanks */
  759. case 'd': /* directory order */
  760. case 'f': /* fold case */
  761. case 'g': /* floating numbers */
  762. case 'i': /* ignore non-ascii */
  763. case 'n': /* numbers */
  764. case 'r': /* reverse */
  765. case 'w': /* ignore white */
  766. if(args.nfield > 0)
  767. fprint(2, "sort: global field set after -k\n");
  768. setfield(0, c);
  769. break;
  770. case 'm':
  771. /* option m silently ignored but required by posix */
  772. break;
  773. default:
  774. fprint(2, "sort: unknown option: -%C\n", c);
  775. done("option");
  776. }
  777. continue;
  778. }
  779. if(c == '+') {
  780. argv[i] = 0; /* clobber args processed */
  781. c = *s;
  782. if(c == '.' || (c >= '0' && c <= '9')) {
  783. newfield();
  784. f = &args.field[args.nfield];
  785. dofield(s, &f->beg1, &f->beg2, 0, 0);
  786. if(f->flags & Bflag) {
  787. f->flags |= B1flag;
  788. f->flags &= ~Bflag;
  789. }
  790. hadplus = 1;
  791. continue;
  792. }
  793. fprint(2, "sort: unknown option: +%C\n", c);
  794. done("option");
  795. }
  796. args.nfile++;
  797. }
  798. for(i=0; i<=args.nfield; i++) {
  799. f = &args.field[i];
  800. /*
  801. * global options apply to fields that
  802. * specify no options
  803. */
  804. if(f->flags == 0) {
  805. f->flags = args.field[0].flags;
  806. if(args.field[0].flags & Bflag)
  807. f->flags |= B1flag;
  808. }
  809. /*
  810. * build buildkey specification
  811. */
  812. switch(f->flags & ~(Bflag|B1flag)) {
  813. default:
  814. fprint(2, "sort: illegal combination of flags: %lx\n", f->flags);
  815. done("option");
  816. case 0:
  817. f->dokey = dokey_;
  818. break;
  819. case Rflag:
  820. f->dokey = dokey_r;
  821. break;
  822. case Gflag:
  823. case Nflag:
  824. case Gflag|Nflag:
  825. case Gflag|Rflag:
  826. case Nflag|Rflag:
  827. case Gflag|Nflag|Rflag:
  828. f->dokey = dokey_gn;
  829. break;
  830. case Mflag:
  831. case Mflag|Rflag:
  832. f->dokey = dokey_m;
  833. makemapm(f);
  834. break;
  835. case Dflag:
  836. case Dflag|Fflag:
  837. case Dflag|Fflag|Iflag:
  838. case Dflag|Fflag|Iflag|Rflag:
  839. case Dflag|Fflag|Iflag|Rflag|Wflag:
  840. case Dflag|Fflag|Iflag|Wflag:
  841. case Dflag|Fflag|Rflag:
  842. case Dflag|Fflag|Rflag|Wflag:
  843. case Dflag|Fflag|Wflag:
  844. case Dflag|Iflag:
  845. case Dflag|Iflag|Rflag:
  846. case Dflag|Iflag|Rflag|Wflag:
  847. case Dflag|Iflag|Wflag:
  848. case Dflag|Rflag:
  849. case Dflag|Rflag|Wflag:
  850. case Dflag|Wflag:
  851. case Fflag:
  852. case Fflag|Iflag:
  853. case Fflag|Iflag|Rflag:
  854. case Fflag|Iflag|Rflag|Wflag:
  855. case Fflag|Iflag|Wflag:
  856. case Fflag|Rflag:
  857. case Fflag|Rflag|Wflag:
  858. case Fflag|Wflag:
  859. case Iflag:
  860. case Iflag|Rflag:
  861. case Iflag|Rflag|Wflag:
  862. case Iflag|Wflag:
  863. case Wflag:
  864. f->dokey = dokey_dfi;
  865. makemapd(f);
  866. break;
  867. }
  868. }
  869. /*
  870. * random spot checks
  871. */
  872. if(args.nfile > 1 && args.cflag) {
  873. fprint(2, "sort: -c can have at most one input file\n");
  874. done("option");
  875. }
  876. return;
  877. }
  878. uint8_t*
  879. skip(uint8_t *l, int n1, int n2, int bflag, int endfield)
  880. {
  881. int i, c, tc;
  882. Rune r;
  883. if(endfield && n1 < 0)
  884. return 0;
  885. c = *l++;
  886. tc = args.tabchar;
  887. if(tc) {
  888. if(tc < Runeself) {
  889. for(i=n1; i>0; i--) {
  890. while(c != tc) {
  891. if(c == '\n')
  892. return 0;
  893. c = *l++;
  894. }
  895. if(!(endfield && i == 1))
  896. c = *l++;
  897. }
  898. } else {
  899. l--;
  900. l += chartorune(&r, (char*)l);
  901. for(i=n1; i>0; i--) {
  902. while(r != tc) {
  903. if(r == '\n')
  904. return 0;
  905. l += chartorune(&r, (char*)l);
  906. }
  907. if(!(endfield && i == 1))
  908. l += chartorune(&r, (char*)l);
  909. }
  910. c = r;
  911. }
  912. } else {
  913. for(i=n1; i>0; i--) {
  914. while(c == ' ' || c == '\t')
  915. c = *l++;
  916. while(c != ' ' && c != '\t') {
  917. if(c == '\n')
  918. return 0;
  919. c = *l++;
  920. }
  921. }
  922. }
  923. if(bflag)
  924. while(c == ' ' || c == '\t')
  925. c = *l++;
  926. l--;
  927. for(i=n2; i>0; i--) {
  928. c = *l;
  929. if(c < Runeself) {
  930. if(c == '\n')
  931. return 0;
  932. l++;
  933. continue;
  934. }
  935. l += chartorune(&r, (char*)l);
  936. }
  937. return l;
  938. }
  939. void
  940. dokey_gn(Key *k, uint8_t *lp, uint8_t *lpe, Field *f)
  941. {
  942. uint8_t *kp;
  943. int c, cl, dp;
  944. int state, nzero, exp, expsign, rflag;
  945. cl = k->klen + 3;
  946. kp = k->key + cl; /* skip place for sign, exponent[2] */
  947. nzero = 0; /* number of trailing zeros */
  948. exp = 0; /* value of the exponent */
  949. expsign = 0; /* sign of the exponent */
  950. dp = 0x4040; /* location of decimal point */
  951. rflag = f->flags&Rflag; /* xor of rflag and - sign */
  952. state = NSstart;
  953. for(;; lp++) {
  954. if(lp >= lpe)
  955. break;
  956. c = *lp;
  957. if(c == ' ' || c == '\t') {
  958. switch(state) {
  959. case NSstart:
  960. case NSsign:
  961. continue;
  962. }
  963. break;
  964. }
  965. if(c == '+' || c == '-') {
  966. switch(state) {
  967. case NSstart:
  968. state = NSsign;
  969. if(c == '-')
  970. rflag = !rflag;
  971. continue;
  972. case NSexp:
  973. state = NSexpsign;
  974. if(c == '-')
  975. expsign = 1;
  976. continue;
  977. }
  978. break;
  979. }
  980. if(c == '0') {
  981. switch(state) {
  982. case NSdigit:
  983. if(rflag)
  984. c = ~c;
  985. *kp++ = c;
  986. cl++;
  987. nzero++;
  988. dp++;
  989. state = NSdigit;
  990. continue;
  991. case NSfract:
  992. if(rflag)
  993. c = ~c;
  994. *kp++ = c;
  995. cl++;
  996. nzero++;
  997. state = NSfract;
  998. continue;
  999. case NSstart:
  1000. case NSsign:
  1001. case NSzero:
  1002. state = NSzero;
  1003. continue;
  1004. case NSzerofract:
  1005. case NSpoint:
  1006. dp--;
  1007. state = NSzerofract;
  1008. continue;
  1009. case NSexpsign:
  1010. case NSexp:
  1011. case NSexpdigit:
  1012. exp = exp*10 + (c - '0');
  1013. state = NSexpdigit;
  1014. continue;
  1015. }
  1016. break;
  1017. }
  1018. if(c >= '1' && c <= '9') {
  1019. switch(state) {
  1020. case NSzero:
  1021. case NSstart:
  1022. case NSsign:
  1023. case NSdigit:
  1024. if(rflag)
  1025. c = ~c;
  1026. *kp++ = c;
  1027. cl++;
  1028. nzero = 0;
  1029. dp++;
  1030. state = NSdigit;
  1031. continue;
  1032. case NSzerofract:
  1033. case NSpoint:
  1034. case NSfract:
  1035. if(rflag)
  1036. c = ~c;
  1037. *kp++ = c;
  1038. cl++;
  1039. nzero = 0;
  1040. state = NSfract;
  1041. continue;
  1042. case NSexpsign:
  1043. case NSexp:
  1044. case NSexpdigit:
  1045. exp = exp*10 + (c - '0');
  1046. state = NSexpdigit;
  1047. continue;
  1048. }
  1049. break;
  1050. }
  1051. if(c == '.') {
  1052. switch(state) {
  1053. case NSstart:
  1054. case NSsign:
  1055. state = NSpoint;
  1056. continue;
  1057. case NSzero:
  1058. state = NSzerofract;
  1059. continue;
  1060. case NSdigit:
  1061. state = NSfract;
  1062. continue;
  1063. }
  1064. break;
  1065. }
  1066. if((f->flags & Gflag) && (c == 'e' || c == 'E')) {
  1067. switch(state) {
  1068. case NSdigit:
  1069. case NSfract:
  1070. state = NSexp;
  1071. continue;
  1072. }
  1073. break;
  1074. }
  1075. break;
  1076. }
  1077. switch(state) {
  1078. /*
  1079. * result is zero
  1080. */
  1081. case NSstart:
  1082. case NSsign:
  1083. case NSzero:
  1084. case NSzerofract:
  1085. case NSpoint:
  1086. kp = k->key + k->klen;
  1087. k->klen += 2;
  1088. kp[0] = 0x20; /* between + and - */
  1089. kp[1] = 0;
  1090. return;
  1091. /*
  1092. * result has exponent
  1093. */
  1094. case NSexpsign:
  1095. case NSexp:
  1096. case NSexpdigit:
  1097. if(expsign)
  1098. exp = -exp;
  1099. dp += exp;
  1100. /*
  1101. * result is fixed point number
  1102. */
  1103. case NSdigit:
  1104. case NSfract:
  1105. kp -= nzero;
  1106. cl -= nzero;
  1107. break;
  1108. }
  1109. /*
  1110. * end of number
  1111. */
  1112. c = 0;
  1113. if(rflag)
  1114. c = ~c;
  1115. *kp = c;
  1116. /*
  1117. * sign and exponent
  1118. */
  1119. c = 0x30;
  1120. if(rflag) {
  1121. c = 0x10;
  1122. dp = ~dp;
  1123. }
  1124. kp = k->key + k->klen;
  1125. kp[0] = c;
  1126. kp[1] = (dp >> 8);
  1127. kp[2] = dp;
  1128. k->klen = cl+1;
  1129. }
  1130. void
  1131. dokey_m(Key *k, uint8_t *lp, uint8_t *lpe, Field *f)
  1132. {
  1133. uint8_t *kp;
  1134. Rune r, place[3];
  1135. int c, cl, pc;
  1136. int rflag;
  1137. rflag = f->flags&Rflag;
  1138. pc = 0;
  1139. cl = k->klen;
  1140. kp = k->key + cl;
  1141. for(;;) {
  1142. /*
  1143. * get the character
  1144. */
  1145. if(lp >= lpe)
  1146. break;
  1147. c = *lp;
  1148. if(c >= Runeself) {
  1149. lp += chartorune(&r, (char*)lp);
  1150. c = r;
  1151. } else
  1152. lp++;
  1153. if(c < nelem(f->mapto)) {
  1154. c = f->mapto[c];
  1155. if(c == 0)
  1156. continue;
  1157. }
  1158. place[pc++] = c;
  1159. if(pc < 3)
  1160. continue;
  1161. for(c=11; c>=0; c--)
  1162. if(memcmp(month[c], place, sizeof(place)) == 0)
  1163. break;
  1164. c += 10;
  1165. if(rflag)
  1166. c = ~c;
  1167. *kp++ = c;
  1168. cl++;
  1169. break;
  1170. }
  1171. c = 0;
  1172. if(rflag)
  1173. c = ~c;
  1174. *kp = c;
  1175. k->klen = cl+1;
  1176. }
  1177. void
  1178. dokey_dfi(Key *k, uint8_t *lp, uint8_t *lpe, Field *f)
  1179. {
  1180. uint8_t *kp;
  1181. Rune r;
  1182. int c, cl, n, rflag;
  1183. cl = k->klen;
  1184. kp = k->key + cl;
  1185. rflag = f->flags & Rflag;
  1186. for(;;) {
  1187. /*
  1188. * get the character
  1189. */
  1190. if(lp >= lpe)
  1191. break;
  1192. c = *lp;
  1193. if(c >= Runeself) {
  1194. lp += chartorune(&r, (char*)lp);
  1195. c = r;
  1196. } else
  1197. lp++;
  1198. /*
  1199. * do the various mappings.
  1200. * the common case is handled
  1201. * completely by the table.
  1202. */
  1203. if(c != 0 && c < Runeself) {
  1204. c = f->mapto[c];
  1205. if(c) {
  1206. *kp++ = c;
  1207. cl++;
  1208. }
  1209. continue;
  1210. }
  1211. /*
  1212. * for characters out of range,
  1213. * the table does not do Rflag.
  1214. * ignore is based on mapto[nelem(f->mapto)-1]
  1215. */
  1216. if(c != 0 && c < nelem(f->mapto)) {
  1217. c = f->mapto[c];
  1218. if(c == 0)
  1219. continue;
  1220. } else {
  1221. if(f->mapto[nelem(f->mapto)-1] == 0)
  1222. continue;
  1223. /*
  1224. * consider building maps as necessary
  1225. */
  1226. if(f->flags & Fflag)
  1227. c = tolowerrune(tobaserune(c));
  1228. if(f->flags & Dflag && !isalpharune(c) &&
  1229. !isdigitrune(c) && !isspacerune(c))
  1230. continue;
  1231. if((f->flags & Wflag) && isspacerune(c))
  1232. continue;
  1233. }
  1234. /*
  1235. * put it in the key
  1236. */
  1237. r = c;
  1238. n = runetochar((char*)kp, &r);
  1239. kp += n;
  1240. cl += n;
  1241. if(rflag)
  1242. while(n > 0) {
  1243. kp[-n] = ~kp[-n];
  1244. n--;
  1245. }
  1246. }
  1247. /*
  1248. * end of key
  1249. */
  1250. k->klen = cl+1;
  1251. if(rflag) {
  1252. *kp = ~0;
  1253. return;
  1254. }
  1255. *kp = 0;
  1256. }
  1257. void
  1258. dokey_r(Key *k, uint8_t *lp, uint8_t *lpe, Field *f)
  1259. {
  1260. int cl, n;
  1261. uint8_t *kp;
  1262. n = lpe - lp;
  1263. if(n < 0)
  1264. n = 0;
  1265. cl = k->klen;
  1266. kp = k->key + cl;
  1267. k->klen = cl+n+1;
  1268. lpe -= 3;
  1269. while(lp < lpe) {
  1270. kp[0] = ~lp[0];
  1271. kp[1] = ~lp[1];
  1272. kp[2] = ~lp[2];
  1273. kp[3] = ~lp[3];
  1274. kp += 4;
  1275. lp += 4;
  1276. }
  1277. lpe += 3;
  1278. while(lp < lpe)
  1279. *kp++ = ~*lp++;
  1280. *kp = ~0;
  1281. }
  1282. void
  1283. dokey_(Key *k, uint8_t *lp, uint8_t *lpe, Field *f)
  1284. {
  1285. int n, cl;
  1286. uint8_t *kp;
  1287. n = lpe - lp;
  1288. if(n < 0)
  1289. n = 0;
  1290. cl = k->klen;
  1291. kp = k->key + cl;
  1292. k->klen = cl+n+1;
  1293. memmove(kp, lp, n);
  1294. kp[n] = 0;
  1295. }
  1296. void
  1297. buildkey(Line *l)
  1298. {
  1299. Key *k;
  1300. uint8_t *lp, *lpe;
  1301. int ll, kl, cl, i, n;
  1302. Field *f;
  1303. ll = l->llen - 1;
  1304. kl = 0; /* allocated length */
  1305. cl = 0; /* current length */
  1306. k = 0;
  1307. for(i=1; i<=args.nfield; i++) {
  1308. f = &args.field[i];
  1309. lp = skip(l->line, f->beg1, f->beg2, f->flags&B1flag, 0);
  1310. if(lp == 0)
  1311. lp = l->line + ll;
  1312. lpe = skip(l->line, f->end1, f->end2, f->flags&Bflag, 1);
  1313. if(lpe == 0)
  1314. lpe = l->line + ll;
  1315. n = (lpe - lp) + 1;
  1316. if(n <= 0)
  1317. n = 1;
  1318. if(cl+(n+4) > kl) {
  1319. kl = cl+(n+4);
  1320. k = realloc(k, sizeof(Key) +
  1321. (kl-1)*sizeof(k->key[0]));
  1322. if(k == 0)
  1323. nomem();
  1324. }
  1325. k->klen = cl;
  1326. (*f->dokey)(k, lp, lpe, f);
  1327. cl = k->klen;
  1328. }
  1329. /*
  1330. * global comparisons
  1331. */
  1332. if(!(args.uflag && cl > 0)) {
  1333. f = &args.field[0];
  1334. if(cl+(ll+4) > kl) {
  1335. kl = cl+(ll+4);
  1336. k = realloc(k, sizeof(Key) +
  1337. (kl-1)*sizeof(k->key[0]));
  1338. if(k == 0)
  1339. nomem();
  1340. }
  1341. k->klen = cl;
  1342. (*f->dokey)(k, l->line, l->line+ll, f);
  1343. cl = k->klen;
  1344. }
  1345. l->key = k;
  1346. k->klen = cl;
  1347. if(args.vflag) {
  1348. if(write(2, l->line, l->llen) != l->llen)
  1349. exits("write");
  1350. for(i=0; i<k->klen; i++) {
  1351. fprint(2, " %.2x", k->key[i]);
  1352. if(k->key[i] == 0x00 || k->key[i] == 0xff)
  1353. fprint(2, "\n");
  1354. }
  1355. }
  1356. }
  1357. void
  1358. makemapm(Field *f)
  1359. {
  1360. int i, c;
  1361. for(i=0; i<nelem(f->mapto); i++) {
  1362. c = 1;
  1363. if(i == ' ' || i == '\t')
  1364. c = 0;
  1365. if(i >= 'a' && i <= 'z')
  1366. c = i + ('A' - 'a');
  1367. if(i >= 'A' && i <= 'Z')
  1368. c = i;
  1369. f->mapto[i] = c;
  1370. if(args.vflag) {
  1371. if((i & 15) == 0)
  1372. fprint(2, " ");
  1373. fprint(2, " %.2x", c);
  1374. if((i & 15) == 15)
  1375. fprint(2, "\n");
  1376. }
  1377. }
  1378. }
  1379. void
  1380. makemapd(Field *f)
  1381. {
  1382. int i, c;
  1383. for(i=0; i<nelem(f->mapto); i++) {
  1384. c = i;
  1385. if(f->flags & Iflag)
  1386. if(c < 040 || c > 0176)
  1387. c = -1;
  1388. if((f->flags & Wflag) && c >= 0)
  1389. if(c == ' ' || c == '\t')
  1390. c = -1;
  1391. if((f->flags & Dflag) && c >= 0)
  1392. if(!(c == ' ' || c == '\t' ||
  1393. (c >= 'a' && c <= 'z') ||
  1394. (c >= 'A' && c <= 'Z') ||
  1395. (c >= '0' && c <= '9'))){
  1396. if(!isupperrune(c = toupperrune(c)))
  1397. c = -1;
  1398. }
  1399. if((f->flags & Fflag) && c >= 0)
  1400. c = toupperrune(tobaserune(c));
  1401. if((f->flags & Rflag) && c >= 0 && i > 0 && i < Runeself)
  1402. c = ~c & 0xff;
  1403. if(c < 0)
  1404. c = 0;
  1405. f->mapto[i] = c;
  1406. if(args.vflag) {
  1407. if((i & 15) == 0)
  1408. fprint(2, " ");
  1409. fprint(2, " %.2x", c);
  1410. if((i & 15) == 15)
  1411. fprint(2, "\n");
  1412. }
  1413. }
  1414. }
  1415. Rune* month[12] =
  1416. {
  1417. ljan,
  1418. lfeb,
  1419. lmar,
  1420. lapr,
  1421. lmay,
  1422. ljun,
  1423. ljul,
  1424. laug,
  1425. lsep,
  1426. loct,
  1427. lnov,
  1428. ldec,
  1429. };
  1430. /************** radix sort ***********/
  1431. enum
  1432. {
  1433. Threshold = 14,
  1434. };
  1435. void rsort4(Key***, uint32_t, int);
  1436. void bsort4(Key***, uint32_t, int);
  1437. void
  1438. sort4(void *a, uint32_t n)
  1439. {
  1440. if(n > Threshold)
  1441. rsort4((Key***)a, n, 0);
  1442. else
  1443. bsort4((Key***)a, n, 0);
  1444. }
  1445. void
  1446. rsort4(Key ***a, uint32_t n, int b)
  1447. {
  1448. Key ***ea, ***t, ***u, **t1, **u1, *k;
  1449. Key ***part[257];
  1450. static int32_t count[257];
  1451. int32_t clist[257+257], *cp, *cp1;
  1452. int c, lowc, higc;
  1453. /*
  1454. * pass 1 over all keys,
  1455. * count the number of each key[b].
  1456. * find low count and high count.
  1457. */
  1458. lowc = 256;
  1459. higc = 0;
  1460. ea = a+n;
  1461. for(t=a; t<ea; t++) {
  1462. k = **t;
  1463. n = k->klen;
  1464. if(b >= n) {
  1465. count[256]++;
  1466. continue;
  1467. }
  1468. c = k->key[b];
  1469. n = count[c]++;
  1470. if(n == 0) {
  1471. if(c < lowc)
  1472. lowc = c;
  1473. if(c > higc)
  1474. higc = c;
  1475. }
  1476. }
  1477. /*
  1478. * pass 2 over all counts,
  1479. * put partition pointers in part[c].
  1480. * save compacted indexes and counts
  1481. * in clist[].
  1482. */
  1483. t = a;
  1484. n = count[256];
  1485. clist[0] = n;
  1486. part[256] = t;
  1487. t += n;
  1488. cp1 = clist+1;
  1489. cp = count+lowc;
  1490. for(c=lowc; c<=higc; c++,cp++) {
  1491. n = *cp;
  1492. if(n) {
  1493. cp1[0] = n;
  1494. cp1[1] = c;
  1495. cp1 += 2;
  1496. part[c] = t;
  1497. t += n;
  1498. }
  1499. }
  1500. *cp1 = 0;
  1501. /*
  1502. * pass 3 over all counts.
  1503. * chase lowest pointer in each partition
  1504. * around a permutation until it comes
  1505. * back and is stored where it started.
  1506. * static array, count[], should be
  1507. * reduced to zero entries except maybe
  1508. * count[256].
  1509. */
  1510. for(cp1=clist+1; cp1[0]; cp1+=2) {
  1511. c = cp1[1];
  1512. cp = count+c;
  1513. while(*cp) {
  1514. t1 = *part[c];
  1515. for(;;) {
  1516. k = *t1;
  1517. n = 256;
  1518. if(b < k->klen)
  1519. n = k->key[b];
  1520. u = part[n]++;
  1521. count[n]--;
  1522. u1 = *u;
  1523. *u = t1;
  1524. if(n == c)
  1525. break;
  1526. t1 = u1;
  1527. }
  1528. }
  1529. }
  1530. /*
  1531. * pass 4 over all partitions.
  1532. * call recursively.
  1533. */
  1534. b++;
  1535. t = a + clist[0];
  1536. count[256] = 0;
  1537. for(cp1=clist+1; (n=cp1[0]) != 0; cp1+=2) {
  1538. if(n > Threshold)
  1539. rsort4(t, n, b);
  1540. else
  1541. if(n > 1)
  1542. bsort4(t, n, b);
  1543. t += n;
  1544. }
  1545. }
  1546. /*
  1547. * bubble sort to pick up
  1548. * the pieces.
  1549. */
  1550. void
  1551. bsort4(Key ***a, uint32_t n, int b)
  1552. {
  1553. Key ***i, ***j, ***k, ***l, **t;
  1554. Key *ka, *kb;
  1555. int n1, n2;
  1556. l = a+n;
  1557. j = a;
  1558. loop:
  1559. i = j;
  1560. j++;
  1561. if(j >= l)
  1562. return;
  1563. ka = **i;
  1564. kb = **j;
  1565. n1 = ka->klen - b;
  1566. n2 = kb->klen - b;
  1567. if(n1 > n2)
  1568. n1 = n2;
  1569. if(n1 <= 0)
  1570. goto loop;
  1571. n2 = ka->key[b] - kb->key[b];
  1572. if(n2 == 0)
  1573. n2 = memcmp(ka->key+b, kb->key+b, n1);
  1574. if(n2 <= 0)
  1575. goto loop;
  1576. for(;;) {
  1577. k = i+1;
  1578. t = *k;
  1579. *k = *i;
  1580. *i = t;
  1581. if(i <= a)
  1582. goto loop;
  1583. i--;
  1584. ka = **i;
  1585. kb = *t;
  1586. n1 = ka->klen - b;
  1587. n2 = kb->klen - b;
  1588. if(n1 > n2)
  1589. n1 = n2;
  1590. if(n1 <= 0)
  1591. goto loop;
  1592. n2 = ka->key[b] - kb->key[b];
  1593. if(n2 == 0)
  1594. n2 = memcmp(ka->key+b, kb->key+b, n1);
  1595. if(n2 <= 0)
  1596. goto loop;
  1597. }
  1598. }