t8.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. #include "a.h"
  2. /*
  3. * 8. Number Registers
  4. * (Reg register implementation is also here.)
  5. */
  6. /*
  7. * \nx N
  8. * \n(xx N
  9. * \n+x N+=M
  10. * \n-x N-=M
  11. *
  12. * .nr R ±N M
  13. * .af R c
  14. *
  15. * formats
  16. * 1 0, 1, 2, 3, ...
  17. * 001 001, 002, 003, ...
  18. * i 0, i, ii, iii, iv, v, ...
  19. * I 0, I, II, III, IV, V, ...
  20. * a 0, a, b, ..., aa, ab, ..., zz, aaa, ...
  21. * A 0, A, B, ..., AA, AB, ..., ZZ, AAA, ...
  22. *
  23. * \gx \g(xx return format of number register
  24. *
  25. * .rr R
  26. */
  27. typedef struct Reg Reg;
  28. struct Reg
  29. {
  30. Reg *next;
  31. Rune *name;
  32. Rune *val;
  33. Rune *fmt;
  34. int inc;
  35. };
  36. Reg *dslist;
  37. Reg *nrlist;
  38. /*
  39. * Define strings and numbers.
  40. */
  41. void
  42. dsnr(Rune *name, Rune *val, Reg **l)
  43. {
  44. Reg *s;
  45. for(s = *l; s != nil; s = *l){
  46. if(runestrcmp(s->name, name) == 0)
  47. break;
  48. l = &s->next;
  49. }
  50. if(val == nil){
  51. if(s){
  52. *l = s->next;
  53. free(s->val);
  54. free(s->fmt);
  55. free(s);
  56. }
  57. return;
  58. }
  59. if(s == nil){
  60. s = emalloc(sizeof(Reg));
  61. *l = s;
  62. s->name = erunestrdup(name);
  63. }else
  64. free(s->val);
  65. s->val = erunestrdup(val);
  66. }
  67. Rune*
  68. getdsnr(Rune *name, Reg *list)
  69. {
  70. Reg *s;
  71. for(s=list; s; s=s->next)
  72. if(runestrcmp(name, s->name) == 0)
  73. return s->val;
  74. return nil;
  75. }
  76. void
  77. ds(Rune *name, Rune *val)
  78. {
  79. dsnr(name, val, &dslist);
  80. }
  81. void
  82. as(Rune *name, Rune *val)
  83. {
  84. Rune *p, *q;
  85. p = getds(name);
  86. if(p == nil)
  87. p = L("");
  88. q = runemalloc(runestrlen(p)+runestrlen(val)+1);
  89. runestrcpy(q, p);
  90. runestrcat(q, val);
  91. ds(name, q);
  92. free(q);
  93. }
  94. Rune*
  95. getds(Rune *name)
  96. {
  97. return getdsnr(name, dslist);
  98. }
  99. void
  100. printds(int t)
  101. {
  102. int n, total;
  103. Reg *s;
  104. total = 0;
  105. for(s=dslist; s; s=s->next){
  106. if(s->val)
  107. n = runestrlen(s->val);
  108. else
  109. n = 0;
  110. total += n;
  111. if(!t)
  112. fprint(2, "%S\t%d\n", s->name, n);
  113. }
  114. fprint(2, "total\t%d\n", total);
  115. }
  116. void
  117. nr(Rune *name, int val)
  118. {
  119. Rune buf[20];
  120. runesnprint(buf, nelem(buf), "%d", val);
  121. _nr(name, buf);
  122. }
  123. void
  124. af(Rune *name, Rune *fmt)
  125. {
  126. Reg *s;
  127. if(_getnr(name) == nil)
  128. _nr(name, L("0"));
  129. for(s=nrlist; s; s=s->next)
  130. if(runestrcmp(s->name, name) == 0)
  131. s->fmt = erunestrdup(fmt);
  132. }
  133. Rune*
  134. getaf(Rune *name)
  135. {
  136. Reg *s;
  137. for(s=nrlist; s; s=s->next)
  138. if(runestrcmp(s->name, name) == 0)
  139. return s->fmt;
  140. return nil;
  141. }
  142. void
  143. printnr(void)
  144. {
  145. Reg *r;
  146. for(r=nrlist; r; r=r->next)
  147. fprint(2, "%S %S %d\n", r->name, r->val, r->inc);
  148. }
  149. /*
  150. * Some internal number registers are actually strings,
  151. * so provide _ versions to get at them.
  152. */
  153. void
  154. _nr(Rune *name, Rune *val)
  155. {
  156. dsnr(name, val, &nrlist);
  157. }
  158. Rune*
  159. _getnr(Rune *name)
  160. {
  161. return getdsnr(name, nrlist);
  162. }
  163. int
  164. getnr(Rune *name)
  165. {
  166. Rune *p;
  167. p = _getnr(name);
  168. if(p == nil)
  169. return 0;
  170. return eval(p);
  171. }
  172. /* new register */
  173. void
  174. r_nr(int argc, Rune **argv)
  175. {
  176. Reg *s;
  177. if(argc < 2)
  178. return;
  179. if(argc < 3)
  180. nr(argv[1], 0);
  181. else{
  182. if(argv[2][0] == '+')
  183. nr(argv[1], getnr(argv[1])+eval(argv[2]+1));
  184. else if(argv[2][0] == '-')
  185. nr(argv[1], getnr(argv[1])-eval(argv[2]+1));
  186. else
  187. nr(argv[1], eval(argv[2]));
  188. }
  189. if(argc > 3){
  190. for(s=nrlist; s; s=s->next)
  191. if(runestrcmp(s->name, argv[1]) == 0)
  192. s->inc = eval(argv[3]);
  193. }
  194. }
  195. /* assign format */
  196. void
  197. r_af(int argc, Rune **argv)
  198. {
  199. USED(argc);
  200. af(argv[1], argv[2]);
  201. }
  202. /* remove register */
  203. void
  204. r_rr(int argc, Rune **argv)
  205. {
  206. int i;
  207. for(i=1; i<argc; i++)
  208. _nr(argv[i], nil);
  209. }
  210. /* fmt integer in base 26 */
  211. void
  212. alpha(Rune *buf, int n, int a)
  213. {
  214. int i, v;
  215. i = 1;
  216. for(v=n; v>0; v/=26)
  217. i++;
  218. if(i == 0)
  219. i = 1;
  220. buf[i] = 0;
  221. while(i > 0){
  222. buf[--i] = a+n%26;
  223. n /= 26;
  224. }
  225. }
  226. struct romanv {
  227. char *s;
  228. int v;
  229. } romanv[] =
  230. {
  231. "m", 1000,
  232. "cm", 900,
  233. "d", 500,
  234. "cd", 400,
  235. "c", 100,
  236. "xc", 90,
  237. "l", 50,
  238. "xl", 40,
  239. "x", 10,
  240. "ix", 9,
  241. "v", 5,
  242. "iv", 4,
  243. "i", 1
  244. };
  245. /* fmt integer in roman numerals! */
  246. void
  247. roman(Rune *buf, int n, int upper)
  248. {
  249. Rune *p;
  250. char *q;
  251. struct romanv *r;
  252. if(upper)
  253. upper = 'A' - 'a';
  254. if(n >= 5000 || n <= 0){
  255. runestrcpy(buf, L("-"));
  256. return;
  257. }
  258. p = buf;
  259. r = romanv;
  260. while(n > 0){
  261. while(n >= r->v){
  262. for(q=r->s; *q; q++)
  263. *p++ = *q + upper;
  264. n -= r->v;
  265. }
  266. r++;
  267. }
  268. *p = 0;
  269. }
  270. Rune*
  271. getname(void)
  272. {
  273. int i, c, cc;
  274. static Rune buf[100];
  275. /* XXX add [name] syntax as in groff */
  276. c = getnext();
  277. if(c < 0)
  278. return L("");
  279. if(c == '\n'){
  280. warn("newline in name\n");
  281. ungetnext(c);
  282. return L("");
  283. }
  284. if(c == '['){
  285. for(i=0; i<nelem(buf)-1; i++){
  286. if((c = getrune()) < 0)
  287. return L("");
  288. if(c == ']'){
  289. buf[i] = 0;
  290. return buf;
  291. }
  292. buf[i] = c;
  293. }
  294. return L("");
  295. }
  296. if(c != '('){
  297. buf[0] = c;
  298. buf[1] = 0;
  299. return buf;
  300. }
  301. c = getnext();
  302. cc = getnext();
  303. if(c < 0 || cc < 0)
  304. return L("");
  305. if(c == '\n' | cc == '\n'){
  306. warn("newline in \\n");
  307. ungetnext(cc);
  308. if(c == '\n')
  309. ungetnext(c);
  310. }
  311. buf[0] = c;
  312. buf[1] = cc;
  313. buf[2] = 0;
  314. return buf;
  315. }
  316. /* \n - return number register */
  317. int
  318. e_n(void)
  319. {
  320. int inc, v, l;
  321. Rune *name, *fmt, buf[100];
  322. Reg *s;
  323. inc = getnext();
  324. if(inc < 0)
  325. return -1;
  326. if(inc != '+' && inc != '-'){
  327. ungetnext(inc);
  328. inc = 0;
  329. }
  330. name = getname();
  331. if(_getnr(name) == nil)
  332. _nr(name, L("0"));
  333. for(s=nrlist; s; s=s->next){
  334. if(runestrcmp(s->name, name) == 0){
  335. if(s->fmt == nil && !inc && s->val[0]){
  336. /* might be a string! */
  337. pushinputstring(s->val);
  338. return 0;
  339. }
  340. v = eval(s->val);
  341. if(inc){
  342. if(inc == '+')
  343. v += s->inc;
  344. else
  345. v -= s->inc;
  346. runesnprint(buf, nelem(buf), "%d", v);
  347. free(s->val);
  348. s->val = erunestrdup(buf);
  349. }
  350. fmt = s->fmt;
  351. if(fmt == nil)
  352. fmt = L("1");
  353. switch(fmt[0]){
  354. case 'i':
  355. case 'I':
  356. roman(buf, v, fmt[0]=='I');
  357. break;
  358. case 'a':
  359. case 'A':
  360. alpha(buf, v, fmt[0]);
  361. break;
  362. default:
  363. l = runestrlen(fmt);
  364. if(l == 0)
  365. l = 1;
  366. runesnprint(buf, sizeof buf, "%0*d", l, v);
  367. break;
  368. }
  369. pushinputstring(buf);
  370. return 0;
  371. }
  372. }
  373. pushinputstring(L(""));
  374. return 0;
  375. }
  376. /* \g - number register format */
  377. int
  378. e_g(void)
  379. {
  380. Rune *p;
  381. p = getaf(getname());
  382. if(p == nil)
  383. p = L("1");
  384. pushinputstring(p);
  385. return 0;
  386. }
  387. void
  388. r_pnr(int argc, Rune **argv)
  389. {
  390. USED(argc);
  391. USED(argv);
  392. printnr();
  393. }
  394. void
  395. t8init(void)
  396. {
  397. addreq(L("nr"), r_nr, -1);
  398. addreq(L("af"), r_af, 2);
  399. addreq(L("rr"), r_rr, -1);
  400. addreq(L("pnr"), r_pnr, 0);
  401. addesc('n', e_n, CopyMode|ArgMode|HtmlMode);
  402. addesc('g', e_g, 0);
  403. }