string.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /* $Header$ */
  2. /* STRING MANIPULATION AND PRINT ROUTINES */
  3. #include <system.h>
  4. #include "string.h"
  5. #include "nopp.h"
  6. #include "str_params.h"
  7. #include "arith.h"
  8. doprnt(fp, fmt, argp)
  9. File *fp;
  10. char *fmt;
  11. int argp[];
  12. {
  13. char buf[SSIZE];
  14. sys_write(fp, buf, format(buf, fmt, (char *)argp));
  15. }
  16. /*VARARGS1*/
  17. printf(fmt, args)
  18. char *fmt;
  19. char args;
  20. {
  21. char buf[SSIZE];
  22. sys_write(STDOUT, buf, format(buf, fmt, &args));
  23. }
  24. /*VARARGS1*/
  25. fprintf(fp, fmt, args)
  26. File *fp;
  27. char *fmt;
  28. char args;
  29. {
  30. char buf[SSIZE];
  31. sys_write(fp, buf, format(buf, fmt, &args));
  32. }
  33. /*VARARGS1*/
  34. char *
  35. sprintf(buf, fmt, args)
  36. char *buf, *fmt;
  37. char args;
  38. {
  39. buf[format(buf, fmt, &args)] = '\0';
  40. return buf;
  41. }
  42. int
  43. format(buf, fmt, argp)
  44. char *buf, *fmt;
  45. char *argp;
  46. {
  47. register char *pf = fmt, *pa = argp;
  48. register char *pb = buf;
  49. while (*pf) {
  50. if (*pf == '%') {
  51. register width, base, pad, npad;
  52. char *arg;
  53. char cbuf[2];
  54. char *badformat = "<bad format>";
  55. /* get padder */
  56. if (*++pf == '0') {
  57. pad = '0';
  58. ++pf;
  59. }
  60. else
  61. pad = ' ';
  62. /* get width */
  63. width = 0;
  64. while (*pf >= '0' && *pf <= '9')
  65. width = 10 * width + *pf++ - '0';
  66. /* get text and move pa */
  67. if (*pf == 's') {
  68. arg = *(char **)pa;
  69. pa += sizeof(char *);
  70. }
  71. else
  72. if (*pf == 'c') {
  73. cbuf[0] = * (char *) pa;
  74. cbuf[1] = '\0';
  75. pa += sizeof(int);
  76. arg = &cbuf[0];
  77. }
  78. else
  79. if (*pf == 'l') {
  80. /* alignment ??? */
  81. if (base = integral(*++pf)) {
  82. arg = int_str(*(long *)pa, base);
  83. pa += sizeof(long);
  84. }
  85. else {
  86. pf--;
  87. arg = badformat;
  88. }
  89. }
  90. else
  91. if (base = integral(*pf)) {
  92. arg = int_str((long)*(int *)pa, base);
  93. pa += sizeof(int);
  94. }
  95. else
  96. if (*pf == '%')
  97. arg = "%";
  98. else
  99. arg = badformat;
  100. npad = width - strlen(arg);
  101. while (npad-- > 0)
  102. *pb++ = pad;
  103. while (*pb++ = *arg++);
  104. pb--;
  105. pf++;
  106. }
  107. else
  108. *pb++ = *pf++;
  109. }
  110. return pb - buf;
  111. }
  112. integral(c)
  113. {
  114. switch (c) {
  115. case 'b':
  116. return -2;
  117. case 'd':
  118. return 10;
  119. case 'o':
  120. return -8;
  121. case 'u':
  122. return -10;
  123. case 'x':
  124. return -16;
  125. }
  126. return 0;
  127. }
  128. /* Integer to String translator
  129. */
  130. char *
  131. int_str(val, base)
  132. register long val;
  133. register base;
  134. {
  135. /* int_str() is a very simple integer to string converter.
  136. base < 0 : unsigned.
  137. base must be an element of [-16,-2] V [2,16].
  138. */
  139. static char numbuf[MAXWIDTH];
  140. static char vec[] = "0123456789ABCDEF";
  141. register char *p = &numbuf[MAXWIDTH];
  142. int sign = (base > 0);
  143. *--p = '\0'; /* null-terminate string */
  144. if (val) {
  145. if (base > 0) {
  146. if (val < (arith)0) {
  147. if ((val = -val) < (arith)0)
  148. goto overflow;
  149. }
  150. else
  151. sign = 0;
  152. }
  153. else
  154. if (base < 0) { /* unsigned */
  155. base = -base;
  156. if (val < (arith)0) {
  157. register mod, i;
  158. overflow:
  159. /* this takes a rainy Sunday afternoon to explain */
  160. /* ??? */
  161. mod = 0;
  162. for (i = 0; i < 8 * sizeof val; i++) {
  163. mod <<= 1;
  164. if (val < 0)
  165. mod++;
  166. val <<= 1;
  167. if (mod >= base) {
  168. mod -= base;
  169. val++;
  170. }
  171. }
  172. *--p = vec[mod];
  173. }
  174. }
  175. do {
  176. *--p = vec[(int) (val % base)];
  177. val /= base;
  178. } while (val != (arith)0);
  179. if (sign)
  180. *--p = '-'; /* don't forget it !! */
  181. }
  182. else
  183. *--p = '0'; /* just a simple 0 */
  184. return p;
  185. }
  186. /* return negative, zero or positive value if
  187. resp. s < t, s == t or s > t
  188. */
  189. int
  190. strcmp(s, t)
  191. register char *s, *t;
  192. {
  193. while (*s == *t++)
  194. if (*s++ == '\0')
  195. return 0;
  196. return *s - *--t;
  197. }
  198. /* return length of s
  199. */
  200. int
  201. strlen(s)
  202. char *s;
  203. {
  204. register char *b = s;
  205. while (*b++)
  206. ;
  207. return b - s - 1;
  208. }
  209. #ifndef NOPP
  210. /* append t to s
  211. */
  212. char *
  213. strcat(s, t)
  214. register char *s, *t;
  215. {
  216. register char *b = s;
  217. while (*s++)
  218. ;
  219. s--;
  220. while (*s++ = *t++)
  221. ;
  222. return b;
  223. }
  224. /* Copy t into s
  225. */
  226. char *
  227. strcpy(s, t)
  228. register char *s, *t;
  229. {
  230. register char *b = s;
  231. while (*s++ = *t++)
  232. ;
  233. return b;
  234. }
  235. char *
  236. rindex(str, chr)
  237. register char *str, chr;
  238. {
  239. register char *retptr = 0;
  240. while (*str)
  241. if (*str++ == chr)
  242. retptr = &str[-1];
  243. return retptr;
  244. }
  245. #endif NOPP