diff options
-rw-r--r-- | include/time.h | 28 | ||||
-rw-r--r-- | kernel/cpu/idt.c | 45 | ||||
-rw-r--r-- | kernel/cpu/idt.h | 32 | ||||
-rw-r--r-- | kernel/drivers/clock.c | 203 | ||||
-rw-r--r-- | kernel/drivers/tty.c | 27 | ||||
-rw-r--r-- | kernel/drivers/uart.c | 21 | ||||
-rw-r--r-- | kernel/include/comus/cpu.h | 59 | ||||
-rw-r--r-- | kernel/kernel.c | 4 | ||||
-rw-r--r-- | kernel/lib/fputc.c | 1 | ||||
-rw-r--r-- | lib/timetostr.c | 247 |
10 files changed, 357 insertions, 310 deletions
diff --git a/include/time.h b/include/time.h index b3b0fc1..4d339a0 100644 --- a/include/time.h +++ b/include/time.h @@ -12,23 +12,23 @@ #include <stddef.h> typedef struct { - int sec; /// Seconds [0,59] - int min; /// Minutes [0,59] - int hour; /// Hour [0,23] - int mday; /// Day of month [1,31] - int mon; /// Month of year [0,11] - int year; /// Years since 1900 - int wday; /// Day of week [0,6] (Sunday = 0) - int yday; /// Day of year [0,365] - int yn; /// Year number [0,99] - int cen; /// Century [19,20] - int leap; /// If year is a leap year (True == 1) + int sec; /// Seconds [0,59] + int min; /// Minutes [0,59] + int hour; /// Hour [0,23] + int mday; /// Day of month [1,31] + int mon; /// Month of year [0,11] + int year; /// Years since 1900 + int wday; /// Day of week [0,6] (Sunday = 0) + int yday; /// Day of year [0,365] + int yn; /// Year number [0,99] + int cen; /// Century [19,20] + int leap; /// If year is a leap year (True == 1) } time_t; typedef enum { - TZ_UTC = 0, - TZ_EST = -5, - TZ_EDT = -4, + TZ_UTC = 0, + TZ_EST = -5, + TZ_EDT = -4, } timezone_t; /** diff --git a/kernel/cpu/idt.c b/kernel/cpu/idt.c index 3bdbe8d..3929990 100644 --- a/kernel/cpu/idt.c +++ b/kernel/cpu/idt.c @@ -1,7 +1,7 @@ -#include "stdlib.h" #include <lib.h> #include <comus/memory.h> #include <comus/asm.h> +#include <comus/cpu.h> #include "idt.h" #include "pic.h" @@ -70,7 +70,7 @@ void idt_init(void) __asm__ volatile("lidt %0" : : "m"(idtr)); } -static void isr_print_regs(struct isr_regs *regs) +static void isr_print_regs(regs_t *regs) { printf("rax: %#016lx (%lu)\n", regs->rax, regs->rax); printf("rbx: %#016lx (%lu)\n", regs->rbx, regs->rbx); @@ -89,44 +89,43 @@ static void isr_print_regs(struct isr_regs *regs) printf("r14: %#016lx (%lu)\n", regs->r14, regs->r14); printf("r15: %#016lx (%lu)\n", regs->r15, regs->r15); printf("rip: %#016lx (%lu)\n", regs->rip, regs->rip); - printf("rflags: %#016lx (%lu)\n", regs->rflags, regs->rflags); - struct rflags *rflags = (struct rflags *)regs->rflags; + printf("rflags: %#016lx (%lu)\n", (uint64_t)regs->rflags.raw, (uint64_t)regs->rflags.raw); puts("rflags: "); - if (rflags->cf) + if (regs->rflags.cf) puts("CF "); - if (rflags->pf) + if (regs->rflags.pf) puts("PF "); - if (rflags->af) + if (regs->rflags.af) puts("AF "); - if (rflags->zf) + if (regs->rflags.zf) puts("ZF "); - if (rflags->sf) + if (regs->rflags.sf) puts("SF "); - if (rflags->tf) + if (regs->rflags.tf) puts("TF "); - if (rflags->if_) + if (regs->rflags.if_) puts("IF "); - if (rflags->df) + if (regs->rflags.df) puts("DF "); - if (rflags->of) + if (regs->rflags.of) puts("OF "); - if (rflags->iopl) + if (regs->rflags.iopl) puts("IOPL "); - if (rflags->nt) + if (regs->rflags.nt) puts("NT "); - if (rflags->md) + if (regs->rflags.md) puts("MD "); - if (rflags->rf) + if (regs->rflags.rf) puts("RF "); - if (rflags->vm) + if (regs->rflags.vm) puts("VM "); - if (rflags->ac) + if (regs->rflags.ac) puts("AC "); - if (rflags->vif) + if (regs->rflags.vif) puts("VIF "); - if (rflags->vip) + if (regs->rflags.vip) puts("VIP "); - if (rflags->id) + if (regs->rflags.id) puts("ID "); puts("\n"); } @@ -172,7 +171,7 @@ char *EXCEPTIONS[] = { }; void idt_exception_handler(uint64_t exception, uint64_t code, - struct isr_regs *state) + regs_t *state) { uint64_t cr2; diff --git a/kernel/cpu/idt.h b/kernel/cpu/idt.h index 7f1d9e6..99a811d 100644 --- a/kernel/cpu/idt.h +++ b/kernel/cpu/idt.h @@ -11,38 +11,6 @@ #include <stdint.h> -struct isr_regs { - uint64_t r15; - uint64_t r14; - uint64_t r13; - uint64_t r12; - uint64_t r11; - uint64_t r10; - uint64_t r9; - uint64_t r8; - uint64_t rbp; - uint64_t rdi; - uint64_t rsi; - uint64_t rdx; - uint64_t rcx; - uint64_t rbx; - uint64_t rax; - - uint64_t rip; - uint64_t cs; - uint64_t rflags; - uint64_t rsp; - uint64_t ss; -}; - -struct rflags { - uint64_t cf : 1, : 1, pf : 1, : 1, af : 1, : 1, zf : 1, sf : 1, - - tf : 1, if_ : 1, df : 1, of : 1, iopl : 2, nt : 1, md : 1, - - rf : 1, vm : 1, ac : 1, vif : 1, vip : 1, id : 1, : 42; -}; - void idt_init(void); #endif /* idt.h */ diff --git a/kernel/drivers/clock.c b/kernel/drivers/clock.c index 80a44df..dd229dc 100644 --- a/kernel/drivers/clock.c +++ b/kernel/drivers/clock.c @@ -4,16 +4,16 @@ #include <comus/drivers/clock.h> #define CMOS_WRITE_PORT 0x70 -#define CMOS_READ_PORT 0x71 +#define CMOS_READ_PORT 0x71 -#define CMOS_REG_SEC 0x00 -#define CMOS_REG_MIN 0x02 -#define CMOS_REG_HOUR 0x04 -#define CMOS_REG_WDAY 0x06 -#define CMOS_REG_MDAY 0x07 -#define CMOS_REG_MON 0x08 -#define CMOS_REG_YEAR 0x09 -#define CMOS_REG_CEN 0x32 +#define CMOS_REG_SEC 0x00 +#define CMOS_REG_MIN 0x02 +#define CMOS_REG_HOUR 0x04 +#define CMOS_REG_WDAY 0x06 +#define CMOS_REG_MDAY 0x07 +#define CMOS_REG_MON 0x08 +#define CMOS_REG_YEAR 0x09 +#define CMOS_REG_CEN 0x32 // Live buffers to work on data static time_t time; @@ -27,133 +27,140 @@ static time_t curr_localtime; static timezone_t curr_timezone = TZ_UTC; static timezone_t last_timezone = TZ_UTC; -static uint8_t cmos_read(uint8_t reg) { - uint8_t hex, ret; +static uint8_t cmos_read(uint8_t reg) +{ + uint8_t hex, ret; - outb(CMOS_WRITE_PORT, reg); - hex = inb(CMOS_READ_PORT); + outb(CMOS_WRITE_PORT, reg); + hex = inb(CMOS_READ_PORT); - ret = hex & 0x0F; - ret += (hex & 0xF0) / 16 * 10; + ret = hex & 0x0F; + ret += (hex & 0xF0) / 16 * 10; - return ret; + return ret; } -static int mday_offset[12] = { - 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 -}; +static int mday_offset[12] = { 0, 31, 59, 90, 120, 151, + 181, 212, 243, 273, 304, 334 }; -static int month_days[12] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; +static int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -static void update_localtime(void) { +static void update_localtime(void) +{ + int change, max; - int change, max; + // set localtime + localtime = time; - // set localtime - localtime = time; + // if tz is UTC, we dont need to do anythin + if (last_timezone == TZ_UTC) + return; - // if tz is UTC, we dont need to do anythin - if (last_timezone == TZ_UTC) return; + localtime.hour += last_timezone; - localtime.hour += last_timezone; + // check if day rolled over + change = localtime.hour < 0 ? -1 : localtime.hour >= 24 ? 1 : 0; + if (!change) + return; - // check if day rolled over - change = localtime.hour < 0 ? -1 : localtime.hour >= 24 ? 1 : 0; - if (!change) return; + // roll over day + localtime.hour = (localtime.hour + 24) % 24; + localtime.wday = (localtime.wday + change + 7) % 7; + localtime.mday += change; + localtime.yday += change; - // roll over day - localtime.hour = (localtime.hour + 24) % 24; - localtime.wday = (localtime.wday + change + 7) % 7; - localtime.mday += change; - localtime.yday += change; + // check if month rolled over + max = month_days[localtime.mon]; + if (localtime.leap && localtime.mon == 1) + max++; + change = localtime.mday < 0 ? -1 : localtime.mday >= max ? 1 : 0; + if (!change) + return; - // check if month rolled over - max = month_days[localtime.mon]; - if (localtime.leap && localtime.mon == 1) max++; - change = localtime.mday < 0 ? -1 : localtime.mday >= max ? 1 : 0; - if (!change) return; + // roll over month + localtime.mon = (localtime.mon + change + 12) % 12; - // roll over month - localtime.mon = (localtime.mon + change + 12) % 12; + // check if year rolled over + max = localtime.leap ? 366 : 365; + change = localtime.yday < 0 ? -1 : localtime.yday >= max ? 1 : 0; + if (!change) + return; - // check if year rolled over - max = localtime.leap ? 366 : 365; - change = localtime.yday < 0 ? -1 : localtime.yday >= max ? 1 : 0; - if (!change) return; + // roll over year + localtime.yn += change; - // roll over year - localtime.yn += change; - - // check if cen rolled over - change = localtime.yn < 0 ? -1 : localtime.yn >= 100 ? 1 : 0; - if (!change) goto year; - - // roll over cen - localtime.cen += change; + // check if cen rolled over + change = localtime.yn < 0 ? -1 : localtime.yn >= 100 ? 1 : 0; + if (!change) + goto year; + // roll over cen + localtime.cen += change; year: - localtime.year = localtime.yn + localtime.cen * 100; - localtime.leap = localtime.year % 4 == 0 && localtime.year % 100 != 0; - - if (localtime.leap && localtime.yday == -1) - localtime.yday = 365; - else if (localtime.yday == -1) - localtime.yday = 364; - else - localtime.yday = 0; + localtime.year = localtime.yn + localtime.cen * 100; + localtime.leap = localtime.year % 4 == 0 && localtime.year % 100 != 0; - localtime.year -= 1900; + if (localtime.leap && localtime.yday == -1) + localtime.yday = 365; + else if (localtime.yday == -1) + localtime.yday = 364; + else + localtime.yday = 0; + localtime.year -= 1900; } -void clock_update(void) { - time.sec = cmos_read(CMOS_REG_SEC); - time.min = cmos_read(CMOS_REG_MIN); - time.hour = cmos_read(CMOS_REG_HOUR); - time.wday = cmos_read(CMOS_REG_WDAY) - 1; - time.mday = cmos_read(CMOS_REG_MDAY); - time.mon = cmos_read(CMOS_REG_MON) - 1; - time.yn = cmos_read(CMOS_REG_YEAR); - time.cen = 20; +void clock_update(void) +{ + time.sec = cmos_read(CMOS_REG_SEC); + time.min = cmos_read(CMOS_REG_MIN); + time.hour = cmos_read(CMOS_REG_HOUR); + time.wday = cmos_read(CMOS_REG_WDAY) - 1; + time.mday = cmos_read(CMOS_REG_MDAY); + time.mon = cmos_read(CMOS_REG_MON) - 1; + time.yn = cmos_read(CMOS_REG_YEAR); + time.cen = 20; - time.year = time.yn + time.cen * 100; + time.year = time.yn + time.cen * 100; - time.leap = time.year % 4 == 0 && time.year % 100 != 0; + time.leap = time.year % 4 == 0 && time.year % 100 != 0; - time.yday = mday_offset[time.mon] + time.mday; + time.yday = mday_offset[time.mon] + time.mday; - if (time.leap && time.mon > 2) - time.yday++; + if (time.leap && time.mon > 2) + time.yday++; - time.year -= 1900; + time.year -= 1900; - update_localtime(); + update_localtime(); - curr_time = time; - curr_localtime = localtime; + curr_time = time; + curr_localtime = localtime; } -void set_timezone(timezone_t tz) { - curr_timezone = tz; +void set_timezone(timezone_t tz) +{ + curr_timezone = tz; } -time_t get_utctime(void) { - return curr_time; +time_t get_utctime(void) +{ + return curr_time; } -time_t get_localtime(void) { - if (curr_timezone != last_timezone) { - last_timezone = curr_timezone; - update_localtime(); - curr_localtime = localtime; - } - return curr_localtime; +time_t get_localtime(void) +{ + if (curr_timezone != last_timezone) { + last_timezone = curr_timezone; + update_localtime(); + curr_localtime = localtime; + } + return curr_localtime; } -size_t get_systemtime(void) { - return 0; +size_t get_systemtime(void) +{ + return 0; } diff --git a/kernel/drivers/tty.c b/kernel/drivers/tty.c index 74715a2..88e161f 100644 --- a/kernel/drivers/tty.c +++ b/kernel/drivers/tty.c @@ -18,9 +18,10 @@ static uint32_t x, y; static uint8_t fg, bg; // blank color -const uint16_t blank = (uint16_t) 0 | 0 << 12 | 15 << 8; +const uint16_t blank = (uint16_t)0 | 0 << 12 | 15 << 8; -static void term_clear_line(int line) { +static void term_clear_line(int line) +{ if (line < 0 || line >= height) return; for (uint8_t x = 0; x < width; x++) { @@ -29,29 +30,33 @@ static void term_clear_line(int line) { } } -static void term_clear(void) { - for (uint8_t y = 0; y < height; y++) - term_clear_line(y); +static void term_clear(void) +{ + for (uint8_t y = 0; y < height; y++) + term_clear_line(y); } -static void term_scroll(int lines) { +static void term_scroll(int lines) +{ cli(); y -= lines; - if (!lines) return; + if (!lines) + return; if (lines >= height || lines <= -height) { term_clear(); } else if (lines > 0) { memmovev(buffer, buffer + lines * width, 2 * (height - lines) * width); term_clear_line(height - lines); } else { - memmovev(buffer + lines * width, buffer + lines, (height + lines) * width); + memmovev(buffer + lines * width, buffer + lines, + (height + lines) * width); } sti(); } void tty_init(void) { - buffer = mapaddr((void*)VGA_ADDR, width * height * sizeof(uint16_t)); + buffer = mapaddr((void *)VGA_ADDR, width * height * sizeof(uint16_t)); x = 0; y = 0; fg = 15; @@ -99,7 +104,7 @@ void tty_out(char c) // set cursor position on screen const uint16_t pos = y * width + x; outb(0x3D4, 0x0F); - outb(0x3D5, (uint8_t) (pos & 0xFF)); + outb(0x3D5, (uint8_t)(pos & 0xFF)); outb(0x3D4, 0x0E); - outb(0x3D5, (uint8_t) ((pos >> 8) & 0xFF)); + outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF)); } diff --git a/kernel/drivers/uart.c b/kernel/drivers/uart.c index c999e45..6dcfe63 100644 --- a/kernel/drivers/uart.c +++ b/kernel/drivers/uart.c @@ -3,12 +3,14 @@ #define PORT 0x3F8 -int uart_init(void) { +int uart_init(void) +{ outb(PORT + 1, 0x00); // disable interrupts outb(PORT + 3, 0x80); // enable DLAB (divisor latch access bit) outb(PORT + 0, 0x03); // (lo) Set baud divisor to 3 38400 baud outb(PORT + 1, 0x00); // (hi) - outb(PORT + 3, 0x03); // disable DLAB, set 8 bits per word, one stop bit, no parity + outb(PORT + 3, + 0x03); // disable DLAB, set 8 bits per word, one stop bit, no parity outb(PORT + 2, 0xC7); // enable and clear FIFOs, set to maximum threshold outb(PORT + 4, 0x0B); // ??? outb(PORT + 4, 0x1E); // set in loopback mode for test @@ -25,19 +27,24 @@ int uart_init(void) { return 0; } -uint8_t uart_in(void) { +uint8_t uart_in(void) +{ // wait for data to be available - while ((inb(PORT + 5) & 0x01) == 0); + while ((inb(PORT + 5) & 0x01) == 0) + ; return inb(PORT); } -void uart_out(uint8_t ch) { +void uart_out(uint8_t ch) +{ // wait for output to be free - while ((inb(PORT + 5) & 0x20) == 0); + while ((inb(PORT + 5) & 0x20) == 0) + ; outb(PORT, ch); } -void uart_out_str(const char *str) { +void uart_out_str(const char *str) +{ while (*str) uart_out(*str++); } diff --git a/kernel/include/comus/cpu.h b/kernel/include/comus/cpu.h index 58fb33d..a976695 100644 --- a/kernel/include/comus/cpu.h +++ b/kernel/include/comus/cpu.h @@ -9,6 +9,65 @@ #ifndef _CPU_H #define _CPU_H +#include <stdint.h> + +typedef union { + uint64_t raw; + struct { + uint64_t cf : 1; + uint64_t : 1; + uint64_t pf : 1; + uint64_t : 1; + uint64_t af : 1; + uint64_t : 1; + uint64_t zf : 1; + uint64_t sf : 1; + uint64_t tf : 1; + uint64_t if_ : 1; + uint64_t df : 1; + uint64_t of : 1; + uint64_t iopl : 2; + uint64_t nt : 1; + uint64_t md : 1; + uint64_t rf : 1; + uint64_t vm : 1; + uint64_t ac : 1; + uint64_t vif : 1; + uint64_t vip : 1; + uint64_t id : 1; + uint64_t : 42; + }; +} rflags_t; + +typedef struct { + // registers + uint64_t r15; + uint64_t r14; + uint64_t r13; + uint64_t r12; + uint64_t r11; + uint64_t r10; + uint64_t r9; + uint64_t r8; + uint64_t rbp; + uint64_t rdi; + uint64_t rsi; + uint64_t rdx; + uint64_t rcx; + uint64_t rbx; + uint64_t rax; + // instruction pointer + uint64_t rip; + // code segment + uint64_t cs; + // rflags + rflags_t rflags; + // stack pointer + uint64_t rsp; + // stack segment + uint64_t ss; +} regs_t; + /** * Initalize current cpu */ diff --git a/kernel/kernel.c b/kernel/kernel.c index 0b411be..7382a7d 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -2,6 +2,7 @@ #include <comus/memory.h> #include <comus/mboot.h> #include <comus/drivers.h> +#include <comus/fs.h> #include <lib.h> #include <stdio.h> #include <time.h> @@ -25,6 +26,9 @@ void main(long magic, volatile void *mboot) // initalize devices drivers_init(); + // load file systems + fs_init(); + // print current time char date[40]; set_timezone(TZ_EDT); diff --git a/kernel/lib/fputc.c b/kernel/lib/fputc.c index ef9b6f6..0d47cb5 100644 --- a/kernel/lib/fputc.c +++ b/kernel/lib/fputc.c @@ -8,4 +8,3 @@ void fputc(FILE *stream, char c) uart_out(c); tty_out(c); } - diff --git a/lib/timetostr.c b/lib/timetostr.c index 0d4e9a5..fa77362 100644 --- a/lib/timetostr.c +++ b/lib/timetostr.c @@ -1,144 +1,143 @@ #include <lib.h> #include <time.h> -static char* ABB_WEEKDAY[7] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +static char *ABB_WEEKDAY[7] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; -static char* FULL_WEEKDAY[7] = { - "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturady" -}; +static char *FULL_WEEKDAY[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturady" }; -static char* ABB_MONTH[12] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; +static char *ABB_MONTH[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; -static char* FULL_MONTH[12] = { - "January", "Feburary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" +static char *FULL_MONTH[12] = { + "January", "Feburary", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" }; -static char *write_num(unsigned int num, unsigned int pad, char *buf, size_t n) { - size_t digits = 1; - unsigned int x = num; - - while (x /= 10, x > 0) digits++; - if (pad == 0) pad = digits; - - for (size_t i = 0; i < pad; i++) { +static char *write_num(unsigned int num, unsigned int pad, char *buf, size_t n) +{ + size_t digits = 1; + unsigned int x = num; - size_t digit; - if (i >= digits) { - digit = 0; - } else { - digit = num % 10; - num /= 10; - } + while (x /= 10, x > 0) + digits++; + if (pad == 0) + pad = digits; - if (pad - i - 1 >= n) continue; - buf[pad - i - 1] = '0' + digit; + for (size_t i = 0; i < pad; i++) { + size_t digit; + if (i >= digits) { + digit = 0; + } else { + digit = num % 10; + num /= 10; + } - } + if (pad - i - 1 >= n) + continue; + buf[pad - i - 1] = '0' + digit; + } - if (pad > n) pad = n; + if (pad > n) + pad = n; - return buf + pad; + return buf + pad; } -void timetostr(time_t *time, char *format, char *buf, size_t n) { - char *index = buf; - char c; - int space; +void timetostr(time_t *time, char *format, char *buf, size_t n) +{ + char *index = buf; + char c; + int space; - while ( - c = *format++, - space = (buf + n) - index, - c != '\0' && space > 0 - ) { - if (c != '%') { - *index++ = c; - continue; - } else { - c = *format++; - } + while (c = *format++, space = (buf + n) - index, c != '\0' && space > 0) { + if (c != '%') { + *index++ = c; + continue; + } else { + c = *format++; + } - switch (c) { - case '%': - *index++ = '%'; - break; - case 'a': - index = strncpy(index, ABB_WEEKDAY[time->wday], space); - break; - case 'A': - index = strncpy(index, FULL_WEEKDAY[time->wday], space); - break; - case 'b': - case 'h': - index = strncpy(index, ABB_MONTH[time->mon], space); - break; - case 'B': - index = strncpy(index, FULL_MONTH[time->mon], space); - break; - case 'C': - index = write_num(time->cen, 0, index, space); - break; - case 'd': - index = write_num(time->mday, 2, index, space); - break; - case 'H': - index = write_num(time->hour, 2, index, space); - break; - case 'I': - index = write_num((time->hour + 12) % 12 + 1, 2, index, space); - break; - case 'j': - index = write_num(time->yday, 3, index, space); - break; - case 'm': - index = write_num(time->mon + 1, 2, index, space); - break; - case 'M': - index = write_num(time->min, 2, index, space); - break; - case 'n': - *index++ = '\n'; - break; - case 'p': - index = strncpy(index, time->hour > 11 ? "PM" : "AM", space); - break; - case 'P': - index = strncpy(index, time->hour > 11 ? "pm" : "am", space); - break; - case 'q': - index = write_num((time->mon + 3) / 3, 0, index, space); - break; - case 'S': - index = write_num(time->sec, 2, index, space); - break; - case 't': - *index++ = '\t'; - break; - case 'u': - index = write_num(((time->wday + 1 )% 7) + 1, 0, index, space); - break; - case 'w': - index = write_num(time->wday, 0, index, space); - break; - case 'y': - index = write_num(time->yn, 2, index, space); - break; - case 'Y': - index = write_num(time->year + 1900, 0, index, space); - break; - default: { - char b[3] = {'%', c, '\0'}; - index = strncpy(index, b, space); - break; - } - } - } + switch (c) { + case '%': + *index++ = '%'; + break; + case 'a': + index = strncpy(index, ABB_WEEKDAY[time->wday], space); + break; + case 'A': + index = strncpy(index, FULL_WEEKDAY[time->wday], space); + break; + case 'b': + case 'h': + index = strncpy(index, ABB_MONTH[time->mon], space); + break; + case 'B': + index = strncpy(index, FULL_MONTH[time->mon], space); + break; + case 'C': + index = write_num(time->cen, 0, index, space); + break; + case 'd': + index = write_num(time->mday, 2, index, space); + break; + case 'H': + index = write_num(time->hour, 2, index, space); + break; + case 'I': + index = write_num((time->hour + 12) % 12 + 1, 2, index, space); + break; + case 'j': + index = write_num(time->yday, 3, index, space); + break; + case 'm': + index = write_num(time->mon + 1, 2, index, space); + break; + case 'M': + index = write_num(time->min, 2, index, space); + break; + case 'n': + *index++ = '\n'; + break; + case 'p': + index = strncpy(index, time->hour > 11 ? "PM" : "AM", space); + break; + case 'P': + index = strncpy(index, time->hour > 11 ? "pm" : "am", space); + break; + case 'q': + index = write_num((time->mon + 3) / 3, 0, index, space); + break; + case 'S': + index = write_num(time->sec, 2, index, space); + break; + case 't': + *index++ = '\t'; + break; + case 'u': + index = write_num(((time->wday + 1) % 7) + 1, 0, index, space); + break; + case 'w': + index = write_num(time->wday, 0, index, space); + break; + case 'y': + index = write_num(time->yn, 2, index, space); + break; + case 'Y': + index = write_num(time->year + 1900, 0, index, space); + break; + default: { + char b[3] = { '%', c, '\0' }; + index = strncpy(index, b, space); + break; + } + } + } - if (space < 1) - buf[n - 1] = '\0'; - else - *index = '\0'; + if (space < 1) + buf[n - 1] = '\0'; + else + *index = '\0'; } |