void add_file(char *p) { char *x = strrchr(p, '.'); if (x == NULL) dunno(p); switch (x[1]) { case 'a': append_obj(&objlist, p, TYPE_A); break; case 's': append_obj(&objlist, p, TYPE_s); break; case 'S': append_obj(&objlist, p, TYPE_S); break; case 'c': /* HACK should be TYPE_C once we split cpp */ append_obj(&objlist, p, TYPE_C_pp); c_files++; break; case 'o': append_obj(&objlist, p, TYPE_O); break; default: dunno(p); } }
/** Analizza la stringa pattern per la verifica che sia uno schema valido per musicmeshfsc. Come effetto collaterale, riempie due vettori di dynamic_str_t (non ha effetti collaterali se si passa NULL ad entrambi i valori) SCHEMA = NOME ("/" NOME)* NOME = NOME1 | NOME2 NOME1 = FISSO NOME2? NOME2 = KEYWORD NOME1? FISSO = ([^/%] | "%%")+ KEYWORD = %artist | %year | %album | ... Nota che KEYWORD e dipende dal contenuto di KEYWORDS, definito in constants.c Al momento gli unici vincoli sono che # non deve né iniziare né terminare per '/' # il carattere '%' non è usato liberamente: esso infatti è usato per delimitare i segnaposto da usare; gli unici segnaposto supportati sono: - %artist -> Artista - %year -> Anno - %album -> Album - %track -> Traccia - %title -> Titolo - %genre -> Genere - %host -> Host - %path -> Path originale - %type -> Tipo del file originale # gli elementi di tipo FISSO non possono essere stringhe vuote, né essere il solo carattere '_' (poiché è usato per altri scopi) es: %artist/%year - %album/%track + %title.%type diventa: NOME "/" NOME "/" NOME NOME2 "/" NOME2 "/" NOME2 KEYWORD"/"KEYWORD NOME1 "/"KEYWORD NOME1 KEYWORD"/"KEYWORD FISSO NOME2 "/"KEYWORD FISSO NOME2 KEYWORD"/"KEYWORD FISSO KEYWORD"/"KEYWORD FISSO KEYWORD NOME1 KEYWORD"/"KEYWORD FISSO KEYWORD"/"KEYWORD FISSO KEYWORD FISSO NOME2 KEYWORD"/"KEYWORD FISSO KEYWORD"/"KEYWORD FISSO KEYWORD FISSO KEYWORD %artist"/" %year " - " %album "/" %track " + " %title "." %type \param schema schema da verificare \param fissi vettore contenente gli elementi fissi riconosciuti \param keywords vettore contenente le keywords riconosciute \return 0 in caso di successo, -1 altrimenti \note fissi e keywords non sono riempiti se viene passato NULL */ int parse_schema(const char* schema, dynamic_obj_t* fissi, dynamic_obj_t* keywords) { dynamic_str_t *el_fisso = NULL, *el_keyword = NULL; if (fissi) { el_fisso = malloc(sizeof(dynamic_str_t)); init_str(el_fisso); } if (keywords) { el_keyword = malloc(sizeof(dynamic_str_t)); init_str(el_keyword); } int ret = nome(schema, 0, el_fisso, el_keyword); if (ret == -1) return -1; // non c'è neanche un frammento while (ret != -1) { if (fissi) append_obj(fissi, el_fisso); if (keywords) append_obj(keywords, el_keyword); if (!schema[ret]) return 0; // fine stringa if (schema[ret++] != '/') return -1; if (fissi) { el_fisso = malloc(sizeof(dynamic_str_t)); init_str(el_fisso); } if (keywords) { el_keyword = malloc(sizeof(dynamic_str_t)); init_str(el_keyword); } ret = nome(schema, ret, el_fisso, el_keyword); } return -1; }
/** Assume che buf sia un dynamic_obj_t Riempie le coppie di buf con le tuple trovate */ int get_columns(void* buf, int n_colonne, char** value, char** header) { (void) header; // non usato dynamic_str_t* row = malloc(sizeof(dynamic_str_t)); init_str(row); for (int i=0; i<n_colonne; i++) append_str(row, value[i]); append_obj((dynamic_obj_t*)buf, row); return 0; }
/** analizza il generico percorso, e avvalora dinamici es: schema = %artist/%year - %album/%track + %title.%type tramite parse_schema() ottengo fissi = [ [""], ["", " - "], ["", " + , "."] ] keywords = [ ["artist"], ["year", "album"], ["track", "title", "type"] ] se ora ho un percorso del tipo path = "/Max Gazzè/2008 - Tra l'aratro e la radio/02 + Il solito sesso.mp3" allora tramite parse_path() == IS_A_FILE ottengo dinamici = [ ["Max Gazzè"], ["2008", "Tra l'aratro e la radio"], ["02", "Il solito sesso", "mp3"] ] se invece ho un percorso tipo path = "/Max Gazzè/2008 - Tra l'aratro e la radio" # già normalizzato! allora tramite parse_path() == IS_A_DIR ottengo dinamici = [ ["Max Gazzè"], ["2008", "Tra l'aratro e la radio"] ] \param path percorso da analizzare \param fissi elementi fissi *già analizzati* tramite parse_schema() \param keywords keywords *già analizzate* tramite parse_schema() \param dinamici elementi dinamici ottenuti sostituendo le keywords (modificato in-place) \return IS_A_FILE se path è un percorso valido, per un file, IS_A_DIR se path è un percorso valido, per una directory, -1 altrimenti */ int parse_path(const char* path, dynamic_obj_t fissi, dynamic_obj_t keywords, dynamic_obj_t* dinamici) { if (!path || !path[0]) // dev'essere almeno una stringa non vuota! return -1; init_obj(dinamici); if ((path[0] == '/') && (!path[1])) // caso particolare: è "/" return IS_A_DIR; dynamic_str_t nomi = split(path+1, '/'); for (int i=0; i<nomi.size; i++) { /* directory = ^ el_fisso (el_dinamico el_fisso)* el_dinamico? $ quindi avrò 0 < el_fissi.size == el_dinamici.size + ( 0 || 1 ) */ dynamic_str_t el_fissi = *(dynamic_str_t*)(fissi.buf[i]); if (!el_fissi.size) return -1; dynamic_str_t el_keywords = *(dynamic_str_t*)(keywords.buf[i]); dynamic_str_t* el_dinamici = malloc(sizeof(dynamic_str_t)); init_str(el_dinamici); int offset = startswith(nomi.buf[i], el_fissi.buf[0]); if (offset == -1) return -1; for (int j=1; j<el_fissi.size; j++) { int new_offset = -1, size_dinamico = 0; char* b = el_fissi.buf[j]; for (; new_offset == -1; size_dinamico += 1) { char* a = nomi.buf[i]+offset+size_dinamico; if (!a[0]) return -1; new_offset = startswith(a, b); // printf("startswith(`%s', `%s') = %d\n", a, b, new_offset); } char tmp[size_dinamico]; tmp[0] = tmp[size_dinamico-1] = '\0'; strncpy(tmp, nomi.buf[i]+offset, size_dinamico-1); append_str(el_dinamici, tmp); offset += new_offset + size_dinamico - 1; } if (el_fissi.size == el_keywords.size) { if (!(nomi.buf[i]+offset)) return -1; int size = strlen(nomi.buf[i]+offset); char tmp[size+1]; tmp[0] = '\0'; strcpy(tmp, nomi.buf[i]+offset); append_str(el_dinamici, tmp); } append_obj(dinamici, el_dinamici); } return keywords.size == dinamici->size ? IS_A_FILE : IS_A_DIR; }
t_obj *my_spot(t_obj *obj, int fd, int *cmp) { t_tmp *tmp; char *s; tmp = new_tmp(); tmp->name = "spot"; while ((s = get_next_line(fd)) && my_strcmp(s, "</SPOT>")) { if (s[0] && s[0] != COMMENT_CHAR) tmp = parse_str(tmp, s, cmp); (*cmp)++; free(s); } obj = append_obj(obj, tmp); free(s); free(tmp); return (obj); }