campo-sirio/cb5/r4save_2.c
alex a0f5e0898b This commit was generated by cvs2svn to compensate for changes in r975,
which included commits to RCS files with non-trunk default branches.

git-svn-id: svn://10.65.10.50/trunk@976 c028cbd2-c16b-5b4b-a496-9718f37d4682
1995-02-06 15:33:45 +00:00

1099 lines
32 KiB
C
Executable File

/* r4save_2.c (c)Copyright Sequiter Software Inc., 1991-1994. All rights reserved. */
#include "d4all.h"
extern int file_version;
extern LIST4 name_list;
int save4long( FILE4SEQ_WRITE *seq, long *lval );
int save4short( FILE4SEQ_WRITE *seq, short *sval );
int ret4long( FILE4SEQ_READ *seq, long *lval );
int ret4short( FILE4SEQ_READ *seq, short *sval );
/************************************************************
*
* Function:
*
* PARAMETERS:
* DATA4* data - data file
* char* index_name - name of the index file to be checked for
* char* index_lookup - buffer used in the function
* char* current - buffer used in the function
*
* DESCRIPTION:this function performs the same operation as d4index(), but
* checks for an index file both with and without path names
*
* RETURNS: 1 - on finding a matching index file, 0 - on failure
*
* By: Raymond Cypher
*
* HISTORY:
*
*/
/* this function performs the same operation as d4index(), but checks for an
index file both with and without path names
*/
int S4FUNCTION r4index_lookup_foo( DATA4 *data, char *index_name,
char *index_lookup, char *current )
{
INDEX4 *index_on ;
int ttype;
if ( data == 0 || index_name == 0 )
#ifdef S4DEBUG
e4severe( e4parm, E4_D4INDEX ) ;
#else
return 0 ;
#endif
ttype = report4index_type();
u4name_piece( index_lookup, 257, index_name, 1, 0 ) ;
#ifndef S4UNIX
c4upper( index_lookup ) ;
#endif
if( r4cli == ttype || r4ndx == ttype )
{
if( d4tag( data, index_lookup ) )
return 1;
u4name_piece( index_lookup, 257, index_name, 0, 0 ) ;
if( d4tag( data, index_lookup ) )
return 1;
}
else
{
index_on = (INDEX4 *)l4first( &data->indexes );
while( index_on )
{
u4name_piece( current, 257, index_on->file.name, 1, 0 ) ;
#ifndef S4UNIX
c4upper( current ) ;
#endif
if ( !strcmp( current, index_lookup ) ) /* check out data->alias? */
return 1;
index_on = (INDEX4 *) l4next( &data->indexes, index_on) ;
}
u4name_piece( index_lookup, 257, index_name, 0, 0 ) ;
#ifndef S4UNIX
c4upper( index_lookup ) ;
#endif
index_on = (INDEX4 *)l4first( &data->indexes );
while( index_on )
{
u4name_piece( current, 257, index_on->file.name, 0, 0 ) ;
#ifndef S4UNIX
c4upper( current ) ;
#endif
if ( !strcmp( current, index_lookup ) ) /* check out data->alias? */
return 1;
index_on = (INDEX4 *) l4next( &data->indexes, index_on) ;
}
}
return( 0 );
}
/* wrapper for above function */
int S4FUNCTION r4index_lookup( DATA4 *data, char *index_name )
{
char *index_lookup, *current;
int retvalue;
index_lookup = (char *)u4alloc_free( data->code_base, 258 );
if( !index_lookup )
return 0;
current = (char*)u4alloc_free( data->code_base, 258 );
if( !current )
{
u4free( index_lookup );
return 0;
}
retvalue = r4index_lookup_foo( data, index_name, index_lookup, current );
u4free( index_lookup );
u4free( current );
return retvalue;
}
/************************************************************
*
* Function: r4open_data_foo()
*
* PARAMETERS:
* char* file_name - full name of the file, potentially including path
* char* alias - alias to set for the data file
* RELATE4* relate - the relate associated with the current report
* CODE4* code_base - CODE4 structure for the app
* char* fnbuf - a buffer used by the function
*
* DESCRIPTION: opens a data file, if the file is already open in the relate
* appropriate aliasing is performed to open the file a second time
*
* RETURNS: a DATA4 pointer on success, NULL on failure
*
* By: Raymond Cypher
*
* HISTORY:
*
*/
DATA4 *r4open_data_foo( char *file_name, char *alias, RELATE4 *relate, CODE4 *code_base, char *fnbuf )
{
DATA4 *old, *nnew;
RELATE4 *relate_on;
char abuf[11];
if( !file_name || !alias )
return NULL;
nnew = old = NULL;
/* if no alias or no relate do a simple d4open() */
if( alias[0] == '\0' || !relate )
{
nnew = d4open( code_base, file_name );
return nnew;
}
#ifndef S4UNIX
c4upper( file_name );
c4upper( alias );
#endif
/* check to see if the file is already open */
relate_on = relate;
while( relate_on )
{
strcpy( fnbuf, relate_on->data->file.name );
#ifndef S4UNIX
c4upper( fnbuf );
#endif
strcpy( abuf, d4alias( relate_on->data ) );
#ifndef S4UNIX
c4upper( abuf );
#endif
if( strcmp( fnbuf, file_name ) == 0 && strcmp(abuf, alias) == 0 )
old = relate_on->data;
relate4next( &relate_on );
}
/* if the file is not already open do a d4open() and set the alias */
if( old == NULL )
{
nnew = d4open( code_base, file_name );
if( nnew && alias[0] != '\0' )
d4alias_set( nnew, alias );
return nnew;
}
/* save the existing files alias, reset it to xxxxxxx open the new file,
set the new files alias, then restore the old files alias */
strcpy( abuf, d4alias(old) );
d4alias_set( old, "XXXXXXXXXX" );
nnew = d4open( code_base, file_name );
if( nnew )
d4alias_set( nnew, alias );
d4alias_set( old, abuf );
return nnew;
}
/* wrapper for above function */
DATA4 *r4open_data( char *file_name, char *alias, RELATE4 *relate, CODE4 *code_base )
{
DATA4 *retvalue;
char *fnbuf;
fnbuf = (char *)u4alloc_free( code_base, 256 );
if( !fnbuf )
return NULL;
retvalue = r4open_data_foo( file_name, alias, relate, code_base, fnbuf );
u4free( fnbuf );
return retvalue;
}
/* frees the list of N4CHANGE structures */
void report4free_name_list()
{
PN4CHANGE nchange;
while( (nchange = (PN4CHANGE)l4pop( &name_list )) != NULL )
{
if( nchange->old_name )
u4free( nchange->old_name );
if( nchange->new_name )
u4free( nchange->new_name );
u4free( nchange );
}
}
/* simple memcompare function that first capitalizes the buffers being compared */
int r4memicmp_foo( char *str1, char *str2, int len, char *buffer )
{
memset( buffer, 0, len + 1 );
memcpy( buffer, str1, len );
#ifndef S4UNIX
c4upper( buffer );
c4upper( str2 );
#endif
return memcmp( str1, str2, len );
}
/* wrapper for above function */
int r4memicmp( char *str1, char *str2, int len )
{
char *buffer;
int retvalue;
buffer = (char *)u4alloc( len+2 );
if( !buffer )
return 1;
retvalue = r4memicmp_foo( str1, str2, len, buffer );
u4free( buffer );
return retvalue;
}
/************************************************************
*
* Function: report4nchange()
*
* PARAMETERS:
* CODE4* c4 - apps code4 struct
* char** psrc - pointer to a pointer to the source string
* int can_alloc - flag specifying whether or not to allocate additional
* memory as needed
* int s_size - size of the source string
*
* DESCRIPTION: in CR when opening a report file, if a data or index file
* cannot be found the user is prompted to enter a new path and/or name.
* If the name of a data file has changed the name must also be changed in
* all the expressions within the report. To do this a list of N4CHANGE
* structures is maintained. N4CHANGE simply contains the old and new names
* for a data file. This function is passed an expression source and is
* responsible for swapping the names.
*
* RETURNS: none
*
* By: Raymond Cypher
*
* HISTORY:
*
*/
void report4nchange( CODE4 *c4, char **psrc, int can_alloc, int s_size )
{
char *orig = NULL, *src = *psrc;
PN4CHANGE nchange;
int pos, src_pos, orig_len;
int old_name_len, new_name_len;
unsigned src_size = s_size;
if( strlen(src) == 0 )
return;
/* for ever N4CHANGE struct in the name list */
nchange = (PN4CHANGE)l4first( &name_list );
while( nchange )
{
/* if no names continue */
if( !nchange->new_name || !nchange->old_name )
continue;
old_name_len = strlen(nchange->old_name);
/* create a buffer to duplicate the expression source */
orig = (char *)u4alloc_free( c4, strlen(src) + 1 );
if( !orig )
return;
/* copy the expression source */
src_pos = 0;
strcpy( orig, src );
orig_len = strlen(orig);
/* run through the copy of the expression source */
for( pos = 0; orig[pos]; pos++ )
{
/* we are copying the duplicated expression source back into the
original buffer, with appropriate insertions */
src[src_pos++] = orig[pos];
/* if the expression source buffer is too small due to changes
do a re-allocation */
if( src_pos == (int)src_size )
{
if( !can_alloc )
{
u4free( orig );
return;
}
u4alloc_again( c4, &src, &src_size, src_size+50 );
if( !src )
return;
}
/* if we're at the end of the expression source, continue */
if( (orig_len - pos) < old_name_len )
continue;
/* is this piece of the expression the current old name */
if( r4memicmp( orig+pos, nchange->old_name, old_name_len ) != 0 )
continue;
if( u4name_char( orig[pos+old_name_len] ) )
continue;
if( pos > 0 )
if( u4name_char( orig[pos-1]) )
continue;
/* insert the new name into the expression source, re-allocating space
if necessary */
new_name_len = strlen( nchange->new_name );
if( (int)src_size <= (pos+new_name_len) )
{
if( !can_alloc )
{
u4free( orig );
return;
}
u4alloc_again( c4, &src, &src_size, src_size + 50 );
if( !src )
{
u4free( orig );
return;
}
}
memcpy( src+(--src_pos), nchange->new_name, new_name_len );
src_pos += new_name_len;
pos += (old_name_len - 1);
} /* end of loop through copy of expression source */
/* end the string */
src[src_pos++] = '\0';
/* next change name */
nchange = (PN4CHANGE)l4next( &name_list, nchange );
/* free the source duplicate buffer */
if( orig )
{
u4free( orig );
orig = NULL;
}
}
if( orig )
{
u4free( orig );
orig = NULL;
}
/* set the pointer to the new source buffer */
*psrc = src;
}
/************************************************************
*
* Function: relate4retrieve_relate_foo()
*
* PARAMETERS:
* FILE4SEQ_READ* seq - sequential read struture for the file i/o
* int open_files - should the data files for the relate be opened
* char* spath - path to look for the data files
* the rest of the parameters are simply character buffers used in the fctn
*
* DESCRIPTION: retrieves a relation from a file. Note: this file and the
* r4save.c source file are compiled directly into the CR executable, as well
* as into the CodeBase DLL. As a result certain sections of this code
* are specific the the executable and call functions in the executable
*
* RETURNS: a RELATE4 pointer on success, NULL on failure
*
* By: Raymond Cypher
*
* HISTORY:
*
*/
RELATE4 * S4FUNCTION relate4retrieve_relate_foo( FILE4SEQ_READ *seq, int open_files, char *spath,
char *dname_buf, char *iname_buf, char *tname_buf,
char *str_buf, char *master_expr_buf,
char *slave_expr_buf, char *tempname_buf )
{
RELATE4 *relate = NULL, *master = NULL;
DATA4 *data;
TAG4 *tag;
INDEX4 *index;
LIST4 indexes;
CODE4 *c4;
INAME4 *iname, *nname;
EXPR4 *expr;
char alias_buf[11], *cptr;
short match_len, relation_type, sort_type, error_action, n_links, code;
int i, err_code, err_flag, repeat_flag, error_code = 0, iindex, tname_err;
long lExt;
#ifdef S4CR2
PN4CHANGE nchange;
int rc;
#endif
/* reset the changed name list */
memset( &name_list, 0, sizeof(name_list) );
c4 = seq->file->code_base;
/* reset the index name list */
memset( &indexes, 0, sizeof(indexes) );
err_code = err_flag = 0;
while( 1 )
{
/* get the data file name */
if( retrieve4string( seq, dname_buf, 256 ) < 0 )
{
/* the error codes are used to allow the continued retrieval of
the relation tree, even if a part of it is not retrievable due
to a missing data or index file */
error_code = 1;
goto CLEANUP;
}
/* get the files alias */
memset( alias_buf, 0, sizeof(alias_buf) );
if( file_version >= 0x24 )
{
if( retrieve4string( seq, alias_buf, sizeof(alias_buf) ) < 0 )
{
error_code = 1;
goto CLEANUP;
}
}
/* retrieve the internal flags of the RELATE4 */
ret4short( seq, &match_len );
ret4short( seq, &relation_type );
ret4short( seq, &sort_type );
ret4short( seq, &error_action );
/* retrieve the names of the index files and place them in the index list
*/
ret4short( seq, &n_links );
for( i = 0; i < n_links; i++ )
{
iname = (INAME4 *)u4alloc_free( c4, sizeof(INAME4) );
if( retrieve4string( seq, iname_buf, 256 ) < 0 )
{
error_code = 1;
goto CLEANUP;
}
iname->index_name = (char *)u4alloc_free( c4, strlen(iname_buf) + 1 );
iname->name_length = strlen(iname_buf) + 1;
#ifdef S4WINDOWS
lstrcpy( iname->index_name, iname_buf );
#else
strcpy( iname->index_name, iname_buf );
#endif
l4add( &indexes, iname );
}
/* get the tag name */
if( retrieve4string( seq, tname_buf, 256 ) < 0 )
{
error_code = 1;
goto CLEANUP;
}
/* retrieve the source for the master expression */
if( retrieve4string( seq, master_expr_buf, 1024 ) < 0 )
{
error_code = 1;
goto CLEANUP;
}
/* check for changed names */
cptr = master_expr_buf;
report4nchange( c4, &cptr, 0, 1024 );
/* the code indicates where the new relate should fall in the tree with
respect to the last relate. The code used is the same as the return
values from relate4next() */
ret4short( seq, &code );
if( !err_flag && !err_code )
{
repeat_flag = 1;
while( repeat_flag )
{
repeat_flag = 0;
/* see if data file is already open */
data = 0;
u4name_piece( str_buf, 256, dname_buf, 0, 0 );
data = d4data( c4, alias_buf );
/* if not already open try to open */
if( !data )
{
/* if not allowed to open, error */
if( !open_files )
{
e4describe( c4, e4result, E4_RESULT_LCF, dname_buf, (char *)0 );
err_flag = 1;
}
/* check for an alternate path */
if( spath && spath[0] != '\0' )
{
u4name_piece( str_buf, 256, dname_buf, 0, 1 );
strcpy( tempname_buf, spath );
strcat( tempname_buf, "\\" );
strcat( tempname_buf, str_buf );
/* open the data file */
data = r4open_data( tempname_buf, alias_buf, master, c4 );
}
else
{
/* open the data file */
data = r4open_data( dname_buf, alias_buf, master, c4 );
}
/* if the open failed */
if( !data )
{
/* if this is for the CR executable interactively get an
alternate file name */
#ifdef S4CR2
nchange = (PN4CHANGE)u4alloc_free( c4, sizeof(N4CHANGE) );
if( nchange )
{
u4name_piece( str_buf, 256, dname_buf, 0, 0 );
nchange->old_name = (char *)u4alloc_free( c4, strlen(str_buf)+1 );
if( nchange->old_name )
{
strcpy( nchange->old_name, str_buf );
rc = AlternateDataFile( dname_buf, 256 );
if( rc == 0 )
{
u4name_piece( str_buf, 256, dname_buf, 0, 0 );
nchange->new_name = (char *)u4alloc_free(c4,strlen(str_buf)+1 );
if( nchange->new_name )
{
strcpy( nchange->new_name, str_buf );
l4add( &name_list, nchange );
repeat_flag = 1;
}
else
{
u4free( nchange->old_name );
u4free( nchange );
err_flag = 1;
}
}
else
err_flag = 1;
}
else
{
u4free( nchange );
err_flag = 1;
}
}
else
err_flag = 1;
#else
/* if not in the executable report an error */
if( spath && spath[0] != '\0' )
e4describe( c4, e4report, E4_REP_DFILE, tempname_buf, (char *)0 );
else
e4describe( c4, e4report, E4_REP_DFILE, dname_buf, (char *)0 );
err_flag = 1;
#endif
}
e4set( c4, 0 );
}
}
}
if( !err_flag && !err_code )
{
/* loop through index file names */
iname = (INAME4 *)l4first( &indexes );
while( iname )
{
repeat_flag = 1;
while( repeat_flag )
{
repeat_flag = 0;
index = NULL;
iindex = 0;
u4name_piece( str_buf, 256, iname->index_name, 0, 0 );
tname_err = c4->tag_name_error;
c4->tag_name_error = 0;
/* check to see if the index is already open */
iindex = r4index_lookup( data, str_buf );
c4->tag_name_error = tname_err;
e4set( c4, 0 );
/* if not already open */
if( !iindex )
{
/* if not allowed to open files report an error */
if( !open_files )
{
e4describe( c4, e4result, E4_RESULT_LCF, iname_buf, (char *)0 );
err_flag = 1;
}
/* by default this compile switch is defined in r4report.h
it forces the index file name to have the default extension
for the compile flag, regardless of the extension saved in
the report. IF the user is using a different extension
he should undefine this switch */
#ifdef S4DEFAULT_INDEX
lExt = u4switch();
if( lExt & 1 )
u4name_ext( iname->index_name, strlen(iname->index_name)+1, "cdx", 1 );
else
if( lExt & 2 )
u4name_ext( iname->index_name, strlen(iname->index_name)+1, "ntx", 1 );
else
if( lExt & 4 )
u4name_ext( iname->index_name, strlen(iname->index_name)+1, "mdx", 1 );
else
if( lExt & 8 )
u4name_ext( iname->index_name, strlen(iname->index_name)+1, "ndx", 1 );
#endif
/* attempt to open the index file */
if( spath && spath[0] != '\0' )
{
u4name_piece( str_buf, 256, iname->index_name, 0, 1 );
strcpy( tempname_buf, spath );
strcat( tempname_buf, "\\" );
strcat( tempname_buf, str_buf );
index = i4open( data, tempname_buf );
}
else
index = i4open( data, iname->index_name );
/* if open fails */
if( !index )
{
/* if in CR executable prompt for alternate */
#ifdef S4CR2
lstrcpy( str_buf, iname->index_name );
rc = AlternateIndexFile( str_buf, 256 );
if( rc == 0 )
{
repeat_flag = 1;
u4free( iname->index_name );
iname->index_name = NULL;
iname->index_name = (char *)u4alloc( lstrlen(str_buf)+1 );
if( iname->index_name )
lstrcpy( iname->index_name, str_buf );
}
else
err_flag = 1;
#else
/* report an error */
if( spath && spath[0] != '\0' )
e4describe( c4, e4report, E4_REP_IFILE, tempname_buf, (char *)0 );
else
e4describe( c4, e4report, E4_REP_IFILE, iname_buf, (char *)0 );
err_flag = 1;
#endif
}
e4set( c4, 0 );
}
}
iname = (INAME4 *)l4next( &indexes, iname );
}
}
if( !err_flag && !err_code )
{
tag = NULL;
/* if this is the first relate do a relate4init() */
if( !relate )
{
master = relate = relate4init( data );
if( !relate )
goto CLEANUP;
/* set the internal flags */
relate->match_len = match_len;
relate->sort_type = sort_type;
relate->relation_type = relation_type;
relate->error_action = error_action;
/* if a tag was specified set it */
if( strlen(tname_buf) )
{
repeat_flag = 1;
while( repeat_flag )
{
repeat_flag = 0;
tag = NULL;
tag = d4tag( data, tname_buf );
if( tag )
{
relate->data_tag = tag;
d4tag_select( data, tag );
}
#ifdef S4CR2
else
{
/* if the specified tag is not available and this is the
.exe prompt for an alternate */
e4set( c4, 0 );
rc = AlternateTagName( tname_buf, 256 );
if( rc == 0 )
repeat_flag = 1;
}
#else
else
e4set( c4, 0 );
#endif
}
}
}
else
{
/* if not the first relate do a create slave */
/* start by getting a tag pointer from the tag name */
if( strlen(tname_buf) )
{
repeat_flag = 1;
while( repeat_flag )
{
repeat_flag = 0;
tag = NULL;
tag = d4tag( data, tname_buf );
if( !tag )
#ifdef S4CR2
{
e4set( c4, 0 );
rc = AlternateTagName( tname_buf, 256 );
if( rc == 0 )
repeat_flag = 1;
else
{
goto CLEANUP;
}
}
#else
{
e4describe( c4, e4report, E4_REP_NOTAG, (char *)tname_buf, 0 );
e4set( c4, 0 );
goto CLEANUP;
}
#endif
}
}
/* try to create the slave */
repeat_flag = 1;
while( repeat_flag )
{
repeat_flag = 0;
expr = expr4parse( master->data, master_expr_buf );
if( expr )
{
expr4free( expr );
relate = relate4create_slave( master, data, master_expr_buf, tag );
}
#ifdef S4CR2
else
{
/* if create slave fales prompt for a different master expr */
e4set( c4, 0 );
rc = AlternateMasterExpression( master_expr_buf, master, 1024 );
if( rc == 0 )
repeat_flag = 1;
else
relate = NULL;
}
#else
else
{
/* report an error */
e4describe( c4, e4report, E4_REP_NOMEXPR, 0, 0 );
e4set( c4, 0 );
relate = NULL;
}
#endif
}
if( !relate )
goto CLEANUP;
relate->match_len = match_len;
relate->sort_type = sort_type;
relate->relation_type = relation_type;
relate->error_action = error_action;
}
}
/* free the index name list */
iname = (INAME4 *)l4first( &indexes );
while( iname )
{
nname = (INAME4 *)l4next( &indexes, iname );
l4remove( &indexes, iname );
u4free( iname->index_name );
u4free( iname );
iname = nname;
}
/* if end of relates leave the loop */
if( code == 2 )
break;
if( err_flag == 0 && err_code > 0 )
{
err_code += code;
if( err_code <= 0 )
{
err_code = 0;
code = 1;
}
}
if( err_flag == 1 )
{
err_flag = 0;
err_code = 1;
}
if( err_code <= 0 )
{
master = relate;
while( code++ <= 0 )
master = master->master;
}
}
/* deal with the sort and query expressions */
memset( master_expr_buf, 0, 1024 );
memset( slave_expr_buf, 0, 1024 );
retrieve4string( seq, master_expr_buf, 1024 );
cptr = master_expr_buf;
report4nchange( c4, &cptr, 0, 1024 );
retrieve4string( seq, slave_expr_buf, 1024 );
cptr = slave_expr_buf;
report4nchange( c4, &cptr, 0, 1024 );
if( master )
{
repeat_flag = 1;
if( strlen( slave_expr_buf) > 0 )
while( repeat_flag )
{
repeat_flag = 0;
expr = expr4parse( master->data, slave_expr_buf );
if( expr )
{
expr4free( expr );
relate4sort_set( master, slave_expr_buf );
}
#ifdef S4CR2
else
{
e4set( c4, 0 );
rc = AlternateSortExpression( slave_expr_buf, master, 1024 );
if( rc == 0 )
repeat_flag = 1;
}
#else
else
{
e4describe( c4, e4report, E4_REP_NOSORT, 0, 0 );
e4set( c4, 0 );
}
#endif
}
repeat_flag = 1;
if( strlen( master_expr_buf ) > 0 )
while( repeat_flag )
{
repeat_flag = 0;
expr = expr4parse( master->data, master_expr_buf );
if( expr )
{
expr4free( expr );
relate4query_set( master, master_expr_buf );
}
#ifdef S4CR2
else
{
e4set( c4, 0 );
rc = AlternateQueryExpression( master_expr_buf, master, 1024 );
if( rc == 0 )
repeat_flag = 1;
}
#else
else
{
e4describe( c4, e4report, E4_REP_NOQUERY, 0, 0 );
e4set( c4, 0 );
}
#endif
}
}
if( relate )
return( &relate->relation->relate );
else
return NULL;
CLEANUP:
iname = (INAME4 *)l4first( &indexes );
while( iname )
{
nname = (INAME4 *)l4next( &indexes, iname );
l4remove( &indexes, iname );
u4free( iname->index_name );
u4free( iname );
iname = nname;
}
if( master )
{
relate4free( master, open_files );
}
else
{
if( relate )
relate4free( relate, open_files );
}
if( error_code )
{
e4describe( c4, e4report, E4_REP_RELERR, 0, 0 );
}
return NULL;
}
/* wrapper for above function */
RELATE4 * S4FUNCTION relate4retrieve_relate( FILE4SEQ_READ *seq, int open_files, char *spath )
{
char *dname_buf = NULL, *iname_buf = NULL, *tname_buf = NULL, *str_buf = NULL;
char *master_expr_buf = NULL, *slave_expr_buf = NULL, *tempname_buf = NULL;
RELATE4 *retvalue = NULL;
dname_buf = (char *)u4alloc_free( seq->file->code_base, 256 );
iname_buf = (char *)u4alloc_free( seq->file->code_base, 256 );
tname_buf = (char *)u4alloc_free( seq->file->code_base, 256 );
str_buf = (char *)u4alloc_free( seq->file->code_base, 256 );
master_expr_buf = (char *)u4alloc_free( seq->file->code_base, 1024 );
slave_expr_buf = (char *)u4alloc_free( seq->file->code_base, 1024 );
tempname_buf = (char *)u4alloc_free( seq->file->code_base, 512 );
if( !dname_buf || !iname_buf || !tname_buf || !str_buf ||
!master_expr_buf || !slave_expr_buf || !tempname_buf )
goto R4LEAVE;
retvalue = relate4retrieve_relate_foo( seq, open_files, spath,
dname_buf, iname_buf, tname_buf, str_buf, master_expr_buf,
slave_expr_buf, tempname_buf );
R4LEAVE:
if( dname_buf )
u4free( dname_buf );
if( iname_buf )
u4free( iname_buf );
if( tname_buf )
u4free( tname_buf );
if( str_buf )
u4free( str_buf );
if( master_expr_buf )
u4free( master_expr_buf );
if( slave_expr_buf )
u4free( slave_expr_buf );
if( tempname_buf )
u4free( tempname_buf );
return retvalue;
}
/* see the CodeReporter manual */
int S4FUNCTION obj4dataFieldSet( POBJ4 obj, char *fname, char ftype, int flength, int fdec )
{
POUT4OBJ oobj;
PREPORT4 report;
if( !obj )
return -1;
report = obj->area->report;
obj->field_type = ftype;
obj->field_len = flength;
obj->field_dec = fdec;
if( fname )
u4ncpy( obj->field_name, fname, sizeof(obj->field_name) );
else
oobj = (POUT4OBJ)l4first( &report->output_objs );
while( oobj )
{
if( oobj->obj == obj )
{
if( fname == NULL || ftype == 0 || flength == 0 )
l4remove( &report->output_objs, oobj );
return 0;
}
oobj = (POUT4OBJ)l4next( &report->output_objs, oobj );
}
oobj = (POUT4OBJ)u4alloc_free( obj->area->report->code_base, sizeof(OUT4OBJ) );
if( !oobj )
return -1;
oobj->obj = obj;
l4add( &report->output_objs, oobj );
return 0;
}
/* see the CodeReporter manual */
int S4FUNCTION report4dataFileSet( PREPORT4 report, char *fname )
{
if( !report )
return -1;
if( report->dfile_name )
u4free( report->dfile_name );
report->dfile_name = NULL;
if( fname == NULL )
return 0;
report->dfile_name = (char *)u4alloc_er( report->code_base, strlen(fname)+1 );
if( !report->dfile_name )
return -1;
u4ncpy( report->dfile_name, fname, strlen(fname)+1 );
return 0;
}
/* see the CodeReporter manual */
int S4FUNCTION report4dataGroup( PREPORT4 report, PGROUP4 group )
{
if( !report )
return -1;
report->output_group = group;
return 0;
}