BibTeXq
query a bibtex file
|
00001 /* 00002 * This work is licensed under a Creative Commons 00003 * Attribution-Noncommercial-Share Alike 3.0 United States License. 00004 * 00005 * http://creativecommons.org/licenses/by-nc-sa/3.0/us/ 00006 * 00007 * You are free: 00008 * 00009 * to Share - to copy, distribute, display, and perform the work 00010 * to Remix - to make derivative works 00011 * 00012 * Under the following conditions: 00013 * 00014 * Attribution. You must attribute the work in the manner specified by the 00015 * author or licensor (but not in any way that suggests that they endorse you 00016 * or your use of the work). 00017 * 00018 * Noncommercial. You may not use this work for commercial purposes. 00019 * 00020 * Share Alike. If you alter, transform, or build upon this work, you may 00021 * distribute the resulting work only under the same or similar license to 00022 * this one. 00023 * 00024 * For any reuse or distribution, you must make clear to others the license 00025 * terms of this work. The best way to do this is by including this header. 00026 * 00027 * Any of the above conditions can be waived if you get permission from the 00028 * copyright holder. 00029 * 00030 * Apart from the remix rights granted under this license, nothing in this 00031 * license impairs or restricts the author's moral rights. 00032 */ 00033 00034 00046 #include <config.h> 00047 00048 #include <stdlib.h> 00049 #include <stdio.h> 00050 #include <inttypes.h> 00051 #include <string.h> 00052 #include <assert.h> 00053 #include <ctype.h> 00054 00055 #ifdef BIBTEXQ_HAVE_DMALLOC 00056 #include <dmalloc.h> 00057 #endif 00058 00059 #include "bibtex_entry.h" 00060 00061 00063 static void remove_extra_spaces(char* str) 00064 { 00065 char* chars; 00066 char* chars_shift; 00067 char prev_char; 00068 int len; 00069 00070 chars = str; 00071 00072 if (len == 0) 00073 { 00074 return; 00075 } 00076 else if (len == 1 && isspace(*chars)) 00077 { 00078 *chars = '\0'; 00079 return; 00080 } 00081 00082 while (*chars != '\0') 00083 { 00084 if (*chars == '\n' || *chars == '\t') 00085 { 00086 chars_shift = chars; 00087 while (*chars_shift != '\0') 00088 { 00089 *chars_shift = *(chars_shift+1); 00090 chars_shift++; 00091 } 00092 } 00093 else 00094 { 00095 chars++; 00096 } 00097 } 00098 00099 chars = str; 00100 prev_char = '\0'; 00101 while (*chars != '\0') 00102 { 00103 if (prev_char == ' ' && *chars == ' ') 00104 { 00105 chars_shift = chars; 00106 while (*chars_shift != '\0') 00107 { 00108 *chars_shift = *(chars_shift+1); 00109 chars_shift++; 00110 } 00111 } 00112 else 00113 { 00114 prev_char = *chars; 00115 chars++; 00116 } 00117 } 00118 } 00119 00120 00133 static void create_bibtex_field 00134 ( 00135 Bibtex_field** field_out, 00136 const char* name, 00137 const char* value 00138 ) 00139 { 00140 Bibtex_field* field; 00141 00142 if (*field_out == NULL) 00143 { 00144 assert(*field_out = malloc(sizeof(Bibtex_field))); 00145 (*field_out)->name = NULL; 00146 (*field_out)->value = NULL; 00147 } 00148 field = *field_out; 00149 00150 field->name = malloc(sizeof(char)*strlen(name)); 00151 field->value = malloc(sizeof(char)*strlen(value)); 00152 00153 strcpy(field->name, name); 00154 strcpy(field->value, value); 00155 00156 remove_extra_spaces(field->name); 00157 remove_extra_spaces(field->value); 00158 } 00159 00160 00169 static void free_bibtex_fields(Bibtex_field** fields, uint32_t num_fields) 00170 { 00171 uint32_t i; 00172 00173 if (fields == NULL || num_fields == 0) 00174 return; 00175 00176 for (i = 0; i < num_fields; i++) 00177 { 00178 free(fields[ i ]->name); 00179 free(fields[ i ]->value); 00180 free(fields[ i ]); 00181 } 00182 free(fields); 00183 } 00184 00185 00186 00187 00198 void create_bibtex_entry 00199 ( 00200 Bibtex_entry** entry_out, 00201 const char* type, 00202 const char* key 00203 ) 00204 { 00205 Bibtex_entry* entry; 00206 00207 if (*entry_out == NULL) 00208 { 00209 assert(*entry_out = malloc(sizeof(Bibtex_entry))); 00210 (*entry_out)->type = NULL; 00211 (*entry_out)->key = NULL; 00212 (*entry_out)->fields = NULL; 00213 (*entry_out)->num_fields = 0; 00214 (*entry_out)->num_unused_fields = 0; 00215 } 00216 else 00217 { 00218 (*entry_out)->num_unused_fields += (*entry_out)->num_fields; 00219 (*entry_out)->num_fields = 0; 00220 } 00221 entry = *entry_out; 00222 00223 entry->type = malloc(sizeof(char)*strlen(type)); 00224 entry->key = malloc(sizeof(char)*strlen(key)); 00225 00226 strcpy(entry->type, type); 00227 strcpy(entry->key, key); 00228 } 00229 00230 00232 void free_bibtex_entry(Bibtex_entry* entry) 00233 { 00234 if (entry == NULL) 00235 return; 00236 00237 free_bibtex_fields(entry->fields, entry->num_fields + 00238 entry->num_unused_fields); 00239 free(entry->type); 00240 free(entry->key); 00241 free(entry); 00242 } 00243 00244 00250 void add_field_to_bibtex_entry 00251 ( 00252 Bibtex_entry* entry, 00253 const char* name, 00254 const char* value 00255 ) 00256 { 00257 Bibtex_field* field = NULL; 00258 00259 if (entry->num_unused_fields > 0) 00260 { 00261 entry->num_unused_fields--; 00262 entry->num_fields++;; 00263 field = entry->fields[ entry->num_fields-1 ]; 00264 } 00265 else 00266 { 00267 entry->num_fields++; 00268 assert(entry->fields = realloc(entry->fields, 00269 entry->num_fields*sizeof(Bibtex_field*))); 00270 } 00271 00272 create_bibtex_field(&field, name, value); 00273 entry->fields[ entry->num_fields-1 ] = field; 00274 } 00275 00276 00281 void write_bibtex_entry(Bibtex_entry* entry, FILE* fp) 00282 { 00283 uint32_t i; 00284 00285 fprintf(fp, "@%s{%s", entry->type, entry->key); 00286 00287 for (i = 0; i < entry->num_fields; i++) 00288 { 00289 fprintf(fp, ",\n %*s = {%s}", 10, 00290 entry->fields[ i ]->name, entry->fields[ i ]->value); 00291 } 00292 00293 fprintf(fp, "\n}\n"); 00294 }