diskwrit.c
上传用户:szhypcb168
上传日期:2007-01-06
资源大小:2187k
文件大小:27k
- /* ---------------------- DATA FILE WRITE ROUTINES ---------------------- */
- /* ------ designed by dpk, rpc & committee; coded by rpc ------------ */
- /* --------------------- Version 1.4 August 1988 --------------------- */
- /* ------------------------------------------------------------------------ */
- /* RELEASE NOTES:
- Version 1.1: Eliminated large fixed-size buffers for default values by
- writing them after values were saved, rather than before. Eliminated large
- fixed-size buffers for saved values, by using malloc and realloc.
- Version 1.2: Added the auto error reporting feature. This feature is
- enabled or disabled via disk_io_erh(flag) which is in its own source file.
- Changed the algorithm for assigning buffers for saved values. Also fixed a few
- subtle bugs and made minor code changes.
- Version 1.3: Increased the amount of text in error reporting and changed
- it to print on stderr instead of stdout.
- Version 1.4: Fixed bug in end_block that made 0 length format file when
- open_type is 3.
- */
- #include "diskio.h"
- #include <stdio.h>
- #include <strings.h>
- #include <sys/file.h>
- /* variable type definitions:
- *
- * TYPE # | C TYPE | # of BYTES | FORTRAN TYPE
- * --------------------------------------------------
- * 1 | short | 2 | integer*2
- * 2 | int | 4 | integer*4
- * 3 | float | 4 | real*4
- */
- static short bytes_in[] = { 2, 4, 4 }; /* number of bytes in the data types */
- #define MAX_BYTES_PER_VAL 4 /* must be set to max value of bytes_in[] */
- #define NUM_DATA_TYPES sizeof(bytes_in)/sizeof(bytes_in[0]) /* elements in bytes_in */
- struct file_data {
- char filename[MAX_FILENAME_LENG + 1]; /* file name, without extension */
- int fd; /* file descriptor */
- short format[2 + 2*MAX_VARS_PER_BLK]; /* block information */
- char vnames[MAX_VARS_PER_BLK][MAX_VARNAME_LENG];/* variable names in block */
- short open_type; /* file open type */
- int bytes_p_blk; /* bytes per block */
- short defined; /* =1 when block defined */
- short var_count; /* inc when variable added */
- };
- static struct file_data fd[MAX_FILES];
- struct variable_data {
- short number; /* number of values per block */
- short bytes; /* number of bytes per value */
- char *base_addr; /* pointer to location for first saved value */
- short num_saved; /* number of values saved since last block end */
- char *bufp; /* pointer to location for next saved value */
- char def_val[MAX_BYTES_PER_VAL]; /* storage for default value */
- };
- static struct variable_data vd[MAX_FILES * MAX_VARS_PER_BLK];
- #define PARAM_OK -999
- struct errs {
- char routine[20]; /* name of routine where error was */
- char name[MAX_FILENAME_LENG+1]; /* filename or variable name */
- int param; /* illegal argument of call in error */
- };
- static struct errs ervar = { "", "", PARAM_OK };
- #define DFE ".sg_data"
- #define FFE ".sg_format"
- extern int errno;
- extern short auto_er; /* flag to enable/disable auto error report & halt */
- extern long lseek();
- extern char *malloc(), *realloc();
- extern char *strcat(), *strcpy(), *strncpy();
- /* ------------------------- OPEN FILE ROUTINE ------------------------- */
- /* DESCRIPTION:
- file_id = open_file ( filename, open_type )
- This routine opens the file "filename" so that data may be written to it.
- The parameter "open_type" specifies the following:
- 1 - delete any prior contents of specified file
- 2 - append to prior contents of specified file
- 3 - if specified file doesn't exist: delete any prior contents
- if specified file does exist: don't open it and return an appropriate
- error message
- Returned value:
- If there are no errors, the returned value is a file id which is used to
- identify this open file when using several other of the disk write routines.
- A valid file id is >= 0. If an error occurs, the returned value is < 0.
- The following errors are detected:
- - file "filename" is already open
- - filename is too long
- - the number of files currently open is the maximum
- - could not create a format file
- - could not create a data file
- - could not open filename.sg_format for reading
- - could not open filename.sg_data for writing
- - file "filename" exists and open_type prohibits overwriting
- - invalid open_type
- */
- open_file ( filename, open_type )
- char filename[];
- int open_type;
- {
- int file_id, i, tempfd;
- char dname[MAX_FILENAME_LENG + sizeof(DFE)];
- char fname[MAX_FILENAME_LENG + sizeof(FFE)];
- strcpy(ervar.routine, "open_file");
- strncpy(ervar.name, filename, MAX_FILENAME_LENG);
- strcat(ervar.name, "");
- /*
- * check to see if this file has already been opened:
- * NOTE: The first call relies on open_type set to 0 by the compiler
- */
- for (i=0; i<MAX_FILES; i++)
- {
- if (fd[i].open_type != 0) /* this file_id is in use, so check name */
- {
- if (strcmp(filename, fd[i].filename) == 0) /* file already open */
- {
- if (auto_er) error_exit(-8);
- return(-8);
- }
- }
- }
- /*
- * look for the first available file_id:
- */
- file_id = -1;
- for (i=0; i<MAX_FILES; i++)
- {
- if (fd[i].open_type == 0) /* this file_id is available */
- {
- file_id = i;
- break;
- }
- }
- if (file_id == -1) /* all files are currently open */
- {
- if (auto_er) error_exit(-1);
- return(-1);
- }
- /*
- * append the data and format extensions to requested filename:
- */
- if (strlen(filename) > MAX_FILENAME_LENG) /* filename too long */
- {
- if (auto_er) error_exit(-9);
- return(-9);
- }
- strcpy(dname, filename);
- strcat(dname, DFE);
- strcpy(fname, filename);
- strcat(fname, FFE);
- if (open_type == 1 || open_type == 3) /* new file or check for file */
- {
- if ( (open_type==3) && (access(dname, F_OK)==0) ) /* file exists */
- {
- if (auto_er) error_exit(-6);
- return(-6);
- }
- /*
- * create an empty format file (to be written in first end_block call):
- */
- tempfd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
- if (tempfd == -1) /* can't create format file */
- {
- perror("The system call error in disk write is");
- if (auto_er) error_exit(-2);
- return(-2);
- }
- close(tempfd); /* close the format file */
- /*
- * create an empty data file:
- */
- tempfd = open(dname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
- if (tempfd == -1) /* can't create data file */
- {
- perror("The system call error in disk write is");
- if (auto_er) error_exit(-3);
- return(-3);
- }
- }
- else if (open_type == 2) /* append to file 'filename' */
- {
- if (access(fname, R_OK) == -1) /* can't read format file */
- {
- perror("The system call error in disk write is");
- if (auto_er) error_exit(-4);
- return(-4);
- }
- tempfd = open(dname, O_WRONLY); /* open data file for writing */
- if (tempfd == -1) /* couldn't open data file for writing */
- {
- perror("The system call error in disk write is");
- if (auto_er) error_exit(-5);
- return(-5);
- }
- lseek(tempfd, (long) 0 , 2); /* go to end of file to append */
- }
- else /* invalid open_type */
- {
- ervar.param = open_type;
- if (auto_er) error_exit(-7);
- return(-7);
- }
- /*
- * define the fd variables:
- */
- strcpy(fd[file_id].filename, filename);
- fd[file_id].open_type = open_type;
- fd[file_id].fd = tempfd;
- fd[file_id].defined = 0;
- fd[file_id].var_count = 0;
- fd[file_id].bytes_p_blk = 0;
- /*
- * For each variable this file may have, set vd[i].bytes = 0. This enables
- * the error of saving before defining to be detected.
- */
- for(i=0; i<MAX_VARS_PER_BLK; i++) vd[var_id_gen(file_id, i+1)].bytes = 0;
- return(file_id);
- }
- /* ---------------------- DEFINE VARIABLE ROUTINE ---------------------- */
- /* DESCRIPTION:
-
- var_id = def_variable ( file_id, name, type, number, def_val )
- This routine defines parameters of a variable to be saved. The
- parameters are the variable's name, data type, number per block, and default
- value. Variables may be defined until the first call to end_block, which ends
- the variable definition process. The string used as the variable's name does
- not have to be the name the calling program uses to reference the variable's
- values. It can be some other string of the programmer's choosing. This name
- is used to select the variable for reading by the disk read routines. It is
- also used to select and label variables in SUNGRAPH. This routine does NOT
- check for duplication of variable names, so be sure that each file variable has
- a unique name. The default value is a pointer to a variable that has been
- initialized to the desired default value. This variable must be of the type
- specified in the argument list of this function (i.e. "type"). It is NOT a
- pointer to a character string. The default value is written if the user saves
- fewer than "number" values per block.
- Returned value:
- When no error occurs, the returned value is a variable id which is used
- to identify this variable when saving its values with the save variable routine.
- A valid variable id is >= 0. If an error occurs, the returned value is < 0.
- The following errors are detected:
- - 'file_id' is out of range
- - 'file_id' corresponds to an unopened file
- - the file variables have already been defined
- - invalid data type specified
- - invalid number of values specified
- - the maximum number of variables have already been defined
- - variable name is too long
- - could not get a buffer for saved values
- */
- def_variable ( file_id, name, type, number, def_val )
- char name[], def_val[];
- int file_id, type, number;
- {
- int i, var_id, var_num, var;
- char *base, *tpntr;
- strcpy(ervar.routine, "def_variable");
- strncpy(ervar.name, name, MAX_FILENAME_LENG);
- strcat(ervar.name, "");
- /*
- * do the easy error checking:
- */
- if (file_id < 0 || file_id >= MAX_FILES) /* invalid id */
- {
- ervar.param = file_id;
- if (auto_er) error_exit(-11);
- return(-11);
- }
- if (fd[file_id].open_type == 0) /* file not open */
- {
- ervar.param = file_id;
- if (auto_er) error_exit(-12);
- return(-12);
- }
- if (fd[file_id].defined == 1) /* all variables defined */
- {
- if (auto_er) error_exit(-13);
- return(-13);
- }
- if (type < 1 || type > NUM_DATA_TYPES) /* invalid type */
- {
- ervar.param = type;
- if (auto_er) error_exit(-14);
- return(-14);
- }
- if (number < 1 || number > MAX_VALUES_PER_VAR) /* invalid number */
- {
- ervar.param = number;
- if (auto_er) error_exit(-15);
- return(-15);
- }
- if (fd[file_id].var_count == MAX_VARS_PER_BLK) /* too many variables */
- {
- if (auto_er) error_exit(-16);
- return(-16);
- }
- if (strlen(name) > MAX_VARNAME_LENG) /* name too long */
- {
- if (auto_er) error_exit(-17);
- return(-17);
- }
- /*
- * assign a variable id and set fd variables:
- */
- var_num = 1 + fd[file_id].var_count++;
- var_id = var_id_gen( file_id, var_num );
- fd[file_id].format[2*var_num] = type;
- fd[file_id].format[2*var_num+1] = number;
- fd[file_id].bytes_p_blk += bytes_in[type-1] * number;
- strcpy(&fd[file_id].vnames[var_num-1][0], name);
- /*
- * set vd variables:
- */
- vd[var_id].number = number;
- vd[var_id].num_saved = 0;
- vd[var_id].bytes = bytes_in[type-1];
- for (i=0; i<vd[var_id].bytes; i++) vd[var_id].def_val[i] = def_val[i];
- /*
- * allocate memory and assign base address:
- */
- if (var_num == 1) /* first variable in this file */
- {
- vd[var_id].base_addr = malloc( (unsigned) fd[file_id].bytes_p_blk);
- if (vd[var_id].base_addr == 0) /* couldn't get memory */
- {
- if (auto_er) error_exit(-10);
- return(-10);
- }
- }
- else /* add a variable to the file */
- {
- base = vd[var_id_gen(file_id, 1)].base_addr;
- tpntr = realloc(base, (unsigned) fd[file_id].bytes_p_blk);
- if (tpntr == 0) /* could not get memory */
- {
- if (auto_er) error_exit(-10);
- return(-10);
- }
- if (tpntr != base) /* buffer was moved by realloc */
- { /* so, move pointers for prior variables */
- for (i=1; i<fd[file_id].var_count; i++)
- {
- var = var_id_gen(file_id, i);
- vd[var].base_addr += tpntr - base;
- vd[var].bufp += tpntr - base;
- }
- free(base); /* and release the old buffer */
- }
- vd[var_id].base_addr = vd[var_id-1].base_addr
- + vd[var_id-1].bytes * vd[var_id-1].number;
- }
- vd[var_id].bufp = vd[var_id].base_addr;
- return(var_id);
- }
- /* ----------------------- SAVE VARIABLE ROUTINE ----------------------- */
- /* DESCRIPTION:
- status = save_variable ( var_id, values, num )
- This routine saves values of a variable that has been defined. "values"
- is the array of which "num" values will be saved. The data type of the values
- array must match that declared when the variable was defined. The routine does
- NOT test for such a match. The number of values saved per call can be from 1
- to the number per block specified when the variable was defined via def_var.
- The total number of values saved per variable cannot exceed the number defined
- when the variable was defined. When saving a single value, be sure that
- "values" is a POINTER to that value.
- Returned value:
- The returned value indicates whether or not the routine encountered an
- error. If no error occurs, the returned value is 0. If an error occurs, the
- returned value is < 0.
- The following errors are detected:
- - attempt to save less than one variable
- - 'var_id' is out of range
- - 'var_id' corresponds to an undefined variable
- - all values of this variable have been saved since last end_block
- - saved less than the specified number of values
- */
- save_variable ( var_id, values, num )
- register char *values;
- int var_id, num;
- {
- register char *bufp, *endp;
- int values_left, error;
- strcpy(ervar.routine, "save_variable");
- strcpy(ervar.name, "UNKNOWN"); /* the first 2 errors have no f or v name */
- /*
- * do the easy error checking:
- */
- if (var_id < 0 || var_id >= MAX_FILES * MAX_VARS_PER_BLK) /* out of range */
- {
- ervar.param = var_id;
- if (auto_er) error_exit(-19);
- return(-19);
- }
- if (vd[var_id].bytes == 0) /* undefined variable */
- {
- ervar.param = var_id;
- if (auto_er) error_exit(-20);
- return(-20);
- }
- strcpy(ervar.name, fd[var_id/MAX_VARS_PER_BLK].vnames[var_id%MAX_VARS_PER_BLK]);
- if (num < 1) /* saving less than one value */
- {
- if (auto_er) error_exit(-18);
- return(-18);
- }
- /*
- * find out if the requested amount of values can be saved:
- */
- values_left = vd[var_id].number - vd[var_id].num_saved;
- if (values_left == 0) /* all values already saved */
- {
- if (auto_er) error_exit(-21);
- return(-21);
- }
- error = 0;
- if (num > values_left) /* not enough space to save all values */
- {
- num = values_left; /* truncate number saved to number left */
- error = -22; /* and report this error */
- }
- vd[var_id].num_saved += num; /* account for the number of values saved */
- /*
- * move the new values to the data buffer:
- */
- bufp = vd[var_id].bufp; /* fetch buffer pointer, for register use */
- endp = vd[var_id].bufp + num * vd[var_id].bytes; /* end of transfer */
- while (bufp < endp) *bufp++ = *values++; /* move values & inc pointers */
- vd[var_id].bufp = bufp; /* restore the advanced buffer pointer */
- if (error<0 && auto_er) error_exit(error);
- return(error);
- }
- /* ------------------------- END BLOCK ROUTINE ------------------------- */
- /* DESCRIPTION:
- status = end_block ( file_id )
- This routine terminates the saving of variables for a block. The values
- in the block are written to the data file. This is the ONLY routine which
- writes values to the data file. The first call to this routine terminates the
- variable definition process, i.e. def_var can no longer be called for this
- file_id.
- Returned value:
- The returned value indicates whether or not the routine encountered an
- error. If no error occurs, the returned value is 0. If an error occurs, the
- returned value is < 0.
- The following errors are detected:
- - 'file_id' is out of range
- - 'file_id' corresponds to an unopened file
- - current variable definition differs from that of appended file
- - error when writing format file
- - error when writing data buffer to disk
- - no variables have been defined
- */
- end_block ( file_id )
- int file_id;
- {
- register int i;
- int var_id, bytes, tempfd, vnum;
- short format[2 + 2*MAX_VARS_PER_BLK];
- char fname[MAX_FILENAME_LENG + sizeof(FFE)];
- strcpy(ervar.routine, "end_block");
- strcpy(ervar.name, "UNKNOWN"); /* the first 2 errors have no f or v name */
- /*
- * do the easy error checking:
- */
- if (file_id < 0 || file_id >= MAX_FILES) /* bogus file_id */
- {
- ervar.param = file_id;
- if (auto_er) error_exit(-11);
- return(-11);
- }
- if (fd[file_id].open_type == 0) /* file not open */
- {
- ervar.param = file_id;
- if (auto_er) error_exit(-12);
- return(-12);
- }
- strcpy(ervar.name, fd[file_id].filename);
- /*
- * for all variables in this file, put default values into unused locations:
- */
- for (vnum=1; vnum<=fd[file_id].var_count; vnum++)
- {
- var_id = var_id_gen(file_id, vnum);
- while (vd[var_id].num_saved++ < vd[var_id].number)
- {
- for (i=0; i<vd[var_id].bytes; i++)
- *vd[var_id].bufp++ = vd[var_id].def_val[i];
- }
- }
- /*
- * If this is the first time end_block is called for this file_id:
- * if appending, compare format of old file with current definition;
- * if writing a new file, write the format information.
- */
- if (fd[file_id].defined == 0) /* first call for this file_id */
- {
- if (fd[file_id].var_count == 0) /* no variables defined */
- {
- if (auto_er) error_exit(-28);
- return(-28);
- }
- fd[file_id].format[0] = 1; /* disk-resident data */
- fd[file_id].format[1] = fd[file_id].var_count;
- fd[file_id].defined = 1; /* indicate that the block has been defined */
- /*
- * make the format file name:
- */
- strcpy(fname, fd[file_id].filename);
- strcat(fname, FFE);
- if (fd[file_id].open_type == 2) /* appending to current file */
- {
- tempfd = open(fname, O_RDONLY);
- read(tempfd, format, 4); /* read the first 2 format values */
- if (format[1] != fd[file_id].format[1]) /* # of vars different */
- {
- close(tempfd); /* close the format file */
- if (auto_er) error_exit(-25);
- return(-25);
- }
- read(tempfd, &format[2], 4*format[1]); /* read var definitions */
- for (i=2; i < 2 + 2*format[1]; i++)
- {
- if (format[i] != fd[file_id].format[i]) /* type or # different */
- {
- close(tempfd); /* close the format file */
- if (auto_er) error_exit(-25);
- return(-25);
- }
- }
- close(tempfd);
- }
- else /* new file; write format info */
- {
- tempfd = open(fname, O_WRONLY);
- /*
- * write the format array:
- */
- bytes = 4 + 4 * fd[file_id].var_count;
- if (bytes != write(tempfd, fd[file_id].format, bytes) )
- {
- close(tempfd); /* close the format file */
- if (bytes == -1) perror("The system call error in disk write is");
- if (auto_er) error_exit(-26);
- return(-26);
- }
- /*
- * write the variable names:
- */
- bytes = fd[file_id].var_count * MAX_VARNAME_LENG;
- if (bytes != write(tempfd, fd[file_id].vnames, bytes) )
- {
- close(tempfd); /* close the format file */
- if (bytes == -1) perror("The system call error in disk write is");
- if (auto_er) error_exit(-26);
- return(-26);
- }
- close(tempfd); /* close the format file */
- }
- }
- /*
- * reset bufp & num_saved in preparation to save the next block:
- */
- for (vnum=1; vnum<=fd[file_id].var_count; vnum++)
- {
- var_id = var_id_gen(file_id, vnum);
- vd[var_id].bufp = vd[var_id].base_addr;
- vd[var_id].num_saved = 0;
- }
- /*
- * write the block buffer:
- */
- bytes = fd[file_id].bytes_p_blk;
- if (bytes != write(fd[file_id].fd, vd[var_id_gen(file_id, 1)].base_addr, bytes) )
- {
- if (bytes == -1) perror("The system call error in disk write is");
- if (auto_er) error_exit(-27);
- return(-27);
- }
- return(0);
- }
- /* ------------------------- CLOSE FILE ROUTINE ------------------------- */
- /* DESCRIPTION:
- status = close_file ( file_id )
- This routine closes the file associated with "file_id". In the event that
- more files need to be written than can be opened simultaneously, this routine
- provides a way to close a file so that another can be opened.
- Returned value:
- The returned value indicates whether or not the routine encountered an
- error. If no error occurs, the returned value is 0. If an error occurs, the
- returned value is < 0.
- The following errors are detected:
- - 'file_id' is out of range
- - 'file_id' corresponds to an unopened file
- */
- close_file ( file_id )
- int file_id;
- {
- strcpy(ervar.routine, "close_file");
- strcpy(ervar.name, "UNKNOWN"); /* can't determine associated file name */
- /*
- * do the easy error checking:
- */
- if (file_id < 0 || file_id >= MAX_FILES) /* bogus file_id */
- {
- ervar.param = file_id;
- if (auto_er) error_exit(-11);
- return(-11);
- }
- if (fd[file_id].open_type == 0) /* file not open */
- {
- ervar.param = file_id;
- if (auto_er) error_exit(-12);
- return(-12);
- }
- close(fd[file_id].fd);
- free(vd[var_id_gen(file_id,1)].base_addr); /* free the saved value buffer */
- fd[file_id].open_type = 0; /* make file_id available */
- return(0);
- }
- /* ------------------- PRINT DISK WRITE ERROR ROUTINE ------------------- */
- /* DESCRIPTION:
- print_disk_write_error ( err_num )
- This routine prints an error message which corresponds to "err_num".
- It is printed on stderr.
- */
- print_disk_write_error ( err_num )
- int err_num;
- {
- char *disk_write_error();
- if (err_num < 0)
- {
- fprintf(stderr, "Disk_IO error in routine '%s'.n", ervar.routine);
- fprintf(stderr, "The filename or variable name associated with the offending call is:n");
- fprintf(stderr, "%sn", ervar.name);
- fprintf(stderr, disk_write_error(err_num) );
- if (ervar.param != PARAM_OK)
- {
- fprintf(stderr, "Its value was: %dn", ervar.param);
- ervar.param = PARAM_OK;
- }
- }
- else fprintf(stderr, disk_write_error(err_num) );
- return;
- }
- /* ---------------------- DISK WRITE ERROR ROUTINE ---------------------- */
- /* DESCRIPTION:
- error_string = disk_write_error ( err_num )
- The disk_write_error routine returns a brief error message which
- corresponds to "err_num".
- */
- char *disk_write_error ( err_num )
- int err_num;
- {
- static char err_string[70];
- static char *err_msg[] = {
- "No error", /* 0 */
- /*
- * OPEN FILE ERRORS:
- */
- "The number of files currently open is the maximum", /* 1 */
- "Could not create a format file", /* 2 */
- "Could not create a data file", /* 3 */
- "Could not open 'filename'.sg_format for reading", /* 4 */
- "Could not open 'filename'.sg_data for writing", /* 5 */
- "File 'filename' exists and you want to protect it", /* 6 */
- "Invalid 'open_type'", /* 7 */
- "File 'filename' is already open", /* 8 */
- "Filename is too long", /* 9 */
- /*
- * DEFINE VARIABLE ERRORS:
- */
- "Could not get a buffer for saved values", /* 10 */
- "'file_id' is out of range", /* 11 */
- "'file_id' corresponds to an unopened file", /* 12 */
- "The file variables have already been defined", /* 13 */
- "The specified data type is not valid", /* 14 */
- "The specified number of values is not valid", /* 15 */
- "The maximum number of variables have already been defined", /* 16 */
- "Variable name is too long", /* 17 */
- /*
- * SAVE VARIABLE ERRORS:
- */
- "Attempt to save less than one value", /* 18 */
- "'var_id' is out of range", /* 19 */
- "'var_id' corresponds to an undefined variable", /* 20 */
- "All values of this variable have been saved", /* 21 */
- "Number of values saved exceeded amount defined", /* 22 */
- "unassigned", /* 22 */
- "unassigned", /* 24 */
- /*
- * END BLOCK ERRORS:
- */
- /* uses errors 11 & 12 from define variable */
- "Current variable definition does not match that of old file", /* 25 */
- "Error when writing format file", /* 26 */
- "Error when writing data buffer to disk", /* 27 */
- "No variables have been defined", /* 28 */
- /*
- * CLOSE FILE ERRORS:
- */
- /* uses errors 11 & 12 from define variable */
- "unassigned", /* 29 */
- /*
- * ALL OTHER ERRORS:
- */
- "Bad value for error number" /* 30 */
- };
- #define NUM 30
- if (err_num > 0) err_num = 0; /* force positive arguments to give no error */
- strcpy(err_string, (-err_num < NUM) ? err_msg[-err_num] : err_msg[NUM] );
- strcat(err_string,".n");
- return(err_string);
- }
- /* -------------------------- SUPPORT ROUTINES -------------------------- */
- /* ----------------------------- VAR_ID_GEN ----------------------------- */
- /* DESCRIPTION:
- Given a file_id and variable number, this routine returns a variable id.
- The variable number range is 1 to MAX_VARS_PER_BLK inclusive.
- */
- static var_id_gen ( file_id, var_num )
- int file_id, var_num;
- {
- return(file_id * MAX_VARS_PER_BLK + var_num - 1);
- }
- /* ----------------------------- ERROR_EXIT ----------------------------- */
- static error_exit(err_num)
- int err_num;
- {
- print_disk_write_error(err_num);
- exit(-1);
- }