Routines in Auth_rtn.c

The routines in Auth_rtn.c revolve around the use of an Auth structure (defined in Auth_rtn.c and known only internally) which contains:

The file then contains the following routines:


ALLOC_AUTH: Routine to allocate an AUTH structure

/************************************************************************/
/*									*/
/*    ALLOC_AUTH - Allocate a new AUTH structure.			*/
/*									*/
/*    Calling Format:							*/
/*									*/
/*	auth_ptr = ALLOC_AUTH ();					*/
/*									*/
/*    Where:								*/
/*									*/
/*	auth_ptr  = Pointer to new AUTH structure (NULL if none)	*/
/*									*/
/*    This routine allocates a new AUTH structure and initializes	*/
/*    the contents of it.						*/
/*									*/
/************************************************************************/


This routine simply allocates an Auth structure and initialises all the relevant fields in it.


BUILD_AUTH: Routine to build an author string from an AUTH structure

/************************************************************************/
/*									*/
/*    BUILD_AUTH - Build up a string of authors from an AUTH structure	*/
/*									*/
/*    Calling Format:							*/
/*									*/
/*	BUILD_AUTH (auth_ptr, buff_ptr, buflen, build_typ);		*/
/*									*/
/*    Where:								*/
/*									*/
/*	auth_ptr  = Pointer to author structure				*/
/*	buff_ptr  = Pointer to output buffer				*/
/*	buflen    = Length of output buffer				*/
/*	build_typ = Type of build required (see below)			*/
/*									*/
/*    This routine is used to build up a string of authors from an	*/
/*    AUTH structure and has a separate build type for each environment	*/
/*    from which it is called.  Currently supported types are:		*/
/*									*/
/*    BLDAUT_PRIMARY = The format used by some parts of the FORMAT	*/
/* program. This just builds a string of the primary author names, */
/* separated by ", " or " & ". Note that, if all authors have the */
/* same surname then it is only listed once. */
/* BLDAUT_ABBREV = The format used in ABBREV.CVT. This is identical */
/* to BLDAUT_PRIMARY except that it is prefixed by "ed." if the */
/* "edited by" flag is set. */
/* BLDAUT_BIBITEM = The format used on an item line in bibliography */
/* text files. For edited books this is ", Surname/Surname/..." */
/* and for other books it is identical to BLDAUT_PRIMARY except */
/* it is prefixed by ", by ". */
/* BLDAUT_CVTFORTH = The format used by the CVTFORTH program. This */
/* is identical to BLADUT_PRIMARY except that it is prefixed by */
/* "by " or "ed. by" as appropriate. */
/* BLDAUT_INTERNAL = The internal format used by the main programs. */ /* BLDAUT_REALINT = The internal format used by the main programs, */ /* but with the "real" names inserted. */ /* */ /************************************************************************/

This routine formats a string of authors held in an Auth structure into the format required by various other programs. The behaviour depends on the type as indicated above:

BLDAUT_PRIMARY:

The routine creates a string of the form "name1, name2 &..." where each name1 (etc.) represents the reverted name (via REVERT_AUTH) of each primary author. Note that if all the authors have the same surname then it is only specified once. Note also that, if the last author is the special {et al.} then it is appended as ", et al." (i.e. without the final &).

This case is handled via the local routine BUILD_AUTH_NORMAL as the same basic format is used by several of the types.

BLDAUT_ABBREV:

The routine uses the same format as BLDAUT_PRIMARY (via BUILD_AUTH_NORMAL) prefixed with "ed. by " if edityp_ptr contains "ed." or "eds.".

BLDAUT_BIBITEM:

The format here depends on whether the Auth structure contains editors or not (i.e. edityp_ptr contains "ed." or "eds."). If it does then the routine creates a string of the form ", surname1/surname2/..." where each surname1 (etc.) represents the surname (only) of each primary author; if it doesn't then it uses the same format as BLDAUT_PRIMARY (via BUILD_AUTH_NORMAL) prefixed with "by ".

BLDAUT_CVTFORTH:

The routine uses the same format as BLDAUT_PRIMARY (via BUILD_AUTH_NORMAL) prefixed with "ed. by " if edityp_ptr contains "ed." or "eds."; with "by " if edityp_ptr is NULL; and with "xxx by " (where xxx is the contents of edityp_ptr) otherwise.

BLDAUT_INTERNAL & BLDAUT_REALINT:

