lorid.c (4226B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stdbool.h> 4 #include <string.h> 5 #include <getopt.h> 6 #include <fontconfig/fontconfig.h> 7 #include "core.h" 8 #include "chordpro.h" 9 #include "config.h" 10 #include "out_pdf.h" 11 12 int 13 main(int argc, char *argv[]) 14 { 15 static struct option long_options[] = { 16 { "print-default-config", no_argument, 0, 'p' }, 17 { "config", required_argument, 0, 'c' }, 18 { "output", required_argument, 0, 'o' }, 19 { "verbose", no_argument, 0, 'v' }, 20 { "version", no_argument, 0, 'V' }, 21 { "help", no_argument, 0, 'h' }, 22 { 0, 0, 0, 0 } 23 }; 24 int o, option_index; 25 int s = 0; 26 const char *chordpro_filepath = NULL; 27 char *config_filepath = NULL; 28 char *input = NULL; 29 char *output = NULL; 30 char *pdf_filename = NULL; 31 struct ChoSong **all_songs = NULL; 32 struct ChoSong **songs = NULL; 33 struct ChoSong **so; 34 struct Config *config = NULL; 35 FILE *fp = NULL; 36 37 while ((o = getopt_long(argc, argv, "pc:o:Vvh", long_options, &option_index)) != -1) { 38 switch(o) { 39 case 'p': 40 config_print_default(); 41 return 0; 42 case 'c': 43 config_filepath = emalloc((strlen(optarg)+1) * sizeof(char)); 44 strcpy(config_filepath, optarg); 45 break; 46 case 'o': 47 output = erealloc(output, (strlen(optarg)+1) * sizeof(char)); 48 strcpy(output, optarg); 49 break; 50 case 'V': 51 printf(VERSION"\n"); 52 return 0; 53 case 'v': 54 cho_log_enable_info_logs(); 55 util_log_enable_info_logs(); 56 break; 57 case 'h': 58 return system("man lorid"); 59 } 60 } 61 if (config_filepath) { 62 config = config_load_from_file(config_filepath); 63 if (!config) { 64 util_log(NULL, 0, LOG_ERR, "Failed to load the config file '%s'.", config_filepath); 65 goto ERR; 66 } 67 } else { 68 char *home = getenv("HOME"); 69 if (!home) { 70 DEBUG("getenv failed."); 71 util_log(NULL, 0, LOG_ERR, "Failed to read the environment variable 'HOME'."); 72 goto ERR; 73 } 74 size_t size = 26 + strlen(home) + 1; 75 char default_config_path[size]; 76 snprintf(default_config_path, size, "%s/.config/lorid/config.toml", home); 77 config = config_load_from_file(default_config_path); 78 if (!config) { 79 util_log(NULL, 0, LOG_INFO, "Loading default config instead of reading from a file."); 80 config = config_load_default(); 81 } 82 } 83 if (argc == optind) { 84 fp = stdin; 85 input = file_read(fp); 86 all_songs = cho_songs_parse(input, NULL, config); 87 if (!all_songs) { 88 DEBUG("cho_songs_parse failed."); 89 goto ERR; 90 } 91 } else if (argc == optind+1) { 92 fp = fopen(argv[argc-1], "r"); 93 if (!fp) { 94 DEBUG("fopen failed."); 95 goto ERR; 96 } 97 input = file_read(fp); 98 chordpro_filepath = argv[argc-1]; 99 all_songs = cho_songs_parse(input, chordpro_filepath, config); 100 if (!all_songs) { 101 DEBUG("cho_songs_parse failed."); 102 goto ERR; 103 } 104 } else { 105 int file_count = argc - optind; 106 int i; 107 for (i = argc-file_count; i<argc; i++) { 108 fp = fopen(argv[i], "r"); 109 if (!fp) { 110 DEBUG("fopen failed."); 111 goto ERR; 112 } 113 input = file_read(fp); 114 songs = cho_songs_parse(input, argv[i], config); 115 if (!songs) { 116 DEBUG("cho_songs_parse failed."); 117 goto ERR; 118 } 119 for (so = songs; *so; s++, so++) { 120 all_songs = erealloc(all_songs, (s+1) * sizeof(struct ChoSong *)); 121 all_songs[s] = *so; 122 } 123 free(input); 124 fclose(fp); 125 free(songs); 126 input = NULL; 127 fp = NULL; 128 songs = NULL; 129 } 130 all_songs = erealloc(all_songs, (s+1) * sizeof(struct ChoSong *)); 131 all_songs[s] = NULL; 132 printf("ending at index %d\n", s); 133 } 134 qsort(all_songs, cho_song_count(all_songs), sizeof(struct ChoSong *), cho_song_compare); 135 pdf_filename = out_pdf_create(chordpro_filepath, output, all_songs, config); 136 if (!pdf_filename) { 137 DEBUG("out_pdf_create failed."); 138 goto ERR; 139 } 140 util_log(NULL, 0, LOG_INFO, "Writing pdf to file: '%s'.", pdf_filename); 141 free(config_filepath); 142 free(input); 143 free(output); 144 free(pdf_filename); 145 cho_songs_free(all_songs); 146 cho_songs_free(songs); 147 config_free(config); 148 if (fp) { 149 fclose(fp); 150 } 151 return 0; 152 ERR: 153 if (s > 0 && all_songs[s-1]) { 154 all_songs = erealloc(all_songs, (s+1) * sizeof(struct ChoSong *)); 155 all_songs[s] = NULL; 156 } 157 free(config_filepath); 158 free(input); 159 free(output); 160 free(pdf_filename); 161 cho_songs_free(all_songs); 162 cho_songs_free(songs); 163 config_free(config); 164 if (fp) { 165 fclose(fp); 166 } 167 return 1; 168 }