123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- #include "str.h"
- #include <ctype.h>
- #include <stdarg.h>
- #include <stdbool.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- char **str_split(char *str, char delim) {
- char **ret;
- if (str == NULL) return NULL;
- if (*str == '\n') {
- ret = malloc(sizeof(char *));
- *ret = NULL;
- return ret;
- }
- int count = 0;
- char *begin = str;
- for (char *p = str; *p != '\0'; p++) {
- if (*p != delim && !(delim == '\0' && isspace(*p))) {
- continue;
- }
- int size = p - begin;
- if (size > 0) count++;
- }
- count++;
- ret = malloc((count + 1) * sizeof(char *));
- memset(ret, 0, (count + 1) * sizeof(char *));
- begin = str;
- int i = 0;
- bool finished = false;
- for (char *p = str; !finished; p++) {
- if (*p == '\0') finished = true;
- if (*p != delim && *p != '\0' && !(delim == '\0' && isspace(*p))) {
- continue;
- }
- int size = p - begin;
- if (size == 0) {
- begin = p + 1;
- continue;
- }
- char *buf = malloc(sizeof(char) * (size + 1));
- buf[size] = '\0';
- memcpy(buf, begin, size * sizeof(char));
- begin = p + 1;
- ret[i] = buf;
- i++;
- }
- return ret;
- }
- void destroy_str_list(char **list) {
- char **p = list;
- while (*p != NULL) {
- free(*p);
- p++;
- }
- free(list);
- }
- char *str_strip(char *str) {
- if (str == NULL) return NULL;
- int len = strlen(str);
- char *begin = str;
- char *end = str + len - 1;
- while (isspace(*begin) && begin < end) {
- begin++;
- }
- while (isspace(*end) && end >= begin) {
- end--;
- }
- len = end - begin + 1;
- char *buf = malloc(sizeof(char) * (len) + 1);
- buf[len] = '\0';
- memcpy(buf, begin, len);
- return buf;
- }
- void init_str_builder(str_builder_t *sb) {
- *sb = (str_builder_t){.size = 0, .cap = 16};
- sb->buf = malloc(sizeof(char) * 17);
- }
- static void sb_reserve(str_builder_t *sb, int extra) {
- if (sb->size + extra <= sb->cap) {
- return;
- }
- int new_cap = (sb->size + extra) * 2;
- sb->buf = realloc(sb->buf, new_cap + 1);
- memset(sb->buf + sb->cap, 0, new_cap - sb->cap + 1);
- sb->cap = new_cap;
- }
- void str_builder_append(str_builder_t *sb, char *format, ...) {
- va_list va1;
- va_list va2;
- va_start(va1, format);
- va_copy(va2, va1);
- int size = vsnprintf(NULL, 0, format, va1);
- sb_reserve(sb, size);
- vsnprintf(sb->buf + sb->size, sb->cap - sb->size + 1, format, va2);
- }
- void str_builder_append_char(str_builder_t *sb, char c) {
- sb_reserve(sb, 1);
- sb->buf[sb->size] = c;
- sb->size++;
- }
- char *fgetline(FILE *fp) {
- str_builder_t sb;
- init_str_builder(&sb);
- while (true) {
- int c = fgetc(fp);
- if (c == EOF && sb.size == 0) return NULL;
- if (c != EOF) str_builder_append_char(&sb, c);
- if (c == EOF || c == '\n') return sb.buf;
- }
- return NULL;
- }
- int fpeek(FILE *fp) {
- int c = fgetc(fp);
- if (c == EOF) return c;
- ungetc(c, fp);
- return c;
- }
|