These two are handled together as the code is almost identical. At it's simplest it simply produces a string of the form "name1/name2/..." where name1 (etc.) corresponds to each autnam_ptr (for BLDAUT_INTERNAL) or realautnam_ptr (for BLDAUT_REALINT). What (really) complicates the routine is the handling of secondary names which might be in the new format or the old format and may be positional or global. Basically, for each primary name the routine scans the structure for any positional secondary names whose secautsub matches and appends the secnam_ptr (for BLDAUT_INTERNAL) or realsecnam_ptr (for BLDAUT_REALINT) either preceded by the appropriate sectyp_ptr (for new style) and put in brackets, or followed by it (for old style). Note also that:


BUILD_AUTH_NORMAL: Internal routine to build up a typical string of authors from an AUTH structure

/************************************************************************/
/* */
/* BUILD_AUTH_NORMAL - Build up a typical string of authors from an */
/* AUTH structure */
/* */
/* Calling Format: */
/* */
/* BUILD_AUTH_NORMAL (auth_ptr, buff_ptr, buflen); */
/* */
/* Where: */
/* */
/* auth_ptr = Pointer to author structure */
/* buff_ptr = Pointer to output buffer */
/* buflen = Length of output buffer */
/* */
/* This routine is used to build up a typical string of authors */
/* from an AUTH structure. It is an internal routine used by */
/* BUILD_AUTH as several types share the same basic format. */
/* */
/* Basically it just builds a string of the primary author names, */
/* separated by ", " or " & ", but note that, if all authors have */
/* the same surname then it is only listed once. */
/* */
/* Note that the string is APPENDED to the output buffer to allow */
/* different callers to add different prefixes as required. */
/* */
/************************************************************************/

The routine first calls CHK_SURNAME to see if all the authors have the same surname. If so it sets the internal variable rvt_type to REVAUT_NORMAL; otherwise it sets it to REVAUT_SURNAME. It then loops through each primary author, reverting them via REVERT_AUTH (specifying the type in rvt_type) and adding them to the buffer separated by ", " except for the last pair which are separated by " & " UNLESS the last author is {et al.}, in which case ", et al." is appended.


BUILD_PART_AUTH: Routine to build an author string (in parts) from an AUTH structure

/************************************************************************/
/*									*/
/*    BUILD_PART_AUTH - Build up a string of authors from an AUTH	*/
/*			structure in multiple parts.			*/
/*									*/
/*    Calling Format:							*/
/*									*/
/*	rtnsts = BUILD_PART_AUTH (auth_ptr, autbuf_ptr, autbuflen,	*/
/*				  coautbuf_ptr, coautbuflen,		*/
/* secnambuf_ptr, secnambuflen, */
/* bylinebuf_ptr, bylinebuflen, */
/* segment, build_typ, prtfil_ptr); */ /* */ /* Where: */ /* */ /* rtnsts = Routine return status */ /* = PSP_FALSE if fewer than "segment" authors */ /* = PSP_TRUE otherwise */ /* auth_ptr = Pointer to author structure */ /* autbuf_ptr = Pointer to author buffer */ /* autbuflen = Length of author buffer */ /* coautbuf_ptr = Pointer to co-author buffer */ /* coautbuflen = Length of co-author buffer */ /* secnambuf_ptr = Pointer to secondary names buffer */ /* secnambuflen = Length of secondary names buffer */ /* bylinebuf_ptr = Pointer to byline buffer */ /* bylinebuflen = Length of byline buffer */ /* segment = Segment to use as main author */ /* = -1 if no segmentation required */ /* build_typ = Type of build required (see below) */ /* prtfil_ptr = Pointer to diagnostics file (may be NULL) */ /* */ /* This routine is used to build up a string of authors from an */ /* AUTH structure from the viewpoint of a single author segment. */ /* It has a separate build type for each environment */ /* from which it is called. Currently supported types are: */ /* */ /* BLDAUT_REALINT = The internal format used by the main programs, */ /* but with the "real" names inserted. */ /* BLDAUT_REALSECINT = Like BLDAUT_REALINT but used for creating */ /* a view of the authors string from a secondary author */ /* */ /************************************************************************/

This routine is used by SCAN_FILE to look at a complex author string from the point of view of each of the authors in turn. The routine is called repeatedly with segment incremented by one each time (starting at zero) until the routine returns an error indicating that segment was too large. Note that, because of the way SCAN_FILE works, it is important that this routine initialises the output buffers even if it is going to return failure. Note that, in all cases, the co-authors are sorted into alphabetical order and any duplicates are deleted.

