/* * utils.c -- misc utils * (C)Copyright 1998 by Hiroshi Takekawa * This file is part of Enfle. * * Last Modified: Sun Oct 17 02:34:06 1999. * $Id: utils.c,v 1.16 1999/10/18 12:24:11 sian Exp $ * * Enfle is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Enfle is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "enfle.h" #include "utils.h" #include "archive.h" #include /* get filename (path base) */ char * get_basename(char *path) { char *ptr = path + strlen(path); while (path < ptr && *--ptr != '/') ; if (*ptr == '/') ptr++; return ptr; } /* get pathdir, return string must be freed */ char * get_pathdir(char *path) { char *ptr = get_basename(path); char *ret; if ((ret = malloc(ptr - path + 1)) == NULL) return NULL; strncpy(ret, path, ptr - path); ret[ptr - path] = '\0'; return ret; } /* replace or add extension like '.png' */ char * replace_ext(char *filename, char *ext) { char *ptr = filename + strlen(filename); char *new; int gap; while (filename < ptr && *--ptr != '.') ; if (*ptr != '.') { gap = strlen(ext); ptr = filename + strlen(filename); } else gap = (int)(strlen(ext) - (strlen(filename) - (ptr - filename) - 1)); if ((new = malloc(strlen(filename) + gap)) == NULL) return NULL; if (ptr != filename) memcpy(new, filename, ptr - filename); strcpy(new + (int)(ptr - filename), ext); return new; } void string_tolower(char *str) { if (str == NULL) return; while (*str != '\0') { *str = tolower(*str); str++; } } static int count_token(char *str, char delimiter) { int count = 0; while (*str != '\0') if (*str++ == delimiter) count++; return count; } /* split string by token character */ char ** split(char *str, char delimiter) { int i, j, k, l; int count; char **ret; if (str == NULL) return NULL; count = count_token(str, delimiter) + 1; if ((ret = malloc(sizeof(char *) * (count + 1))) == NULL) return NULL; k = 0; for (i = 0; i < strlen(str);) { j = i; while (str[i] != '\0' && str[i] != delimiter) i++; l = i - j; i++; if ((ret[k] = malloc(l + 1)) == NULL) { for (k-- ; k >= 0; k--) free(ret[k]); free(ret); return NULL; } if (l) strncpy(ret[k], str + j, l); ret[k++][l] = '\0'; } if (k > count) { fprintf(stderr, "split: FATAL: k > count\n"); for (k-- ; k < count; k--) free(ret[k]); free(ret); return NULL; } for (; k < count; k++) { if ((ret[k] = malloc(1)) == NULL) { for (k-- ; k < count; k--) free(ret[k]); free(ret); return NULL; } ret[k][0] = '\0'; } ret[k] = NULL; return ret; } /* free string array */ void free_string_array(char **strs) { int i = 0; if (strs) { while (strs[i] != NULL) free(strs[i++]); free(strs); } } /* * little endian read routines. * NOTE: Please don't make these endian-independent. * Prepare new functions to read big endian data. * Because endianness tends to be fixed toward each format. * If you read architecture-dependent data, handle it by yourself... */ unsigned long read_little_dword(Archive *ar) { unsigned char c[4]; if (archive_read(ar, c, 4) != 4) { fprintf(stderr, "read_little_dword: read error\n"); return -1; } return (((((c[3] << 8) + c[2]) << 8) + c[1]) << 8) + c[0]; } unsigned short read_little_word(Archive *ar) { unsigned char c[2]; if (archive_read(ar, c, 2) != 2) { fprintf(stderr, "read_little_word: read error\n"); return -1; } return (c[1] << 8) + c[0]; } unsigned short read_big_word(Archive *ar) { unsigned char c[2]; if (archive_read(ar, c, 2) != 2) { fprintf(stderr, "read_big_word: read error\n"); return -1; } return (c[0] << 8) + c[1]; } unsigned char read_uchar(Archive *ar) { unsigned char c; fprintf(stderr, "*** read_uchar() is deprecated! use archive_getc()\n"); if (archive_read(ar, &c, 1) != 1) { #ifdef DEBUG if (feof(ar->fp)) fprintf(stderr, "read_uchar: eof\n"); else perror("read_uchar: read error: "); #endif return -1; /* meaningless.. */ } return c; } unsigned long get_little_dword(void *ptr) { unsigned char *p = (unsigned char *)ptr; return (((((p[3] << 8) + p[2]) << 8) + p[1]) << 8) + p[0]; } unsigned short get_little_word(void *ptr) { unsigned char *p = (unsigned char *)ptr; return (p[1] << 8) + p[0]; } void put_little_dword(void *ptr, unsigned long d) { unsigned char *p = (unsigned char *)ptr; *p++ = d & 0xff; *p++ = (d >> 8) & 0xff; *p++ = (d >> 16) & 0xff; *p++ = (d >> 24) & 0xff; } void put_little_word(void *ptr, unsigned short d) { unsigned char *p = (unsigned char *)ptr; *p++ = d & 0xff; *p = (d >> 8) & 0xff; }