this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Implement Merge operation in PlistBuddy

+128 -25
+128 -25
src/PlistBuddy/PlistBuddy.c
··· 20 20 CFPropertyListRef parseValue(enum PropertyType type, const char* string); 21 21 void deleteEntry(const char* entry); 22 22 void copyEntry(const char* src, const char* dst); 23 + void mergeFile(const char* path, const char* entry); 23 24 24 25 // Forces XML output when printing to screen 25 26 bool forceXML = false; ··· 159 160 return outputFile != NULL; 160 161 } 161 162 163 + CFPropertyListRef loadPlist(const char* filePath) 164 + { 165 + SInt32 errorCode = 0; 166 + CFStringRef errorString = NULL; 167 + CFDataRef data = NULL; 168 + CFPropertyListRef plist; 169 + CFStringRef path = CFStringCreateWithCString(kCFAllocatorDefault, filePath, kCFStringEncodingUTF8); 170 + CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path, kCFURLPOSIXPathStyle, false); 171 + 172 + CFRelease(path); 173 + 174 + CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, url, &data, NULL, NULL, &errorCode); 175 + CFRelease(url); 176 + 177 + if (errorCode != 0) 178 + { 179 + printf("Error Reading File: %s\n", filePath); 180 + return false; 181 + } 182 + 183 + plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, data, kCFPropertyListMutableContainers, &errorString); 184 + 185 + if (errorString != NULL) 186 + { 187 + CFShow(errorString); 188 + CFRelease(errorString); 189 + 190 + printf("Error Reading File: %s\n", filePath); 191 + } 192 + 193 + return plist; 194 + } 195 + 162 196 bool revertToFile(void) 163 197 { 164 198 if (plist != NULL) ··· 172 206 } 173 207 else 174 208 { 175 - SInt32 errorCode = 0; 176 - CFStringRef errorString = NULL; 177 - CFDataRef data = NULL; 178 - CFStringRef path = CFStringCreateWithCString(kCFAllocatorDefault, outputFile, kCFStringEncodingUTF8); 179 - CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path, kCFURLPOSIXPathStyle, false); 180 - 181 - CFRelease(path); 182 - 183 - CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, url, &data, NULL, NULL, &errorCode); 184 - CFRelease(url); 185 - 186 - if (errorCode != 0) 187 - { 188 - printf("Error Reading File: %s\n", outputFile); 189 - return false; 190 - } 191 - 192 - plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, data, kCFPropertyListMutableContainers, &errorString); 209 + bool rv; 193 210 194 - if (errorString != NULL) 195 - { 196 - CFShow(errorString); 197 - CFRelease(errorString); 211 + plist = loadPlist(outputFile); 212 + rv = plist != NULL; 198 213 199 - printf("Error Reading File: %s\n", outputFile); 200 - } 214 + if (plist == NULL) 215 + plist = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 201 216 202 - return plist != NULL; 217 + return rv; 203 218 } 204 219 } 205 220 ··· 458 473 else if (isCommand(cmd, "Merge", &next)) 459 474 { 460 475 // file.plist [entryDst] 476 + if (!next) 477 + { 478 + puts("Missing arguments"); 479 + return; 480 + } 481 + 482 + // FIXME: This isn't quite correct, this doesn't support paths with spaces 483 + char* path = getWord(next, &next); 484 + 485 + mergeFile(path, next); 486 + free(path); 461 487 } 462 488 else if (isCommand(cmd, "Import", &next)) 463 489 { ··· 1050 1076 free(leafName); 1051 1077 } 1052 1078 1079 + void mergeFile(const char* path, const char* entry) 1080 + { 1081 + CFPropertyListRef dest, fileContents; 1082 + 1083 + fileContents = loadPlist(path); 1084 + if (fileContents == NULL) 1085 + return; 1086 + 1087 + if (entry != NULL && *entry) 1088 + { 1089 + resolvePlistEntry(entry, NULL, &dest, NULL, true); 1090 + if (dest == NULL) 1091 + { 1092 + printf("Merge: Entry, \"%s\", Does Not Exist\n", entry); 1093 + CFRelease(fileContents); 1094 + return; 1095 + } 1096 + } 1097 + else 1098 + dest = plist; 1099 + 1100 + CFTypeID typeID = CFGetTypeID(dest); 1101 + CFTypeID sourceTypeID = CFGetTypeID(fileContents); 1102 + 1103 + if (typeID == CFArrayGetTypeID()) 1104 + { 1105 + if (sourceTypeID == CFArrayGetTypeID()) 1106 + { 1107 + CFArrayAppendArray((CFMutableArrayRef) dest, fileContents, CFRangeMake(0, CFArrayGetCount(fileContents))); 1108 + } 1109 + else if (sourceTypeID == CFDictionaryGetTypeID()) 1110 + { 1111 + CFIndex count = CFDictionaryGetCount((CFDictionaryRef) fileContents); 1112 + void** values = malloc(sizeof(void*) * count); 1113 + CFDictionaryGetKeysAndValues((CFDictionaryRef) fileContents, NULL, (const void**) values); 1114 + 1115 + CFArrayReplaceValues((CFMutableArrayRef) dest, CFRangeMake(CFArrayGetCount((CFArrayRef) dest) - 1, 0), (const void**) values, count); 1116 + free(values); 1117 + } 1118 + else 1119 + { 1120 + CFArrayAppendValue((CFMutableArrayRef) dest, fileContents); 1121 + } 1122 + } 1123 + else if (typeID == CFDictionaryGetTypeID()) 1124 + { 1125 + if (sourceTypeID == CFDictionaryGetTypeID()) 1126 + { 1127 + CFIndex count = CFDictionaryGetCount((CFDictionaryRef) fileContents); 1128 + void** values = malloc(sizeof(void*) * count); 1129 + void** keys = malloc(sizeof(void*) * count); 1130 + 1131 + CFDictionaryGetKeysAndValues((CFDictionaryRef) fileContents, (const void**) keys, (const void**) values); 1132 + 1133 + for (CFIndex i = 0; i < count; i++) 1134 + CFDictionarySetValue((CFMutableDictionaryRef) dest, keys[i], values[i]); 1135 + 1136 + free(keys); 1137 + free(values); 1138 + } 1139 + else if (sourceTypeID == CFArrayGetTypeID()) 1140 + { 1141 + puts("Merge: Can't Add array Entries to dict"); 1142 + } 1143 + else 1144 + { 1145 + CFDictionarySetValue((CFMutableDictionaryRef) dest, CFSTR(""), fileContents); 1146 + } 1147 + } 1148 + else 1149 + { 1150 + puts("Merge: Specified Entry Must Be a Container"); 1151 + } 1152 + 1153 + CFRelease(fileContents); 1154 + } 1155 +