Routines in Lib_rtn.c

The file contains the following routines:


ADD_CVT_DETAILS: Routine to read in a list of known conversion details

/************************************************************************/
/*					                                    				*/
/*    ADD_CVT_DETAILS - Add a set of conversion details					*/
/*		                                    							*/
/*    Calling Format:                       							*/
/*									                                    */
/*	    ADD_CVT_DETAILS (details_ptr, prtfil_ptr);						*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		details_ptr = Conversion details to be added					*/
/*		prtfil_ptr  = Pointer to log file (may be NULL)					*/
/*									                                    */
/*    This routine adds the specified conversion details to the array	*/
/*	  for the current group.											*.
/*									                                    */
/************************************************************************/

BINARY_CHOP: Routine to perform a binary chop on an array of char* pointers

/************************************************************************/
/*																		*/
/*    BINARY_CHOP - Do a Binary Chop search of a char* array			*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		match_sub = BINARY_CHOP (inp_ptr, inp_len, array_ptr,			*/
/*								 item_cnt, item_size, item_off,			*/
/*								 index_ptr, prtfil_ptr);				*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		match_sub = Index of matched entry (-1 if no match)				*/
/*		inp_ptr   = Pointer to input buffer to be matched				*/
/*		inp_len   = Length of string to compare.  If the items are		*/
/*				    fixed-width then the input will be padded with		*/
/*					spaces; otherwise it will be null-terminated.		*/
/*		array_ptr = Pointer to array of char* pointers.					*/
/*		item_cnt  = Count of items in array (-1 => no array).			*/
/*		item_size = Size of items if fixed-width (0 if null-terminated)	*/
/*		item_off  = Offset in each item of string to be matched.		*/
/*		index_ptr = Index array pointer; NULL if no index array			*/
/*		prtfil_ptr = Pointer to log file (may be NULL)					*/
/*																		*/
/*    This routine is called by any routine that wants to perform a		*/
/*    binary chop search on an array of character strings.				*/
/*																		*/
/************************************************************************/

CHECK_ERR: Routine to check if error is known error and, if not, print it to screen & log file

/************************************************************************/
/*																		*/
/*    CHECK_ERR - Check an error string to see if it is a known error	*/
/*				  and, if not, print it to the screen and log file		*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		status = CHECK_ERR (prtfil_ptr, format_ptr, ...);				*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		status	   = PSP_TRUE if error was known error					*/
/*				   = PSP_FALSE otherwise								*/
/*		prtfil_ptr = Pointer to log file (may be NULL)					*/
/*		format_ptr = Pointer to format string for vprintf				*/
/*		...        = Additional parameters for vprintf					*/
/*																		*/
/*    This routine simply performs a printf operation both to the		*/
/*    screen and to the log file.  It avoids the need for having two	*/
/*    printf statements everywhere (and stops them getting out of step).*/
/*																		*/
/************************************************************************/

CHK_CONDSTR: Routine to check if a conditional string matches for us

/************************************************************************/
/*																		*/
/*    CHK_CONDSTR - Validate a buffer according to format string		*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		status = CHK_CONDSTR (prtfil_ptr, our_types, condstr, inpbuf);	*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		status		= PSP_TRUE if conditional string matches us			*/
/*					= PSP_FALSE otherwise								*/
/*		prtfil_ptr	= Pointer to file to reprort errors on				*/
/*		our_types	= Our types (separated by |)						*/
/*		condstr		= Conditional string								*/
/*		inpbuf		= Input buffer (to use in error messages)			*/
/*																		*/
/*	  The conditional string contains one or more conditional flags		*/
/*	  separated by '/' characters. Each flag is either INC_xxx which	*/
/*	  means the record is only required for type 'XXX' or EXC_xxx which	*/
/*	  means the record is required for anything except type 'XXX'.		*/
/*	  There may be multiple INC_xxx or EXC_xxx flags in the string but	*/
/*	  they must all be of the same type.								*/
/*																		*/
/************************************************************************/

CHK_GENFMT: Routine to check that a string follows the rules defined in a format string

