mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-27 07:34:20 +00:00
NOT YET PART OF SEAMONKEY:
* initial pass at handling the update of interface indices.
This commit is contained in:
parent
ec67fd947d
commit
a356faf7da
@ -32,15 +32,33 @@
|
||||
#endif
|
||||
|
||||
/* Forward declarations. */
|
||||
typedef struct fixElement fixElement;
|
||||
static int compare_IDEs_by_IID(const void *ap, const void *bp);
|
||||
static int compare_IDEs_by_name(const void *ap, const void *bp);
|
||||
static int compare_IDEs_by_name_space(const void *ap, const void *bp);
|
||||
static int compare_fixElements_by_name(const void *ap, const void *bp);
|
||||
static int compare_IIDs(const void *ap, const void *bp);
|
||||
PRBool shrink_IDE_array(XPTInterfaceDirectoryEntry *ide,
|
||||
int element_to_delete, int num_interfaces);
|
||||
PRBool update_fix_array(fixElement *deleted, int new_index);
|
||||
static int get_new_index(const fixElement *fix, int num_elements,
|
||||
int target_file, int target_interface);
|
||||
PRBool copy_IDE(XPTInterfaceDirectoryEntry *from,
|
||||
XPTInterfaceDirectoryEntry *to);
|
||||
static void xpt_dump_usage(char *argv[]);
|
||||
|
||||
struct fixElement {
|
||||
nsID *iid;
|
||||
char* name;
|
||||
int file_num;
|
||||
int interface_num;
|
||||
PRBool is_deleted;
|
||||
int index;
|
||||
};
|
||||
|
||||
/* Global variables. */
|
||||
int numberOfInterfaces = 0;
|
||||
int trueNumberOfInterfaces = 0;
|
||||
int totalNumberOfInterfaces = 0;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
@ -49,13 +67,16 @@ main(int argc, char **argv)
|
||||
XPTCursor curs, *cursor = &curs;
|
||||
XPTHeader *header;
|
||||
XPTInterfaceDirectoryEntry *newIDE, *IDE_array;
|
||||
XPTInterfaceDescriptor *id;
|
||||
XPTTypeDescriptor *td;
|
||||
XPTAnnotation *ann;
|
||||
uint32 header_sz, len;
|
||||
struct stat file_stat;
|
||||
size_t flen = 0;
|
||||
char *head, *data, *whole;
|
||||
FILE *in, *out;
|
||||
int i,j;
|
||||
fixElement *newFix, *fix_array;
|
||||
int i,j,l;
|
||||
int k = 0;
|
||||
|
||||
if (argc < 3) {
|
||||
@ -107,16 +128,24 @@ main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
numberOfInterfaces += header->num_interfaces;
|
||||
totalNumberOfInterfaces += header->num_interfaces;
|
||||
if (k == 0) {
|
||||
IDE_array = PR_CALLOC(numberOfInterfaces * sizeof(XPTInterfaceDirectoryEntry));
|
||||
IDE_array = PR_CALLOC(totalNumberOfInterfaces * sizeof(XPTInterfaceDirectoryEntry));
|
||||
fix_array = PR_CALLOC(totalNumberOfInterfaces * sizeof(fixElement));
|
||||
} else {
|
||||
newIDE = PR_REALLOC(IDE_array, numberOfInterfaces * sizeof(XPTInterfaceDirectoryEntry));
|
||||
newIDE = PR_REALLOC(IDE_array, totalNumberOfInterfaces * sizeof(XPTInterfaceDirectoryEntry));
|
||||
newFix = PR_REALLOC(fix_array, totalNumberOfInterfaces * sizeof(fixElement));
|
||||
|
||||
if (!newIDE) {
|
||||
perror("FAILED: PR_REALLOC of IDE_array");
|
||||
return 1;
|
||||
}
|
||||
if (!newFix) {
|
||||
perror("FAILED: PR_REALLOC of newFix");
|
||||
return 1;
|
||||
}
|
||||
IDE_array = newIDE;
|
||||
fix_array = newFix;
|
||||
}
|
||||
|
||||
for (j=0; j<header->num_interfaces; j++) {
|
||||
@ -125,6 +154,12 @@ main(int argc, char **argv)
|
||||
perror("FAILED: 1st copying of IDE");
|
||||
return 1;
|
||||
}
|
||||
fix_array[k].iid = &IDE_array[k].iid;
|
||||
fix_array[k].name = IDE_array[k].name;
|
||||
fix_array[k].file_num = i-2;
|
||||
fix_array[k].interface_num = j+1;
|
||||
fix_array[k].is_deleted = PR_FALSE;
|
||||
|
||||
k++;
|
||||
}
|
||||
|
||||
@ -140,16 +175,180 @@ main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Sort both IDE_array and fix_array by name so we can check for
|
||||
* name_space::name collisions.
|
||||
*/
|
||||
qsort(IDE_array,
|
||||
numberOfInterfaces,
|
||||
totalNumberOfInterfaces,
|
||||
sizeof(XPTInterfaceDirectoryEntry),
|
||||
compare_IDEs_by_name);
|
||||
|
||||
qsort(fix_array,
|
||||
totalNumberOfInterfaces,
|
||||
sizeof(fixElement),
|
||||
compare_fixElements_by_name);
|
||||
|
||||
/* Iterate through fix_array now that it is in its final form (sorted)
|
||||
* and set the index. Index is i+1 because index 0 is reserved for
|
||||
* the special case (no parent interface).
|
||||
*/
|
||||
for (i=0; i<totalNumberOfInterfaces; i++) {
|
||||
fix_array[k].index = i+1;
|
||||
}
|
||||
|
||||
/* trueNumberOfInterfaces == number of interfaces left after deletions
|
||||
* are made. Initialize it here to be the same as the total number of
|
||||
* interfaces we'ce encountered thus far.
|
||||
*/
|
||||
trueNumberOfInterfaces = totalNumberOfInterfaces;
|
||||
|
||||
/* Iterate through the sorted interfaces. Start at one so we don't
|
||||
* accidentally walk off the end of the array.
|
||||
*/
|
||||
i = 1;
|
||||
while (i != trueNumberOfInterfaces) {
|
||||
|
||||
/* Check for name_space::name collision.
|
||||
*/
|
||||
if (compare_IDEs_by_name(&IDE_array[i-1], &IDE_array[i]) == 0 &&
|
||||
compare_IDEs_by_name_space(&IDE_array[i-1], &IDE_array[i]) == 0) {
|
||||
|
||||
/* If one of the interfaces is unresolved, delete that one
|
||||
* preferentailly.
|
||||
*/
|
||||
if (!&IDE_array[i-1].iid) {
|
||||
/* Shrink the IDE_array to delete the duplicate interface.
|
||||
*/
|
||||
if (!shrink_IDE_array(IDE_array,
|
||||
i-1,
|
||||
trueNumberOfInterfaces)) {
|
||||
perror("FAILED: shrink_IDE_array");
|
||||
return 1;
|
||||
}
|
||||
/* Update the fix_array so that the index that corresponds
|
||||
* to the just-deleted IDE now points to the surviving IDE
|
||||
* of the same name. Indices are one-based, so the second
|
||||
* argument is passed as i+1 (instead of i).
|
||||
*/
|
||||
update_fix_array(&fix_array[i-1], i+1);
|
||||
/* Decrement the true number of interfaces since we just
|
||||
* deleted one. There's more than one way to get out of
|
||||
* this loop.
|
||||
*/
|
||||
trueNumberOfInterfaces--;
|
||||
} else {
|
||||
if (!&IDE_array[i].iid ||
|
||||
(compare_IIDs(&IDE_array[i-1].iid, &IDE_array[i].iid) == 0)) {
|
||||
/* Shrink the IDE_array to delete the duplicate interface.
|
||||
*/
|
||||
if (!shrink_IDE_array(IDE_array,
|
||||
i,
|
||||
trueNumberOfInterfaces)) {
|
||||
perror("FAILED: shrink_IDE_array");
|
||||
return 1;
|
||||
}
|
||||
/* Update the fix_array so that the index that corresponds
|
||||
* to the just-deleted IDE now points to the surviving IDE
|
||||
* of the same name. Indices are one-based, so the second
|
||||
* argument is passed as i (instead of i-1).
|
||||
*/
|
||||
update_fix_array(&fix_array[i], i);
|
||||
/* Decrement the true number of interfaces since we just
|
||||
* deleted one. There's more than one way to get out of
|
||||
* this loop.
|
||||
*/
|
||||
trueNumberOfInterfaces--;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Only increment if there was no name_space::name collision.
|
||||
*/
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Iterate through the remaining interfaces. There's some magic here -
|
||||
* we walk fix_array at the same time skipping over ones that have
|
||||
* been deleted. This should work correctly since we only ever delete
|
||||
* things in a linear manner.
|
||||
*/
|
||||
for (i=0,j=0;
|
||||
i<trueNumberOfInterfaces && j<totalNumberOfInterfaces;
|
||||
i++,j++) {
|
||||
|
||||
/* Define id to save some keystrokes.
|
||||
*/
|
||||
id = IDE_array[i].interface_descriptor;
|
||||
/* Skip ahead in fix_array until past the deleted elements.
|
||||
*/
|
||||
while (fix_array[j].is_deleted) {
|
||||
j++;
|
||||
}
|
||||
/* Fix parent_interface first.
|
||||
*/
|
||||
if (id->parent_interface != 0) {
|
||||
id->parent_interface =
|
||||
get_new_index(fix_array, totalNumberOfInterfaces,
|
||||
fix_array[j].file_num, id->parent_interface);
|
||||
}
|
||||
/* Iterate through the method descriptors looking for params of
|
||||
* type TD_INTERFACE_TYPE.
|
||||
*/
|
||||
for (k=0; k<id->num_methods; k++) {
|
||||
/* Cycle through the params first.
|
||||
*/
|
||||
for (l=0; l<id->method_descriptors[k].num_args; l++) {
|
||||
/* Define td to save some keystrokes.
|
||||
*/
|
||||
td = &id->method_descriptors[k].params[l].type;
|
||||
if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) {
|
||||
td->type.interface =
|
||||
get_new_index(fix_array,
|
||||
totalNumberOfInterfaces,
|
||||
fix_array[j].file_num,
|
||||
td->type.interface);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the result param too. Define td again to save
|
||||
* some keystrokes.
|
||||
*/
|
||||
td = &id->method_descriptors[k].result->type;
|
||||
if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) {
|
||||
td->type.interface =
|
||||
get_new_index(fix_array, totalNumberOfInterfaces,
|
||||
fix_array[j].file_num, td->type.interface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sort the IDE_array by IID for output to xpt file.
|
||||
*/
|
||||
qsort(IDE_array,
|
||||
trueNumberOfInterfaces,
|
||||
sizeof(XPTInterfaceDirectoryEntry),
|
||||
compare_IDEs_by_IID);
|
||||
|
||||
header = XPT_NewHeader(numberOfInterfaces);
|
||||
/* Iterate through the array quickly looking for duplicate IIDS.
|
||||
* This shouldn't happen, i.e. is a failure condition, so bail
|
||||
* if we find a duplicate. If we have more than one entry, start
|
||||
* at one so we don't accidentally grep the ether.
|
||||
*/
|
||||
if (trueNumberOfInterfaces>1) {
|
||||
for (i=1; i<trueNumberOfInterfaces; i++) {
|
||||
if (compare_IDEs_by_IID(&IDE_array[i-1], &IDE_array[i]) == 0) {
|
||||
perror("Error: Whoa, Nellie! You've got duplicate IIDs.");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header = XPT_NewHeader(trueNumberOfInterfaces);
|
||||
ann = XPT_NewAnnotation(XPT_ANN_LAST, NULL, NULL);
|
||||
header->annotations = ann;
|
||||
for (i=0; i<numberOfInterfaces; i++) {
|
||||
for (i=0; i<trueNumberOfInterfaces; i++) {
|
||||
if (!copy_IDE(&IDE_array[i], &header->interface_directory[i])) {
|
||||
perror("FAILED: 2nd copying of IDE");
|
||||
return 1;
|
||||
@ -215,6 +414,24 @@ compare_IDEs_by_name(const void *ap,
|
||||
|
||||
return strcmp(ide1->name, ide2->name);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_IDEs_by_name_space(const void *ap,
|
||||
const void *bp)
|
||||
{
|
||||
const XPTInterfaceDirectoryEntry *ide1 = ap, *ide2 = bp;
|
||||
|
||||
return strcmp(ide1->name_space, ide2->name_space);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_fixElements_by_name(const void *ap,
|
||||
const void *bp)
|
||||
{
|
||||
const fixElement *fix1 = ap, *fix2 = bp;
|
||||
|
||||
return strcmp(fix1->name, fix2->name);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_IIDs(const void *ap, const void *bp)
|
||||
@ -233,6 +450,59 @@ compare_IIDs(const void *ap, const void *bp)
|
||||
#undef COMPARE
|
||||
}
|
||||
|
||||
PRBool
|
||||
shrink_IDE_array(XPTInterfaceDirectoryEntry *ide, int element_to_delete,
|
||||
int num_interfaces)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (element_to_delete >= num_interfaces) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
for (i=element_to_delete+1; i<num_interfaces; i++) {
|
||||
if (!copy_IDE(&ide[i], &ide[i-1])) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/* update_fix_array marks a fixElement as deleted and updates the index
|
||||
* marker. Deleted elements are not used for comparison purposes with
|
||||
* IDE_array. There only purpose is to set the interface index (if
|
||||
* necessary) for id->parent_interfaces and TypeDescriptors once the IDEs
|
||||
* are sorted and pruned.
|
||||
*/
|
||||
PRBool
|
||||
update_fix_array(fixElement *deleted, int new_index)
|
||||
{
|
||||
deleted->is_deleted = PR_TRUE;
|
||||
deleted->index = new_index;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/* get_new_index returns the new interface index by walking the fix_array
|
||||
* until the file_num and interface_num match the target values. Indices
|
||||
* are one-based; zero represents the special case (no parent interface).
|
||||
*/
|
||||
static int
|
||||
get_new_index(const fixElement *fix, int num_elements,
|
||||
int target_file, int target_interface)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<num_elements; i++) {
|
||||
if (fix[i].file_num == target_file &&
|
||||
fix[i].interface_num == target_interface)
|
||||
return fix[i].index;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRBool
|
||||
copy_IDE(XPTInterfaceDirectoryEntry *from, XPTInterfaceDirectoryEntry *to)
|
||||
{
|
||||
|
@ -32,15 +32,33 @@
|
||||
#endif
|
||||
|
||||
/* Forward declarations. */
|
||||
typedef struct fixElement fixElement;
|
||||
static int compare_IDEs_by_IID(const void *ap, const void *bp);
|
||||
static int compare_IDEs_by_name(const void *ap, const void *bp);
|
||||
static int compare_IDEs_by_name_space(const void *ap, const void *bp);
|
||||
static int compare_fixElements_by_name(const void *ap, const void *bp);
|
||||
static int compare_IIDs(const void *ap, const void *bp);
|
||||
PRBool shrink_IDE_array(XPTInterfaceDirectoryEntry *ide,
|
||||
int element_to_delete, int num_interfaces);
|
||||
PRBool update_fix_array(fixElement *deleted, int new_index);
|
||||
static int get_new_index(const fixElement *fix, int num_elements,
|
||||
int target_file, int target_interface);
|
||||
PRBool copy_IDE(XPTInterfaceDirectoryEntry *from,
|
||||
XPTInterfaceDirectoryEntry *to);
|
||||
static void xpt_dump_usage(char *argv[]);
|
||||
|
||||
struct fixElement {
|
||||
nsID *iid;
|
||||
char* name;
|
||||
int file_num;
|
||||
int interface_num;
|
||||
PRBool is_deleted;
|
||||
int index;
|
||||
};
|
||||
|
||||
/* Global variables. */
|
||||
int numberOfInterfaces = 0;
|
||||
int trueNumberOfInterfaces = 0;
|
||||
int totalNumberOfInterfaces = 0;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
@ -49,13 +67,16 @@ main(int argc, char **argv)
|
||||
XPTCursor curs, *cursor = &curs;
|
||||
XPTHeader *header;
|
||||
XPTInterfaceDirectoryEntry *newIDE, *IDE_array;
|
||||
XPTInterfaceDescriptor *id;
|
||||
XPTTypeDescriptor *td;
|
||||
XPTAnnotation *ann;
|
||||
uint32 header_sz, len;
|
||||
struct stat file_stat;
|
||||
size_t flen = 0;
|
||||
char *head, *data, *whole;
|
||||
FILE *in, *out;
|
||||
int i,j;
|
||||
fixElement *newFix, *fix_array;
|
||||
int i,j,l;
|
||||
int k = 0;
|
||||
|
||||
if (argc < 3) {
|
||||
@ -107,16 +128,24 @@ main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
numberOfInterfaces += header->num_interfaces;
|
||||
totalNumberOfInterfaces += header->num_interfaces;
|
||||
if (k == 0) {
|
||||
IDE_array = PR_CALLOC(numberOfInterfaces * sizeof(XPTInterfaceDirectoryEntry));
|
||||
IDE_array = PR_CALLOC(totalNumberOfInterfaces * sizeof(XPTInterfaceDirectoryEntry));
|
||||
fix_array = PR_CALLOC(totalNumberOfInterfaces * sizeof(fixElement));
|
||||
} else {
|
||||
newIDE = PR_REALLOC(IDE_array, numberOfInterfaces * sizeof(XPTInterfaceDirectoryEntry));
|
||||
newIDE = PR_REALLOC(IDE_array, totalNumberOfInterfaces * sizeof(XPTInterfaceDirectoryEntry));
|
||||
newFix = PR_REALLOC(fix_array, totalNumberOfInterfaces * sizeof(fixElement));
|
||||
|
||||
if (!newIDE) {
|
||||
perror("FAILED: PR_REALLOC of IDE_array");
|
||||
return 1;
|
||||
}
|
||||
if (!newFix) {
|
||||
perror("FAILED: PR_REALLOC of newFix");
|
||||
return 1;
|
||||
}
|
||||
IDE_array = newIDE;
|
||||
fix_array = newFix;
|
||||
}
|
||||
|
||||
for (j=0; j<header->num_interfaces; j++) {
|
||||
@ -125,6 +154,12 @@ main(int argc, char **argv)
|
||||
perror("FAILED: 1st copying of IDE");
|
||||
return 1;
|
||||
}
|
||||
fix_array[k].iid = &IDE_array[k].iid;
|
||||
fix_array[k].name = IDE_array[k].name;
|
||||
fix_array[k].file_num = i-2;
|
||||
fix_array[k].interface_num = j+1;
|
||||
fix_array[k].is_deleted = PR_FALSE;
|
||||
|
||||
k++;
|
||||
}
|
||||
|
||||
@ -140,16 +175,180 @@ main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Sort both IDE_array and fix_array by name so we can check for
|
||||
* name_space::name collisions.
|
||||
*/
|
||||
qsort(IDE_array,
|
||||
numberOfInterfaces,
|
||||
totalNumberOfInterfaces,
|
||||
sizeof(XPTInterfaceDirectoryEntry),
|
||||
compare_IDEs_by_name);
|
||||
|
||||
qsort(fix_array,
|
||||
totalNumberOfInterfaces,
|
||||
sizeof(fixElement),
|
||||
compare_fixElements_by_name);
|
||||
|
||||
/* Iterate through fix_array now that it is in its final form (sorted)
|
||||
* and set the index. Index is i+1 because index 0 is reserved for
|
||||
* the special case (no parent interface).
|
||||
*/
|
||||
for (i=0; i<totalNumberOfInterfaces; i++) {
|
||||
fix_array[k].index = i+1;
|
||||
}
|
||||
|
||||
/* trueNumberOfInterfaces == number of interfaces left after deletions
|
||||
* are made. Initialize it here to be the same as the total number of
|
||||
* interfaces we'ce encountered thus far.
|
||||
*/
|
||||
trueNumberOfInterfaces = totalNumberOfInterfaces;
|
||||
|
||||
/* Iterate through the sorted interfaces. Start at one so we don't
|
||||
* accidentally walk off the end of the array.
|
||||
*/
|
||||
i = 1;
|
||||
while (i != trueNumberOfInterfaces) {
|
||||
|
||||
/* Check for name_space::name collision.
|
||||
*/
|
||||
if (compare_IDEs_by_name(&IDE_array[i-1], &IDE_array[i]) == 0 &&
|
||||
compare_IDEs_by_name_space(&IDE_array[i-1], &IDE_array[i]) == 0) {
|
||||
|
||||
/* If one of the interfaces is unresolved, delete that one
|
||||
* preferentailly.
|
||||
*/
|
||||
if (!&IDE_array[i-1].iid) {
|
||||
/* Shrink the IDE_array to delete the duplicate interface.
|
||||
*/
|
||||
if (!shrink_IDE_array(IDE_array,
|
||||
i-1,
|
||||
trueNumberOfInterfaces)) {
|
||||
perror("FAILED: shrink_IDE_array");
|
||||
return 1;
|
||||
}
|
||||
/* Update the fix_array so that the index that corresponds
|
||||
* to the just-deleted IDE now points to the surviving IDE
|
||||
* of the same name. Indices are one-based, so the second
|
||||
* argument is passed as i+1 (instead of i).
|
||||
*/
|
||||
update_fix_array(&fix_array[i-1], i+1);
|
||||
/* Decrement the true number of interfaces since we just
|
||||
* deleted one. There's more than one way to get out of
|
||||
* this loop.
|
||||
*/
|
||||
trueNumberOfInterfaces--;
|
||||
} else {
|
||||
if (!&IDE_array[i].iid ||
|
||||
(compare_IIDs(&IDE_array[i-1].iid, &IDE_array[i].iid) == 0)) {
|
||||
/* Shrink the IDE_array to delete the duplicate interface.
|
||||
*/
|
||||
if (!shrink_IDE_array(IDE_array,
|
||||
i,
|
||||
trueNumberOfInterfaces)) {
|
||||
perror("FAILED: shrink_IDE_array");
|
||||
return 1;
|
||||
}
|
||||
/* Update the fix_array so that the index that corresponds
|
||||
* to the just-deleted IDE now points to the surviving IDE
|
||||
* of the same name. Indices are one-based, so the second
|
||||
* argument is passed as i (instead of i-1).
|
||||
*/
|
||||
update_fix_array(&fix_array[i], i);
|
||||
/* Decrement the true number of interfaces since we just
|
||||
* deleted one. There's more than one way to get out of
|
||||
* this loop.
|
||||
*/
|
||||
trueNumberOfInterfaces--;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Only increment if there was no name_space::name collision.
|
||||
*/
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Iterate through the remaining interfaces. There's some magic here -
|
||||
* we walk fix_array at the same time skipping over ones that have
|
||||
* been deleted. This should work correctly since we only ever delete
|
||||
* things in a linear manner.
|
||||
*/
|
||||
for (i=0,j=0;
|
||||
i<trueNumberOfInterfaces && j<totalNumberOfInterfaces;
|
||||
i++,j++) {
|
||||
|
||||
/* Define id to save some keystrokes.
|
||||
*/
|
||||
id = IDE_array[i].interface_descriptor;
|
||||
/* Skip ahead in fix_array until past the deleted elements.
|
||||
*/
|
||||
while (fix_array[j].is_deleted) {
|
||||
j++;
|
||||
}
|
||||
/* Fix parent_interface first.
|
||||
*/
|
||||
if (id->parent_interface != 0) {
|
||||
id->parent_interface =
|
||||
get_new_index(fix_array, totalNumberOfInterfaces,
|
||||
fix_array[j].file_num, id->parent_interface);
|
||||
}
|
||||
/* Iterate through the method descriptors looking for params of
|
||||
* type TD_INTERFACE_TYPE.
|
||||
*/
|
||||
for (k=0; k<id->num_methods; k++) {
|
||||
/* Cycle through the params first.
|
||||
*/
|
||||
for (l=0; l<id->method_descriptors[k].num_args; l++) {
|
||||
/* Define td to save some keystrokes.
|
||||
*/
|
||||
td = &id->method_descriptors[k].params[l].type;
|
||||
if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) {
|
||||
td->type.interface =
|
||||
get_new_index(fix_array,
|
||||
totalNumberOfInterfaces,
|
||||
fix_array[j].file_num,
|
||||
td->type.interface);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the result param too. Define td again to save
|
||||
* some keystrokes.
|
||||
*/
|
||||
td = &id->method_descriptors[k].result->type;
|
||||
if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) {
|
||||
td->type.interface =
|
||||
get_new_index(fix_array, totalNumberOfInterfaces,
|
||||
fix_array[j].file_num, td->type.interface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sort the IDE_array by IID for output to xpt file.
|
||||
*/
|
||||
qsort(IDE_array,
|
||||
trueNumberOfInterfaces,
|
||||
sizeof(XPTInterfaceDirectoryEntry),
|
||||
compare_IDEs_by_IID);
|
||||
|
||||
header = XPT_NewHeader(numberOfInterfaces);
|
||||
/* Iterate through the array quickly looking for duplicate IIDS.
|
||||
* This shouldn't happen, i.e. is a failure condition, so bail
|
||||
* if we find a duplicate. If we have more than one entry, start
|
||||
* at one so we don't accidentally grep the ether.
|
||||
*/
|
||||
if (trueNumberOfInterfaces>1) {
|
||||
for (i=1; i<trueNumberOfInterfaces; i++) {
|
||||
if (compare_IDEs_by_IID(&IDE_array[i-1], &IDE_array[i]) == 0) {
|
||||
perror("Error: Whoa, Nellie! You've got duplicate IIDs.");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header = XPT_NewHeader(trueNumberOfInterfaces);
|
||||
ann = XPT_NewAnnotation(XPT_ANN_LAST, NULL, NULL);
|
||||
header->annotations = ann;
|
||||
for (i=0; i<numberOfInterfaces; i++) {
|
||||
for (i=0; i<trueNumberOfInterfaces; i++) {
|
||||
if (!copy_IDE(&IDE_array[i], &header->interface_directory[i])) {
|
||||
perror("FAILED: 2nd copying of IDE");
|
||||
return 1;
|
||||
@ -215,6 +414,24 @@ compare_IDEs_by_name(const void *ap,
|
||||
|
||||
return strcmp(ide1->name, ide2->name);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_IDEs_by_name_space(const void *ap,
|
||||
const void *bp)
|
||||
{
|
||||
const XPTInterfaceDirectoryEntry *ide1 = ap, *ide2 = bp;
|
||||
|
||||
return strcmp(ide1->name_space, ide2->name_space);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_fixElements_by_name(const void *ap,
|
||||
const void *bp)
|
||||
{
|
||||
const fixElement *fix1 = ap, *fix2 = bp;
|
||||
|
||||
return strcmp(fix1->name, fix2->name);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_IIDs(const void *ap, const void *bp)
|
||||
@ -233,6 +450,59 @@ compare_IIDs(const void *ap, const void *bp)
|
||||
#undef COMPARE
|
||||
}
|
||||
|
||||
PRBool
|
||||
shrink_IDE_array(XPTInterfaceDirectoryEntry *ide, int element_to_delete,
|
||||
int num_interfaces)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (element_to_delete >= num_interfaces) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
for (i=element_to_delete+1; i<num_interfaces; i++) {
|
||||
if (!copy_IDE(&ide[i], &ide[i-1])) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/* update_fix_array marks a fixElement as deleted and updates the index
|
||||
* marker. Deleted elements are not used for comparison purposes with
|
||||
* IDE_array. There only purpose is to set the interface index (if
|
||||
* necessary) for id->parent_interfaces and TypeDescriptors once the IDEs
|
||||
* are sorted and pruned.
|
||||
*/
|
||||
PRBool
|
||||
update_fix_array(fixElement *deleted, int new_index)
|
||||
{
|
||||
deleted->is_deleted = PR_TRUE;
|
||||
deleted->index = new_index;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/* get_new_index returns the new interface index by walking the fix_array
|
||||
* until the file_num and interface_num match the target values. Indices
|
||||
* are one-based; zero represents the special case (no parent interface).
|
||||
*/
|
||||
static int
|
||||
get_new_index(const fixElement *fix, int num_elements,
|
||||
int target_file, int target_interface)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<num_elements; i++) {
|
||||
if (fix[i].file_num == target_file &&
|
||||
fix[i].interface_num == target_interface)
|
||||
return fix[i].index;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRBool
|
||||
copy_IDE(XPTInterfaceDirectoryEntry *from, XPTInterfaceDirectoryEntry *to)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user