sort.c 28 KB

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