sort.c 27 KB

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