1: /* Output like sprintf to a buffer of specified size. 2: Also takes args differently: pass one pointer to an array of strings 3: in addition to the format string which is separate. 4: Copyright (C) 1985 Richard M. Stallman. 5: 6: This file is part of GNU Emacs. 7: 8: GNU Emacs is distributed in the hope that it will be useful, 9: but WITHOUT ANY WARRANTY. No author or distributor 10: accepts responsibility to anyone for the consequences of using it 11: or for whether it serves any particular purpose or works at all, 12: unless he says so in writing. Refer to the GNU Emacs General Public 13: License for full details. 14: 15: Everyone is granted permission to copy, modify and redistribute 16: GNU Emacs, but only under the conditions described in the 17: GNU Emacs General Public License. A copy of this license is 18: supposed to have been given to you along with GNU Emacs so you 19: can know your rights and responsibilities. It should be in a 20: file named COPYING. Among other things, the copyright notice 21: and this notice must be preserved on all copies. */ 22: 23: 24: #include <stdio.h> 25: #include <ctype.h> 26: 27: doprnt (buffer, bufsize, format, args) 28: char *buffer; 29: register int bufsize; 30: char *format; 31: char **args; 32: { 33: int cnt = 0; /* Number of arg to gobble next */ 34: register char *fmt = format; /* Pointer into format string */ 35: register char *bufptr = buffer; /* Pointer into output buffer.. */ 36: char tembuf[80]; 37: register int tem; 38: char *string; 39: char fmtcpy[20]; 40: int minlen; 41: 42: bufsize--; 43: while (*fmt && bufsize > 0) /* Loop until end of format string or buffer full */ 44: { 45: if (*fmt == '%') /* Check for a '%' character */ 46: { 47: fmt++; 48: /* Copy this one %-spec into fmtcopy. */ 49: string = fmtcpy; 50: *string++ = '%'; 51: while (1) 52: { 53: *string++ = *fmt; 54: if (! (*fmt >= '0' && *fmt <= '9') && *fmt != '-' && *fmt != ' ') 55: break; 56: fmt++; 57: } 58: *string = 0; 59: minlen = 0; 60: switch (*fmt++) 61: { 62: default: 63: error ("Invalid format operation %%%c", fmt[-1]); 64: 65: case 'b': 66: case 'd': 67: case 'o': 68: case 'x': 69: sprintf (tembuf, fmtcpy, args[cnt++]); 70: /* Now copy tembuf into final output, truncating as nec. */ 71: string = tembuf; 72: goto doit; 73: 74: case 's': 75: string = args[cnt++]; 76: if (fmtcpy[1] != 's') 77: minlen = atoi (&fmtcpy[1]); 78: /* Copy string into final output, truncating if no room. */ 79: doit: 80: tem = strlen (string); 81: minlen -= tem; 82: while (minlen > 0 && bufsize > 0) 83: { 84: *bufptr++ = ' '; 85: bufsize--; 86: minlen--; 87: } 88: if (tem > bufsize) 89: tem = bufsize; 90: strncpy (bufptr, string, tem); 91: bufptr += tem; 92: bufsize -= tem; 93: continue; 94: 95: case 'c': 96: *bufptr++ = (int) args[cnt++]; 97: bufsize--; 98: continue; 99: 100: case '%': 101: fmt--; /* Drop thru and this % will be treated as normal */ 102: } 103: } 104: *bufptr++ = *fmt++; /* Just some characters; Copy 'em */ 105: bufsize--; 106: }; 107: 108: *bufptr = 0; /* Make sure our string end with a '\0' */ 109: return bufptr - buffer; 110: }