|
|
1.1 ! root 1: /* ! 2: * libc/gen/strftime.c ! 3: * C standard date and time library. ! 4: * strftime() ! 5: * ANSI 4.12.3.5. ! 6: * "C" locale-specific time and date formatting, ! 7: * with the locale-dependent stuff wired in here. ! 8: * Special thanks to the ANSI committee for this marvelous idea. ! 9: */ ! 10: ! 11: #include <stddef.h> ! 12: #include <string.h> ! 13: #include <time.h> ! 14: ! 15: /* Forward. */ ! 16: static char *toasc(); ! 17: static char *convert(); ! 18: ! 19: /* Static data. */ ! 20: static const char *weekdays[] = { ! 21: "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ! 22: }; ! 23: static const char *months[] = { ! 24: "January", "February", "March", "April", "May", "June", ! 25: "July", "August", "September", "October", "November", "December" ! 26: }; ! 27: ! 28: size_t ! 29: strftime(s, maxsize, format, timeptr) ! 30: char *s; ! 31: size_t maxsize; ! 32: const char *format; ! 33: const struct tm *timeptr; ! 34: { ! 35: register size_t nchars, i; ! 36: register int j; ! 37: register char *x; ! 38: char c; ! 39: ! 40: for (nchars = 0; ; ) { ! 41: if ((c = *format++) != '%') { ! 42: if (++nchars > maxsize) ! 43: return 0; ! 44: *s++ = c; ! 45: if (c == '\0') ! 46: return --nchars; ! 47: } else { ! 48: ! 49: /* Perform a conversion. */ ! 50: x = NULL; ! 51: switch (c = *format++) { ! 52: ! 53: case 'a': ! 54: case 'A': ! 55: x = weekdays[timeptr->tm_wday]; ! 56: i = (c == 'a') ? 3 : strlen(x); ! 57: break; ! 58: ! 59: case 'b': ! 60: case 'B': ! 61: x = months[timeptr->tm_mon]; ! 62: i = (c == 'b') ? 3 : strlen(x); ! 63: break; ! 64: ! 65: case 'c': ! 66: x = asctime(timeptr); ! 67: i = 24; /* suppress the '\n' */ ! 68: break; ! 69: ! 70: case 'd': ! 71: j = timeptr->tm_mday; ! 72: i = 2; ! 73: break; ! 74: ! 75: case 'H': ! 76: j = timeptr->tm_hour; ! 77: i = 2; ! 78: break; ! 79: ! 80: case 'I': ! 81: if ((j = timeptr->tm_hour % 12) == 0) ! 82: j = 12; ! 83: i = 2; ! 84: break; ! 85: ! 86: case 'j': ! 87: j = timeptr->tm_yday + 1; ! 88: i = 3; ! 89: break; ! 90: ! 91: case 'm': ! 92: j = timeptr->tm_mon + 1; ! 93: i = 2; ! 94: break; ! 95: ! 96: case 'M': ! 97: j = timeptr->tm_min; ! 98: i = 2; ! 99: break; ! 100: ! 101: case 'p': ! 102: x = (timeptr->tm_hour) < 12 ? "AM" : "PM"; ! 103: i = 2; ! 104: break; ! 105: ! 106: case 'S': ! 107: j = timeptr->tm_sec; ! 108: i = 2; ! 109: break; ! 110: ! 111: case 'U': ! 112: j = (timeptr->tm_yday + 7 - timeptr->tm_wday) / 7; ! 113: i = 2; ! 114: break; ! 115: ! 116: case 'w': ! 117: j = (timeptr->tm_yday + 8 - timeptr->tm_wday) / 7; ! 118: if (timeptr->tm_wday == 0) ! 119: --j; ! 120: i = 2; ! 121: break; ! 122: ! 123: case 'W': ! 124: j = timeptr->tm_wday; ! 125: i = 1; ! 126: break; ! 127: ! 128: case 'x': ! 129: x = convert(timeptr->tm_mon+1, ! 130: timeptr->tm_mday, ! 131: timeptr->tm_year, ! 132: '/'); ! 133: i = 8; ! 134: break; ! 135: ! 136: case 'X': ! 137: x = convert(timeptr->tm_hour, ! 138: timeptr->tm_min, ! 139: timeptr->tm_sec, ! 140: ':'); ! 141: i = 8; ! 142: break; ! 143: ! 144: case 'y': ! 145: j = timeptr->tm_year; ! 146: i = 2; ! 147: break; ! 148: ! 149: case 'Y': ! 150: j = timeptr->tm_year + 1900; ! 151: i = 4; ! 152: break; ! 153: ! 154: case 'z': ! 155: x = &tzname[(timeptr->tm_isdst==1) ? 1 :0][0]; ! 156: i = strlen(x); ! 157: break; ! 158: ! 159: /* Default case has undefined behavior. */ ! 160: /* This copies the given character, e.g. "%e" copies "e". */ ! 161: case '%': ! 162: default: ! 163: x = &c; ! 164: i = 1; ! 165: break; ! 166: } ! 167: ! 168: /* Convert j to i ASCII digits if necessary. */ ! 169: if (x == NULL) ! 170: x = toasc(j, i); ! 171: ! 172: /* Copy i characters from x to the result string. */ ! 173: /* If nchars+i == maxsize, there will be no room for NUL. */ ! 174: if ((nchars += i) >= maxsize) ! 175: return 0; ! 176: strncpy(s, x, i); ! 177: s += i; ! 178: } ! 179: } ! 180: } ! 181: ! 182: /* ! 183: * Convert i to n ASCII decimal digits. ! 184: */ ! 185: static ! 186: char * ! 187: toasc(i, n) register unsigned int i, n; ! 188: { ! 189: static char *buf[6]; ! 190: char *cp; ! 191: ! 192: cp = &buf[5]; ! 193: *cp = '\0'; ! 194: while (n--) { ! 195: *--cp = '0' + (i % 10); ! 196: i /= 10; ! 197: } ! 198: return cp; ! 199: } ! 200: ! 201: /* ! 202: * Convert a time or date to "hh:mm:ss" or "mm/dd/yy". ! 203: * The result is not NUL-terminated. ! 204: */ ! 205: static ! 206: char * ! 207: convert(i1, i2, i3, sep) int i1, i2, i3, sep; ! 208: { ! 209: static char buf[8]; ! 210: register char *s; ! 211: ! 212: s = &buf[0]; ! 213: *s++ = '0' + i1 / 10; ! 214: *s++ = '0' + i1 % 10; ! 215: *s++ = sep; ! 216: *s++ = '0' + i2 / 10; ! 217: *s++ = '0' + i2 % 10; ! 218: *s++ = sep; ! 219: *s++ = '0' + i3 / 10; ! 220: *s++ = '0' + i3 % 10; ! 221: return buf; ! 222: } ! 223: ! 224: /* end of libc/gen/strftime.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.