home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / s / sd-27.zip / sdsi.c < prev    next >
C/C++ Source or Header  |  1992-11-23  |  10KB  |  426 lines

  1. /* SD -- square dance caller's helper.
  2.  
  3.     Copyright (C) 1990, 1991, 1992  William B. Ackerman.
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 1, or (at your option)
  8.     any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19.     This is for version 25. */
  20.  
  21. /* This defines the following functions:
  22.    general_initialize
  23.    generate_random_number
  24.    generate_random_concept_p
  25.    get_mem
  26.    free_mem
  27.    get_date
  28.    open_file
  29.    probe_file
  30.    write_file
  31.    close_file
  32.    print_line
  33.    print_id_error
  34.    init_error
  35.    add_resolve_indices
  36.    final_exit
  37.    open_database
  38.    read_from_database
  39.    close_database
  40.    fill_in_neglect_percentage
  41.    parse_number
  42.    open_call_list_file
  43.    read_from_call_list_file
  44.    write_to_call_list_file
  45.    close_call_list_file
  46.  
  47. and the following external variables:
  48.    random_number
  49.    hashed_randoms
  50.    database_filename
  51. */
  52.  
  53.  
  54. #define _POSIX_SOURCE
  55.  
  56. #include <stdio.h>
  57. #include <errno.h>
  58. #include <string.h>
  59. #include <time.h>
  60. #include <unistd.h>
  61.  
  62. /* We take pity on those poor souls who are compelled to use
  63.     troglodyte development environments. */
  64.  
  65. #ifdef __STDC__
  66. #include <stdlib.h>
  67. #else
  68. extern void free(void *ptr);
  69. extern char *malloc(unsigned int siz);
  70. extern void exit(int code);
  71. extern void srand48(long int);
  72. extern long int lrand48(void);
  73. #endif
  74.  
  75. #include "sd.h"
  76. #include "paths.h"
  77.  
  78.  
  79. /* These variables are external. */
  80.  
  81. int random_number;
  82. int hashed_randoms;
  83.  
  84.  
  85. static int last_hashed_randoms;
  86. static FILE *fp;
  87. static FILE *fildes;
  88. static long_boolean file_error;
  89. static char fail_message[MAX_ERR_LENGTH];
  90. static char fail_errstring[MAX_ERR_LENGTH];
  91.  
  92.  
  93. static char *get_errstring(void)
  94. {
  95. #ifdef sun
  96.    extern int sys_nerr;
  97.    extern char *sys_errlist[];
  98.  
  99.    if (errno < sys_nerr) return sys_errlist[errno];
  100.    else return "?unknown error?";
  101. #else
  102.    return strerror(errno);
  103. #endif
  104. }
  105.  
  106.  
  107. extern void general_initialize(void)
  108. {
  109.    srand48(time((long int *)0));
  110. }
  111.  
  112.  
  113. extern int generate_random_number(int modulus)
  114. {
  115.    int j;
  116.  
  117.    random_number = lrand48();
  118.    j = random_number % modulus;
  119.    last_hashed_randoms = hashed_randoms;       /* save in case we need to undo it */
  120.    hashed_randoms = hashed_randoms*37+j;
  121.    return(j);
  122. }
  123.  
  124.  
  125. extern long_boolean generate_random_concept_p(void)
  126. {
  127.    int i = generate_random_number(8);
  128.  
  129.    /* Since we are not going to use the random number in a one-to-one way, we run the risk
  130.       of not having hashed_randoms uniquely represent what is happening.  To remedy
  131.       the problem, we undo the transformation that was just made to hashed_randoms,
  132.       and redo it with just the information we intend to use. */
  133.  
  134.    hashed_randoms = last_hashed_randoms*37;       /* Now just need to add something. */
  135.  
  136.    if (i < CONCEPT_PROBABILITY) {
  137.       hashed_randoms++;          /* This should do the trick. */
  138.       return (TRUE);
  139.    }
  140.    else {
  141.       return (FALSE);
  142.    }
  143. }
  144.  
  145.  
  146. extern void *get_mem(unsigned int siz)
  147. {
  148.    void *buf;
  149.  
  150.    buf = malloc(siz);
  151.    if (!buf) {
  152.       fprintf(stderr, "Can't allocate %d bytes of memory.\n", siz);
  153.       perror("malloc");
  154.       exit_program(2);
  155.    }
  156.    return(buf);
  157. }
  158.  
  159.  
  160. extern void free_mem(void *ptr)
  161. {
  162.    free(ptr);
  163. }
  164.  
  165.  
  166. extern void get_date(char dest[])
  167. {
  168.    long int clock;
  169.    char *junk;
  170.    char *dstptr;
  171.  
  172.    time(&clock);
  173.    junk = ctime(&clock);
  174.    dstptr = dest;
  175.    string_copy(&dstptr, junk);
  176.    if (dstptr[-1] == '\n') dstptr[-1] = '\0';         /* Stupid UNIX! */
  177. }
  178.  
  179.  
  180.  
  181. extern void open_file(void)
  182. {
  183.    int this_file_position;
  184.  
  185.    file_error = FALSE;
  186.  
  187.    if (!(fildes = fopen(outfile_string, "a"))) {
  188.       (void) strncpy(fail_errstring, get_errstring(), MAX_ERR_LENGTH);
  189.       (void) strncpy(fail_message, "open", MAX_ERR_LENGTH);
  190.       file_error = TRUE;
  191.       return;
  192.    }
  193.  
  194.    this_file_position = ftell(fildes);
  195.  
  196.    if ((last_file_position != -1) && (last_file_position != this_file_position)) {
  197.       writestuff("Warning -- file has been modified since last sequence.");
  198.       newline();
  199.       newline();
  200.    }
  201.  
  202.    if (this_file_position == 0) {
  203.       writestuff("File does not exist, creating it.");
  204.       newline();
  205.       newline();
  206.    }
  207.    else {
  208.       char junk[1];
  209.  
  210.       if (last_file_position == -1) {
  211.          writestuff("Appending to existing file.");
  212.          newline();
  213.          newline();
  214.       }
  215.  
  216.       junk[0] = '\f';      /* Write a formfeed (end-of-page indicator). */
  217.       if ((fwrite(junk, 1, 1, fildes) != 1) || ferror(fildes)) {
  218.          (void) strncpy(fail_errstring, get_errstring(), MAX_ERR_LENGTH);
  219.          (void) strncpy(fail_message, "write", MAX_ERR_LENGTH);
  220.          file_error = TRUE;
  221.       }
  222.    }
  223. }
  224.  
  225.  
  226. extern long_boolean probe_file(char filename[])
  227. {
  228.    /* If the file does not exist, we allow it, even though creation may
  229.       not be possible because of directory permissions.  It is unfortunate
  230.       that there is no feasible way to determine whether a given pathname
  231.       could be opened for writing. */
  232.    if (access(filename, F_OK) || !access(filename, W_OK))
  233.       return (TRUE);
  234.    else
  235.       return (FALSE);
  236. }
  237.  
  238.  
  239. extern void write_file(char line[])
  240. {
  241.    int size;
  242.    char nl = '\n';
  243.  
  244.    if (file_error) return;    /* Don't keep trying after a failure. */
  245.  
  246.    size = strlen(line);
  247.    if ((fwrite(line, 1, size, fildes) != size) || ferror(fildes)) {
  248.       (void) strncpy(fail_errstring, get_errstring(), MAX_ERR_LENGTH);
  249.       (void) strncpy(fail_message, "write", MAX_ERR_LENGTH);
  250.       file_error = TRUE;      /* Indicate that sequence will not get written. */
  251.       return;
  252.    }
  253.  
  254.    if ((fwrite(&nl, 1, 1, fildes) != 1) || ferror(fildes)) {
  255.       (void) strncpy(fail_errstring, get_errstring(), MAX_ERR_LENGTH);
  256.       (void) strncpy(fail_message, "write", MAX_ERR_LENGTH);
  257.       file_error = TRUE;      /* Indicate that sequence will not get written. */
  258.    }
  259. }
  260.  
  261.  
  262. extern void close_file(void)
  263. {
  264.    char foo[MAX_ERR_LENGTH*10];
  265.  
  266.    if (file_error) goto fail;
  267.    last_file_position = ftell(fildes);
  268.  
  269.    if (!fclose(fildes)) return;
  270.  
  271.    (void) strncpy(fail_errstring, get_errstring(), MAX_ERR_LENGTH);
  272.    (void) strncpy(fail_message, "close", MAX_ERR_LENGTH);
  273.  
  274.    fail:
  275.  
  276.    (void) strncpy(foo, "WARNING!!!  Sequence has not been written!  File ", MAX_ERR_LENGTH);
  277.    (void) strncat(foo, fail_message, MAX_ERR_LENGTH);
  278.    (void) strncat(foo, " failure on \"", MAX_ERR_LENGTH);
  279.    (void) strncat(foo, outfile_string, MAX_ERR_LENGTH);
  280.    (void) strncat(foo, "\": ", MAX_ERR_LENGTH);
  281.    (void) strncat(foo, fail_errstring, MAX_ERR_LENGTH);
  282.    specialfail(foo);
  283. }
  284.  
  285. /* Used only for printing error messages, so writes to stderr */
  286. extern void print_line(char s[])
  287. {
  288.    fprintf(stderr, "%s\n", s);
  289. }
  290.  
  291.  
  292. extern void print_id_error(int n)
  293. {
  294.    fprintf(stderr, "Call didn't identify self -- %d\n", n);
  295. }
  296.  
  297.  
  298. extern void init_error(char s[])
  299. {
  300.    fprintf(stderr, "Error initializing program: %s\n", s);
  301. }
  302.  
  303.  
  304. extern void add_resolve_indices(char junk[], int cur, int max)
  305. {
  306.    sprintf(junk, "%d out of %d", cur, max);
  307. }
  308.  
  309.  
  310.  
  311. extern void final_exit(int code)
  312. {
  313.    exit(code);
  314. }
  315.  
  316. char *database_filename = DATABASE_FILENAME;
  317.  
  318. extern void open_database(void)
  319. {
  320.    int format_version, n;
  321.  
  322.    if (!(fp = fopen(database_filename, "r"))) {
  323.       fprintf(stderr, "Can't open database file.\n");
  324.       perror(database_filename);
  325.       exit_program(1);
  326.    }
  327.  
  328.    if (read_from_database() != DATABASE_MAGIC_NUM) {
  329.       fprintf(stderr,
  330.          "Database file \"%s\" has improper format.\n", database_filename);
  331.       exit_program(1);
  332.    }
  333.  
  334.    format_version = read_from_database();
  335.    if (format_version != DATABASE_FORMAT_VERSION) {
  336.       fprintf(stderr,
  337.          "Database format version (%d) is not the required one (%d) -- you must recompile the database.\n",
  338.          format_version, DATABASE_FORMAT_VERSION);
  339.       exit_program(1);
  340.    }
  341.  
  342.    abs_max_calls = read_from_database();
  343.    max_base_calls = read_from_database();
  344.  
  345.    n = read_from_database();
  346.    sprintf(major_database_version, "%d", n);
  347.    n = read_from_database();
  348.    sprintf(minor_database_version, "%d", n);
  349. }
  350.  
  351.  
  352. extern int read_from_database(void)
  353. {
  354.    int bar;
  355.  
  356.    bar = (fgetc(fp)&0xFF) << 8;
  357.    bar |= fgetc(fp)&0xFF;
  358.    return(bar);
  359. }
  360.  
  361.  
  362. extern void close_database(void)
  363. {
  364.    fclose(fp);
  365. }
  366.  
  367.  
  368. extern int parse_number(char junk[])
  369. {
  370.    int n;
  371.  
  372.    if (sscanf(junk, "%d", &n) != 1) return(0);
  373.    return(n);
  374. }
  375.  
  376.  
  377. extern void fill_in_neglect_percentage(char junk[], int n)
  378. {
  379.    sprintf(junk, "LEAST RECENTLY USED %d%% OF THE CALLS ARE:", n);
  380. }
  381.  
  382.  
  383. static FILE *call_list_file;
  384.  
  385. extern long_boolean open_call_list_file(call_list_mode_t call_list_mode, char filename[])
  386. {
  387.    if (call_list_mode == call_list_mode_abridging) {
  388.       call_list_file = fopen(filename, "r");
  389.    }
  390.    else {
  391.       call_list_file = fopen(filename, "w");
  392.    }
  393.  
  394.    if (!call_list_file) {
  395.       printf("Can't open call list file\n");
  396.       perror(filename);
  397.       return TRUE;
  398.    }
  399.    else
  400.       return FALSE;
  401. }
  402.  
  403.  
  404. extern char *read_from_call_list_file(char name[], int n)
  405. {
  406.    return (fgets(name, n, call_list_file));
  407. }
  408.  
  409.  
  410. extern void write_to_call_list_file(char name[])
  411. {
  412.    fputs(name, call_list_file);
  413.    fputs("\n", call_list_file);
  414. }
  415.  
  416.  
  417. extern long_boolean close_call_list_file(void)
  418. {
  419.    if (fclose(call_list_file)) {
  420.       printf("Can't close call list file\n");
  421.       return TRUE;
  422.    }
  423.    else
  424.       return FALSE;
  425. }
  426.