Note also that, on input, the secondary names buffer (secnambuf_ptr) contains the global secondary names to avoid the need to keep calculating them.

We also

Note that, throughout:

For BLDAUT_REALINT, the outputs are calculated as follows:

Thus, for example, we might have:

There are a couple of points to note here:

For BLDAUT_REALSECINT it is a bit more complicated as it depends on the type of secondary name that segment points to (in this case segment must be >= 0). There are currently five different types:

by/err/gho/hp/ps

In this case, the outputs are calculated as follows:

Note that we also use this code for the internal type of "xx". Thus, for example, we might have:

with

As this is really an uncredited primary author we treat it much the same was as for ordinary primary authors - i.e.:

Thus, for example, we might have:

as told by

This is a little complex as we need to invert the telling - i.e.:

Thus, for example, we might have:

as told to

This is identical to as told by except that authbuf has ", as told to" appended and the recast primary authors have a type of "as told by"

adapt/after/ed/music/tr/read by

These are all the other secondary names and are quite simple in that we need:

Thus, for example, we might have:


CHK_SURNAME - Check if authors have the same surname

/************************************************************************/
/* */
/* CHK_SURNAME - Check if authors have the same surname */
/* */
/* Calling Format: */
/* */
/* status = CHK_SURNAME (auth_ptr, check_typ); */
/* */
/* Where: */
/* */
/* status = PSP_TRUE if multiple surnames & all the same */
/* = PSP_FALSE otherwise */
/* check_typ = Type to check (1=primary; 2=secondary) */
/* */
/* This routine checks to see if all authors of a particular type */
/* in an AUTH structure share the same surname. */
/* */
/************************************************************************/

COMPARE_AUTH: Routine to compare two AUTH structures

/************************************************************************/
/* */
/* COMPARE_AUTH - Compare one AUTH structure to another. */
/* */
/* Calling Format: */
/* */
/* COMPARE_AUTH (newaut_ptr, oldaut_ptr, context_ptr, prtfil_ptr); */
/* */
/* Where: */
/* */
/* newaut_ptr = Pointer to AUTH structure to be set up */
/* oldaut_ptr = Pointer to AUTH structure to copy data from */
/* context_ptr = Pointer to context string for error messages */
/* prtfil_ptr = Pointer to diagnostics file (may be NULL) */
/* */
/* This routine compares the contents of two AUTH structures. */
/* */
/************************************************************************/

The routine just "does what it says on the tin", logging a diagnostic if there are any mismatches. It was developed when working on an alternative version of FIXUP_BYLINE to ensure the results were the same and has been left in place for any similar purposes in future.


CONVERT_AUTH: Routine to convert a string of authors from external to internal format

/************************************************************************/
/*									*/
/*    CONVERT_AUTH - Convert a string of authors from external to	*/
/*		 internal format					*/
/*									*/
/*    Calling Format:							*/
/*									*/
/*	rtnsts = CONVERT_AUTH (inpbuf_ptr, outbuf_ptr, buflen);		*/
/*									*/
/*    Where:								*/
/*									*/
/*	rtnsts     = Status of Operation				*/
/*		   = PSP_TRUE if OK					*/
/*		   = PSP_FALSE if no room for conversion		*/
/*	inpbuf_ptr = Pointer to input buffer				*/
/*	outbuf_ptr = Pointer to output buffer				*/
/*	buflen     = Length of output buffer				*/
/*									*/
/*    Authors are held externally in the format:			*/
/*									*/
/*	{ed. }Name1{, Name2...}{ & Name3}				*/
/*									*/
/*    where each name is of the form:					*/
/*									*/
/*	{First Name} Last Name{, Oddments}{ ,Number}			*/
/*									*/
/*    this routine converts the list into the format:			*/
/*									*/
/*	Name1{/Name2...}{!ed{s}.}					*/
/*									*/
/*    where each name is of the form:					*/
/*									*/
/*	Last Name{, First Name{, Oddments}}{ ,Number}			*/
/*									*/
/*    Note that this is not guaranteed to work as the comma in the	*/
/*    external format is inherently ambiguous and may be separating two	*/
/*    authors or be separating an author's last name from oddments.	*/
/*									*/
/*    In addition, there is no simple way of determining which are last	*/
/*    names and which are first names.  For the moment, the routine	*/
/*    will assume that the last "word" in a name is the surname, unless	*/
/*    the preceding word is "van", "de" or "del", in which case they	*/
/*    are also assumed to be part of the surname.			*/
/*									*/
/*    Note also that external formats are sometimes abbreviated to	*/
/*    something like "Groff & Lucy Conklin", and there's not much we	*/
/*    can do about that at the moment.					*/
/*									*/
/************************************************************************/