/************************************************************************/
/*																		*/
/*    CHK_GENFMT - Validate a buffer according to format string			*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		status = CHK_GENFMT (format_ptr, recbuf_ptr);					*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		status     = PSP_TRUE if buffer matches the format string		*/
/*				   = PSP_FALSE otherwise								*/
/*		format_ptr = Pointer to null-terminated format string			*/
/*		recbuf_ptr   = Pointer to null-terminated buffer to validate	*/
/*																		*/
/*    This routine checks the input buffer to see if it has the			*/
/*    format defined by the format string.  The format string contains	*/
/*    either literals (inside single quotes) or command strings.		*/
/*    The command strings are of the form:								*/
/*																		*/
/*		X - Any number of characters of type 'X'						*/
/*		nX - Exactly n characters of type 'X'							*/
/*		nX - At least n characters of type 'X'							*/
/*		n-mX - Between n and m (inclusive) characters of type 'X'		*/
/*																		*/
/*    where 'X' may be one of the following:							*/
/*																		*/
/*		A = Alphabetic Character (any case)								*/
/*		D = Digit														*/
/*		L = Lowercase Alphabetic										*/
/*		R = Roman Numerals												*/
/*		U = Uppercase Alphabetic										*/
/*																		*/
/*    Note that no error messages are output by this routine.			*/
/*																		*/
/************************************************************************/

CPTR_COMP_RTN: Routine to sort an array of char* pointers

/************************************************************************/
/*																		*/
/*    CPTR_COMP_RTN - Compare two boilerplate entries					*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		ival = CPTR_COMP_RTN (rec1_ptr, rec2_ptr);						*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		ival     = -1 if rec1 < rec2; 0 if equal; +1 if rec1 > rec2		*/
/*		rec1_ptr = Pointer to pointer to first record					*/
/*		rec2_ptr = Pointer to pointer to second record					*/
/*																		*/
/*    This routine is called by qsort to sort an array of pointers		*/
/*    to character strings into order.									*/
/*																		*/
/************************************************************************/

CPTR_COMP_NOCASE: Routine to sort an array of char* pointers ignoring case

/************************************************************************/
/*																		*/
/*    CPTR_COMP_NOCASE - Compare two boilerplate entries ignoring case	*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		ival = CPTR_COMP_NOCASE (rec1_ptr, rec2_ptr);					*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		ival     = -1 if rec1 < rec2; 0 if equal; +1 if rec1 > rec2		*/
/*		rec1_ptr = Pointer to pointer to first record					*/
/*		rec2_ptr = Pointer to pointer to second record					*/
/*																		*/
/*    This routine is called by qsort to sort an array of pointers		*/
/*    to character strings into order, ignoring case.					*/
/*																		*/
/************************************************************************/

END_ERR_GROUP: Routine to check unmatched exception errors for the current group

/************************************************************************/
/*																		*/
/*    END_ERR_GROUP - Find unmatched exception errors for current group	*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		rtnsts = END_ERR_GROUP (prtfil_ptr);							*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		rtnsts	   = PSP_TRUE if there were any unmatched exceptions	*/
/*				   = PSP_FALSE otherwise								*/
/*		prtfil_ptr = Pointer to log file (may be NULL)					*/
/*																		*/
/*    This routine simply scans the exception errors array to see if	*/
/*	  there are any unmatched exception errors for the current group	*/
/*	  and, if so, logs a diagnostic.									*/
/*																		*/
/************************************************************************/

FIND_CHR: Routine to find a character, allowing for accent trigraphs

/************************************************************************/
/*									                                    */
/*    FIND_CHR - Find character, allowing for accent trigraphs		    */
/*									                                    */
/*    Calling Format:							                        */
/*									                                    */
/*	    char_ptr = FIND_CHR (buff_ptr, char);				            */
/*									                                    */
/*    Where:								                            */
/*									                                    */
/*	    char_ptr = Pointer to first occurrence of character		        */
/*	    buff_ptr = Pointer to buffer to be scanned			            */
/*	    char     = Character to search for				                */
/*									                                    */
/*    This routine is the equivalent of STRCHR but allows for the fact	*/
/*    that the character being searched for might be embedded in part	*/
/*    of an accent trigraph.						                    */
/*									                                    */
/************************************************************************/

FIND_CVT_DETAILS: Routine to find the conversion details for a specific US ID

/************************************************************************/
/*					                                    				*/
/*    FIND_CVT_DETAILS - Find a set of conversion details				*/
/*		                                    							*/
/*    Calling Format:                       							*/
/*									                                    */
/*	    rtnsts = FIND_CVT_DETAILS (class_ptr, details_ptr,				*/
/*								   detailbuflen, prtfil_ptr);			*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		rtnsts		 = PSP_TRUE if conversion details found				*/
/*					   PSP_FALSE otherwise								*/
/*		class_ptr    = magazine ID in US format							*/
/*		details_ptr  = Buffer to hold conversion details				*/
/*		detailbuflen = Length of conversion details buffer				*/
/*		prtfil_ptr   = Pointer to log file (may be NULL)				*/
/*									                                    */
/*    This routine looks for, and returns, a set of conversion details	*/
/*	  for a given US abbreviation.										*.
/*									                                    */
/************************************************************************/

