NESe (pronounced "Nessie") is a NES emulator based on the e6502 emulator, also written in C with a focus on speed and portability for use on embedded platforms, especially ARM.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

116 lines
2.9KB

  1. #include <errno.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "file.h"
  5. const char* basename(const char* filename) {
  6. const char* slash = filename + strlen(filename) - 1;
  7. for ( ; slash >= filename &&
  8. *slash != '\\' &&
  9. *slash != '/';
  10. --slash );
  11. return &slash[1];
  12. }
  13. int make_filename(char* filename, int max_len,
  14. const char* orig_name,
  15. const char* subdir, const char* ext) {
  16. int status = 0;
  17. int remain = max_len;
  18. const char* orig_base = basename(orig_name);
  19. const char* orig_dot = strrchr(orig_base, '.');
  20. int orig_path_len = orig_base - orig_name;
  21. int orig_base_len = (NULL == orig_dot) ?
  22. strlen(orig_base) :
  23. (orig_dot - orig_base);
  24. // Part 1/4: Leading path
  25. if (0 == status && orig_path_len <= remain) {
  26. memcpy(filename, orig_name, orig_path_len);
  27. remain -= orig_path_len;
  28. filename += orig_path_len;
  29. } else {
  30. status = -1;
  31. }
  32. // Part 2/4: Subdirectory
  33. if (0 == status && NULL != subdir) {
  34. int subdir_len = strlen(subdir);
  35. if ((subdir_len + 1) <= remain) {
  36. memcpy(filename, subdir, subdir_len);
  37. filename += subdir_len;
  38. *filename++ = '/';
  39. remain -= (subdir_len + 1);
  40. } else {
  41. status = -1;
  42. }
  43. }
  44. // Part 3/4: Basename
  45. if (0 == status && orig_base_len <= remain) {
  46. memcpy(filename, orig_name, orig_base_len);
  47. remain -= orig_base_len;
  48. filename += orig_base_len;
  49. } else {
  50. status = -1;
  51. }
  52. // Part 4/4: Extension
  53. if (0 == status && NULL != ext) {
  54. int ext_len = strlen(ext);
  55. if ((ext_len + 1) <= remain) {
  56. *filename++ = '.';
  57. memcpy(filename, ext, ext_len);
  58. remain -= (ext_len + 1);
  59. filename += ext_len;
  60. } else {
  61. status = -1;
  62. }
  63. }
  64. return (status < 0 ? status : (max_len - remain));
  65. }
  66. int write_file(const char* filename, const void* data, int len) {
  67. int status = -1;
  68. FILE* file = fopen(filename, "wb");
  69. if (NULL != file) {
  70. if (1 == fwrite(data, len, 1, file)) {
  71. status = 0;
  72. } else {
  73. fprintf(stderr, "Failed to write %d bytes from %s: %d\n", len, filename, errno);
  74. }
  75. fclose(file);
  76. } else {
  77. fprintf(stderr, "Failed to open %s: %d\n", filename, errno);
  78. }
  79. return status;
  80. }
  81. int read_file(const char* filename, void* data, int len) {
  82. int status = -1;
  83. FILE* file = fopen(filename, "rb");
  84. if (NULL != file) {
  85. if (1 == fread(data, len, 1, file)) {
  86. status = 0;
  87. } else {
  88. fprintf(stderr, "Failed to read %d bytes from %s: %d\n", len, filename, errno);
  89. }
  90. fclose(file);
  91. } else {
  92. fprintf(stderr, "Failed to open %s: %d\n", filename, errno);
  93. }
  94. return status;
  95. }