The routine first checks to see if the input string starts with "[" and, if so, simply returns it unchanged as anything within [...] is never converted.

It then checks to see if there is "ed. " at the start of the string and, if so, sets an internal flag (ediflg) and steps over it.

One ongoing problem in the routine is the insertion of spaces between initials. To take a classic example, if the input name is "B.A. Smith, B.A." we need to insert a space between the first "B.A." pair but not the second pair! Most of this fixup is done after we have split and inverted the names, but that code depends on there being a space between initial(s) and surname so can't handle input strings like "B.A." or "B.A.Smith". As a quick and dirty fix the routine first checks to see if the whole input string has at least one period and no spaces and, if so, inserts a space after the last period in the string. Obviously this won't handle all cases but as this is only an auxiliary routine that does not form part of the "main" programs it doesn't matter if it gets some bits wrong. The bulk of the conversion is then done via the local routine TRANSLATE_AUTH.

After that we do the bulk of the fixing up of adjacent initials without spaces by scanning for any pair of capital letters separated only by a period and, if found, adding a space after the period. Note that we only do this for the first two parts of the name (should never be needed in the surname?) to avoid inserting spaces between a degree as discussed above. It also looks for any solitary capital letters either surrounded by spaces, or at the end of the string and preceded by a space and, if found adds a period after it, to handle names like "Roy A Gallant". Note that this adds a fake period to names like "A Traveller" which become "Traveller, A." but, again, this is only an auxiliary routine so these can be handled "by hand".

Finally, the routine checks to see if ediflg is set and, if so, appends either "!ed." or "!eds." depending on whether there is a single or multiple authors.


COPY_AUTH: Routine to copy one AUTH structure to another

/************************************************************************/
/* */
/* COPY_AUTH - Copy one AUTH structure to another. */
/* */
/* Calling Format: */
/* */
/* status = COPY_AUTH (newaut_ptr, oldaut_ptr, prtfil_ptr); */
/* */
/* Where: */
/* */
/* status = PSP_TRUE if everything OK */
/* = PSP_FALSE if a MALLOC call failed */
/* newaut_ptr = Pointer to AUTH structure to be set up */
/* oldaut_ptr = Pointer to AUTH structure to copy data from */
/* prtfil_ptr = Pointer to diagnostics file (may be NULL) */
/* */
/* This routine copies the contents of one AUTH structure to another.*/
/* */
/************************************************************************/

The routine just "does what it says on the tin", logging a diagnostic if there are any mismatches. It was developed when working on an alternative version of FIXUP_BYLINE to ensure the results were the same and has been left in place for any similar purposes in future.


CXX_TRANSLATE_AUTHORS: Routine to translate an author string to "full" names, callable from C++

/************************************************************************/
/*					                                    				*/
/*    CXX_TRANSLATE_AUTHORS - Translate author string to real authors	*/
/*				Shell around C routines callable from C++				*/
/*		                                    							*/
/*    Calling Format:                       							*/
/*									                                    */
/*	    CXX_TRANS_AUTH ();					                			*/
/*									                                    */
/*    This routine simply checks the author exception structures,		*/
/*	  freeing up any allocated memory.	                      			*/
/*									                                    */
/************************************************************************/

FIXUP_BYLINE: Routine to fix up a byline structure

/************************************************************************/
/*									*/
/* FIXUP_BYLINE - Try to fix up secondary names for a byline */
/* */
/* Calling Format: */
/* */
/* rtnsts = FIXUP_BYLINE (byline_strptr, auth_strptr, prtfil_ptr); */
/* */
/* Where: */
/* */
/* rtnsts = Status of Operation */ /* = PSP_TRUE if OK */ /* = PSP_FALSE if the fixup was too complex */ /* byline_strptr = Pointer to AUTH structure for byline */
/* auth_strptr = Pointer to AUTH structure for main author */
/* prtfil_ptr = Pointer to diagnostics file (may be NULL) */
/* */
/* This routine tries to fix up the secondary names for a byline */
/* based on the information given for the main author. */
/* */
/************************************************************************/

