Open Chinese Convert  0.4.1
A project for conversion between Traditional and Simplified Chinese
 All Data Structures Files Functions Variables Groups Pages
utils.c
1 /*
2  * Open Chinese Convert
3  *
4  * Copyright 2010-2013 BYVoid <byvoid@byvoid.com>
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include "utils.h"
20 #include <unistd.h>
21 
22 #ifdef __APPLE__
23  # include "TargetConditionals.h"
24  # ifdef TARGET_OS_MAC
25  # include <mach-o/dyld.h>
26  # elif TARGET_OS_IPHONE
27  # elif TARGET_IPHONE_SIMULATOR
28  # else /* ifdef TARGET_OS_MAC */
29  # endif /* ifdef TARGET_OS_MAC */
30 #elif defined _WIN32 || defined _WIN64
31  # include <GL\glut.h>
32 #endif /* ifdef __APPLE__ */
33 
34 #define PATH_BUFFER_SIZE 4096
35 
36 void perr(const char* str) {
37  fputs(str, stderr);
38 }
39 
40 int qsort_int_cmp(const void* a, const void* b) {
41  return *((int*)a) - *((int*)b);
42 }
43 
44 char* mstrcpy(const char* str) {
45  char* strbuf = (char*)malloc(sizeof(char) * (strlen(str) + 1));
46 
47  strcpy(strbuf, str);
48  return strbuf;
49 }
50 
51 char* mstrncpy(const char* str, size_t n) {
52  char* strbuf = (char*)malloc(sizeof(char) * (n + 1));
53 
54  strncpy(strbuf, str, n);
55  strbuf[n] = '\0';
56  return strbuf;
57 }
58 
59 void skip_utf8_bom(FILE* fp) {
60  int bom[3];
61  int n;
62 
63  /* UTF-8 BOM is EF BB BF */
64  if (fp == NULL) {
65  return;
66  }
67 
68  /* If we are not at beginning of file, return */
69  if (ftell(fp) != 0) {
70  return;
71  }
72 
73  /* Try to read first 3 bytes */
74  for (n = 0; n <= 2 && (bom[n] = getc(fp)) != EOF; n++) {}
75 
76  /* If we can only read <3 bytes, push them back */
77  /* Or if first 3 bytes is not BOM, push them back */
78  if ((n < 3) || (bom[0] != 0xEF) || (bom[1] != 0xBB) || (bom[2] != 0xBF)) {
79  for (n--; n >= 0; n--) {
80  ungetc(bom[n], fp);
81  }
82  }
83 
84  /* Otherwise, BOM is already skipped */
85 }
86 
87 const char* executable_path(void) {
88  static char path_buffer[PATH_BUFFER_SIZE];
89  static int calculated = 0;
90 
91  if (!calculated) {
92 #ifdef __linux
93  ssize_t res = readlink("/proc/self/exe", path_buffer, sizeof(path_buffer));
94  assert(res != -1);
95 #elif __APPLE__
96  uint32_t size = sizeof(path_buffer);
97  int res = _NSGetExecutablePath(path_buffer, &size);
98  assert(res == 0);
99 #elif _WIN32 || _WIN64
100 
101  // TODO windows
102  assert(0);
103 #else /* ifdef __linux */
104 
105  /* Other unsupported os */
106  assert(0);
107 #endif /* ifdef __linux */
108  char* last_sep = strrchr(path_buffer, '/');
109  assert(last_sep != NULL);
110  *last_sep = '\0';
111  calculated = 1;
112  }
113  return path_buffer;
114 }
115 
116 char* try_open_file(const char* path) {
117  /* Try to find file in current working directory */
118  FILE* fp = fopen(path, "r");
119 
120  if (fp) {
121  fclose(fp);
122  return mstrcpy(path);
123  }
124 
125  /* If path is absolute, return NULL */
126  if (is_absolute_path(path)) {
127  return NULL;
128  }
129 
130  /* Try to find file in executable directory*/
131  const char* exe_dir = executable_path();
132  char* filename =
133  (char*)malloc(sizeof(char) * (strlen(path) + strlen(exe_dir) + 2));
134  sprintf(filename, "%s/%s", exe_dir, path);
135  fp = fopen(filename, "r");
136 
137  if (fp) {
138  fclose(fp);
139  return filename;
140  }
141  free(filename);
142 
143  /* Try to use PKGDATADIR */
144  filename =
145  (char*)malloc(sizeof(char) * (strlen(path) + strlen(PKGDATADIR) + 2));
146  sprintf(filename, "%s/%s", PKGDATADIR, path);
147  fp = fopen(filename, "r");
148 
149  if (fp) {
150  fclose(fp);
151  return filename;
152  }
153  free(filename);
154  return NULL;
155 }
156 
157 char* get_file_path(const char* filename) {
158  const char* last_sep = strrchr(filename, '/');
159 
160  if (last_sep == NULL) {
161  last_sep = filename;
162  }
163  char* path = mstrncpy(filename, last_sep - filename);
164  return path;
165 }
166 
167 int is_absolute_path(const char* path) {
168  if (path[0] == '/') {
169  return 1;
170  }
171 
172  if (path[1] == ':') {
173  return 1;
174  }
175  return 0;
176 }