/*
file_utils.c
c Ronny Lorenz
Vienna RNA package
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdarg.h>
#include <errno.h>
#include <libgen.h>
#include "ViennaRNA/utils.h"
#include "ViennaRNA/file_utils.h"
#define PRIVATE static
#define PUBLIC
/*
#################################
# GLOBAL VARIABLES #
#################################
*/
/*
#################################
# PRIVATE VARIABLES #
#################################
*/
#ifdef _WIN32
#ifdef __MINGW32__
#include <direct.h>
#endif
#define DIRSEPC '\\'
#define DIRSEPS "\\"
#else
#define DIRSEPC '/'
#define DIRSEPS "/"
#endif
/*
#################################
# PRIVATE FUNCTION DECLARATIONS #
#################################
*/
PRIVATE int is_absolute_path(const char *p);
/*
#################################
# BEGIN OF FUNCTION DEFINITIONS #
#################################
*/
PUBLIC void
vrna_file_copy(FILE *from, FILE *to){
int c;
while ((c = getc(from)) != EOF) (void)putc(c, to);
}
PUBLIC char *
vrna_read_line(FILE *fp){ /* reads lines of arbitrary length from fp */
char s[512], *line, *cp;
int len=0, size=0, l;
line=NULL;
do {
if (fgets(s, 512, fp)==NULL) break;
cp = strchr(s, '\n');
if (cp != NULL) *cp = '\0';
l = len + (int)strlen(s);
if (l+1>size) {
size = (int)((l+1)*1.2);
line = (char *) vrna_realloc(line, size*sizeof(char));
}
strcat(line+len, s);
len=l;
} while(cp==NULL);
return line;
}
PUBLIC int
vrna_mkdir_p(const char *path){
struct stat sb;
char *slash, *ptr;
int done = 0;
if(!is_absolute_path(path))
ptr = vrna_strdup_printf(".%c%s", DIRSEPC, path);
else
ptr = strdup(path);
slash = ptr;
while (!done) {
slash += strspn(slash, DIRSEPS);
slash += strcspn(slash, DIRSEPS);
done = (*slash == '\0');
*slash = '\0';
if (stat(ptr, &sb)) {
#ifdef _WIN32
if (errno != ENOENT || (_mkdir(ptr) &&
errno != EEXIST)) {
#else
if (errno != ENOENT || (mkdir(ptr, 0777) &&
errno != EEXIST)) {
#endif
vrna_message_warning("Can't create directory %s", ptr);
free(ptr);
return -1;
}
} else if (!S_ISDIR(sb.st_mode)) {
vrna_message_warning("File exists but is not a directory %s: %s", ptr, strerror(ENOTDIR));
free(ptr);
return -1;
}
*slash = DIRSEPC;
}
free(ptr);
return 0;
}
PUBLIC char *
vrna_basename(const char *path){
char *name, *p, *ptr;
int pos;
name = NULL;
if(path){
ptr = strrchr(path, DIRSEPC);
if(ptr && (*(ptr + 1) != '\0'))
name = strdup(ptr + 1);
else if(!ptr)
name = strdup(path);
}
return name;
}
PUBLIC char *
vrna_dirname(const char *path){
char *name, *p, *ptr;
int pos;
name = NULL;
if(path){
if(!is_absolute_path(path))
ptr = vrna_strdup_printf(".%c%s", DIRSEPC, path);
else
ptr = strdup(path);
pos = (int)strlen(ptr);
p = ptr + pos;
do{ /* remove part after last separator */
*p = '\0';
} while((--p > ptr) && (*p != DIRSEPC));
if(p > ptr)
name = ptr;
}
return name;
}
#ifdef _WIN32
PRIVATE int
is_drive_char(const char c){
if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
return 1;
return 0;
}
#endif
PRIVATE int
is_absolute_path(const char *p){
if(*p == DIRSEPC)
return 1;
#ifdef _WIN32
if(is_drive_char((const char)*p) && (strlen(p) > 3))
if((*(p + 1) == ':') && ((*(p + 2) == '\\') || (*(p + 2) == '/')))
return 1;
#endif
return 0;
}