adjuster.h

/* 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);

adjuster.c

/* 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.