15b81b6b3SRodney W. Grimes /* 25b81b6b3SRodney W. Grimes * Mach Operating System 35b81b6b3SRodney W. Grimes * Copyright (c) 1991,1990 Carnegie Mellon University 45b81b6b3SRodney W. Grimes * All Rights Reserved. 55b81b6b3SRodney W. Grimes * 65b81b6b3SRodney W. Grimes * Permission to use, copy, modify and distribute this software and its 75b81b6b3SRodney W. Grimes * documentation is hereby granted, provided that both the copyright 85b81b6b3SRodney W. Grimes * notice and this permission notice appear in all copies of the 95b81b6b3SRodney W. Grimes * software, derivative works or modified versions, and any portions 105b81b6b3SRodney W. Grimes * thereof, and that both notices appear in supporting documentation. 115b81b6b3SRodney W. Grimes * 125b81b6b3SRodney W. Grimes * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 135b81b6b3SRodney W. Grimes * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 145b81b6b3SRodney W. Grimes * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 155b81b6b3SRodney W. Grimes * 165b81b6b3SRodney W. Grimes * Carnegie Mellon requests users of this software to return to 175b81b6b3SRodney W. Grimes * 185b81b6b3SRodney W. Grimes * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 195b81b6b3SRodney W. Grimes * School of Computer Science 205b81b6b3SRodney W. Grimes * Carnegie Mellon University 215b81b6b3SRodney W. Grimes * Pittsburgh PA 15213-3890 225b81b6b3SRodney W. Grimes * 235b81b6b3SRodney W. Grimes * any improvements or extensions that they make and grant Carnegie the 245b81b6b3SRodney W. Grimes * rights to redistribute these changes. 255b81b6b3SRodney W. Grimes * 26058284fcSBruce Evans * $Id: db_output.c,v 1.11 1995/05/30 07:57:02 rgrimes Exp $ 275b81b6b3SRodney W. Grimes */ 280edf66ecSRodney W. Grimes 295b81b6b3SRodney W. Grimes /* 305b81b6b3SRodney W. Grimes * Author: David B. Golub, Carnegie Mellon University 315b81b6b3SRodney W. Grimes * Date: 7/90 325b81b6b3SRodney W. Grimes */ 335b81b6b3SRodney W. Grimes 345b81b6b3SRodney W. Grimes /* 355b81b6b3SRodney W. Grimes * Printf and character output for debugger. 365b81b6b3SRodney W. Grimes */ 375b81b6b3SRodney W. Grimes 38f540b106SGarrett Wollman #include <sys/param.h> 39f540b106SGarrett Wollman #include <sys/systm.h> 40f540b106SGarrett Wollman #include <machine/stdarg.h> 41f540b106SGarrett Wollman #include <ddb/ddb.h> 42058284fcSBruce Evans #include <ddb/db_output.h> 43f540b106SGarrett Wollman #include <machine/cons.h> 445b81b6b3SRodney W. Grimes 455b81b6b3SRodney W. Grimes /* 465b81b6b3SRodney W. Grimes * Character output - tracks position in line. 475b81b6b3SRodney W. Grimes * To do this correctly, we should know how wide 485b81b6b3SRodney W. Grimes * the output device is - then we could zero 495b81b6b3SRodney W. Grimes * the line position when the output device wraps 505b81b6b3SRodney W. Grimes * around to the start of the next line. 515b81b6b3SRodney W. Grimes * 525b81b6b3SRodney W. Grimes * Instead, we count the number of spaces printed 535b81b6b3SRodney W. Grimes * since the last printing character so that we 545b81b6b3SRodney W. Grimes * don't print trailing spaces. This avoids most 555b81b6b3SRodney W. Grimes * of the wraparounds. 565b81b6b3SRodney W. Grimes */ 575b81b6b3SRodney W. Grimes int db_output_position = 0; /* output column */ 585b81b6b3SRodney W. Grimes int db_last_non_space = 0; /* last non-space character */ 595b81b6b3SRodney W. Grimes int db_tab_stop_width = 8; /* how wide are tab stops? */ 605b81b6b3SRodney W. Grimes #define NEXT_TAB(i) \ 615b81b6b3SRodney W. Grimes ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width) 625b81b6b3SRodney W. Grimes int db_max_width = 80; /* output line width */ 635b81b6b3SRodney W. Grimes 64058284fcSBruce Evans static char *db_ksprintn __P((u_long ul, int base, int *lenp)); 65058284fcSBruce Evans static void db_printf_guts __P((const char *, va_list)); 665b81b6b3SRodney W. Grimes 675b81b6b3SRodney W. Grimes /* 685b81b6b3SRodney W. Grimes * Force pending whitespace. 695b81b6b3SRodney W. Grimes */ 705b81b6b3SRodney W. Grimes void 715b81b6b3SRodney W. Grimes db_force_whitespace() 725b81b6b3SRodney W. Grimes { 735b81b6b3SRodney W. Grimes register int last_print, next_tab; 745b81b6b3SRodney W. Grimes 755b81b6b3SRodney W. Grimes last_print = db_last_non_space; 765b81b6b3SRodney W. Grimes while (last_print < db_output_position) { 775b81b6b3SRodney W. Grimes next_tab = NEXT_TAB(last_print); 785b81b6b3SRodney W. Grimes if (next_tab <= db_output_position) { 795b81b6b3SRodney W. Grimes while (last_print < next_tab) { /* DON'T send a tab!!! */ 805b81b6b3SRodney W. Grimes cnputc(' '); 815b81b6b3SRodney W. Grimes last_print++; 825b81b6b3SRodney W. Grimes } 835b81b6b3SRodney W. Grimes } 845b81b6b3SRodney W. Grimes else { 855b81b6b3SRodney W. Grimes cnputc(' '); 865b81b6b3SRodney W. Grimes last_print++; 875b81b6b3SRodney W. Grimes } 885b81b6b3SRodney W. Grimes } 895b81b6b3SRodney W. Grimes db_last_non_space = db_output_position; 905b81b6b3SRodney W. Grimes } 915b81b6b3SRodney W. Grimes 925b81b6b3SRodney W. Grimes /* 935b81b6b3SRodney W. Grimes * Output character. Buffer whitespace. 945b81b6b3SRodney W. Grimes */ 95381fe1aaSGarrett Wollman void 965b81b6b3SRodney W. Grimes db_putchar(c) 975b81b6b3SRodney W. Grimes int c; /* character to output */ 985b81b6b3SRodney W. Grimes { 995b81b6b3SRodney W. Grimes if (c > ' ' && c <= '~') { 1005b81b6b3SRodney W. Grimes /* 1015b81b6b3SRodney W. Grimes * Printing character. 1025b81b6b3SRodney W. Grimes * If we have spaces to print, print them first. 1035b81b6b3SRodney W. Grimes * Use tabs if possible. 1045b81b6b3SRodney W. Grimes */ 1055b81b6b3SRodney W. Grimes db_force_whitespace(); 1065b81b6b3SRodney W. Grimes cnputc(c); 1075b81b6b3SRodney W. Grimes db_output_position++; 1085b81b6b3SRodney W. Grimes db_last_non_space = db_output_position; 1095b81b6b3SRodney W. Grimes } 1105b81b6b3SRodney W. Grimes else if (c == '\n') { 1118a129caeSDavid Greenman /* Newline */ 1128a129caeSDavid Greenman cnputc(c); 1138a129caeSDavid Greenman db_output_position = 0; 1148a129caeSDavid Greenman db_last_non_space = 0; 1158a129caeSDavid Greenman db_check_interrupt(); 1168a129caeSDavid Greenman } 1178a129caeSDavid Greenman else if (c == '\r') { 1185b81b6b3SRodney W. Grimes /* Return */ 1195b81b6b3SRodney W. Grimes cnputc(c); 1205b81b6b3SRodney W. Grimes db_output_position = 0; 1215b81b6b3SRodney W. Grimes db_last_non_space = 0; 1225b81b6b3SRodney W. Grimes db_check_interrupt(); 1235b81b6b3SRodney W. Grimes } 1245b81b6b3SRodney W. Grimes else if (c == '\t') { 1255b81b6b3SRodney W. Grimes /* assume tabs every 8 positions */ 1265b81b6b3SRodney W. Grimes db_output_position = NEXT_TAB(db_output_position); 1275b81b6b3SRodney W. Grimes } 1285b81b6b3SRodney W. Grimes else if (c == ' ') { 1295b81b6b3SRodney W. Grimes /* space */ 1305b81b6b3SRodney W. Grimes db_output_position++; 1315b81b6b3SRodney W. Grimes } 1325b81b6b3SRodney W. Grimes else if (c == '\007') { 1335b81b6b3SRodney W. Grimes /* bell */ 1345b81b6b3SRodney W. Grimes cnputc(c); 1355b81b6b3SRodney W. Grimes } 1365b81b6b3SRodney W. Grimes /* other characters are assumed non-printing */ 1375b81b6b3SRodney W. Grimes } 1385b81b6b3SRodney W. Grimes 1395b81b6b3SRodney W. Grimes /* 1405b81b6b3SRodney W. Grimes * Return output position 1415b81b6b3SRodney W. Grimes */ 1425b81b6b3SRodney W. Grimes int 1435b81b6b3SRodney W. Grimes db_print_position() 1445b81b6b3SRodney W. Grimes { 1455b81b6b3SRodney W. Grimes return (db_output_position); 1465b81b6b3SRodney W. Grimes } 1475b81b6b3SRodney W. Grimes 1485b81b6b3SRodney W. Grimes /* 1495b81b6b3SRodney W. Grimes * Printing 1505b81b6b3SRodney W. Grimes */ 151381fe1aaSGarrett Wollman void 152381fe1aaSGarrett Wollman db_printf(const char *fmt, ...) 1535b81b6b3SRodney W. Grimes { 1545b81b6b3SRodney W. Grimes va_list listp; 1555b81b6b3SRodney W. Grimes va_start(listp, fmt); 1565b81b6b3SRodney W. Grimes db_printf_guts (fmt, listp); 1575b81b6b3SRodney W. Grimes va_end(listp); 1585b81b6b3SRodney W. Grimes } 1595b81b6b3SRodney W. Grimes 1605b81b6b3SRodney W. Grimes /* alternate name */ 1615b81b6b3SRodney W. Grimes 1625b81b6b3SRodney W. Grimes /*VARARGS1*/ 163381fe1aaSGarrett Wollman void 164058284fcSBruce Evans kdbprintf(const char *fmt, ...) 1655b81b6b3SRodney W. Grimes { 1665b81b6b3SRodney W. Grimes va_list listp; 1675b81b6b3SRodney W. Grimes va_start(listp, fmt); 1685b81b6b3SRodney W. Grimes db_printf_guts (fmt, listp); 1695b81b6b3SRodney W. Grimes va_end(listp); 1705b81b6b3SRodney W. Grimes } 1715b81b6b3SRodney W. Grimes 1725b81b6b3SRodney W. Grimes /* 173572de915SRodney W. Grimes * End line if too long. 174572de915SRodney W. Grimes */ 175572de915SRodney W. Grimes void 176572de915SRodney W. Grimes db_end_line() 177572de915SRodney W. Grimes { 178572de915SRodney W. Grimes if (db_output_position >= db_max_width) 179572de915SRodney W. Grimes db_printf("\n"); 180572de915SRodney W. Grimes } 181572de915SRodney W. Grimes 182572de915SRodney W. Grimes /* 1835b81b6b3SRodney W. Grimes * Put a number (base <= 16) in a buffer in reverse order; return an 1845b81b6b3SRodney W. Grimes * optional length and a pointer to the NULL terminated (preceded?) 1855b81b6b3SRodney W. Grimes * buffer. 1865b81b6b3SRodney W. Grimes */ 1875b81b6b3SRodney W. Grimes static char * 1885b81b6b3SRodney W. Grimes db_ksprintn(ul, base, lenp) 1895b81b6b3SRodney W. Grimes register u_long ul; 1905b81b6b3SRodney W. Grimes register int base, *lenp; 1915b81b6b3SRodney W. Grimes { /* A long in base 8, plus NULL. */ 1925b81b6b3SRodney W. Grimes static char buf[sizeof(long) * NBBY / 3 + 2]; 1935b81b6b3SRodney W. Grimes register char *p; 1945b81b6b3SRodney W. Grimes 1955b81b6b3SRodney W. Grimes p = buf; 1965b81b6b3SRodney W. Grimes do { 1975b81b6b3SRodney W. Grimes *++p = "0123456789abcdef"[ul % base]; 1985b81b6b3SRodney W. Grimes } while (ul /= base); 1995b81b6b3SRodney W. Grimes if (lenp) 2005b81b6b3SRodney W. Grimes *lenp = p - buf; 2015b81b6b3SRodney W. Grimes return (p); 2025b81b6b3SRodney W. Grimes } 2035b81b6b3SRodney W. Grimes 204381fe1aaSGarrett Wollman static void 2055b81b6b3SRodney W. Grimes db_printf_guts(fmt, ap) 2065b81b6b3SRodney W. Grimes register const char *fmt; 2075b81b6b3SRodney W. Grimes va_list ap; 2085b81b6b3SRodney W. Grimes { 2095b81b6b3SRodney W. Grimes register char *p; 2105b81b6b3SRodney W. Grimes register int ch, n; 2115b81b6b3SRodney W. Grimes u_long ul; 2125b81b6b3SRodney W. Grimes int base, lflag, tmp, width; 2135b81b6b3SRodney W. Grimes char padc; 2145b81b6b3SRodney W. Grimes int ladjust; 2155b81b6b3SRodney W. Grimes int sharpflag; 2165b81b6b3SRodney W. Grimes int neg; 2175b81b6b3SRodney W. Grimes 2185b81b6b3SRodney W. Grimes for (;;) { 2195b81b6b3SRodney W. Grimes padc = ' '; 2205b81b6b3SRodney W. Grimes width = 0; 2215b81b6b3SRodney W. Grimes while ((ch = *(u_char *)fmt++) != '%') { 2225b81b6b3SRodney W. Grimes if (ch == '\0') 2235b81b6b3SRodney W. Grimes return; 2245b81b6b3SRodney W. Grimes db_putchar(ch); 2255b81b6b3SRodney W. Grimes } 2265b81b6b3SRodney W. Grimes lflag = 0; 2275b81b6b3SRodney W. Grimes ladjust = 0; 2285b81b6b3SRodney W. Grimes sharpflag = 0; 2295b81b6b3SRodney W. Grimes neg = 0; 2305b81b6b3SRodney W. Grimes reswitch: switch (ch = *(u_char *)fmt++) { 2315b81b6b3SRodney W. Grimes case '0': 2325b81b6b3SRodney W. Grimes padc = '0'; 2335b81b6b3SRodney W. Grimes goto reswitch; 2345b81b6b3SRodney W. Grimes case '1': case '2': case '3': case '4': 2355b81b6b3SRodney W. Grimes case '5': case '6': case '7': case '8': case '9': 2365b81b6b3SRodney W. Grimes for (width = 0;; ++fmt) { 2375b81b6b3SRodney W. Grimes width = width * 10 + ch - '0'; 2385b81b6b3SRodney W. Grimes ch = *fmt; 2395b81b6b3SRodney W. Grimes if (ch < '0' || ch > '9') 2405b81b6b3SRodney W. Grimes break; 2415b81b6b3SRodney W. Grimes } 2425b81b6b3SRodney W. Grimes goto reswitch; 2435b81b6b3SRodney W. Grimes case 'l': 2445b81b6b3SRodney W. Grimes lflag = 1; 2455b81b6b3SRodney W. Grimes goto reswitch; 2465b81b6b3SRodney W. Grimes case '-': 2475b81b6b3SRodney W. Grimes ladjust = 1; 2485b81b6b3SRodney W. Grimes goto reswitch; 2495b81b6b3SRodney W. Grimes case '#': 2505b81b6b3SRodney W. Grimes sharpflag = 1; 2515b81b6b3SRodney W. Grimes goto reswitch; 2525b81b6b3SRodney W. Grimes case 'b': 2535b81b6b3SRodney W. Grimes ul = va_arg(ap, int); 2545b81b6b3SRodney W. Grimes p = va_arg(ap, char *); 255169cd910SPoul-Henning Kamp for (p = db_ksprintn(ul, *p++, NULL); *p;p--) 256169cd910SPoul-Henning Kamp db_putchar(*p); 2575b81b6b3SRodney W. Grimes 2585b81b6b3SRodney W. Grimes if (!ul) 2595b81b6b3SRodney W. Grimes break; 2605b81b6b3SRodney W. Grimes 261169cd910SPoul-Henning Kamp for (tmp = 0; *p;) { 262169cd910SPoul-Henning Kamp n = *p++; 2635b81b6b3SRodney W. Grimes if (ul & (1 << (n - 1))) { 2645b81b6b3SRodney W. Grimes db_putchar(tmp ? ',' : '<'); 2655b81b6b3SRodney W. Grimes for (; (n = *p) > ' '; ++p) 2665b81b6b3SRodney W. Grimes db_putchar(n); 2675b81b6b3SRodney W. Grimes tmp = 1; 2685b81b6b3SRodney W. Grimes } else 2695b81b6b3SRodney W. Grimes for (; *p > ' '; ++p); 2705b81b6b3SRodney W. Grimes } 2715b81b6b3SRodney W. Grimes if (tmp) 2725b81b6b3SRodney W. Grimes db_putchar('>'); 2735b81b6b3SRodney W. Grimes break; 2745b81b6b3SRodney W. Grimes case '*': 2755b81b6b3SRodney W. Grimes width = va_arg (ap, int); 2765b81b6b3SRodney W. Grimes if (width < 0) { 2775b81b6b3SRodney W. Grimes ladjust = !ladjust; 2785b81b6b3SRodney W. Grimes width = -width; 2795b81b6b3SRodney W. Grimes } 2805b81b6b3SRodney W. Grimes goto reswitch; 2815b81b6b3SRodney W. Grimes case 'c': 2825b81b6b3SRodney W. Grimes db_putchar(va_arg(ap, int)); 2835b81b6b3SRodney W. Grimes break; 2845b81b6b3SRodney W. Grimes case 's': 2855b81b6b3SRodney W. Grimes p = va_arg(ap, char *); 286d2984da1SBruce Evans if (p == NULL) 287d2984da1SBruce Evans p = "(null)"; 2885b81b6b3SRodney W. Grimes width -= strlen (p); 2895b81b6b3SRodney W. Grimes if (!ladjust && width > 0) 2905b81b6b3SRodney W. Grimes while (width--) 2915b81b6b3SRodney W. Grimes db_putchar (padc); 292169cd910SPoul-Henning Kamp for (;*p;p++) 293169cd910SPoul-Henning Kamp db_putchar(*p); 2945b81b6b3SRodney W. Grimes if (ladjust && width > 0) 2955b81b6b3SRodney W. Grimes while (width--) 2965b81b6b3SRodney W. Grimes db_putchar (padc); 2975b81b6b3SRodney W. Grimes break; 2985b81b6b3SRodney W. Grimes case 'r': 2995b81b6b3SRodney W. Grimes ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 3005b81b6b3SRodney W. Grimes if ((long)ul < 0) { 3015b81b6b3SRodney W. Grimes neg = 1; 3025b81b6b3SRodney W. Grimes ul = -(long)ul; 3035b81b6b3SRodney W. Grimes } 3045b81b6b3SRodney W. Grimes base = db_radix; 3055b81b6b3SRodney W. Grimes if (base < 8 || base > 16) 3065b81b6b3SRodney W. Grimes base = 10; 3075b81b6b3SRodney W. Grimes goto number; 3085b81b6b3SRodney W. Grimes case 'n': 3095b81b6b3SRodney W. Grimes ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 3105b81b6b3SRodney W. Grimes base = db_radix; 3115b81b6b3SRodney W. Grimes if (base < 8 || base > 16) 3125b81b6b3SRodney W. Grimes base = 10; 3135b81b6b3SRodney W. Grimes goto number; 3145b81b6b3SRodney W. Grimes case 'd': 3155b81b6b3SRodney W. Grimes ul = lflag ? va_arg(ap, long) : va_arg(ap, int); 3165b81b6b3SRodney W. Grimes if ((long)ul < 0) { 3175b81b6b3SRodney W. Grimes neg = 1; 3185b81b6b3SRodney W. Grimes ul = -(long)ul; 3195b81b6b3SRodney W. Grimes } 3205b81b6b3SRodney W. Grimes base = 10; 3215b81b6b3SRodney W. Grimes goto number; 3225b81b6b3SRodney W. Grimes case 'o': 3235b81b6b3SRodney W. Grimes ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 3245b81b6b3SRodney W. Grimes base = 8; 3255b81b6b3SRodney W. Grimes goto number; 3265b81b6b3SRodney W. Grimes case 'u': 3275b81b6b3SRodney W. Grimes ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 3285b81b6b3SRodney W. Grimes base = 10; 3295b81b6b3SRodney W. Grimes goto number; 3305b81b6b3SRodney W. Grimes case 'z': 3315b81b6b3SRodney W. Grimes ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 3325b81b6b3SRodney W. Grimes if ((long)ul < 0) { 3335b81b6b3SRodney W. Grimes neg = 1; 3345b81b6b3SRodney W. Grimes ul = -(long)ul; 3355b81b6b3SRodney W. Grimes } 3365b81b6b3SRodney W. Grimes base = 16; 3375b81b6b3SRodney W. Grimes goto number; 3385b81b6b3SRodney W. Grimes case 'x': 3395b81b6b3SRodney W. Grimes ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 3405b81b6b3SRodney W. Grimes base = 16; 3415b81b6b3SRodney W. Grimes number: p = (char *)db_ksprintn(ul, base, &tmp); 3425b81b6b3SRodney W. Grimes if (sharpflag && ul != 0) { 3435b81b6b3SRodney W. Grimes if (base == 8) 3445b81b6b3SRodney W. Grimes tmp++; 3455b81b6b3SRodney W. Grimes else if (base == 16) 3465b81b6b3SRodney W. Grimes tmp += 2; 3475b81b6b3SRodney W. Grimes } 3485b81b6b3SRodney W. Grimes if (neg) 3495b81b6b3SRodney W. Grimes tmp++; 3505b81b6b3SRodney W. Grimes 3515b81b6b3SRodney W. Grimes if (!ladjust && width && (width -= tmp) > 0) 3525b81b6b3SRodney W. Grimes while (width--) 3535b81b6b3SRodney W. Grimes db_putchar(padc); 3545b81b6b3SRodney W. Grimes if (neg) 3555b81b6b3SRodney W. Grimes db_putchar ('-'); 3565b81b6b3SRodney W. Grimes if (sharpflag && ul != 0) { 3575b81b6b3SRodney W. Grimes if (base == 8) { 3585b81b6b3SRodney W. Grimes db_putchar ('0'); 3595b81b6b3SRodney W. Grimes } else if (base == 16) { 3605b81b6b3SRodney W. Grimes db_putchar ('0'); 3615b81b6b3SRodney W. Grimes db_putchar ('x'); 3625b81b6b3SRodney W. Grimes } 3635b81b6b3SRodney W. Grimes } 3645b81b6b3SRodney W. Grimes if (ladjust && width && (width -= tmp) > 0) 3655b81b6b3SRodney W. Grimes while (width--) 3665b81b6b3SRodney W. Grimes db_putchar(padc); 3675b81b6b3SRodney W. Grimes 368169cd910SPoul-Henning Kamp for (;*p;p--) 369169cd910SPoul-Henning Kamp db_putchar(*p); 3705b81b6b3SRodney W. Grimes break; 3715b81b6b3SRodney W. Grimes default: 3725b81b6b3SRodney W. Grimes db_putchar('%'); 3735b81b6b3SRodney W. Grimes if (lflag) 3745b81b6b3SRodney W. Grimes db_putchar('l'); 3755b81b6b3SRodney W. Grimes /* FALLTHROUGH */ 3765b81b6b3SRodney W. Grimes case '%': 3775b81b6b3SRodney W. Grimes db_putchar(ch); 3785b81b6b3SRodney W. Grimes } 3795b81b6b3SRodney W. Grimes } 3805b81b6b3SRodney W. Grimes } 381