/* This is the header file for the Adjuster module. It is also included by
the Cases module. */
/* external function */
extern void
Adjust_Attributes(
file log_stream,
area *area_pointer,
string weights_filename,
cardinal level,
boolean inputable_latex);
/* This is the implementation file for the Adjuster module. */
#include <stdio.h>
#include <stdlib.h>
#include "shyster.h"
#include "cases.h"
#include "adjuster.h"
#include "scales.h"
#include "consultant.h"
static void
error_exit(
file stream,
const string message)
{
Write_Error_Message_And_Exit(stream, "Adjuster", message);
}
static void
write_weight(
file stream,
weight_type weight)
/* Writes the value of weight in words. */
{
if (weight.infinite) {
fprintf(stream, "infinite weight");
} else if (Is_Zero(weight.finite))
fprintf(stream, "no weight");
else {
fprintf(stream, "a weight of ");
Write_Floating_Point(stream, weight.finite, Empty_String);
}
}
static void
adjust_weight(
file log_stream,
area *area_pointer,
cardinal attribute_number,
cardinal level,
boolean *adjustment_made)
/* Allows the legal expert to set the weight of attribute attribute_number in
the area pointed to by area_pointer. Sets adjustment_made to TRUE, if an
adjustment is made. */
{
cardinal count = 1;
attribute *attribute_pointer;
char dummy;
int option;
weight_type old_weight;
floating_point new_weight;
/* find attribute attribute_number */
for (attribute_pointer = area_pointer->attribute_head;
(count++ < attribute_number) && (attribute_pointer != NULL);
attribute_pointer = attribute_pointer->next);
/* tell the legal expert about the attribute's current weight */
fprintf(stdout, "A%u has ", attribute_number);
write_weight(stdout, attribute_pointer->weight);
fprintf(stdout, ".\n");
/* make a copy of the weight */
old_weight.infinite = attribute_pointer->weight.infinite;
old_weight = attribute_pointer->weight;
option = Get_Option("Infinite, Zero, or Other", "IZO");
/* adjust the attribute's weight as requested */
switch (option) {
case 'I':
attribute_pointer->weight.infinite = TRUE;
break;
case 'Z':
Zero_Weight(&attribute_pointer->weight);
break;
case 'O':
fprintf(stdout, "New weight for A%u: ", attribute_number);
if (fscanf(stdin, "%f%c", &new_weight, &dummy) == EOF)
error_exit(log_stream, "fscanf input failed for floating_point");
attribute_pointer->weight.infinite = FALSE;
attribute_pointer->weight.finite = new_weight;
break;
case Quit_Character:
return;
}
*adjustment_made = TRUE;
/* report on the adjustment */
Indent(log_stream, level);
fprintf(log_stream, "A%u, which had ", attribute_number);
write_weight(log_stream, old_weight);
fprintf(log_stream, ", now has ");
write_weight(log_stream, attribute_pointer->weight);
fprintf(log_stream, ".\n");
}
static void
adjust_result_weight(
file log_stream,
area *area_pointer,
cardinal attribute_number,
cardinal level,
boolean *adjustment_made)
/* Allows the legal expert to set any of the result weights for attribute
attribute_number in the area pointed to by area_pointer. Sets
*adjustment_made to TRUE, if an adjustment is made. */
{
cardinal count = 1,
result_number;
attribute *attribute_pointer;
char dummy;
int option;
weight_type old_weight;
floating_point new_weight;
weight_list_element *weights_pointer;
result *result_pointer;
/* find attribute attribute_number */
for (attribute_pointer = area_pointer->attribute_head;
(count++ < attribute_number) && (attribute_pointer != NULL);
attribute_pointer = attribute_pointer->next);
/* tell the legal expert about the attribute's current result weights */
fprintf(stdout, "A%u has the following result weights:", attribute_number);
weights_pointer = attribute_pointer->weights_head;
result_pointer = area_pointer->result_head;
for (count = 1; count <= area_pointer->number_of_results;
count++) {
if (count != 1)
fprintf(stdout, ";");
fprintf(stdout, "\n");
Indent(stdout, 1);
fprintf(stdout, "%u: %s result has ", count, result_pointer->identifier);
write_weight(stdout, weights_pointer->weight);
weights_pointer = weights_pointer->next;
result_pointer = result_pointer->next;
}
fprintf(stdout, ".\n");
/* prompt the legal expert for a result number */
do {
fprintf(stdout, "Result number (1-%u): ",
area_pointer->number_of_results);
if (fscanf(stdin, "%u%c", &result_number, &dummy) == EOF)
error_exit(log_stream, "fscanf input failed for cardinal");
} while (result_number > area_pointer->number_of_results);
if (result_number != 0) {
/* find the result weight */
weights_pointer = attribute_pointer->weights_head;
result_pointer = area_pointer->result_head;
for (count = 1; count < result_number; count++) {
weights_pointer = weights_pointer->next;
result_pointer = result_pointer->next;
}
/* make a copy of the result weight */
old_weight.infinite = weights_pointer->weight.infinite;
old_weight = weights_pointer->weight;
option = Get_Option("Infinite, Zero, or Other", "IZO");
/* adjust the result weight as requested */
switch (option) {
case 'I':
weights_pointer->weight.infinite = TRUE;
break;
case 'Z':
Zero_Weight(&weights_pointer->weight);
break;
case 'O':
fprintf(stdout, "New weight for A%u for %s result: ",
attribute_number, result_pointer->identifier);
if (fscanf(stdin, "%f%c", &new_weight, &dummy) == EOF)
error_exit(log_stream, "fscanf input failed for floating_point");
weights_pointer->weight.infinite = FALSE;
weights_pointer->weight.finite = new_weight;
break;
case Quit_Character:
return;
}
*adjustment_made = TRUE;
/* report on the adjustment */
Indent(log_stream, level);
fprintf(log_stream, "A%u, which had ", attribute_number);
write_weight(log_stream, old_weight);
fprintf(log_stream, " for %s result, now has ", result_pointer->identifier);
write_weight(log_stream, weights_pointer->weight);
fprintf(log_stream, " for that result.\n");
}
}
extern void
Adjust_Attributes(
file log_stream,
area *area_pointer,
string weights_filename,
cardinal level,
boolean inputable_latex)
/* Allows the legal expert to set any of the weights (including result
weights) in the area pointed to by area_pointer. Prompts the expert by
writing to stdout; reads the expert's response from stdin. Writes a table
of weights to the adjusted weights file weights_filename (if it is not
NULL). Writes LaTeX code that can be included in another LaTeX document
(i.e. not stand-alone code), if inputable_latex is TRUE. */
{
file weights_stream = NULL;
char dummy;
static char filename[Max_Filename_Length];
char message[Max_Error_Message_Length];
cardinal attribute_number;
int option;
boolean adjustment_made = FALSE;
Indent(log_stream, level);
fprintf(log_stream, "Entering Adjuster module.\n\n");
fprintf(stdout, "Adjust weights in %s area ...\n", area_pointer->identifier);
do {
/* prompt the legal expert for an attribute number */
do {
fprintf(stdout, "Attribute number (1-%u): ",
area_pointer->number_of_attributes);
if (fscanf(stdin, "%u%c", &attribute_number, &dummy) == EOF)
error_exit(log_stream, "fscanf input failed for cardinal");
} while (attribute_number > area_pointer->number_of_attributes);
if (attribute_number != 0) {
option = Get_Option("Weight or Result weight", "WR");
/* adjust the attribute's weight, or one of its result weights, as
requested */
switch (option) {
case 'W':
adjust_weight(log_stream, area_pointer, attribute_number,
level + 1, &adjustment_made);
break;
case 'R':
adjust_result_weight(log_stream, area_pointer, attribute_number,
level + 1, &adjustment_made);
break;
case Quit_Character:
attribute_number = 0;
break;
}
}
} while (attribute_number != 0);
if (adjustment_made) {
fprintf(log_stream, "\n");
if (weights_filename != NULL) {
/* a weights filename was specified, so open the adjusted weights
file */
sprintf(filename, "%s-%s%s", weights_filename, area_pointer->identifier,
LaTeX_File_Extension);
if ((weights_stream = fopen(filename, "w")) == NULL) {
sprintf(message, "can't open adjusted weights file \"%s\"", filename);
error_exit(log_stream, message);
}
Indent(log_stream, level + 1);
fprintf(log_stream, "Writing adjusted weights to \"%s\".\n\n", filename);
}
if (weights_stream != NULL) {
/* write the table of adjusted weights */
fprintf(weights_stream, "%% Adjusted weights file\n\n");
Write_LaTeX_Header(weights_stream, inputable_latex);
fprintf(weights_stream, "%s{%s area}\n\n", Heading, area_pointer->identifier);
Write_Weights_Table(weights_stream, area_pointer);
Write_LaTeX_Trailer(weights_stream, inputable_latex);
}
if (weights_filename != NULL)
/* a weights filename was specified, so close the adjusted weights
file */
if (fclose(weights_stream) == EOF) {
sprintf(message, "can't close adjusted weights file \"%s\"", filename);
error_exit(log_stream, message);
}
} else {
Indent(log_stream, level + 1);
fprintf(log_stream, "No adjustments made.\n\n");
}
Indent(log_stream, level);
fprintf(log_stream, "Leaving Adjuster module.\n\n");
}
Other SHYSTER modules: Shyster, Statutes, Cases, Tokenizer, Parser, Dumper, Checker, Scales, Consultant, Odometer and Reporter.