Kaynağa Gözat

feat(gblibc): add {ge,pu}tc_unlocked

greatbridf 2 yıl önce
ebeveyn
işleme
a3b9f3e011
2 değiştirilmiş dosya ile 75 ekleme ve 25 silme
  1. 10 3
      gblibc/include/stdio.h
  2. 65 22
      gblibc/src/stdio.c

+ 10 - 3
gblibc/include/stdio.h

@@ -16,16 +16,20 @@ extern "C" {
 
 typedef struct __io_file {
     int fd;
+    uint32_t flags;
+
     char* rbuf;
-    char* wbuf;
     size_t rpos;
-    size_t wpos;
+    size_t rcnt;
     size_t rbsz;
+
+    char* wbuf;
+    size_t wpos;
     size_t wbsz;
-    uint32_t flags;
 } FILE;
 
 int putchar(int character);
+int getchar(void);
 
 int puts(const char* str);
 char* gets(char* str);
@@ -44,9 +48,12 @@ FILE* fopen(const char* path, const char* mode);
 int fflush(FILE* stream);
 int fclose(FILE* stream);
 
+int getc_unlocked(FILE* stream);
+int putc_unlocked(int character, FILE* stream);
 int fputs_unlocked(const char* s, FILE* stream);
 int fputc_unlocked(int character, FILE* stream);
 int fputs(const char* s, FILE* stream);
+int fgetc(FILE* stream);
 int fputc(int character, FILE* stream);
 
 extern FILE* stdout;

+ 65 - 22
gblibc/src/stdio.c

@@ -378,15 +378,14 @@ int puts(const char* str)
 
 char* gets(char* buf)
 {
-    int n = read(STDIN_FILENO, buf, __SIZE_MAX__);
-    if (n > 0) {
-      if (buf[n-1] == '\n')
-        buf[n-1] = 0;
-      else
-        buf[n] = 0;
-      return buf;
-    }
-    return NULL;
+    int c, num = 0;
+    while ((c = getchar()) != EOF && c != '\n')
+        buf[num++] = c;
+    buf[num] = 0;
+
+    if (c == EOF)
+        return NULL;
+    return buf;
 }
 
 int vfprintf_u32(uint32_t num, FILE* stream)
@@ -681,16 +680,7 @@ int fclose(FILE* stream)
 
 int fputc_unlocked(int c, FILE* stream)
 {
-    if (stream->wbuf) {
-        stream->wbuf[stream->wpos++] = c;
-        if (stream->wpos == stream->wbsz || c == '\n')
-            fflush(stream);
-    } else {
-        // TODO: set EOF on error
-        write(stream->fd, &c, 1);
-    }
-
-    return c;
+    return putc_unlocked(c, stream);
 }
 
 int fputs_unlocked(const char* s, FILE* stream)
@@ -705,12 +695,65 @@ int fputs_unlocked(const char* s, FILE* stream)
 
 int fputc(int c, FILE* stream)
 {
-    // TODO: locked version
-    return fputc_unlocked(c, stream);
+    // TODO: lock the stream
+    return putc_unlocked(c, stream);
 }
 
 int fputs(const char* s, FILE* stream)
 {
-    // TODO: locked version
+    // TODO: lock the stream
     return fputs_unlocked(s, stream);
 }
+
+static inline int __fillbuf(FILE* stream)
+{
+    // TODO: set EOF flag
+    if ((stream->rcnt = read(stream->fd, stream->rbuf, stream->rbsz)) >= 2147483648U) {
+        stream->rcnt = 0;
+        return EOF;
+    }
+    stream->rpos = 0;
+    return 0;
+}
+
+int getc_unlocked(FILE* stream)
+{
+    if (stream->rbuf) {
+        if (stream->rpos == stream->rcnt) {
+            if (__fillbuf(stream) < 0)
+                return EOF;
+        }
+        return stream->rbuf[stream->rpos++];
+    } else {
+        int c;
+        // TODO: set EOF on error
+        if (read(stream->fd, &c, 1) < 0)
+            return EOF;
+        return c;
+    }
+}
+
+int putc_unlocked(int c, FILE* stream)
+{
+    if (stream->wbuf) {
+        stream->wbuf[stream->wpos++] = c;
+        if (stream->wpos == stream->wbsz || c == '\n')
+            fflush(stream);
+    } else {
+        // TODO: set EOF on error
+        if (write(stream->fd, &c, 1) < 0)
+            return EOF;
+    }
+
+    return c;
+}
+
+int getchar(void)
+{
+    return fgetc(stdin);
+}
+
+int fgetc(FILE* stream)
+{
+    return getc_unlocked(stream);
+}