FIND_CVT_GROUP: Routine to set up the conversion details pointer for the start of a group

/************************************************************************/
/*																		*/
/*    FIND_CVT_GROUP - Find entry for given file in conversion details	*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		FIND_CVT_GROUP (file_name, prtfil_ptr);							*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		file_name = Name of file being checked							*/
/*		prtfil_ptr = Pointer to log file (may be NULL)					*/
/*																		*/
/*    This routine scans the conversion details array to see if			*/
/*	  there is a section for the named file and, if so, sets up a		*/
/*	  pointer to the first entry in the array for it.					*/
/*																		*/
/************************************************************************/

FIND_STR: Routine to find a string, allowing for accent trigraphs

/************************************************************************/
/*									                                    */
/*    FIND_STR - Find string, allowing for accent trigraphs				*/
/*									                                    */
/*    Calling Format:							                        */
/*									                                    */
/*	    char_ptr = FIND_STR (buff_ptr, inpstr);				            */
/*									                                    */
/*    Where:								                            */
/*									                                    */
/*	    char_ptr = Pointer to first occurrence of character		        */
/*	    buff_ptr = Pointer to buffer to be scanned			            */
/*	    srch_ptr = Pointer to string to search for						*/
/*									                                    */
/*    This routine is the equivalent of STRSTR but allows for the fact	*/
/*    that the first character in the seatch string might be embedded	*/
/*	  in part of an accent trigraph.						            */
/*									                                    */
/************************************************************************/

PRINT_ERR: Routine to print to screen & log file

/************************************************************************/
/*																		*/
/*    PRINT_ERR - Print a string to the screen and a log file			*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		PRINT_ERR (prtfil_ptr, format_ptr, ...);						*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		prtfil_ptr = Pointer to log file (may be NULL)					*/
/*		format_ptr = Pointer to format string for vprintf				*/
/*		...        = Additional parameters for vprintf					*/
/*																		*/
/*    This routine simply performs a printf operation both to the		*/
/*    screen and to the log file.  It avoids the need for having two	*/
/*    printf statements everywhere (and stops them getting out of step).*/
/*																		*/
/************************************************************************/

READ_CVT_DETAILS: Routine to read in a list of known conversion details

/************************************************************************/
/*					                                    				*/
/*    READ_CVT_DETAILS - Read list of known conversion details			*/
/*		                                    							*/
/*    Calling Format:                       							*/
/*									                                    */
/*	    READ_CVT_DETAILS (cvtfil_ptr, prtfil_ptr);				        */
/*									                                    */
/*    This routine simply reads a list of file names and known			*/
/*	  conversion details from excfil_ptr and stores them in a			*/
/*	  global array.														*/
/*									                                    */
/************************************************************************/

READ_ERR_EXCEPT: Routine to read in a list of known error exceptions

/************************************************************************/
/*					                                    				*/
/*    READ_ERR_EXCEPT - Read list of allowed error exceptions			*/
/*		                                    							*/
/*    Calling Format:                       							*/
/*									                                    */
/*	    READ_ERR_EXCEPT (excfil_ptr, prtfil_ptr);				        */
/*									                                    */
/*    This routine simply reads a list of file names and expected		*/
/*	  error messages from excfil_ptr and stores them in a global array.	*/
/*									                                    */
/************************************************************************/

RESET_CVT_GROUP: Routine to reset the conversion details pointer for the start of a group

/************************************************************************/
/*																		*/
/*    RESET_CVT_GROUP - Reset entry for given file in conversion		*/
/*						details											*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		RESET_CVT_GROUP (file_name, prtfil_ptr);						*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		file_name = Name of file being converted						*/
/*		prtfil_ptr = Pointer to log file (may be NULL)					*/
/*																		*/
/*    This routine calls FIND_CVT_GROUP to find any existing group for	*/
/*	  this file and, if found, disables it before starting a new one	*/
/*	  for the same file at the end of the array.						*/
/*																		*/
/************************************************************************/

SAF_CAT: Routine to put a safe shell around strcat

