1 #include <string.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include "file_utils.h" 6 #include "Perforce.h" 7 #include <utils/String8.h> 8 #include <sys/fcntl.h> 9 #include <sys/stat.h> 10 #include <errno.h> 11 #include <string.h> 12 #include <stdlib.h> 13 #include <cstdio> 14 #include "log.h" 15 16 using namespace android; 17 using namespace std; 18 19 static string 20 parent_dir(const string& path) 21 { 22 return string(String8(path.c_str()).getPathDir().string()); 23 } 24 25 static int 26 mkdirs(const char* last) 27 { 28 String8 dest; 29 const char* s = last-1; 30 int err; 31 do { 32 s++; 33 if (s > last && (*s == '.' || *s == 0)) { 34 String8 part(last, s-last); 35 dest.appendPath(part); 36 #ifdef HAVE_MS_C_RUNTIME 37 err = _mkdir(dest.string()); 38 #else 39 err = mkdir(dest.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP); 40 #endif 41 if (err != 0) { 42 return err; 43 } 44 last = s+1; 45 } 46 } while (*s); 47 return 0; 48 } 49 50 string 51 translated_file_name(const string& file, const string& locale) 52 { 53 const char* str = file.c_str(); 54 const char* p = str + file.length(); 55 const char* rest = NULL; 56 const char* values = p; 57 58 while (p > str) { 59 p--; 60 if (*p == '/') { 61 rest = values; 62 values = p; 63 if (0 == strncmp("values", values+1, rest-values-1)) { 64 break; 65 } 66 } 67 } 68 values++; 69 70 string result(str, values-str); 71 result.append(values, rest-values); 72 73 string language, region; 74 if (locale == "") { 75 language = ""; 76 region = ""; 77 } 78 else if (!split_locale(locale, &language, ®ion)) { 79 return ""; 80 } 81 82 if (language != "") { 83 result += '-'; 84 result += language; 85 } 86 if (region != "") { 87 result += "-r"; 88 result += region; 89 } 90 91 result += rest; 92 93 return result; 94 } 95 96 ValuesFile* 97 get_values_file(const string& filename, const Configuration& configuration, 98 int version, const string& versionString, bool printOnFailure) 99 { 100 int err; 101 string text; 102 103 log_printf("get_values_file filename=%s\n", filename.c_str()); 104 err = Perforce::GetFile(filename, versionString, &text, printOnFailure); 105 if (err != 0 || text == "") { 106 return NULL; 107 } 108 109 ValuesFile* result = ValuesFile::ParseString(filename, text, configuration, version, 110 versionString); 111 if (result == NULL) { 112 fprintf(stderr, "unable to parse file: %s\n", filename.c_str()); 113 exit(1); 114 } 115 return result; 116 } 117 118 ValuesFile* 119 get_local_values_file(const string& filename, const Configuration& configuration, 120 int version, const string& versionString, bool printOnFailure) 121 { 122 int err; 123 string text; 124 char buf[2049]; 125 int fd; 126 ssize_t amt; 127 128 fd = open(filename.c_str(), O_RDONLY); 129 if (fd == -1) { 130 fprintf(stderr, "unable to open file: %s\n", filename.c_str()); 131 return NULL; 132 } 133 134 while ((amt = read(fd, buf, sizeof(buf)-1)) > 0) { 135 text.append(buf, amt); 136 } 137 138 close(fd); 139 140 if (text == "") { 141 return NULL; 142 } 143 144 ValuesFile* result = ValuesFile::ParseString(filename, text, configuration, version, 145 versionString); 146 if (result == NULL) { 147 fprintf(stderr, "unable to parse file: %s\n", filename.c_str()); 148 exit(1); 149 } 150 return result; 151 } 152 153 void 154 print_file_status(size_t j, size_t J, const string& message) 155 { 156 printf("\r%s file %zd of %zd...", message.c_str(), j, J); 157 fflush(stdout); 158 } 159 160 int 161 write_to_file(const string& filename, const string& text) 162 { 163 mkdirs(parent_dir(filename).c_str()); 164 int fd = open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0666); 165 if (fd < 0) { 166 fprintf(stderr, "unable to open file for write (%s): %s\n", strerror(errno), 167 filename.c_str()); 168 return -1; 169 } 170 171 ssize_t amt = write(fd, text.c_str(), text.length()); 172 173 close(fd); 174 175 if (amt < 0) { 176 return amt; 177 } 178 return amt == (ssize_t)text.length() ? 0 : -1; 179 } 180 181 182