file_.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. #include "__ofunc.h"
  2. static void setFunctionData(Value *value, LinkValue *cls, Inter *inter) {
  3. value->data.function.function_data.pt_type = inter->data.default_pt_type;
  4. value->data.function.function_data.cls = cls;
  5. value->data.function.function_data.run = false;
  6. }
  7. ResultType file_new(O_FUNC){
  8. LinkValue *value = NULL;
  9. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  10. {.must=-1}};
  11. int status = 1;
  12. setResultCore(result);
  13. arg = parserValueArgument(ap, arg, &status, NULL);
  14. if (status != 1) {
  15. setResultError(E_ArgumentException, FEW_ARG, LINEFILE, true, CNEXT_NT);
  16. return R_error;
  17. }
  18. value = make_new(inter, belong, ap[0].value);
  19. value->value->type = V_file;
  20. value->value->data.file.is_std = true;
  21. value->value->data.file.path = NULL;
  22. value->value->data.file.mode = NULL;
  23. value->value->data.file.file = NULL;
  24. run_init(value, arg, LINEFILE, CNEXT_NT);
  25. return result->type;
  26. }
  27. ResultType file_init(O_FUNC){
  28. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  29. {.type=name_value, .must=0, .name=L"file", .long_arg=false},
  30. {.type=name_value, .must=0, .name=L"mode", .long_arg=false},
  31. {.must=-1}};
  32. LinkValue *file;
  33. char *path;
  34. char *mode;
  35. setResultCore(result);
  36. parserArgumentUnion(ap, arg, CNEXT_NT);
  37. if (!CHECK_RESULT(result))
  38. return result->type;
  39. freeResult(result);
  40. if ((file = ap[0].value)->value->type != V_file) {
  41. setResultError(E_TypeException, INSTANCE_ERROR(file), LINEFILE, true, CNEXT_NT);
  42. return R_error;
  43. }
  44. if (ap[1].value == NULL) {
  45. setResult(result, inter);
  46. return result->type;
  47. } else if (ap[1].value->value->type != V_str) {
  48. setResultError(E_TypeException, ONLY_ACC(file, str), LINEFILE, true, CNEXT_NT);
  49. return R_error;
  50. } else
  51. path = memWcsToStr(ap[1].value->value->data.str.str, false);
  52. if (ap[2].value != NULL && ap[2].value->value->type == V_str)
  53. mode = memWcsToStr(ap[2].value->value->data.str.str, false);
  54. else
  55. mode = memStrcpy("r");
  56. if (checkFileReadble(path) != 1) {
  57. setResultError(E_TypeException, L"file is not readable", LINEFILE, true, CNEXT_NT);
  58. return R_error;
  59. }
  60. file->value->data.file.path = path;
  61. file->value->data.file.mode = mode;
  62. file->value->data.file.is_std = false;
  63. file->value->data.file.file = fopen(path, mode);
  64. if (file->value->data.file.file == NULL)
  65. setResultFromERR(E_TypeException, CNEXT_NT);
  66. else
  67. setResult(result, inter);
  68. return result->type;
  69. }
  70. ResultType file_read(O_FUNC){
  71. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  72. {.type=name_value, .must=0, .name=L"n", .long_arg=false},
  73. {.must=-1}};
  74. LinkValue *file;
  75. wchar_t *tmp = NULL;
  76. setResultCore(result);
  77. parserArgumentUnion(ap, arg, CNEXT_NT);
  78. if (!CHECK_RESULT(result))
  79. return result->type;
  80. freeResult(result);
  81. if ((file = ap[0].value)->value->type != V_file || file->value->data.file.file == NULL) {
  82. setResultError(E_TypeException, INSTANCE_ERROR(file), LINEFILE, true, CNEXT_NT);
  83. return R_error;
  84. }
  85. fseek(file->value->data.file.file, 0L, SEEK_CUR); // 改变文件状态(什么都没做)
  86. if (ap[1].value != NULL) { // 指定数量读取
  87. size_t n;
  88. wint_t ch;
  89. if (ap[1].value->value->type == V_int)
  90. n = ap[1].value->value->data.int_.num;
  91. else if (ap[1].value->value->type == V_dou)
  92. n = (vint)ap[1].value->value->data.dou.num;
  93. else {
  94. setResultError(E_TypeException, ONLY_ACC(n, num), LINEFILE, true, CNEXT_NT);
  95. return R_error;
  96. }
  97. tmp = memWide(n);
  98. for (int count=0; count < n && (ch = getwc(file->value->data.file.file)) != WEOF; count++)
  99. tmp[count] = ch;
  100. } else {
  101. size_t n = 0;
  102. size_t step = 50;
  103. wint_t ch;
  104. tmp = NULL;
  105. for (int count=1; (ch = fgetwc(file->value->data.file.file)) != WEOF; count++) { // 全部读取
  106. if (count > n) {
  107. n += step;
  108. tmp = memWideExpansion(tmp, n, true);
  109. }
  110. tmp[count - 1] = ch;
  111. }
  112. }
  113. makeStringValue(tmp, LINEFILE, CNEXT_NT);
  114. memFree(tmp);
  115. return result->type;
  116. }
  117. ResultType file_readline(O_FUNC){
  118. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  119. {.must=-1}};
  120. LinkValue *file;
  121. wchar_t *tmp = NULL;
  122. size_t n = 0;
  123. size_t step = 50;
  124. wint_t ch;
  125. setResultCore(result);
  126. parserArgumentUnion(ap, arg, CNEXT_NT);
  127. if (!CHECK_RESULT(result))
  128. return result->type;
  129. freeResult(result);
  130. if ((file = ap[0].value)->value->type != V_file || file->value->data.file.file == NULL) {
  131. setResultError(E_TypeException, INSTANCE_ERROR(file), LINEFILE, true, CNEXT_NT);
  132. return R_error;
  133. }
  134. fseek(file->value->data.file.file, 0L, SEEK_CUR); // 改变文件状态(什么都没做)
  135. tmp = NULL;
  136. for (int count=1; (ch = fgetwc(file->value->data.file.file)) != WEOF && ch != '\n'; count++) { // 读取到行末
  137. if (count > n) {
  138. n += step;
  139. tmp = memWideExpansion(tmp, n, true);
  140. }
  141. tmp[count - 1] = ch;
  142. }
  143. makeStringValue(tmp, LINEFILE, CNEXT_NT);
  144. memFree(tmp);
  145. return result->type;
  146. }
  147. ResultType file_write(O_FUNC){
  148. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  149. {.type=name_value, .must=1, .name=L"str", .long_arg=false},
  150. {.must=-1}};
  151. LinkValue *file;
  152. setResultCore(result);
  153. parserArgumentUnion(ap, arg, CNEXT_NT);
  154. if (!CHECK_RESULT(result))
  155. return result->type;
  156. freeResult(result);
  157. if ((file = ap[0].value)->value->type != V_file || file->value->data.file.file == NULL) {
  158. setResultError(E_TypeException, INSTANCE_ERROR(file), LINEFILE, true, CNEXT_NT);
  159. return R_error;
  160. }
  161. if (ap[1].value->value->type != V_str) {
  162. setResultError(E_TypeException, ONLY_ACC(str, str), LINEFILE, true, CNEXT_NT);
  163. return R_error;
  164. }
  165. fseek(file->value->data.file.file, 0L, 1); // 改变文件状态(什么都没做)
  166. fprintf(file->value->data.file.file, "%ls", ap[1].value->value->data.str.str);
  167. setResult(result, inter);
  168. return result->type;
  169. }
  170. ResultType file_get_seek(O_FUNC){
  171. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  172. {.must=-1}};
  173. LinkValue *file;
  174. long seek;
  175. setResultCore(result);
  176. parserArgumentUnion(ap, arg, CNEXT_NT);
  177. if (!CHECK_RESULT(result))
  178. return result->type;
  179. freeResult(result);
  180. if ((file = ap[0].value)->value->type != V_file || file->value->data.file.file == NULL) {
  181. setResultError(E_TypeException, INSTANCE_ERROR(file), LINEFILE, true, CNEXT_NT);
  182. return R_error;
  183. }
  184. seek = ftell(file->value->data.file.file);
  185. makeIntValue(seek, LINEFILE, CNEXT_NT);
  186. return result->type;
  187. }
  188. ResultType file_err_core(O_FUNC, int type){
  189. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  190. {.must=-1}};
  191. LinkValue *file;
  192. setResultCore(result);
  193. parserArgumentUnion(ap, arg, CNEXT_NT);
  194. if (!CHECK_RESULT(result))
  195. return result->type;
  196. freeResult(result);
  197. if ((file = ap[0].value)->value->type != V_file || file->value->data.file.file == NULL) {
  198. setResultError(E_TypeException, INSTANCE_ERROR(file), LINEFILE, true, CNEXT_NT);
  199. return R_error;
  200. }
  201. switch (type) {
  202. case 1:
  203. makeBoolValue(feof(file->value->data.file.file), LINEFILE, CNEXT_NT);
  204. break;
  205. case 2:
  206. makeBoolValue(ferror(file->value->data.file.file), LINEFILE, CNEXT_NT);
  207. break;
  208. case 3:
  209. clearerr(file->value->data.file.file);
  210. default:
  211. setResult(result, inter);
  212. break;
  213. }
  214. return result->type;
  215. }
  216. ResultType file_isend(O_FUNC){
  217. return file_err_core(CO_FUNC(arg, var_list, result, belong), 1);
  218. }
  219. ResultType file_iserr(O_FUNC){
  220. return file_err_core(CO_FUNC(arg, var_list, result, belong), 2);
  221. }
  222. ResultType file_clean_err(O_FUNC){
  223. return file_err_core(CO_FUNC(arg, var_list, result, belong), 3);
  224. }
  225. ResultType file_seek(O_FUNC){
  226. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  227. {.type=name_value, .must=1, .name=L"seek", .long_arg=false},
  228. {.type=name_value, .must=0, .name=L"where", .long_arg=false},
  229. {.must=-1}};
  230. LinkValue *file;
  231. int where;
  232. setResultCore(result);
  233. parserArgumentUnion(ap, arg, CNEXT_NT);
  234. if (!CHECK_RESULT(result))
  235. return result->type;
  236. freeResult(result);
  237. if ((file = ap[0].value)->value->type != V_file || file->value->data.file.file == NULL) {
  238. setResultError(E_TypeException, INSTANCE_ERROR(file), LINEFILE, true, CNEXT_NT);
  239. return R_error;
  240. }
  241. if (ap[1].value->value->type != V_int) {
  242. setResultError(E_TypeException, ONLY_ACC(seek, int), LINEFILE, true, CNEXT_NT);
  243. return R_error;
  244. }
  245. if (ap[2].value != NULL) {
  246. if (ap[2].value->value->type != V_int) {
  247. setResultError(E_TypeException, ONLY_ACC(where, int), LINEFILE, true, CNEXT_NT);
  248. return R_error;
  249. }
  250. switch (ap[2].value->value->data.int_.num) {
  251. case 0:
  252. where = SEEK_SET;
  253. break;
  254. case 1:
  255. where = SEEK_CUR;
  256. break;
  257. case 2:
  258. where = SEEK_END;
  259. break;
  260. default:
  261. setResultError(E_TypeException, ONLY_ACC(where, (int)0/1/2), LINEFILE, true, CNEXT_NT);
  262. return R_error;
  263. }
  264. } else
  265. where = SEEK_SET;
  266. fgetwc(file->value->data.file.file); // 必须先读取一个字节才可以调用seek
  267. fseek(file->value->data.file.file, ap[1].value->value->data.int_.num, where);
  268. setResult(result, inter);
  269. return result->type;
  270. }
  271. ResultType file_close(O_FUNC){
  272. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  273. {.must=-1}};
  274. LinkValue *file;
  275. setResultCore(result);
  276. parserArgumentUnion(ap, arg, CNEXT_NT);
  277. if (!CHECK_RESULT(result)) {
  278. return result->type;
  279. }
  280. freeResult(result);
  281. if ((file = ap[0].value)->value->type != V_file) {
  282. setResultError(E_TypeException, INSTANCE_ERROR(file), LINEFILE, true, CNEXT_NT);
  283. return R_error;
  284. }
  285. if (file->value->data.file.file != NULL && !file->value->data.file.is_std) {
  286. fclose(file->value->data.file.file);
  287. file->value->data.file.file = NULL;
  288. file->value->data.file.is_std = true;
  289. memFree(file->value->data.file.path);
  290. memFree(file->value->data.file.mode);
  291. }
  292. setResult(result, inter);
  293. return result->type;
  294. }
  295. ResultType file_enter(O_FUNC){
  296. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  297. {.must=-1}};
  298. setResultCore(result);
  299. parserArgumentUnion(ap, arg, CNEXT_NT);
  300. if (!CHECK_RESULT(result)) {
  301. return result->type;
  302. }
  303. freeResult(result);
  304. if (ap[0].value->value->type != V_file || ap[0].value->value->data.file.file == NULL) {
  305. setResultError(E_TypeException, INSTANCE_ERROR(file), LINEFILE, true, CNEXT_NT);
  306. return R_error;
  307. }
  308. setResultOperation(result, ap[0].value);
  309. return result->type;
  310. }
  311. void registeredFile(R_FUNC){
  312. LinkValue *object = inter->data.base_obj[B_FILE];
  313. NameFunc tmp[] = {{L"read", file_read, object_free_, .var=nfv_notpush},
  314. {L"write", file_write, object_free_, .var=nfv_notpush},
  315. {L"close", file_close, object_free_, .var=nfv_notpush},
  316. {L"get_seek", file_get_seek, object_free_, .var=nfv_notpush},
  317. {L"seek", file_seek, object_free_, .var=nfv_notpush},
  318. {L"readline", file_readline, object_free_, .var=nfv_notpush},
  319. {L"end", file_isend, object_free_, .var=nfv_notpush},
  320. {L"err", file_iserr, object_free_, .var=nfv_notpush},
  321. {L"clean", file_clean_err, object_free_, .var=nfv_notpush},
  322. {inter->data.mag_func[M_ENTER], file_enter, object_free_, .var=nfv_notpush},
  323. // {inter->data.mag_func[M_DEL], file_close, object_free_, .var=nfv_notpush},
  324. {inter->data.mag_func[M_EXIT], file_close, object_free_, .var=nfv_notpush},
  325. {inter->data.mag_func[M_NEW], file_new, class_free_, .var=nfv_notpush},
  326. {inter->data.mag_func[M_INIT], file_init, object_free_, .var=nfv_notpush},
  327. {NULL, NULL}};
  328. gc_addTmpLink(&object->gc_status);
  329. addBaseClassVar(L"file", object, belong, inter);
  330. iterBaseClassFunc(tmp, object, CFUNC_CORE(inter->var_list));
  331. gc_freeTmpLink(&object->gc_status);
  332. }
  333. void makeBaseFile(Inter *inter){
  334. LinkValue *file = makeBaseChildClass(inter->data.base_obj[B_VOBJECT], inter);
  335. gc_addStatementLink(&file->gc_status);
  336. inter->data.base_obj[B_FILE] = file;
  337. }