/************************************************************************/
/*																		*/
/*    SAF_CAT - Append a character string, truncating if necessary		*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		SAF_CAT (outbuf_ptr, inpbuf_ptr, buflen);						*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		outbuf_ptr = Pointer to output buffer							*/
/*		inpbuf_ptr = Pointer to input buffer							*/
/*		buflen     = Size of output buffer								*/
/*																		*/
/*    This routine is a shell around STRCAT that ensures that the		*/
/*    output buffer doesn't overflow.  If truncation is required		*/
/*    then an @ sign is stuck at the end.								*/
/*																		*/
/************************************************************************/

SAF_CHRCAT: Routine to emulate a safe MEMCAT Routine for 1 char

/************************************************************************/
/*																		*/
/*    SAF_CHRCAT - Append a single character, truncating if necessary	*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		SAF_CHRCAT (outbuf_ptr, inpchr, buflen);						*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		outbuf_ptr = Pointer to output buffer							*/
/*		inpchr	   = Input character									*/
/*		buflen     = Size of output buffer								*/
/*																		*/
/*    This routine is a version of SAF_CAT that inserts a single		*/
/*    character rather than a string.									*/
/*																		*/
/************************************************************************/

SAF_CPY: Routine to put a safe shell around strcpy

/************************************************************************/
/*																		*/
/*    SAF_CPY - Copy a character string, truncating if necessary		*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		SAF_CPY (outbuf_ptr, inpbuf_ptr, buflen);						*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		outbuf_ptr = Pointer to output buffer							*/
/*		inpbuf_ptr = Pointer to input buffer							*/
/*		buflen     = Size of output buffer								*/
/*																		*/
/*    This routine is a shell around STRCPY that ensures that the		*/
/*    output buffer doesn't overflow.  If truncation is required		*/
/*    then an @ sign is stuck at the end.								*/
/*																		*/
/************************************************************************/

SAF_NCAT: Routine to emulate a safe MEMCAT Routine

/************************************************************************/
/*																		*/
/*    SAF_NCAT - Append a fixed number of characters, truncating if		*/
/*				 necessary												*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		SAF_NCAT (outbuf_ptr, inpbuf_ptr, inplen, buflen);				*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		outbuf_ptr = Pointer to output buffer							*/
/*		inpbuf_ptr = Pointer to input buffer							*/
/*		inplen     = Size of input buffer								*/
/*		buflen     = Size of output buffer								*/
/*																		*/
/*    This routine emulates a MEMCAT function and also ensures that the	*/
/*    output buffer doesn't overflow.  If truncation is required		*/
/*    then an @ sign is stuck at the end.								*/
/*																		*/
/************************************************************************/

SET_ERRNAM: Routine to set up file name for error log

/************************************************************************/
/*																		*/
/*    SET_ERRNAM - Set error name for given file						*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		SET_ERRNAM (file_name);											*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		file_name = Name of file being processed						*/
/*				  = "" if no name to be used							*/
/*																		*/
/*    This routine remembers the name of the current file being			*/
/*	  processed for output to the log file if necessary.				*/
/*																		*/
/************************************************************************/

SETUP_SPACES: Routine to set up leading tabs/spaces in a buffer

/************************************************************************/
/*																		*/
/*    SETUP_SPACES - Set up buffer with tabs/spaces to given length		*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		SETUP_SPACES (buff_ptr, buff_len, size);						*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		buff_ptr = Pointer to buffer to be set up						*/
/*		buff_len = Size of buffer pointed to by buff_ptr				*/
/*		size     = Size of tabs/spaces to be set up						*/
/*																		*/
/*    This routine simply sets up the buffer with the appropriate		*/
/*    number of tabs and/or spaces to reach the sepcified size.  For	*/
/*    example, a size of 10 would generate a tab followed by 2 spaces.	*/
/*																		*/
/************************************************************************/

SPLIT: Routine to split a record into constituent fields

