printl.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /* (C) C.D.F. Miller, Heriot-Watt University, March 1984
  2. *
  3. * Permission is hereby given to reproduce or modify this
  4. * software freely, provided that this notice be retained,
  5. * and that no use be made of the software for commercial
  6. * purposes without the express written permission of the
  7. * author.
  8. */
  9. #include <err.h>
  10. #include <lbl.h>
  11. #include "printl.h"
  12. void printr(char, int, FILE *);
  13. static void printd(int, FILE *);
  14. static void printa(char, int, FILE *);
  15. static void auxprinta(char, int, FILE *);
  16. void
  17. labelPrint(Label *lab, FILE *out)
  18. {
  19. rg format f = lab->l_type->t_format;
  20. rg int i;
  21. for (i = 0; i <= lab->l_bottom; i++) {
  22. while (*f) {
  23. if (*f != '%')
  24. putc(*f, out);
  25. else
  26. switch (*++f) {
  27. default:
  28. putc(*f, out);
  29. break;
  30. case '\0':
  31. putc('%', out);
  32. break;
  33. case '0':
  34. printd(lab->l_levels[i] - 1, out);
  35. f++;
  36. goto loopend;
  37. case '1':
  38. printd(lab->l_levels[i], out);
  39. f++;
  40. goto loopend;
  41. case 'i':
  42. case 'I':
  43. printr(*f, lab->l_levels[i],
  44. out);
  45. f++;
  46. goto loopend;
  47. case 'a':
  48. case 'A':
  49. printa(*f, lab->l_levels[i],
  50. out);
  51. f++;
  52. goto loopend;
  53. }
  54. f++;
  55. }
  56. warnx("%sformat too short to print label %s", maybe_loc(), lab->l_name);
  57. break;
  58. loopend:
  59. continue;
  60. }
  61. }
  62. /* Print Decimal */
  63. void
  64. printd(int n, FILE *out)
  65. {
  66. fprintf(out, "%u", n);
  67. }
  68. /* Print Alphabetic
  69. * actually base 26 (digits a-z), displaced by 1!
  70. * a is either "a" or "A" for upper or lower case.
  71. */
  72. void
  73. printa(char a, int n, FILE *out)
  74. {
  75. if (n == 0)
  76. putc('0', out);
  77. else
  78. auxprinta(a, n - 1, out);
  79. }
  80. void
  81. auxprinta(char a, int n, FILE *out)
  82. {
  83. if (n > 25)
  84. auxprinta(a, n / 26 - 1, out);
  85. putc((int)a + n % 26, out);
  86. }
  87. /* Print Roman
  88. * a is either "a" or "A" for upper or lower case.
  89. */
  90. void
  91. printr(char a, int n, FILE *out)
  92. {
  93. if (n == 0) {
  94. putc('0', out);
  95. return;
  96. }
  97. if (n >= 50000) {
  98. putc('!', out);
  99. return;
  100. }
  101. while (n >= 10000)
  102. putc(a + ('Z' - 'I'), out), n -= 10000;
  103. if (n >= 9000)
  104. putc(a + ('M' - 'I'), out), putc(a + ('Z' - 'I'), out), n -= 9000;
  105. if (n >= 5000)
  106. putc(a + ('W' - 'I'), out), n -= 5000;
  107. if (n >= 4000)
  108. putc(a + ('M' - 'I'), out), putc(a + ('W' - 'I'), out), n -= 4000;
  109. while (n >= 1000)
  110. putc(a + ('M' - 'I'), out), n -= 1000;
  111. if (n >= 900)
  112. putc(a + ('C' - 'I'), out), putc(a + ('M' - 'I'), out), n -= 900;
  113. if (n >= 500)
  114. putc(a + ('D' - 'I'), out), n -= 500;
  115. if (n >= 400)
  116. putc(a + ('C' - 'I'), out), putc(a + ('D' - 'I'), out), n -= 400;
  117. while (n >= 100)
  118. putc(a + ('C' - 'I'), out), n -= 100;
  119. if (n >= 90)
  120. putc(a + ('X' - 'I'), out), putc(a + ('C' - 'I'), out), n -= 90;
  121. if (n >= 50)
  122. putc(a + ('L' - 'I'), out), n -= 50;
  123. if (n >= 40)
  124. putc(a + ('X' - 'I'), out), putc(a + ('L' - 'I'), out), n -= 40;
  125. while (n >= 10)
  126. putc(a + ('X' - 'I'), out), n -= 10;
  127. if (n >= 9)
  128. putc(a + ('I' - 'I'), out), putc(a + ('X' - 'I'), out), n -= 9;
  129. if (n >= 5)
  130. putc(a + ('V' - 'I'), out), n -= 5;
  131. if (n >= 4)
  132. putc(a + ('I' - 'I'), out), putc(a + ('V' - 'I'), out), n -= 4;
  133. while (n >= 1)
  134. putc(a + ('I' - 'I'), out), n -= 1;
  135. }