char *closeOf() { if (Of) { rbm_fclose(Of); return strbuf_getall((STRBUF *) Of); } else { return ""; } }
static void c50(char **namesv, char **datav, char **costv, int *subset, int *rules, int *utility, int *trials, int *winnow, double *sample, int *seed, int *noGlobalPruning, double *CF, int *minCases, int *fuzzyThreshold, int *earlyStopping, int *prunem, char **treev, char **rulesv, char **outputv) { int val; /* Used by setjmp/longjmp for implementing rbm_exit */ // Announce ourselves for testing // Rprintf("c50 called\n"); // Initialize the globals to the values that the c50 // program would have at the start of execution initglobals(); // Set globals based on the arguments. This is analogous // to parsing the command line in the c50 program. setglobals(*subset, *rules, *utility, *trials, *prunem, *winnow, *sample, *seed, *noGlobalPruning, *CF, *minCases, *fuzzyThreshold, *earlyStopping, *costv); // Handles the strbufv data structure rbm_removeall(); // Deallocates memory allocated by NewCase. // Not necessary since it's also called at the end of this function, // but it doesn't hurt, and I'm feeling paranoid. FreeCases(); // XXX Should this be controlled via an option? // Rprintf("Calling setOf\n"); setOf(); // Create a strbuf using *namesv as the buffer. // Note that this is a readonly strbuf since we can't // extend *namesv. STRBUF *sb_names = strbuf_create_full(*namesv, strlen(*namesv)); // Register this strbuf using the name "undefined.names" if (rbm_register(sb_names, "undefined.names", 0) < 0) { error("undefined.names already exists"); } // Create a strbuf using *datav and register it as "undefined.data" STRBUF *sb_datav = strbuf_create_full(*datav, strlen(*datav)); // XXX why is sb_datav copied? was that part of my debugging? // XXX or is this the cause of the leak? if (rbm_register(strbuf_copy(sb_datav), "undefined.data", 0) < 0) { error("undefined data already exists"); } // Create a strbuf using *costv and register it as "undefined.costs" if (strlen(*costv) > 0) { // Rprintf("registering cost matrix: %s", *costv); STRBUF *sb_costv = strbuf_create_full(*costv, strlen(*costv)); // XXX should sb_costv be copied? if (rbm_register(sb_costv, "undefined.costs", 0) < 0) { error("undefined.cost already exists"); } } else { // Rprintf("no cost matrix to register\n"); } /* * We need to initialize rbm_buf before calling any code that * might call exit/rbm_exit. */ if ((val = setjmp(rbm_buf)) == 0) { // Real work is done here // Rprintf("Calling c50main\n"); c50main(); // Rprintf("c50main finished\n"); if (*rules == 0) { // Get the contents of the the tree file STRBUF *treebuf = rbm_lookup("undefined.tree"); if (treebuf != NULL) { char *treeString = strbuf_getall(treebuf); char *treeObj = R_alloc(strlen(treeString) + 1, 1); strcpy(treeObj, treeString); // I think the previous value of *treev will be garbage collected *treev = treeObj; } else { // XXX Should *treev be assigned something in this case? // XXX Throw an error? } } else { // Get the contents of the the rules file STRBUF *rulesbuf = rbm_lookup("undefined.rules"); if (rulesbuf != NULL) { char *rulesString = strbuf_getall(rulesbuf); char *rulesObj = R_alloc(strlen(rulesString) + 1, 1); strcpy(rulesObj, rulesString); // I think the previous value of *rulesv will be garbage collected *rulesv = rulesObj; } else { // XXX Should *rulesv be assigned something in this case? // XXX Throw an error? } } } else { Rprintf("c50 code called exit with value %d\n", val - JMP_OFFSET); } // Close file object "Of", and return its contents via argument outputv char *outputString = closeOf(); char *output = R_alloc(strlen(outputString) + 1, 1); strcpy(output, outputString); *outputv = output; // Deallocates memory allocated by NewCase FreeCases(); // We reinitialize the globals on exit out of general paranoia initglobals(); }