When we have a record such as:

E 83A0~Hogan, Robert J.~Pfalz Alarm %%2 [anonymously]~ss1936G-8Dec~

the only byline that can be derived from the bit in brackets is "Anon." but this won't match the original byline of "Anon. ,(by:Hogan, Robert J.)". In a trivial case like this it is not too difficult to construct an appropriate secondary name for the byline, but the procedure becomes exponentially harder as the complexity of the structure increases and, ultimately, is unsolvable in the general case. Fortunately we live in a finite universe so the routine will do what it can and log an error for anything else for future study.

The routine first checks for the anomalous case of:

E A0~Mellen, Mark~Lawyer Who Wouldn't Stay Dead ["One Lawyer Who Wouldn't Stay Dead", as told by Jim Higgins]~ss1926GHSDec~The ~

where we have zero primary bylines and a single "as told..." secondary byline. This is really messy as we need to change the secondary byline to a primary byline and add the main author as a secondary (e.g. constructing "Higgins, Jim ,(as told to:Mellen, Mark)").

Once we've handled that case we want to compare the names in the two structures to see which match. Note, before we do this, we check for any in the main author structure that are qualified by ", (err:" or ", (gho:" as, in this case, the primary names are never relevant). Otherwise we just check each primary and secondary name in the byline against each primary and secondary name in the main authors, flagging each pair that matches.

We then need to tidy things up a bit and work out what we missed. For example, if we have a pseudonym that appears on both sides then we're not interested in the authors behind the pseudonym, so we check for any instances where we have matched the primary name and flag any secondary names for that primary name as also having been matched. Once we've done that we scan through all the secondary names to see which haven't been matched - each time we find one we remember it and flag the corresponding primary author as having been matched. There are a couple of wrinkles to this:

We then scan through the primary names to add any others we haven't matched (and which, because of the prior step, don't have any defined secondary names).

In the vast majority of cases (e.g. a single author reprinting something under a pseudonym or vice versa) we'll end up with no unmatched names so we don't need to take any action.

