/* *********************************************************************************** * * Bitterness - v1995.05.04 * * The Bitterness Calculator takes into account both the time of boil and the wort * gravity during the boil. The numbers are my own, based partly on data and partly * on experience. Your experience and brewing practices may be different than mine * so here's the official disclaimer: Your Mileage May Vary (YMMV). * * This one is for the US units page--IBU.html: * * (1.65*0.000125^(gravity-1))*(1-EXP(-0.04*time))*alpha*mass*28.3*1000 * --------------------------------------------------------------------- * (3.785*volume*4.15) * * and this one for the metric units page--ibumetric.html: * * (1.65*0.000125^(gravity-1))*(1-EXP(-0.04*time))*alpha*mass*1000 * ----------------------------------------------------------------- * (volume*4.15) * * The variables above are named exactly how they're named in the HTML. * * input: * version=US&volume=5&gravity=1.050&mass=2.0&alpha=5.0&time=60 * * To test this routine's POST method, do the following: * setenv REQUEST_METHOD POST * setenv CONTENT_TYPE "application/x-www-form-urlencoded" * setenv CONTENT_LENGTH 60 * Bitterness.exe < input > output.html * * To test this routine's GET method. do the following: * setenv REQUEST_METHOD GET * setenv QUERY_STRING "version=US&volume=5&gravity=1.050&mass=2.0&alpha=5.0&time=60" * Bitterness.exe > output.html * ************************************************************************************ */ #include #include #include #include #include "/usr/include/math.h" #include #include #include #define COEFF1 1.65 #define COEFF2 1.25e-4 #define COEFF3 0.04 #define COEFF4 4.15 #define GRAMSPEROUNCE 28.3 #define LITERSPERGALLON 3.785 #define GRAMSPERKG 1000.0 typedef enum {METRIC, US} units; extern char *metric_unit_page[]; extern char *english_unit_page[]; void metric_ivars(volume, gravity, mass, alpha, time, bitterness) float volume; float gravity; float mass; float alpha; float time; float bitterness; { char buffer[256]; sprintf(buffer,"
  • Boil Volume = liters \n",volume); fputs(buffer,stdout); sprintf(buffer,"
  • Boil wort gravity (specific gravity) = \n",gravity); fputs(buffer,stdout); sprintf(buffer,"
  • Mass of hops added = grams \n",mass); fputs(buffer,stdout); sprintf(buffer,"
  • Alpha acid rating = percent \n",alpha*100.0); fputs(buffer,stdout); sprintf(buffer,"
  • Time hops were boiled = minutes \n",time); fputs(buffer,stdout); sprintf(buffer,"
  • Approximate Bittering Units = %.1f\n", bitterness); fputs(buffer,stdout); } void english_ivars(volume, gravity, mass, alpha, time, bitterness) float volume; float gravity; float mass; float alpha; float time; float bitterness; { char buffer[256]; sprintf(buffer,"
  • Boil Volume = gallons \n",volume); fputs(buffer,stdout); sprintf(buffer,"
  • Boil wort gravity (specific gravity) = \n",gravity); fputs(buffer,stdout); sprintf(buffer,"
  • Mass of hops added = ounces \n",mass); fputs(buffer,stdout); sprintf(buffer,"
  • Alpha acid rating = percent \n",alpha*100.0); fputs(buffer,stdout); sprintf(buffer,"
  • Time hops were boiled = minutes \n",time); fputs(buffer,stdout); sprintf(buffer,"
  • Approximate Bittering Units = %5.1f\n", bitterness); fputs(buffer,stdout); } void print_error(reason) char *reason; { printf("Error in Calculation.\n"); printf("

    Error in Calculation.

    \n"); printf(" %s.

    \n",reason); exit(0); } /* Parse a Key=Value pairing, and look for '=' sign in ascending or descending order */ #define AscendingOrder 1 #define DescendingOrder 2 char * parseKeyValuePair(string,order) char *string; int order; { char *ptr = NULL; /* Find the equal sign and set ptr to next character. */ if(order == AscendingOrder) ptr = (char *)(index(string,'=') + sizeof(char)); else if(order == DescendingOrder) ptr = (char *)(rindex(string,'=') + sizeof(char)); /* Advance ptr one character is present character is a space */ if(ptr) { while(isspace(*ptr)) ptr += sizeof(char); } return ptr; } int main(argc, argv) int argc; char **argv; { int i; int line, nline; int nstr = 0; int len = 0; int lineno; char **page; char *ptr = NULL; char *method = NULL; char *string[7]; char buffer[256]; void (*ivars)(); /* INPUT VARIABLES */ float alpha = -1.0; /* Alpha acid rating (percent) */ float gravity = -1.0; /* Boil wort gravity (specific gravity) */ float mass = -1.0; /* Mass of hops added (grams/ounces) */ float time = -1.0; /* Time hops were boiled (Minutes) */ float volume = -1.0; /* Boil Volume (liters/gallons) */ #ifdef USUNITS units version = US; /* type of units, US or Metric */ #else units version = METRIC; /* type of units, US or Metric */ #endif /* OUTPUT VARIABLES */ float bitterness; /* Bitterness result. */ #ifdef DEBUG /* MIME HTML header */ printf("Content-type: text/html\n\n"); #endif /* If the request method is GET, read the environment variable for data. */ method = getenv("REQUEST_METHOD"); if(!method) method = "UNKNOWN"; if(strcmp(method,"GET")==0) { ptr = getenv("QUERY_STRING"); if(ptr == NULL) { printf("No query information to decode.\n"); exit(1); } len = strlen(ptr); string[0] = (char *)malloc((len+1)*sizeof(char)); strcpy(string[0], ptr); } /* If the request method is POST, read stdin for variable data. */ else if(strcmp(method,"POST")==0) { if(strcmp(getenv("CONTENT_TYPE"),"application/x-www-form-urlencoded")) { printf("This script can only be used to decode form results. \n"); exit(1); } len = atoi(getenv("CONTENT_LENGTH")); string[0] = (char *)malloc((len+1)*sizeof(char)); fread(string[0], sizeof(char), len, stdin); string[0][len] = '\0'; #ifdef DEBUG printf("REQUEST_METHOD = %s\n",method); printf("CONTENT_TYPE = %s\n", getenv("CONTENT_TYPE")); printf("CONTENT_LENGTH = %i\n", len); #endif } else { printf("Unknown REQUEST_METHOD = %s.\n", method); exit(1); } #ifdef DEBUG printf("strlen(string[0]) = %i\n",len); printf("string[0] = %s\n",string[0]); #endif /* Parse argument into "name=value" strings */ nstr = 1; for(i=0; i", "", "", "", "", "Hop Bitterness Calculator", "", "", "", "", "

    ", "", "

    Bitterness Calculator

    ", "", "

    ", "", "The Bitterness Calculator takes into account both the time of boil", "and the wort gravity during the boil. The numbers are my own, based ", "partly on data and partly on experience. Your experience and brewing ", "practices may be different than mine so here's the official disclaimer:", "Your Mileage May Vary (YMMV). Have fun with this and don't forget to ", "let me know what you think of it.

    ", "", "Fill out the form below to find out the estimated Bittering ", "Units (BU) in your homebrew. When you finish entering all", "the values click Calculate to send them to the calculator ", "program.

    ", "", "

    ", "", "

    Use US units instead

    ", "", "

    ", "", "", "

    Please enter the following values:

    ", "", "

      ", "
    ", "", "", "", "

    ", "", "

    ", "", "

    ", "", "

    ", "Send feedback to: gtinseth (at) yahoo (dot) com", "
    ", "
    ", "", "

    ", "", "

    ", "", "", "", "", "", NULL}; /************************ US UNITS PAGE *************************************/ char *english_unit_page[] = { "", "", "", "", "", "", "Hop Bitterness Calculator", "", "", "", "", "

    ", "", "

    Bitterness Calculator

    ", "", "

    ", "", "The Bitterness Calculator takes into account both the time of boil", "and the wort gravity during the boil. The numbers are my own, based ", "partly on data and partly on experience. Your experience and brewing ", "practices may be different than mine so here's the official disclaimer:", "Your Mileage May Vary (YMMV). Have fun with this and don't forget to ", "let me know what you think of it.

    ", "", "Fill out the form below to find out the estimated Bittering ", "Units (BU) in your homebrew. When you finish entering all", "the values click Calculate to send them to the calculator ", "program.

    ", "", "

    ", "", "

    Use metric units instead

    ", "", "

    ", "", "", "

    Please enter the following values:

    ", "", "

      ", "
    ", "", "", "", "

    ", "", "

    ", "", "

    ", "", "

    ", "Send feedback to: gtinseth (at) yahoo (dot) com", "
    ", "
    ", "", "

    ", "", "

    ", "", "", "", "", "", NULL};