644
startContractionCommand (ContractionTable *table) {
645
if (!table->data.external.commandStarted) {
646
const char *command[] = {table->command, NULL};
647
HostCommandOptions options;
649
initializeHostCommandOptions(&options);
650
options.asynchronous = 1;
651
options.standardInput = &table->data.external.standardInput;
652
options.standardOutput = &table->data.external.standardOutput;
654
logMessage(LOG_DEBUG, "starting external contraction table: %s", table->command);
655
if (runHostCommand(command, &options) != 0) return 0;
656
logMessage(LOG_DEBUG, "external contraction table started: %s", table->command);
658
table->data.external.commandStarted = 1;
665
stopContractionCommand (ContractionTable *table) {
666
if (table->data.external.commandStarted) {
667
fclose(table->data.external.standardInput);
668
fclose(table->data.external.standardOutput);
670
logMessage(LOG_DEBUG, "external contraction table stopped: %s", table->command);
671
table->data.external.commandStarted = 0;
676
initializeCommonFields (ContractionTable *table) {
677
table->characters.array = NULL;
678
table->characters.size = 0;
679
table->characters.count = 0;
681
table->cache.input.characters = NULL;
682
table->cache.input.size = 0;
683
table->cache.input.count = 0;
685
table->cache.output.cells = NULL;
686
table->cache.output.size = 0;
687
table->cache.output.count = 0;
689
table->cache.offsets.array = NULL;
690
table->cache.offsets.size = 0;
691
table->cache.offsets.count = 0;
640
694
ContractionTable *
641
695
compileContractionTable (const char *fileName) {
642
696
ContractionTable *table = NULL;
698
if (isHostCommand(fileName)) {
699
if ((table = malloc(sizeof(*table)))) {
700
memset(table, 0, sizeof(*table));
702
if ((table->command = strdup(fileName))) {
703
initializeCommonFields(table);
704
table->data.external.commandStarted = 0;
706
if (startContractionCommand(table)) {
710
free(table->command);
644
723
if (setGlobalTableVariables(CONTRACTION_TABLE_EXTENSION, CONTRACTION_SUBTABLE_EXTENSION)) {
645
724
ContractionTableData ctd;
646
725
memset(&ctd, 0, sizeof(ctd));
665
744
if (processDataFile(fileName, processContractionTableLine, &ctd)) {
666
745
if (saveCharacterTable(&ctd)) {
667
746
if ((table = malloc(sizeof(*table)))) {
668
table->header.fields = getContractionTableHeader(&ctd);
669
table->size = getDataSize(ctd.area);
747
initializeCommonFields(table);
748
table->command = NULL;
750
table->data.internal.header.fields = getContractionTableHeader(&ctd);
751
table->data.internal.size = getDataSize(ctd.area);
670
752
resetDataArea(ctd.area);
672
table->characters = NULL;
673
table->charactersSize = 0;
674
table->characterCount = 0;
693
773
destroyContractionTable (ContractionTable *table) {
694
if (table->characters) {
695
free(table->characters);
696
table->characters = NULL;
700
free(table->header.fields);
774
if (table->characters.array) {
775
free(table->characters.array);
776
table->characters.array = NULL;
779
if (table->cache.input.characters) {
780
free(table->cache.input.characters);
781
table->cache.input.characters = NULL;
784
if (table->cache.output.cells) {
785
free(table->cache.output.cells);
786
table->cache.output.cells = NULL;
789
if (table->cache.offsets.array) {
790
free(table->cache.offsets.array);
791
table->cache.offsets.array = NULL;
794
if (table->command) {
795
stopContractionCommand(table);
796
free(table->command);
799
if (table->data.internal.size) {
800
free(table->data.internal.header.fields);
706
807
ensureContractionTableExtension (const char *path) {
707
return ensureExtension(path, CONTRACTION_TABLE_EXTENSION);
808
return ensureFileExtension(path, CONTRACTION_TABLE_EXTENSION);
812
makeContractionTablePath (const char *directory, const char *name) {
813
return makeFilePath(directory, name, CONTRACTION_TABLE_EXTENSION);