PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/Csound5.13.0/util1/csd_util/makecsd.c

#
C | 328 lines | 271 code | 19 blank | 38 comment | 144 complexity | 027c9cbba66ae1e681e6482f70ac8176 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, BSD-3-Clause, LGPL-2.0
  1. /* makecsd utility - written by Istvan Varga, Mar 2003 */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <errno.h>
  6. static char *orcname = NULL, *sconame = NULL, *optname = NULL;
  7. static int nr_infiles = 0;
  8. static int max_infiles = 0;
  9. static char **infile_names = NULL;
  10. static int output_is_stdout = 1;
  11. static char *outflname = NULL;
  12. static FILE *outfile = NULL;
  13. static int tabstop_size = 0;
  14. /* convert 6 bits of input and write to output file */
  15. extern int encode_byte(FILE*, FILE*);
  16. /* convert an entire input file */
  17. extern void encode_file(char*, FILE*);
  18. /* line width */
  19. extern int maxlinepos;
  20. static int setorchnam(char *s)
  21. {
  22. char *c;
  23. if (orcname != NULL) return 0; /* orchestra name is already set */
  24. if (strlen(s) < 5) return 0; /* name is too short */
  25. c = s + (int) strlen(s);
  26. /* check if extension is correct */
  27. --c; if (*c != 'C' && *c != 'c') return 0;
  28. --c; if (*c != 'R' && *c != 'r') return 0;
  29. --c; if (*c != 'O' && *c != 'o') return 0;
  30. --c; if (*c != '.') return 0;
  31. /* set orchestra name and report success */
  32. orcname = s;
  33. return 1;
  34. }
  35. static int setscornam(char *s)
  36. {
  37. char *c;
  38. if (sconame != NULL) return 0; /* score name is already set */
  39. if (strlen(s) < 5) return 0; /* name is too short */
  40. c = s + (int) strlen(s);
  41. /* check if extension is correct */
  42. --c; if (*c != 'O' && *c != 'o') return 0;
  43. --c; if (*c != 'C' && *c != 'c') return 0;
  44. --c; if (*c != 'S' && *c != 's') return 0;
  45. --c; if (*c != '.') return 0;
  46. /* set score name and report success */
  47. sconame = s;
  48. return 1;
  49. }
  50. /* read a single character from orc/sco input file, with check for */
  51. /* end of file and Unix/MS-DOS/Mac format files */
  52. static int mygetc(FILE *f, int *end_of_file)
  53. {
  54. int c;
  55. if (*end_of_file) return (-1); /* end of file */
  56. c = getc(f);
  57. if (c == '\r') { /* deal with MS-DOS and Mac files */
  58. c = getc(f);
  59. if (c == EOF) {
  60. *end_of_file = 1;
  61. return '\n';
  62. }
  63. if (c != '\n') /* CR-only: Mac format */
  64. ungetc(c, f);
  65. return '\n';
  66. }
  67. if (c == EOF) {
  68. *end_of_file = 1; /* end of file */
  69. return (-1);
  70. }
  71. return c;
  72. }
  73. /* write a line to output file, with tab->space conversion if requested */
  74. static void write_line(FILE *outfl, char *buf, int n)
  75. {
  76. int linepos = 0;
  77. while (n--) {
  78. if (tabstop_size && *buf == '\t') { /* expand tabs to spaces */
  79. do {
  80. putc(' ', outfl);
  81. } while ((++linepos) % tabstop_size);
  82. }
  83. else {
  84. if (*buf == '\n') linepos = -1; /* new line: reset line position */
  85. putc((int) *buf, outfl);
  86. linepos++;
  87. }
  88. buf++;
  89. }
  90. }
  91. static void convert_txt_file(char *inflname, FILE *outfl)
  92. {
  93. FILE *infile;
  94. char linebuf[16384];
  95. int linepos = 0, c, frstline = 1;
  96. int is_eof;
  97. /* open file */
  98. infile = fopen(inflname, "rb");
  99. if (infile == NULL) {
  100. fprintf(stderr, "makecsd: error opening input file %s: %s\n",
  101. inflname, strerror(errno));
  102. exit(-1);
  103. }
  104. is_eof = 0;
  105. /* read entire file and copy to output */
  106. while (!is_eof) {
  107. /* read next non-empty line to buffer */
  108. linepos = 0;
  109. do {
  110. c = mygetc(infile, &is_eof);
  111. if (is_eof || c == '\n') {
  112. /* end of line: remove any trailing white space */
  113. while (linepos &&
  114. (linebuf[linepos - 1] == ' ' || linebuf[linepos - 1] == '\t'))
  115. linepos--;
  116. linebuf[linepos++] = '\n';
  117. if (is_eof || /* end of file */
  118. (linepos > 1 && linebuf[linepos - 2] != '\n'))
  119. break; /* or a new non-empty line */
  120. }
  121. else
  122. linebuf[linepos++] = c;
  123. } while (1);
  124. if (is_eof) break; /* end of file */
  125. /* at beginning of file: skip any leading empty lines */
  126. if (frstline) {
  127. int n = -1;
  128. frstline = 0;
  129. while (++n < linepos && linebuf[n] == '\n');
  130. /* if there is anything to print */
  131. if (n < linepos)
  132. write_line(outfl, &(linebuf[n]), linepos - n);
  133. }
  134. else /* otherwise just print as it is */
  135. write_line(outfl, &(linebuf[0]), linepos);
  136. }
  137. /* at end of file: skip any trailing empty lines */
  138. while (linepos && linebuf[linepos - 1] == '\n')
  139. linepos--;
  140. linebuf[linepos++] = '\n';
  141. /* and print last line */
  142. write_line(outfl, &(linebuf[0]), linepos);
  143. /* close input file */
  144. fclose(infile); infile = NULL;
  145. }
  146. int main(int argc, char **argv)
  147. {
  148. int i, j;
  149. /* parse command line options */
  150. i = 0;
  151. j = argc;
  152. while (--j) {
  153. i++;
  154. if (!strcmp(argv[i], "-w")) { /* line width */
  155. if (!(--j)) {
  156. fprintf(stderr, "makecsd: missing option for -w\n");
  157. exit(-1);
  158. }
  159. i++;
  160. maxlinepos = (int) atoi(argv[i]);
  161. if (maxlinepos < 20) maxlinepos = 20;
  162. if (maxlinepos > 200) maxlinepos = 200;
  163. }
  164. else if (!strcmp(argv[i], "-o")) { /* output file name */
  165. if (!(--j)) {
  166. fprintf(stderr, "makecsd: missing option for -o\n");
  167. exit(-1);
  168. }
  169. i++;
  170. outflname = argv[i];
  171. if (!strcmp(outflname, "-"))
  172. output_is_stdout = 1;
  173. else
  174. output_is_stdout = 0;
  175. }
  176. else if (!strcmp(argv[i], "-t")) { /* tabstop size */
  177. if (!(--j)) {
  178. fprintf(stderr, "makecsd: missing option for -t\n");
  179. exit(-1);
  180. }
  181. i++;
  182. tabstop_size = (int) atoi(argv[i]);
  183. if (tabstop_size < 0) tabstop_size = 0;
  184. if (tabstop_size > 24) tabstop_size = 24;
  185. }
  186. else if (!strcmp(argv[i], "-f")) { /* options file name */
  187. if (!(--j)) {
  188. fprintf(stderr, "makecsd: missing option for -f\n");
  189. exit(-1);
  190. }
  191. i++;
  192. optname = argv[i];
  193. }
  194. else { /* input file name */
  195. if (*(argv[i]) == '-') {
  196. fprintf(stderr, "makecsd: invalid option: %s\n", argv[i]);
  197. exit(-1);
  198. }
  199. if (!(setorchnam(argv[i]) || setscornam(argv[i]))) {
  200. /* if input is neither an orchestra, nor a score file, */
  201. /* encode it as Base64 */
  202. if (nr_infiles >= max_infiles) {
  203. /* extend number of input files */
  204. max_infiles = max_infiles + (max_infiles >> 2) + 16;
  205. infile_names = (char**) realloc(infile_names,
  206. sizeof(char*) * max_infiles);
  207. if (infile_names == NULL) {
  208. fprintf(stderr, "makecsd: not enough memory\n");
  209. exit(-1);
  210. }
  211. }
  212. infile_names[nr_infiles] = argv[i];
  213. nr_infiles++;
  214. }
  215. }
  216. }
  217. if (!nr_infiles && (orcname == NULL && sconame == NULL)) {
  218. /* print usage */
  219. fprintf(stderr, "makecsd: no input files\n");
  220. fprintf(stderr,
  221. "usage: makecsd [OPTIONS ... ] infile1 [ infile2 [ ... ]]\n");
  222. fprintf(stderr, "options:\n");
  223. fprintf(stderr,
  224. " -t <n> expand tabs to spaces using tabstop size ");
  225. fprintf(stderr, "n (default: disabled)\n");
  226. fprintf(stderr,
  227. " -w <n> set Base64 line width to n (default: 72)\n");
  228. fprintf(stderr,
  229. " -f <fname> read CSD options from file 'fname'\n");
  230. fprintf(stderr,
  231. " -o <fname> output file name (default: stdout)\n");
  232. exit(-1);
  233. }
  234. /* open output file */
  235. if (!output_is_stdout) {
  236. outfile = fopen(outflname, "w");
  237. if (outfile == NULL) {
  238. fprintf(stderr, "makecsd: error opening output file %s: %s\n",
  239. outflname, strerror(errno));
  240. exit(-1);
  241. }
  242. }
  243. else
  244. outfile = stdout;
  245. /* create CSD file */
  246. fprintf(outfile, "<CsoundSynthesizer>\n");
  247. fprintf(outfile, "; this CSD file was generated with makecsd v1.1\n");
  248. fprintf(outfile, "; (written by Istvan Varga, Mar 2003)\n");
  249. fprintf(outfile, "<CsOptions>\n");
  250. fprintf(outfile, "; set command line options here\n");
  251. /* CSD options */
  252. for (i = 0; i < nr_infiles; i++) {
  253. char *s = infile_names[i], *s0;
  254. j = (int) strlen(s);
  255. if (j < 4) continue;
  256. /* check for MIDI file */
  257. if (s[j - 1] != 'D' && s[j - 1] != 'd') continue;
  258. if (s[j - 2] != 'I' && s[j - 2] != 'i') continue;
  259. if (s[j - 3] != 'M' && s[j - 3] != 'm') continue;
  260. if (s[j - 4] != '.') continue;
  261. /* add to options if found */
  262. /* strip any leading components from file name */
  263. s0 = s; s = s0 + ((int) strlen(s0) - 1);
  264. while (s >= s0 && *s != '/' && *s != '\\' && *s != ':') s--;
  265. s++;
  266. fprintf(outfile, "-F %s\n", s);
  267. break;
  268. }
  269. if (optname != NULL) {
  270. /* copy options file if specified */
  271. convert_txt_file(optname, outfile);
  272. /* hack: remove blank line from end of options */
  273. fflush(outfile); fseek(outfile, -1L, SEEK_END);
  274. }
  275. else if (i >= nr_infiles) {
  276. fprintf(outfile, "\n"); /* put blank line if there are no options */
  277. }
  278. fprintf(outfile, "</CsOptions>\n");
  279. /* orchestra */
  280. if (orcname != NULL) {
  281. fprintf(outfile, "<CsInstruments>\n");
  282. convert_txt_file(orcname, outfile);
  283. fprintf(outfile, "</CsInstruments>\n");
  284. }
  285. else {
  286. fprintf(stderr, "makecsd: warning: no orchestra file\n");
  287. }
  288. /* score */
  289. if (sconame != NULL) {
  290. fprintf(outfile, "<CsScore>\n");
  291. convert_txt_file(sconame, outfile);
  292. fprintf(outfile, "</CsScore>\n");
  293. }
  294. else {
  295. fprintf(stderr, "makecsd: warning: no score file\n");
  296. }
  297. /* Base64 encode any remaining input files */
  298. for (i = 0; i < nr_infiles; i++)
  299. encode_file(infile_names[i], outfile);
  300. /* end of CSD file */
  301. fprintf(outfile, "</CsoundSynthesizer>\n\n");
  302. /* close output file */
  303. if (!output_is_stdout) {
  304. fflush(outfile);
  305. fclose(outfile);
  306. }
  307. free(infile_names);
  308. return 0;
  309. }