/************************************************************************/
/*									                                    */
/*    SPLIT - Split record into constituent parts			            */
/*									                                    */
/*    Calling Format:							                        */
/*									                                    */
/*	    SPLIT (inlin_ptr, fld_ptr, fldcnt_ptr, max_fields, divider);    */
/*									                                    */
/*    Where:								                            */
/*									                                    */
/*	    inlin_ptr  = Pointer to input record				            */
/*	    fld_ptr    = Array of Pointers to Fields to be set up		    */
/*	    fldcnt_ptr = Pointer to int to hold Field Count			        */
/*	    max_fields = Maximum number of fields supported by fld_ptr	    */
/*	    divider    = Divider character (e.g. '~' or 0X1F)		        */
/*									                                    */
/*    This routine will replace each occurrence of "divider" in the     */
/*    string pointed to by inlin_ptr by a null, and will set up an	    */
/*    element of fld_ptr to point to each segment so created, including	*/
/*    the last one.  Special care is taken to allow for a fake divider	*/
/*    being used as part of a multi-character accent sequence. Note	    */
/*    that if the last character in the line is a divider then there	*/
/*    will be an "extra" field of length 0 returned.			        */
/*									                                    */
/*    fldcnt_ptr will be set to a count of the fields created,		    */
/*    excluding any null fields at the end.  A total of max_fields	    */
/*    entries will be set up in fld_ptr, with unused ones pointing	    */
/*    to a null string.							                        */
/*									                                    */
/*    Note that fld_ptr is ONLY valid as long as the buffer pointed	    */
/*    to by inlin_ptr is unchanged.					                    */
/*									                                    */
/************************************************************************/

START_ERR_GROUP: Routine to set up the error exceptions pointer for the start of a group

/************************************************************************/
/*																		*/
/*    START_ERR_GROUP - Find entry for given file in exception errors	*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		START_ERR_GROUP (file_name, prtfil_ptr);						*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		file_name = Name of file being checked							*/
/*				  = "" if no groups in file								*/
/*				  = "*" if all entries to be checked					*/
/*		prtfil_ptr = Pointer to log file (may be NULL)					*/
/*																		*/
/*    This routine scans the exception errors array to see if			*/
/*	  there is a section for the named file and, if so, sets up a		*/
/*	  pointer to the first entry in the array for it.					*/
/*	  It also outputs the (full) filename to the screen and remembers	*/
/*	  it for output to the log file if necessary.						*/
/*																		*/
/************************************************************************/

STR_CVTLOWER: Routine to convert a character string to lower case

/************************************************************************/
/*																		*/
/*    STR_CVTLOWER - Convert a character string to lower case			*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*			STR_CVTLOWER (buff_ptr);									*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		buff_ptr = Pointer to buffer to be converted					*/
/*																		*/
/*    This routine simply iterates through the input string, calling	*/
/*    tolower for each character in turn.								*/
/*																		*/
/************************************************************************/

STR_CVTNUMBER: Routine to convert a character string into a number

/************************************************************************/
/* */
/* STR_CVTNUMBER - Convert a character string to a number */
/* */
/* Calling Format: */
/* */
/* number = STR_CVTNUMBER (buff_ptr); */
/* */
/* Where: */
/* */
/* number = Converted number or -1 if non-numeric character found*/
/* buff_ptr = Pointer to buffer to be converted */
/* */
/* This routine simply iterates through the input string, checking */
/* each character is numeric and calculating the total if so. */
/* */
/************************************************************************/

This routine simply does what it says on the tin. It is intended as a more efficient way of converting a string of numbers into an integer than sscanf as well as handling errors better.


STR_CVTUPPER: Routine to convert a character string to upper case

/************************************************************************/
/*																		*/
/*    STR_CVTUPPER - Convert a character string to upper case			*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		STR_CVTUPPER (buff_ptr);										*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		buff_ptr = Pointer to buffer to be converted					*/
/*																		*/
/*    This routine simply iterates through the input string, calling	*/
/*    toupper for each character in turn.								*/
/*																		*/
/************************************************************************/

STR_NOTRAIL: Routine to strip off trailing spaces

/************************************************************************/
/*																		*/
/*    STR_NOTRAIL - Strip off trailing blanks							*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		STR_NOTRAIL (buff_ptr);											*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		buff_ptr = Pointer to null-terminated input buffer				*/
/*																		*/
/************************************************************************/

WRITE_CVT_DETAILS: Routine to write out the list of known conversion details

/************************************************************************/
/*					                                    				*/
/*    WRITE_CVT_DETAILS - Output list of known conversion details		*/
/*		                                    							*/
/*    Calling Format:                       							*/
/*									                                    */
/*	    WRITE_CVT_DETAILS (cvtfil_ptr, prtfil_ptr);				        */
/*									                                    */
/*    This routine outputs the contents of the global array to the		*/
/*	  specified file, ignoring any that have been disabled.				*/
/*									                                    */
/************************************************************************/