From ace65b453151845bc361f21f3e5b651c35f9f126 Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Wed, 22 May 2024 13:00:41 -0400 Subject: massive refactor for mp and organization --- lib/buddymap.c | 168 ------------------------------------------------------- lib/buddymap.h | 35 ------------ lib/format.h | 13 ----- lib/hashtable.c | 109 ------------------------------------ lib/hashtable.h | 34 ----------- lib/jove.h | 15 ----- lib/kpanic.c | 15 ----- lib/linkedlist.c | 34 ----------- lib/linkedlist.h | 26 --------- lib/ltostr.c | 26 --------- lib/mem.c | 52 ----------------- lib/sfmt.c | 112 ------------------------------------- lib/spinlock.h | 27 --------- lib/string.c | 16 ------ lib/string.h | 18 ------ lib/toupper.c | 26 --------- 16 files changed, 726 deletions(-) delete mode 100644 lib/buddymap.c delete mode 100644 lib/buddymap.h delete mode 100644 lib/format.h delete mode 100644 lib/hashtable.c delete mode 100644 lib/hashtable.h delete mode 100644 lib/jove.h delete mode 100644 lib/kpanic.c delete mode 100644 lib/linkedlist.c delete mode 100644 lib/linkedlist.h delete mode 100644 lib/ltostr.c delete mode 100644 lib/mem.c delete mode 100644 lib/sfmt.c delete mode 100644 lib/spinlock.h delete mode 100644 lib/string.c delete mode 100644 lib/string.h delete mode 100644 lib/toupper.c (limited to 'lib') diff --git a/lib/buddymap.c b/lib/buddymap.c deleted file mode 100644 index 6a616c9..0000000 --- a/lib/buddymap.c +++ /dev/null @@ -1,168 +0,0 @@ -#include "buddymap.h" -#include "jove.h" - -#define BLOCK_AT_LAYER(blocks, l, i) blocks[l][i / BUDDY_BLOCK_BITS] -#define BLOCK_BITMASK(i) (1ULL << (i % BUDDY_BLOCK_BITS)) - -bool -buddy_bit_test(struct BuddyMap *map, size_t l, size_t i) -{ - return (BLOCK_AT_LAYER(map->blocks, l, i) & BLOCK_BITMASK(i)) > 0; -} - -void -buddy_bit_mark(struct BuddyMap *map, size_t l, size_t i) -{ - size_t wi = i << l; - size_t bits = 1ULL << l; - for(size_t wl = 0; wl < map->orders; wl++) { - if(bits == 0) { - if(buddy_bit_test(map, wl - 1, (wi << 1) + 1)) bits = 1; - } - for(size_t bit = 0; bit < bits; bit++) { - size_t rbit = bit + wi; - if(l == 0 && !buddy_bit_test(map, 0, rbit)) map->free--; - BLOCK_AT_LAYER(map->blocks, wl, rbit) |= BLOCK_BITMASK(rbit); - } - bits >>= 1; - wi >>= 1; - } -} - -void -buddy_bit_free(struct BuddyMap *map, size_t l, size_t i) -{ - size_t wi = i << l; - size_t bits = 1ULL << l; - for(size_t wl = 0; wl < map->orders; wl++) { - if(bits == 0) bits = 1; - for(size_t bit = 0; bit < bits; bit++) { - size_t rbit = bit + wi; - if(l == 0 && buddy_bit_test(map, 0, rbit)) map->free++; - BLOCK_AT_LAYER(map->blocks, wl, rbit) &= ~BLOCK_BITMASK(rbit); - } - bits >>= 1; - wi >>= 1; - } -} - -static void -s_buddy_op_range( - struct BuddyMap *map, - size_t l, - size_t start, - size_t end, - void (*op)(struct BuddyMap*, size_t, size_t)) -{ - size_t layerw = 1ULL << l; - size_t start_off = start % layerw; - size_t end_off = end % layerw; - - size_t start_real = start + (start_off > 0 ? (layerw - start_off) : 0); - size_t end_real = end - end_off; - - if(start_real != start) s_buddy_op_range(map, l - 1, start, start_real, op); - if(end_real != end) s_buddy_op_range(map, l - 1, end_real, end, op); - - size_t start_bit = start_real >> l; - size_t end_bit = end_real >> l; - if(start_bit == end_bit || end_bit < start_bit) return; - for(size_t bit = start_bit; bit < end_bit; bit++) - op(map, l, bit); -} - -static size_t -s_buddy_layer_bestfit(struct BuddyMap *map, size_t length) -{ - if(length == 1) return 0; - size_t length_log2 = LOG2(length); - if(length_log2 > map->orders) length_log2 = map->orders - 1; - return length_log2; -} - -void -buddy_mark_range(struct BuddyMap *map, size_t start, size_t end) -{ - size_t l = s_buddy_layer_bestfit(map, end - start); - s_buddy_op_range(map, l, start, end, buddy_bit_mark); -} -void -buddy_free_range(struct BuddyMap *map, size_t start, size_t end) -{ - size_t l = s_buddy_layer_bestfit(map, end - start); - s_buddy_op_range(map, l, start, end, buddy_bit_free); -} - -static intmax_t -s_buddy_top_firstfree(struct BuddyMap *map) -{ - size_t layer = map->orders - 1; - size_t layer_bits = map->bits >> layer; - size_t layer_blocks = layer_bits / BUDDY_BLOCK_BITS; - for(size_t i = 0; i < layer_blocks; i++) { - if(map->blocks[layer][i] == (uintptr_t)-1) continue; - for(size_t j = 0; j < BUDDY_BLOCK_BITS; j++) { - size_t bit = (i * BUDDY_BLOCK_BITS) + j; - if(buddy_bit_test(map, layer, bit)) continue; - return bit; - } - } - return -1; -} - -static intmax_t -s_buddy_top_alloc_contig(struct BuddyMap *map, size_t length) -{ - size_t layer = map->orders - 1; - size_t layer_bits = map->bits >> layer; - - size_t contig_base = 0; - size_t contig_bits = 0; - for(size_t i = 0; i < layer_bits; i++) { - if(buddy_bit_test(map, layer, i)) { - contig_base = i + 1; - contig_bits = 0; - continue; - } - if(++contig_bits == length) { - return contig_base; - } - } - return -1; -} - -intmax_t -buddy_alloc(struct BuddyMap *map, size_t length) -{ - size_t layer = s_buddy_layer_bestfit(map, length); - size_t layerw = 1ULL << layer; - size_t allocw = length / layerw; - - if(allocw == 0) allocw = 1; - if(allocw > 1) - return s_buddy_top_alloc_contig(map, length); - - intmax_t alloci = s_buddy_top_firstfree(map); - if(alloci < 0) { - klogf("Top layer is full!\n"); - return -1; - } - - for(int wlayer = map->orders - 2; wlayer > layer; wlayer--) { - alloci <<= 1; - if(buddy_bit_test(map, wlayer, alloci)) { - alloci++; - } - } - alloci <<= 1; - if(buddy_bit_test(map, layer, alloci)) alloci++; - - s_buddy_op_range(map, layer, alloci, alloci + length, buddy_bit_mark); - return alloci; -} - -void -buddy_free(struct BuddyMap *map, size_t i, size_t length) -{ - buddy_free_range(map, i, i + length); -} diff --git a/lib/buddymap.h b/lib/buddymap.h deleted file mode 100644 index 1af8dfb..0000000 --- a/lib/buddymap.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef JOVE_LIB_BUDDYMAP_H -#define JOVE_LIB_BUDDYMAP_H 1 - -#include -#include -#include - -#define BUDDY_BLOCK_BYTES sizeof(intmax_t) -#define BUDDY_BLOCK_BITS (BUDDY_BLOCK_BYTES * 8) - -#define BUDDY_BITS_FOR(range) (range * 2) -#define BUDDY_BLOCKS_FOR(range) (BUDDY_BITS_FOR(range) / BUDDY_BLOCK_BITS) - -struct BuddyMap -{ - size_t orders; - size_t bits; - size_t free; - uintmax_t **blocks; -}; - -#define BUDDY_BIT_PARTIAL 0 -#define BUDDY_BIT_FULL 1 - -bool buddy_bit_test(struct BuddyMap *map, size_t l, size_t i); -void buddy_bit_mark(struct BuddyMap *map, size_t l, size_t i); -void buddy_bit_free(struct BuddyMap *map, size_t l, size_t i); - -void buddy_mark_range(struct BuddyMap *map, size_t start, size_t end); -void buddy_free_range(struct BuddyMap *map, size_t start, size_t end); - -intmax_t buddy_alloc(struct BuddyMap *map, size_t length); -void buddy_free(struct BuddyMap *map, size_t i, size_t length); - -#endif diff --git a/lib/format.h b/lib/format.h deleted file mode 100644 index 5a2b75c..0000000 --- a/lib/format.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef JOVE_LIB_FORMAT_H -#define JOVE_LIB_FORMAT_H 1 - -#include -#include - -size_t ltostr(char *s, size_t limit, unsigned long l, bool sgn, int radix); - -char *sfmt(char *s, size_t limit, const char *fmt, ...); -#include -char *svfmt(char *s, size_t limit, const char *fmt, va_list ap); - -#endif diff --git a/lib/hashtable.c b/lib/hashtable.c deleted file mode 100644 index 17f1e74..0000000 --- a/lib/hashtable.c +++ /dev/null @@ -1,109 +0,0 @@ -#include "hashtable.h" -#include "string.h" -#include "mem/memory.h" - -static size_t -s_hash_function_mul(const void *data, size_t len) -{ - size_t hash = 1; - const char *cdata = (const char*)data; - for(size_t i = 0; i < len; i++) { - hash *= ((size_t)cdata[i]) + 1; - } - return hash; -} - -static size_t -s_hash_function_mul_s(const void *data, size_t _) -{ - return s_hash_function_mul(data, strlen(data)); -} - -void -_hashtable_new(struct HashTable *table, size_t obj_size, size_t key_size) -{ - *table = (struct HashTable){ - .buckets = NULL, - .bucket_count = 0, - .bucket_capacity = 2, - .obj_size = obj_size, - .key_size = key_size, - .hash_function = s_hash_function_mul - }; - table->buckets = mem_alloc(sizeof(struct SLinkedList) * 2); -} - -void -_hashtable_news(struct HashTable *table, size_t obj_size) -{ - *table = (struct HashTable){ - .buckets = NULL, - .bucket_count = 0, - .bucket_capacity = 2, - .obj_size = obj_size, - .key_size = -1, - .hash_function = s_hash_function_mul_s - }; - table->buckets = mem_alloc(sizeof(struct SLinkedList) * 2); -} - -void -hashtable_insert(struct HashTable *table, const void *key, void *data) -{ - size_t hash = table->hash_function(key, table->key_size); - if(table->bucket_capacity == table->bucket_count) { - struct SLinkedList *old_buckets = table->buckets; - size_t old_buckets_count = table->bucket_count; - - table->bucket_capacity *= 2; - table->bucket_count = 0; - table->buckets = mem_alloc(sizeof(struct SLinkedList) * table->bucket_capacity); - for(size_t i = 0; i < old_buckets_count; i++) { - for(struct SLLNode *node = old_buckets[i].head; node != NULL; node = node->next) { - struct HashTableValue *value = (struct HashTableValue*)(&node->data); - hashtable_insert(table, value->key, value->value); - mem_free(node); - } - } - } - - size_t index = hash % table->bucket_capacity; - struct SLinkedList *bucket = &table->buckets[index]; - struct SLLNode *node = mem_alloc(sizeof(struct SLLNode) + sizeof(struct HashTableValue) + table->obj_size); - struct HashTableValue *value = (struct HashTableValue*)(node->data); - - value->key = key; - memcpy(value->value, data, table->obj_size); - - table->bucket_count++; - if(bucket->count == 0) { - sll_new(bucket, table->obj_size); - sll_push(bucket, node); - return; - } - for(struct SLLNode *onode = bucket->head; onode != NULL; onode = onode->next) - { - struct HashTableValue *ovalue = (struct HashTableValue*)onode->data; - size_t keylen = table->key_size > 0 ? table->key_size : strlen((const char*)key) + 1; - if(memcmp(ovalue->key, value->key, keylen) == 0) { - memcpy(ovalue->value, value->value, table->obj_size); - return; - } - } - sll_push(bucket, node); -} - -void* -_hashtable_get(struct HashTable *table, const void *key) -{ - size_t hash = table->hash_function(key, table->key_size); - size_t index = hash % table->bucket_capacity; - struct SLinkedList *bucket = &table->buckets[index]; - for(struct SLLNode *node = bucket->head; node != NULL; node = node->next) - { - struct HashTableValue *value = (struct HashTableValue*)node->data; - size_t keylen = table->key_size > 0 ? table->key_size : strlen((const char*)value->key); - if(memcmp(key, value->key, keylen) == 0) return value->value; - } - return NULL; -} diff --git a/lib/hashtable.h b/lib/hashtable.h deleted file mode 100644 index fe6f5c3..0000000 --- a/lib/hashtable.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef JOVE_LIB_HASHTABLE_H -#define JOVE_LIB_HASHTABLE_H 1 - -#include -#include -#include "linkedlist.h" - -struct HashTableValue -{ - const void *key; - char value[]; -}; - -struct HashTable { - struct SLinkedList *buckets; - size_t bucket_count; - size_t bucket_capacity; - - size_t obj_size; - int key_size; - size_t (*hash_function)(const void*, size_t); -}; - -void _hashtable_new(struct HashTable *table, size_t obj_size, size_t key_size); -#define hashtable_new(table, type, keytype) _hashtable_new(table, sizeof(type), sizeof(keytype)) - -void _hashtable_news(struct HashTable *table, size_t obj_size); -#define hashtable_news(table, type) _hashtable_news(table, sizeof(type)) - -void hashtable_insert(struct HashTable *table, const void *key, void *data); -void *_hashtable_get(struct HashTable *table, const void *key); -#define hashtable_get(table, key, type) (type*)_hashtable_get(table, key) - -#endif diff --git a/lib/jove.h b/lib/jove.h deleted file mode 100644 index 6015112..0000000 --- a/lib/jove.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef JOVE_LIB_JOVE_H -#define JOVE_LIB_JOVE_H 1 - -#define ALWAYS_INLINE inline __attribute__((always_inline)) -#define PAGEALIGN __attribute__((aligned(0x1000))) - -#define LOG2(n) (31 - __builtin_clz(n)) - -extern void *_kernel_start; -extern void *_kernel_end; - -__attribute__((noreturn)) void _kpanic(const char *file, int line, const char *fmt, ...); -#define kpanic(...) _kpanic(__FILE__, __LINE__, __VA_ARGS__) - -#endif diff --git a/lib/kpanic.c b/lib/kpanic.c deleted file mode 100644 index 97e42eb..0000000 --- a/lib/kpanic.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "jove.h" -#include "io/log.h" - -#include - -__attribute__((noreturn)) -void _kpanic(const char *file, int line, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - klogf("!!! PANIC !!!\n%s:%i\n", file, line); - kvlogf(fmt, ap); - va_end(ap); - for(;;) __asm__ volatile("hlt"); -} diff --git a/lib/linkedlist.c b/lib/linkedlist.c deleted file mode 100644 index 6cc6403..0000000 --- a/lib/linkedlist.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "linkedlist.h" - -void -sll_new(struct SLinkedList *list, size_t obj_size) -{ - list->obj_size = obj_size; - list->count = 0; - list->head = list->tail = NULL; -}; - -void -sll_push(struct SLinkedList *list, void *data) -{ - struct SLLNode *node = (struct SLLNode*)data; - if(list->tail != NULL) { - list->tail->next = node; - } - if(list->head == NULL) - list->head = node; - list->tail = node; - list->count++; -} - -void* -sll_get(struct SLinkedList *list, size_t index) -{ - struct SLLNode *node = list->head; - if(node == NULL) return NULL; - if(index > list->count) return list->tail; - for(size_t i = 0; i < index; i++) { - node = node->next; - } - return node; -} diff --git a/lib/linkedlist.h b/lib/linkedlist.h deleted file mode 100644 index 26c148e..0000000 --- a/lib/linkedlist.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef JOVE_LIB_LINKEDLIST_H -#define JOVE_LIB_LINKEDLIST_H 1 - -#include -#include - -struct SLLNode { - struct SLLNode *next; - char data[]; -}; - -/*Singly Linked List*/ -struct SLinkedList -{ - struct SLLNode *head; - struct SLLNode *tail; - - size_t obj_size; - size_t count; -}; - -void sll_new(struct SLinkedList *list, size_t obj_size); -void sll_push(struct SLinkedList *list, void *node); -void *sll_get(struct SLinkedList *list, size_t index); - -#endif diff --git a/lib/ltostr.c b/lib/ltostr.c deleted file mode 100644 index e28be31..0000000 --- a/lib/ltostr.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "format.h" - -size_t -ltostr(char *s, size_t limit, unsigned long l, bool sgn, int radix) -{ - size_t si = 0; - size_t digits = 0; - if((long)l < 0 && sgn) { - l = -((long)l); - s[0] = '-'; - } - for(unsigned long lv = l; lv != 0; lv /= radix) - digits++; - digits = digits > limit ? limit : digits; - - if(digits-- == 0) - s[si++] = '0'; - for(unsigned long lv = l; lv != 0; lv /= radix) - { - if(si >= limit) return si; - int digit = lv % radix; - s[(digits - si)] = (digit >= 10 ? (digit + 'a' - 10) : digit + '0'); - si++; - } - return si; -} diff --git a/lib/mem.c b/lib/mem.c deleted file mode 100644 index b60fbbd..0000000 --- a/lib/mem.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "string.h" -#include "mem/memory.h" - -void* -memset(void *dest, int c, size_t n) -{ - char *destc = (char*)dest; - for(size_t i = 0; i < n; i++) - destc[i] = c; - return dest; -} - -void* -memcpy(void *dest, const void *src, size_t n) -{ - char *destc = (char*)dest; - const char *srcc = (const char*)src; - for(size_t i = 0; i < n; i++) - destc[i] = srcc[i]; - return dest; -} - -void* -memmove(void *dest, const void *src, size_t n) -{ - char *destc = (char*)dest; - const char *srcc = (const char*)src; - if(destc + n < srcc) return memcpy(dest, src, n); - char buffer[n]; - memcpy(buffer, src, n); - return memcpy(destc, buffer, n); -} - -int -memcmp(const void *a, const void *b, size_t n) -{ - const char *ac = (const char*)a; - const char *bc = (const char*)b; - for(size_t i = 0; i < n; i++) { - if(ac[i] != bc[i]) return ac[i] - bc[i]; - } - return 0; -} - -char* -strdup(const char *s) -{ - size_t slen = strlen(s); - char *ret = mem_alloc(slen); - memcpy(ret, s, slen); - return ret; -} diff --git a/lib/sfmt.c b/lib/sfmt.c deleted file mode 100644 index f903cbf..0000000 --- a/lib/sfmt.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "string.h" -#include "format.h" - -char* -sfmt(char *s, size_t limit, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - - s = svfmt(s, limit, fmt, ap); - - va_end(ap); - return s; -} - -char* -svfmt(char *s, size_t limit, const char *fmt, va_list ap) -{ - - size_t fmtlen = strlen(fmt); - size_t si = 0; - for(size_t fmti = 0; fmti < fmtlen; fmti++) - { - if(si >= limit) break; - if(fmt[fmti] != '%') { - s[si++] = fmt[fmti]; - continue; - } - // TODO: Format flags - fmti++; - - bool alt = false; - bool zpad = false; - for(;;fmti++){ - if(fmt[fmti] == '#') { alt = true; continue; } - if(fmt[fmti] == '0') { zpad = true; continue; } - break; - } - int fwidth = 0; - if(fmt[fmti] >= '1' && fmt[fmti] <= '9') - { - for(;fmt[fmti] >= '0' && fmt[fmti] <= '9';fmti++) { - fwidth *= 10; - fwidth += fmt[fmti] - '0'; - } - } - int precision = 0; - if(fmt[fmti] == '.') - { - fmti++; - for(;fmt[fmti] >= '0' && fmt[fmti] <= '9';fmti++) { - precision *= 10; - precision += fmt[fmti] - '0'; - } - } - - bool sgn = true; - bool upper = false; - int radix = 10; - switch(fmt[fmti]) - { - case '%': - s[si++] = '%'; - break; - case 'b': - radix = 2; - case 'X': - upper = true; - case 'x': - if(radix == 10) - radix = 16; - case 'o': - if(radix == 10) - radix = 8; - case 'u': - sgn = false; - case 'i': { - if((radix == 8 || radix == 16) && alt) { - s[si++] = '0'; - if(radix == 16) { - s[si++] = 'x'; - } - if(radix == 2) { - s[si++] = 'b'; - } - } - size_t osi = si; - size_t nlen = ltostr(&s[si], limit - si, va_arg(ap, long), sgn, radix); - if(upper) sntoupper(&s[si], nlen); - si += nlen; - - int lpad = fwidth - (int)nlen; - if(lpad > 0) - { - if(lpad + osi >= limit) lpad = (limit - osi - 1); - memmove(&s[osi + lpad], &s[osi], nlen); - memset(&s[osi], zpad ? '0' : ' ', lpad); - si += lpad; - } - } break; - case 's': { - const char *str = va_arg(ap, char*); - size_t slen = strlen(str); - size_t wlen = slen > limit - si ? limit - si : slen; - for(size_t i = 0; i < wlen; i++) - s[si++] = str[i]; - } break; - } - } - s[si] = 0; - return s; -} diff --git a/lib/spinlock.h b/lib/spinlock.h deleted file mode 100644 index 75af28a..0000000 --- a/lib/spinlock.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef JOVE_LIB_SPINLOCK_H -#define JOVE_LIB_SPINLOCK_H 1 - -#include - -typedef struct Spinlock -{ - atomic_flag flg; - - const char *locker_file; - const char *locker_func; - int locker_line; -} spinlock_t; - -#define spinlock_acquire(lock) \ - while(atomic_flag_test_and_set_explicit(&lock.flg, memory_order_acquire)) \ - __builtin_ia32_pause(); \ - lock.locker_file = __FILE__; \ - lock.locker_func = __FUNCTION__; \ - lock.locker_line = __LINE__ - -#define spinlock_release(lock) \ - atomic_flag_clear_explicit(&lock.flg, memory_order_release); \ - lock.locker_file = lock.locker_func = NULL; \ - lock.locker_line = -1 - -#endif diff --git a/lib/string.c b/lib/string.c deleted file mode 100644 index 4bb1bad..0000000 --- a/lib/string.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "string.h" - -size_t strlen(const char *s) { - size_t l = 0; - for(; *s != 0; s++, l++); - return l; -} - -int strcmp(const char *a, const char *b) -{ - size_t i = 0; - for(; a[i] != 0 && b[i] != 0; i++) { - if(a[i] != b[i]) return a[i] - b[i]; - } - return a[i] - b[i]; -} diff --git a/lib/string.h b/lib/string.h deleted file mode 100644 index a91ec94..0000000 --- a/lib/string.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef JOVE_LIB_STRING_H -#define JOVE_LIB_STRING_H 1 - -#include - -int toupper(int c); -char *stoupper(char *s); -char *sntoupper(char *s, size_t limit); - -size_t strlen(const char *s); - -void *memset(void *dest, int c, size_t n); -void *memcpy(void *dest, const void *src, size_t n); -void *memmove(void *dest, const void *src, size_t n); -int memcmp(const void *a, const void *b, size_t n); -int strcmp(const char *a, const char *b); - -#endif diff --git a/lib/toupper.c b/lib/toupper.c deleted file mode 100644 index 807eb38..0000000 --- a/lib/toupper.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "string.h" - -int -toupper(int c) -{ - if(c >= 'a' && c <= 'z') - c -= ('a' - 'A'); - return c; -} - -char* -stoupper(char *s) -{ - char *o = s; - for(; *s != 0; s++) - *s = toupper(*s); - return o; -} - -char* -sntoupper(char *s, size_t limit) -{ - for(size_t i = 0; i < limit; i++) - s[i] = toupper(s[i]); - return s; -} -- cgit v1.2.1