summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-04 12:00:48 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-04 12:00:48 -0400
commitceef8e2d87ec60042827e6d6aaf73b6df774051c (patch)
tree16721f404e8aeeba05d8769ceabab8334ed4d176
parentswitch to c11 (diff)
downloadcomus-ceef8e2d87ec60042827e6d6aaf73b6df774051c.tar.gz
comus-ceef8e2d87ec60042827e6d6aaf73b6df774051c.tar.bz2
comus-ceef8e2d87ec60042827e6d6aaf73b6df774051c.zip
fmt
-rw-r--r--include/time.h28
-rw-r--r--kernel/cpu/idt.c45
-rw-r--r--kernel/cpu/idt.h32
-rw-r--r--kernel/drivers/clock.c203
-rw-r--r--kernel/drivers/tty.c27
-rw-r--r--kernel/drivers/uart.c21
-rw-r--r--kernel/include/comus/cpu.h59
-rw-r--r--kernel/kernel.c4
-rw-r--r--kernel/lib/fputc.c1
-rw-r--r--lib/timetostr.c247
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';
}