123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- /* (C) C.D.F. Miller, Heriot-Watt University, March 1984
- *
- * Permission is hereby given to reproduce or modify this
- * software freely, provided that this notice be retained,
- * and that no use be made of the software for commercial
- * purposes without the express written permission of the
- * author.
- */
- #include <err.h>
- #include <lbl.h>
- #include "printl.h"
- void printr(char, int, FILE *);
- static void printd(int, FILE *);
- static void printa(char, int, FILE *);
- static void auxprinta(char, int, FILE *);
- void
- labelPrint(Label *lab, FILE *out)
- {
- rg format f = lab->l_type->t_format;
- rg int i;
- for (i = 0; i <= lab->l_bottom; i++) {
- while (*f) {
- if (*f != '%')
- putc(*f, out);
- else
- switch (*++f) {
- default:
- putc(*f, out);
- break;
- case '\0':
- putc('%', out);
- break;
- case '0':
- printd(lab->l_levels[i] - 1, out);
- f++;
- goto loopend;
- case '1':
- printd(lab->l_levels[i], out);
- f++;
- goto loopend;
- case 'i':
- case 'I':
- printr(*f, lab->l_levels[i],
- out);
- f++;
- goto loopend;
- case 'a':
- case 'A':
- printa(*f, lab->l_levels[i],
- out);
- f++;
- goto loopend;
- }
- f++;
- }
- warnx("%sformat too short to print label %s", maybe_loc(), lab->l_name);
- break;
- loopend:
- continue;
- }
- }
- /* Print Decimal */
- void
- printd(int n, FILE *out)
- {
- fprintf(out, "%u", n);
- }
- /* Print Alphabetic
- * actually base 26 (digits a-z), displaced by 1!
- * a is either "a" or "A" for upper or lower case.
- */
- void
- printa(char a, int n, FILE *out)
- {
- if (n == 0)
- putc('0', out);
- else
- auxprinta(a, n - 1, out);
- }
- void
- auxprinta(char a, int n, FILE *out)
- {
- if (n > 25)
- auxprinta(a, n / 26 - 1, out);
- putc((int)a + n % 26, out);
- }
- /* Print Roman
- * a is either "a" or "A" for upper or lower case.
- */
- void
- printr(char a, int n, FILE *out)
- {
- if (n == 0) {
- putc('0', out);
- return;
- }
- if (n >= 50000) {
- putc('!', out);
- return;
- }
- while (n >= 10000)
- putc(a + ('Z' - 'I'), out), n -= 10000;
- if (n >= 9000)
- putc(a + ('M' - 'I'), out), putc(a + ('Z' - 'I'), out), n -= 9000;
- if (n >= 5000)
- putc(a + ('W' - 'I'), out), n -= 5000;
- if (n >= 4000)
- putc(a + ('M' - 'I'), out), putc(a + ('W' - 'I'), out), n -= 4000;
- while (n >= 1000)
- putc(a + ('M' - 'I'), out), n -= 1000;
- if (n >= 900)
- putc(a + ('C' - 'I'), out), putc(a + ('M' - 'I'), out), n -= 900;
- if (n >= 500)
- putc(a + ('D' - 'I'), out), n -= 500;
- if (n >= 400)
- putc(a + ('C' - 'I'), out), putc(a + ('D' - 'I'), out), n -= 400;
- while (n >= 100)
- putc(a + ('C' - 'I'), out), n -= 100;
- if (n >= 90)
- putc(a + ('X' - 'I'), out), putc(a + ('C' - 'I'), out), n -= 90;
- if (n >= 50)
- putc(a + ('L' - 'I'), out), n -= 50;
- if (n >= 40)
- putc(a + ('X' - 'I'), out), putc(a + ('L' - 'I'), out), n -= 40;
- while (n >= 10)
- putc(a + ('X' - 'I'), out), n -= 10;
- if (n >= 9)
- putc(a + ('I' - 'I'), out), putc(a + ('X' - 'I'), out), n -= 9;
- if (n >= 5)
- putc(a + ('V' - 'I'), out), n -= 5;
- if (n >= 4)
- putc(a + ('I' - 'I'), out), putc(a + ('V' - 'I'), out), n -= 4;
- while (n >= 1)
- putc(a + ('I' - 'I'), out), n -= 1;
- }
|