Assuming we do have something to do, we next check for cases where all the (remaining) main authors are undefined (typically "Anon.") or house names or joint pseudonyms (which, by definition, weren't qualified or the secondary names would be in the list instead). This covers cases where an item by a known author is reprinted anonymously, or under a house name or joint pseudonym. It also covers cases where an item by an unknown author under a house name is reprinted under another house name. None of these need any action so we just exit.

A slight variant on this is if all unmatched authors on both sides are unknown, house or joint pseudonyms (11/13/15) when, again, there is no need to do anything. We can't combine this with the former as that is OK if the byline has some known authors which would be a problem if we start including type 11 unknown pseudonyms.

The next possibility is that we have no unmatched byline authors. We must have some unmatched main authors (or the first check would have thrown us out) so the only option is that these are uncredited co-authors so we add them to the first byline author with a type of "with:".

At this point, the only options we can handle is where we have a single unmatched byline author and at least one unmatched main authors. Zero unmatched main authors would mean we have a byline we can't explain and multiple unmatched byline authors mean we have a situation such as:

E123A0~Real Author 1/Real Author 2~Story [as by House Name 1 & House Name 2]

which is theoretically possible but unsolvable as we don't know which author used which house name. At the moment there are no instances of this in the database so we can worry about it if and when they arise (the routine will report a problem in such a case).

For the options we can handle, we simply add all the unmatched main authors to the (single) unmatched byline and the only question is what prefix we should use:

That should cover all the possibilities (hopefully) but we log an error if there's anything we've missed.


FREE_AUTH: Routine to free an AUTH structure

/************************************************************************/
/*									*/
/*    FREE_AUTH - Free an AUTH structure.				*/
/*									*/
/*    Calling Format:							*/
/*									*/
/*	FREE_AUTH (auth_ptr);						*/
/*									*/
/*    Where:								*/
/*									*/
/*	auth_ptr  = Pointer to AUTH structure				*/
/*									*/
/*    This routine frees an AUTH structure and any buffers allocated	*/
/*    to it.								*/
/*									*/
/************************************************************************/

FREE_AUTH_EXCEPT: Routine to free the author exceptions data structures

/************************************************************************/
/*					                                    				*/
/*    FREE_AUTH_EXCEPT - Free memory allocated to author exceptions		*/
/*		                                    							*/
/*    Calling Format:                       							*/
/*									                                    */
/*	    FREE_AUTH_EXCEPT ();					                		*/
/*									                                    */
/*    This routine simply checks the author exception structures,		*/
/*	  freeing up any allocated memory.	                      			*/
/*									                                    */
/************************************************************************/

GET_REAL_AUTHORS: Routine to identify the real author(s) associated with an item

/************************************************************************/
/* */
/* GET_REAL_AUTHORS - get the real authors behind an AUTH structure. */
/* */
/* Calling Format: */
/* */
/* GET_REAL_AUTHORS (auth_ptr, byline_ptr, nambuf_ptr, nambuflen); */
/* */
/* Where: */
/* */
/* auth_ptr = Pointer to AUTH structure for main author */
/* byline_ptr = Pointer to AUTH structure for byline */
/* = NULL if no byline on author */
/* nambuf_ptr = Pointer to buffer for real names */
/* nambuflen = Length of buffer for real names */
/* */
/* This routine is used to build up a string of the real author */
/* names in a pair of AUTH structures. */
/* */
/************************************************************************/

This routine is used to build up a string of the real author names in a pair of AUTH structures and is called by SCAN_FILE primarily for use in XVALIDATE.

For each AUTH structure in turn, it scans each primary author to see if there is one or more secondary name associated with it. If so, the secondary name(s) are added to the array of names; otherwise, if it is a "real name" (i.e. not a house name, nor a joint pseudonym, nor "Anon.") we add the real name to the array of names.

We then scan through the global secondary names and add any authors there unless the associated type is "after" or "read by" as these are also contributing authors (in a way).

Once we have all the names, we sort them into alphabetical order and eliminate any duplicates. We also eliminate any cases where we have a set of initials that match one of the other authors in the list, or where we have an instance of "The Author of xxx" unless it is the only entry in the list.

We then call BUILD_AUTHSTR to concatenate the names and return them to the caller.


LOCUS_COMPACT: Routine to compact a LOCUS 'A' record prior to sorting

/************************************************************************/
/*									*/
/*    LOCUS_COMPACT - compact a Locus 'A' record for sorting		*/
/*									*/
/*    Calling Format:							*/
/*									*/
/*	status = LOCUS_COMPACT (outbuf_ptr, inpbuf_ptr);		*/
/*									*/
/*    Where:								*/
/*									*/
/*	status     = Status of Operation				*/
/*		   = PSP_TRUE is all OK					*/
/*		   = PSP_FALSE if a fatal error occurred		*/
/*	outbuf_ptr = Pointer to buffer to hold compacted record		*/
/*	inpbuf_ptr = Pointer to record to be compacted			*/
/*									*/
/*    Note that no error messages are output by this routine.		*/
/*									*/
/************************************************************************/

This routine compact a Locus 'A' record into a standard format that can be used as a sort key by any program that wants to create a consistent sort order (e.g. ASORT, MERGE, IDXGEN, etc.). The key generated is of the form:

   Author^x1fCategory^x1fTitle^x1fDate^x1fEdition~

where:

Note that any accent trigraphs are converted to the fallback character and the buffer is converted to upper case.


MATCH_AUTH: Routine to match authors in a namelist against an AUTH structure

/************************************************************************/
/*																		*/
/*    MATCH_AUTH - Match a namelist against an AUTH structure			*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*	rtnsts = MATCH_AUTH (auth_ptr, namelist, isub_ptr, type_ptr,		*/
/*				 coauth, pseud);										*/
/*																		*/
/*    Where:															*/
/*																		*/
/*	rtnsts   = Routine return status:									*/
/*		   = PSP_TRUE if an author matches; PSP_FALSE otherwise			*/
/*	auth_ptr = Pointer to author structure								*/
/*	namelist = Array of pointer to associated names						*/
/*	isub_ptr = Pointer to int to hold subscript of matched author		*/
/*	type_ptr = Pointer to int to hold type of match:					*/
/*			 = AUTHTYPE_AUTH for primary author							*/
/*			 = AUTHTYPE_EDIT for primary editor							*/
/*			 = AUTHTYPE_REFER if author is referred to					*/
/*			 = AUTHTYPE_TRANS if author is a translator					*/
/*			 = AUTHTYPE_UNKNOWN if some other match						*/
/*	coauth   = Buffer to hold co-author names							*/
/*	pseud    = Buffer to hold pseudonym name							*/
/*																		*/
/*    This routine compares all the authors in the namelist with all	*/
/*    authors in the AUTH structure to see if there is a match.  If so	*/
/*    then it returns the subscript of the name that matched and the	*/
/*    type of match.													*/
/*																		*/
/*    If the match was a primary match (author or editor) then any		*/
/*    co-authors/editors are returned as well (in Locus format).  In	*/
/*    addition, if the author has appeared under a pseudonym, then the	*/
/*    pseudonym is also returned.										*/
/*																		*/
/*    If the match was as a translator, then any co-translators are		*/
/*    returned as co-authors and the real authors of the item are		*/
/*    returned in the pseudonym field.									*/
/*																		*/
/*    If the match was as a referral, then no further information is	*/
/*    returned.															*/
/*																		*/
/*    Note that this routine will only return information on the FIRST	*/
/*    match found, and will search for each name in the namelist in		*/
/*    order.															*/
/*																		*/
/************************************************************************/

PRINT_AUTH: Routine to print out the contents of an AUTH structure

/************************************************************************/
/*																		*/
/*    PRINT_AUTH - Print out the contents of an AUTH structure			*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		PRINT_AUTH (auth_ptr, prtfil_ptr);								*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		auth_ptr   = Pointer to author structure						*/
/*	    prtfil_ptr = Pointer to diagnostics file (may be NULL)		    */
/*																		*/
/*    This is a diagnostic routine that simply dumps out the contents	*/
/*    of the AUTH structure.											*/
/*																		*/
/************************************************************************/

READ_AUTH_EXCEPT: Routine to set up a list of allowed author exceptions

/************************************************************************/
/*					                                    				*/
/*    READ_AUTH_EXCEPT - Read list of allowed author exceptions			*/
/*		                                    							*/
/*    Calling Format:                       							*/
/*									                                    */
/*	    READ_AUTH_EXCEPT (ambigfil_ptr, prtfil_ptr);              		*/
/*									                                    */
/*    This routine simply reads a list of names from ambig_ptr			*/
/*	  which are allowed to be Exception and stores them in a global		*/
/*	  array with an associated exception type.                 			*/
/*									                                    */
/************************************************************************/

RESET_AUTH: Routine to reset the contents of an AUTH structure

/************************************************************************/
/*																		*/
/*    RESET_AUTH - Reset an AUTH structure.								*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		RESET_AUTH (auth_ptr);											*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		auth_ptr  = Pointer to AUTH structure							*/
/*																		*/
/*    This is an internal routine that resets an AUTH structure so		*/
/*    that it can be reused.											*/
/*																		*/
/************************************************************************/

REVERT_AUTH: Routine to revert an author from internal to external format

/************************************************************************/
/*																		*/
/*    REVERT_AUTH - Revert an author from internal to external format	*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		rtnsts = REVERT_AUTH (inpbuf_ptr, outbuf_ptr, buflen, rvttyp);	*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		rtnsts     = Status of Operation								*/
/*				   = PSP_TRUE if OK										*/
/*				   = PSP_FALSE if no room for conversion				*/
/*		inpbuf_ptr = Pointer to input buffer							*/
/*		outbuf_ptr = Pointer to output buffer							*/
/*		buflen     = Length of output buffer							*/
/*		rvt_type   = Reversion type:									*/
/* = REVAUT_NORMAL: normal format */
/* = REVAUT_SURNAME: format w/o surname */
/* */
/* Authors are held internally in the format: */
/* */
/* Last Name{, First Name{, Oddments}}{ #Number} { ,[?]} */
/* */
/* this routine converts the name into the format: */
/* */
/* {First Name} Last Name{, Oddments}{?} */
/* */
/* although only the First Name is output for REVAUT_SURNAME */
/* */
/* Note that the result is APPENDED to the output buffer. */
/* */ /************************************************************************/

This does pretty much what it says on the tin, converting an internal name such as "Smith, Fred, Jr." to "Fred Smith, Jr.". A few notes of possible interest:


SORT_AUTH: Routine to sort the contents of an AUTH structure into alphabetical order

/************************************************************************/
/*									*/
/*    SORT_AUTH - Sort an AUTH structure into alphabetical order	*/
/*									*/
/*    Calling Format:							*/
/*									*/
/*	SORT_AUTH (auth_ptr);						*/
/*									*/
/*    Where:								*/
/*									*/
/*	auth_ptr   = Pointer to author structure			*/
/*									*/
/*    This routine simply sorts the entries in the author structure	*/
/*    into alphabetical order (for standardisation).			*/
/*									*/
/************************************************************************/

This pretty much does what it says on the tin. Points to note are:


SPLIT_AUTH: Routine to split an author string into an AUTH structure

/************************************************************************/
/*																		*/
/*    SPLIT_AUTH - Split author string into constituent parts		    */
/*																		*/
/*    Calling Format:							                        */
/*																		*/
/*	    status = SPLIT_AUTH (buff_ptr, auth_ptr, prtfil_ptr);		    */
/*																		*/
/*    Where:								                            */
/*																		*/
/*	    status     = PSP_FALSE if any problems parsing string		    */
/*		           = PSP_TRUE otherwise					                */
/*	    buff_ptr   = Pointer to input buffer				            */
/*	    auth_ptr   = Pointer to author structure			            */
/*	    prtfil_ptr = Pointer to diagnostics file (may be NULL)		    */
/*																		*/
/*    This routine will split a standard "Locus" author string into	    */
/*    its constituent parts in an AUTH structure.			            */
/*																		*/
/************************************************************************/

TRANSLATE_AUTH: Internal routine to convert a string of authors from external to internal format

/************************************************************************/
/* */
/* TRANSLATE_AUTH - Convert a string of authors from external to */
/* internal format. */
/* */
/* Calling Format: */
/* */
/* rtnsts = TRANSLATE_AUTH (inpbuf_ptr, outbuf_ptr, buflen); */
/* */
/* Where: */
/* */
/* rtnsts = Status of Operation */
/* = PSP_TRUE if OK */
/* = PSP_FALSE if no room for conversion */
/* inpbuf_ptr = Pointer to input buffer */
/* outbuf_ptr = Pointer to output buffer */
/* buflen = Length of output buffer */
/* */
/* This is an internal routine common to both CONVERT_AUTH and */
/* TIDY_BYLINE, which see for details of conversion. */
/* */
/************************************************************************/

This routine is primarily called by CONVERT_AUTH (q.v. for a description) but may also be called directly if we know the input string is in the correct format. Basically the routine tries to parse a string of authors names into the appropriate internal format. Some points worth noting:

Note that it would be nice to add somewhere (maybe in MAGPARSE) an automatic trap for an 06~ERR_STR so as to handle cases where the above consistently produces the wrong result (e.g. "Guy de Maupassant").


VAL_AUTH: Routine to validate a string of author names

/************************************************************************/
/*																		*/
/*    VAL_AUTH - Validate a buffer containing author name(s)			*/
/*																		*/
/*    Calling Format:													*/
/*																		*/
/*		status = VAL_AUTH (auth_type, recbuf_ptr, date_ptr,				*/
/*						   prtfil_ptr);									*/
/*																		*/
/*    Where:															*/
/*																		*/
/*		status     = PSP_TRUE if buffer matches the format string		*/
/*				   = PSP_FALSE otherwise								*/
/*		auth_type  = Type of author field to validate					*/
/*			1 = 'A' record authors allowing multiple names.				*/
/*			2 =  Artists												*/
/*			3 = 'AP' record authors (only a single name).				*/
/*			4 = 'AR' record authors (!ed. may precede first /)			*/
/*			5 = 'DN' record authors										*/
/*			6 = 'EA' record authors (may include ![ref.] and/or !ed)	*/
/*		   16 = Main authors in STORY.IDX								*/
/*		recbuf_ptr = Pointer to null-terminated buffer to validate		*/
/*		date_ptr   = Date of current entry ("" if not required)			*/
/*		valflag    = validation flags: bitmask of						*/
/*						VALAUT_LETTER  - Item is a letter				*/
/*						VALAUT_MAJOR   - Do major checks				*/
/*						VALAUT_MEDIUM  - Do medium checks				*/
/*						VALAUT_MINOR   - Do minor checks				*/
/*						VALAUT_ARTWORK - Item is artwork				*/
/*		prtfil_ptr = Pointer to diagnostics file (may be NULL)			*/
/*																		*/
/*    This routine checks the input buffer to see if it contains one	*/
/*    or more valid author names.										*/
/*																		*/
/************************************************************************/