#include #include #include #include #include "cart.h" #include "util.h" uvlong hash(char* str, int array_sz) { uvlong h; uchar* p; h = 0; for (p = (unsigned char*)str; *p != '\0'; p++) h = 37 * h + *p; if (array_sz == 0) return h; else return h % array_sz; } char clca(char c) { return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c; } /* char to lowercase */ char cuca(char c) { return c >= 'a' && c <= 'z' ? c - ('a' - 'A') : c; } /* char to uppercase */ int slen(char* s) { int i = 0; while (s[i] && s[++i]) { ; } return i; } /* string length */ char* st__(char* s, char (*fn)(char)) { int i = 0; char c; while ((c = s[i])) s[i++] = fn(c); return s; } char* stuc(char* s) { return st__(s, cuca); } /* string to uppercase */ char* stlc(char* s) { return st__(s, clca); } /* string to lowercase */ char* scpy(char* src, char* dst, int len) { int i = 0; while ((dst[i] = src[i]) && i < len - 2) i++; dst[i + 1] = '\0'; return dst; } /* string copy */ int scmp(char* a, char* b) { int i = 0; while (a[i] == b[i]) if (!a[i++]) return 1; return 0; } /* string compare */ char* scsw(char* s, char a, char b) { int i = 0; char c; while ((c = s[i])) s[i++] = c == a ? b : c; return s; } /* string char swap */ char* scat(char* dst, const char* src) { char* ptr = dst + slen(dst); while (*src) *ptr++ = *src++; *ptr = '\0'; return dst; } /* string cat */ int ssin(char* s, char* ss) { int a = 0, b = 0; while (s[a]) { if (s[a] == ss[b]) { if (!ss[b + 1]) return a - b; b++; } else b = 0; a++; } return -1; } /* string substring index */ char* ccat(char* dst, char c) { int len = slen(dst); dst[len] = c; dst[len + 1] = '\0'; return dst; } Blob* read_bytes(char* path) { FILE* f; char* buf; long count; Blob* self; f = fopen(path, "rb"); if (f == nil) return nil; fseek(f, 0, SEEK_END); count = ftell(f); rewind(f); buf = malloc(count * sizeof(char)); if (!fread(buf, count, 1, f)) { fclose(f); return nil; } else { fclose(f); self = malloc(sizeof(Blob)); self->data = buf; self->length = count; return self; } } Blob* read_chars(char* path) { FILE* f; char* buf; long count; Blob* self; f = fopen(path, "r"); if (f == nil) return nil; fseek(f, 0, SEEK_END); count = ftell(f); rewind(f); buf = malloc(count * sizeof(char)); if (!fread(buf, count, 1, f)) { fclose(f); return nil; } else { fclose(f); self = malloc(sizeof(Blob)); self->data = buf; self->length = count; return self; } } int issymlink(char* name) { struct stat s; return lstat(name, &s) >= 0 && S_ISLNK(s.st_mode); } int rm_dir(char* f) { char* name; int fd, i, j, n, ndir, nname; Dir* dirbuf; int fail = 0; fd = open(f, OREAD); if (fd < 0) { return 0; } n = dirreadall(fd, &dirbuf); close(fd); if (n < 0) { return 0; } nname = strlen(f) + 1 + STATMAX + 1; /* plenty! */ name = malloc(nname); if (name == 0) { return 0; } ndir = 0; for (i = 0; i < n; i++) { snprint(name, nname, "%s/%s", f, dirbuf[i].name); if (remove(name) != -1 || issymlink(name)) dirbuf[i].qid.type = QTFILE; /* so we won't recurse */ else { if (dirbuf[i].qid.type & QTDIR) ndir++; else fail = 1; } } if (ndir) for (j = 0; j < n; j++) if (dirbuf[j].qid.type & QTDIR) { snprint(name, nname, "%s/%s", f, dirbuf[j].name); rmdir(name); } if (remove(f) == -1) fail = 1; free(name); free(dirbuf); return fail ? 0 : 1; } void strreverse(char* begin, char* end) { char aux; while (end > begin) aux = *end, *end-- = *begin, *begin++ = aux; } void itoa(int value, char* str, int base) { static char num[] = "0123456789abcdefghijklmnopqrstuvwxyz"; char* wstr = str; int sign; // Validate base if (base < 2 || base > 35) { *wstr = '\0'; return; } // Take care of sign if ((sign = value) < 0) value = -value; // Conversion. Number is reversed. do *wstr++ = num[value % base]; while (value /= base); if (sign < 0) *wstr++ = '-'; *wstr = '\0'; // Reverse string strreverse(str, wstr - 1); }