1 /* 2 # This file is part of the Astrometry.net suite. 3 # Licensed under a 3-clause BSD style license - see LICENSE 4 */ 5 6 #ifndef IOUTILS_H 7 #define IOUTILS_H 8 9 #include <stdio.h> 10 #include <stdint.h> 11 #include <sys/types.h> 12 #include <time.h> 13 14 #include "astrometry/an-bool.h" 15 #include "astrometry/bl.h" 16 #include "astrometry/keywords.h" 17 18 extern uint32_t ENDIAN_DETECTOR; 19 20 void QSORT_R(void* base, size_t nmembers, size_t member_size, 21 void* token, int (*compar)(void *, const void *, const void *)); 22 23 /** 24 You should define the "comparison" function like this: 25 26 static int QSORT_COMPARISON_FUNCTION(my_comparison, void* token, const void* v1, const void* v2) { 27 */ 28 #define QSORT_COMPARISON_FUNCTION(func, thunk, v1, v2) func(thunk, v1, v2) 29 30 int copy_file(const char* infn, const char* outfn); 31 32 int pad_fid(FILE* fid, size_t len, char pad); 33 int pad_file(char* filename, size_t len, char pad); 34 35 /* 36 The "basename" function may overwrite its arg and may return a pointer 37 to static memory... both undesirable. This replacement returns a newly- 38 allocated string containing the result. 39 */ 40 Malloc 41 char* basename_safe(const char* path); 42 43 Malloc 44 char* dirname_safe(const char* path); 45 46 // Returns (system + user) CPU time, in seconds. 47 float get_cpu_usage(void); 48 49 //int log_resource_usage(int loglevel); 50 51 /* 52 Searches for the given "filename" in the given set of directories. 53 Returns a newly allocated string "dir/filename", or NULL if none of 54 the paths exists and is readable. 55 */ 56 char* find_file_in_dirs(const char** dirs, int ndirs, const char* filename, anbool allow_absolute); 57 58 // Are strings s1 and s2 equal? 59 anbool streq(const char* s1, const char* s2); 60 anbool strcaseeq(const char* s1, const char* s2); 61 62 /* 63 Copy data from "fin" to "fout", starting at offset "offset" 64 (from the beginning of "fin"), and length "length". 65 Returns 0 on success. 66 */ 67 int pipe_file_offset(FILE* fin, off_t offset, off_t length, FILE* fout); 68 69 int write_file(const char* fn, const char* data, int len); 70 71 /* 72 It's not really _safe_ as such, it just prints an error message if it fails... 73 */ 74 void 75 ATTRIB_FORMAT(printf,2,3) 76 asprintf_safe(char** strp, const char* format, ...); 77 78 int run_command_get_outputs(const char* cmd, sl** outlines, sl** errlines); 79 80 void get_mmap_size(size_t start, size_t size, off_t* mapstart, size_t* mapsize, int* pgap); 81 82 // If "dir" is NULL, create temp file in $TMP, or /tmp if not set. 83 char* create_temp_file(const char* fn, const char* dir); 84 85 // If "dir" is NULL, create temp file in $TMP, or /tmp if not set. 86 char* create_temp_dir(const char* name, const char* dir); 87 88 char* shell_escape(const char* str); 89 90 int mkdir_p(const char* path); 91 92 // Returns 0 on error. 93 time_t file_get_last_modified_time(const char* fn); 94 95 anbool file_exists(const char* fn); 96 97 anbool file_readable(const char* fn); 98 99 anbool file_executable(const char* fn); 100 101 anbool path_is_dir(const char* path); 102 103 void* file_get_contents(const char* fn, size_t* len, anbool addzero); 104 105 char* file_get_contents_offset(const char* fn, int offset, int length); 106 107 sl* fid_add_lines(FILE* fid, anbool include_newlines, sl* list); 108 109 sl* file_get_lines(const char* fn, anbool include_newlines); 110 111 sl* fid_get_lines(FILE* fid, anbool include_newlines); 112 113 sl* dir_get_contents(const char* path, sl* result, anbool filesonly, anbool recursive); 114 115 int file_get_last_modified_string(const char* fn, const char* timeformat, 116 anbool utc, char* output, size_t outsize); 117 118 /** 119 Splits the given "str" into words, so that the first line is at most 120 "firstlinew" long. Subsequent lines have length <= "linew". If 121 "lst" is non-NULL, the words are added into it. Otherwise a new sl 122 is allocated. 123 */ 124 sl* split_long_string(const char* str, int firstlinew, int linew, sl* lst); 125 126 // Split a string on the first instance of "splitstr". 127 // Places the addresses of (newly-allocated) copies of the first and seconds parts of the string. 128 // Returns 1 if the string is found. 129 int split_string_once(const char* str, const char* splitstr, char** first, char** second); 130 131 /** 132 If "cmdline" starts with "keyword", returns 1 and places the address of 133 the start of the next word in "p_next_word". 134 */ 135 int is_word(const char* cmdline, const char* keyword, char** p_next_word); 136 137 int starts_with(const char* str, const char* prefix); 138 139 int ends_with(const char* str, const char* prefix); 140 141 char* strdup_safe(const char* str); 142 143 void add_sigbus_mmap_warning(void); 144 void reset_sigbus_mmap_warning(void); 145 146 int write_u8(FILE* fout, unsigned char val); 147 int write_u16(FILE* fout, unsigned int val); 148 int write_u32(FILE* fout, unsigned int val); 149 int write_uints(FILE* fout, unsigned int* val, int n); 150 int write_double(FILE* fout, double val); 151 int write_float(FILE* fout, float val); 152 int write_fixed_length_string(FILE* fout, char* s, int length); 153 int write_string(FILE* fout, char* s); 154 155 int write_u32_portable(FILE* fout, unsigned int val); 156 int write_u32s_portable(FILE* fout, unsigned int* val, int n); 157 158 int read_u8(FILE* fin, unsigned char* val); 159 int read_u16(FILE* fout, unsigned int* val); 160 int read_u32(FILE* fin, unsigned int* val); 161 int read_double(FILE* fin, double* val); 162 int read_fixed_length_string(FILE* fin, char* s, int length); 163 char* read_string(FILE* fin); 164 char* read_string_terminated(FILE* fin, const char* terminators, int nterminators, 165 anbool include_terminator); 166 167 int read_u32_portable(FILE* fin, unsigned int* val); 168 int read_u32s_portable(FILE* fin, unsigned int* val, int n); 169 170 struct buffered_read_data { 171 void* buffer; 172 int blocksize; 173 int elementsize; 174 int ntotal; 175 int nbuff; 176 int off; 177 int buffind; 178 int (*refill_buffer)(void* userdata, void* buffer, unsigned int offs, unsigned int nelems); 179 void* userdata; 180 }; 181 typedef struct buffered_read_data bread_t; 182 183 bread_t* buffered_read_new(int elementsize, int Nbuffer, int Ntotal, 184 int (*refill_buffer)(void* userdata, void* buffer, unsigned int offs, unsigned int nelems), 185 void* userdata); 186 187 void* buffered_read(bread_t* buff); 188 189 void buffered_read_pushback(bread_t* br); 190 191 void buffered_read_reset(bread_t* br); 192 193 void buffered_read_free(bread_t* br); 194 195 void buffered_read_resize(bread_t* br, int newsize); 196 197 #endif 198