static int processIncludes(TextPackage *package, const char *input, DFBuffer *output, const char *path, DFError **error) { int ok = 1; const char **lines = DFStringSplit(input,"\n",0); for (int lineno = 0; lines[lineno] && ok; lineno++) { const char *line = lines[lineno]; if (DFStringHasPrefix(line,"#include \"") && DFStringHasSuffix(line,"\"")) { char *inclRelPath = DFSubstring(line,10,strlen(line)-1); char *inclAbsPath = DFAppendPathComponent(path,inclRelPath); char *inclDirName = DFPathDirName(inclAbsPath); char *inclContent = DFStringReadFromFile(inclAbsPath,error); if (inclContent == NULL) { DFErrorFormat(error,"%s: %s",inclRelPath,DFErrorMessage(error)); ok = 0; } else if (!processIncludes(package,inclContent,output,inclDirName,error)) { ok = 0; } free(inclRelPath); free(inclAbsPath); free(inclDirName); free(inclContent); } else { DFBufferFormat(output,"%s\n",line); } } free(lines); return ok; }
static int parsePackage(TextPackage *package, const char *string, const char *path, DFError **error) { DFBuffer *replaced = DFBufferNew(); if (!strcmp(path,"")) path = "."; if (!processIncludes(package,string,replaced,path,error)) { DFBufferRelease(replaced); return 0; } char *currentKey = strdup(""); DFBuffer *currentValue = DFBufferNew(); const char **lines = DFStringSplit(replaced->data,"\n",0); for (int lineno = 0; lines[lineno]; lineno++) { const char *line = lines[lineno]; if (!DFStringHasPrefix(line,"#")) { DFBufferFormat(currentValue,"%s\n",line); } else if (DFStringHasPrefix(line,"#item ")) { package->keys = (char **)realloc(package->keys,(package->nkeys+2)*sizeof(char *)); package->keys[package->nkeys++] = strdup(currentKey); package->keys[package->nkeys] = NULL; DFHashTableAdd(package->items,currentKey,currentValue->data); free(currentKey); DFBufferRelease(currentValue); currentKey = DFSubstring(line,6,strlen(line)); currentValue = DFBufferNew(); } else if (DFStringHasPrefix(line,"##")) { DFBufferFormat(currentValue,"%s\n",&line[1]); } else { DFErrorFormat(error,"Unknown command: %s on line %d",line,(lineno+1)); return 0; } } package->keys = (char **)realloc(package->keys,(package->nkeys+2)*sizeof(char *)); package->keys[package->nkeys++] = strdup(currentKey); package->keys[package->nkeys] = NULL; DFHashTableAdd(package->items,currentKey,currentValue->data); free(lines); free(currentKey); DFBufferRelease(currentValue); DFBufferRelease(replaced); return 1; }
int textPackageGet(const char *filename, const char *itemPath, DFError **error) { char *value = DFStringReadFromFile(filename,error); if (value == NULL) { DFErrorFormat(error,"%s: %s",filename,DFErrorMessage(error)); return 0; } const char **components = DFStringSplit(itemPath,"/",0); for (size_t i = 0; components[i]; i++) { const char *name = components[i]; char *filePath = DFPathDirName(filename); TextPackage *package = TextPackageNewWithString(value,filePath,error); free(filePath); if (package == NULL) { free(value); free(components); return 0; } free(value); value = xstrdup(DFHashTableLookup(package->items,name)); if (value == NULL) { DFErrorFormat(error,"%s: Item %s not found",filename,itemPath); TextPackageRelease(package); free(value); free(components); return 0; } TextPackageRelease(package); } free(components); printf("%s",value); free(value); return 1; }