예제 #1
0
char *
STrindex_DB(
	const char	*str,
	const char	*mstr,
	register size_t	len)
{
	char	*where = NULL;

	if (len <= 0)
		len = MAXI2;

	while (len > 0 && *str != '\0')
	{
		if (CMcmpcase(str, mstr) == 0)
			where = (char *)str;

		CMbytedec(len, str);
		CMnext(str);
	}

	if (where != NULL && *where != '\0')
		return (where);
	else
		return (NULL);
}
예제 #2
0
/*{
** Name:	open_outfile	- creates or appends to an output file
**
** Description:
**	Creates or opens (for append) a file in a directory and sets a
**	LOCATION structure.
**
** Inputs:
**	out_filename	- output file name
**	out_dir		- output directory
**	create_or_append - create a new file or append to existing file
**	uniq		- make a unique filename
**
** Outputs:
**	loc_name	- output file path
**
** Returns:
**	NULL	- open failed
**	FILE *	- file pointer
*/
FILE *
open_outfile(
char	*out_filename,
char	*out_dir,
char	*create_or_append,
char	*loc_name,
bool	uniq)
{
	FILE	*out_file;
	char	*p;
	char	filename[MAX_LOC+1];
	LOCATION	loc;

	if (loc_name == NULL)
		return (NULL);

	if (CMcmpcase(create_or_append, ERx("c")) == 0)
	{
		STcopy(out_dir, filename);
		LOfroms(PATH, filename, &loc);

		/* if uniq is 1, create a unique filename */
		if (uniq == 1)
			LOuniq(out_filename, ERx(""), &loc);
		else
			LOfstfile(out_filename, &loc);

		if (SIfopen(&loc, ERx("w"), SI_TXT, SI_MAX_TXT_REC, &out_file)
			!= OK)
		{
			IIUGerr(E_RM00F2_Err_open_outfile, UG_ERR_ERROR, 1,
				out_filename);
			return (NULL);
		}
		LOtos(&loc, &p);
		STcopy(p, loc_name);
	}
	else
	{
		LOfroms(PATH & FILENAME, loc_name, &loc);
		if (SIfopen(&loc, ERx("a"), SI_TXT, SI_MAX_TXT_REC, &out_file)
			!= OK)
		{
			IIUGerr(E_RM00F2_Err_open_outfile, UG_ERR_ERROR, 1,
				out_filename);
			return (NULL);
		}
	}
	return (out_file);
}
예제 #3
0
char *
STindex_DB(
	const char	*str,
	const char	*mstr,
	size_t	len)
{
	if (str == NULL || mstr == NULL)
		return (NULL);

	if (len <= 0)
		len = 32767;

	while (len > 0 && *str != '\0')
	{
		if (CMcmpcase(str, mstr) == 0)
			return ((char *)str);

		CMbytedec(len, str);
		CMnext(str);
	}

	return (NULL);
}
예제 #4
0
/*
 * regatom - the lowest level
 *
 * Optimization:  gobbles an entire sequence of ordinary characters so that
 * it can turn them into a single node, which is smaller to store and
 * faster to run.  Backslashed characters are exceptions, each becoming a
 * separate node; the code is simpler that way and it's not worth fixing.
 */
static char *
regatom(i4 *flagp)
{
    register char *ret;
    i4 flags;
    char null_byte = '\0';

    *flagp = WORST;		/* Tentatively. */

    switch (*regparse) {
    case '^':
        CMnext( regparse );
        ret = regnode(BOL);
        break;
    case '$':
        CMnext( regparse );
        ret = regnode(EOL);
        break;
    case '.':
        CMnext( regparse );
        ret = regnode(ANY);
        *flagp |= HASWIDTH|SIMPLE;
        break;
    case '[': {
        char *range_start = NULL;
        bool double_start;
        u_i2 first_u2, last_u2;
        u_char first_u1, last_u1;

        CMnext( regparse );
        if (*regparse == '^') {	/* Complement of range. */
            ret = regnode(ANYBUT);
            CMnext( regparse );
        } else
            ret = regnode(ANYOF);
        if (*regparse == ']' || *regparse == '-') {
            regc( regparse );
            CMnext( regparse );
        }
        while (*regparse != '\0' && *regparse != ']') {
            if (*regparse == '-') {
                char range_op = '-';

                CMnext( regparse );
                if( *regparse == ']' ||
                        *regparse == '\0'
                  )
                    regc( &range_op );
                else {
                    char *tmp;
                    bool invalid = FALSE;
                    bool double_end;

                    if( range_start == NULL )
                        invalid = TRUE;

                    double_end =
                        CMdbl1st( regparse );

                    if( !invalid &&
                            double_end
                            && !double_start
                      )
                        invalid = TRUE;

                    if( !invalid &&
                            double_start
                            && !double_start
                      )
                        invalid = TRUE;

                    if( !invalid &&
                            CMcmpcase( range_start,
                                       regparse ) > 0
                      )
                        invalid = TRUE;

                    if( double_start )
                        _FAIL("don't know how to support character classes containing double-byte ranges");

                    if( invalid )
                        _FAIL("invalid [] range");
                    /* no double-byte ranges! */
                    /*
                    ** Initialize the value for the end of the range.
                    */
                    last_u1 = UCHARAT(regparse);
                    for (; first_u1 <= last_u1;
                            first_u1++
                        )
                        regc( (char *)
                              &first_u1 );

                    CMnext( regparse );
                }
            } else {
                range_start = regparse;
                if( CMdbl1st( range_start ) )
                {
                    double_start = TRUE;
                    first_u2 = *(u_i2 *) range_start;
                }
                else
                {
                    double_start = FALSE;
                    first_u1 = UCHARAT(range_start);
                }
                regc( regparse );
                CMnext( regparse );
            }
        }
        regc( &null_byte );
        if (*regparse != ']')
            _FAIL("unmatched []");
        CMnext( regparse );
        *flagp |= HASWIDTH|SIMPLE;
    }
    break;
    case '(':
        CMnext( regparse );
        ret = reg(1, &flags);
        if (ret == NULL)
            return(NULL);
        *flagp |= flags&(HASWIDTH|SPSTART);
        break;
    case '\0':
    case '|':
    case ')':
        CMnext( regparse );
        _FAIL("internal urp");	/* Supposed to be caught earlier. */
        break;
    case '?':
    case '+':
    case '*':
        CMnext( regparse );
        _FAIL("?+* follows nothing");
        break;
    case '\\':
        CMnext( regparse );
        if (*regparse == '\0')
            _FAIL("trailing \\");
        ret = regnode(EXACTLY);
        regc( regparse );
        CMnext( regparse );
        regc( &null_byte );
        *flagp |= HASWIDTH|SIMPLE;
        break;
    default: {
        register i4  len;
        register char ender;

        len = my_strcspn(regparse, META);
        if (len <= 0)
            _FAIL("internal disaster");
        ender = *(regparse+len);
        if (len > 1 && ISMULT(ender))
            len--;	/* Back off clear of ?+* operand. */
        *flagp |= HASWIDTH;
        if (len == 1)
            *flagp |= SIMPLE;
        ret = regnode(EXACTLY);
        while (len > 0) {
            regc( regparse );
            CMbytedec( len, regparse );
            CMnext( regparse );
        }
        regc( &null_byte );
    }
    break;
    }

    return(ret);
}
예제 #5
0
static bool
pp_eval_boolexp( char **strptr, char *goal )
{
	bool boolval[2];
	i4  notval[2];
	i4  oper = OPER_NONE;
	i4  curval = 0;
	i4  maxval;
	i4  goalfound = FALSE;
	char *parser = *strptr;
	bool rtn;

	notval[0] = notval[1] = 0;
	maxval = (sizeof(boolval) / sizeof(boolval[0])) - 1;
	while (goalfound == FALSE)
	{

		/* Are we through yet? */
		if( CMcmpcase( parser, goal ) == 0 )
		{
			goalfound = TRUE;
			CMnext(parser);
		}

		/* If the string is empty then bail out */
		else if( STlength( parser ) == 0)
			break;

		/* Have we exhausted our parsing capabilities? */
		else if (curval > maxval)
			break;

		/* If this is white space then just skip over it */
		else if( CMwhite( parser ))
			CMnext( parser );

		/* Is this an end to a parenthetical expression? */
		/* its not our goal, but it could be someones */
		else if( CMcmpcase( parser, ERx(")") ) == 0 &&
			*goal != EOS)
		{
			goalfound = TRUE;
			break;
		}

		/* Is this a NOT (!) to reverse the value of next boolean? */
		else if( CMcmpcase( parser, ERx("!") ) == 0 )
		{
			/* Use the xor operator to toggle, allows for !(!val) */
			notval[curval] ^= 1;
			CMnext(parser);
		}

		/* Is this a parenthetical expression? */
		else if( CMcmpcase( parser,ERx("(") ) == 0)
		{
			CMnext(parser);
			boolval[curval++] = pp_eval_boolexp(&parser, ERx(")"));
		}

		/* Is this an AND (&&) operator? */
 		else if( STbcompare( parser, 2, ERx("&&"), 2, 0 ) == 0) 
		{
			if (oper != OPER_NONE)
			{
				SIfprintf( stderr, E_YAPP001 );
				SIfprintf( stderr, E_YAPP00F );
				yydump();
			}
			oper = OPER_AND;

			CMnext(parser);
			CMnext(parser);

			boolval[curval++] = pp_eval_boolexp(&parser, ERx("\n"));
		}

		/* Is this an OR (||) operator? */
 		else if( STbcompare( parser, 2, ERx("||"), 2, 0 ) == 0) 
		{
			if (oper != OPER_NONE)
			{
				SIfprintf( stderr, E_YAPP001 );
				SIfprintf( stderr, E_YAPP011 );
				yydump();
			}
			oper = OPER_OR;

			CMnext(parser);
			CMnext(parser);

			boolval[curval++] = pp_eval_boolexp(&parser, ERx("\n"));
		}

		/* Is this the defined() preprocessor macro? */
 		else if( STbcompare( parser, 7, ERx("defined"), 7, 0 ) == 0 ) 
		{
			char defsym[MAX_SYMLEN + 1];
			char *defptr;

			/* Initialize the symbol name */
			STcopy(ERx(""), defsym);

			/* Try and find the beginning '(' */
			while (STlength(parser) > 0 &&
				CMcmpcase(parser, ERx("(") ) != 0)
				CMnext(parser);

			/* Skip over the open parenthesis, ( */
			if (STlength(parser) != 0)
				CMnext(parser);

			/* Skip over any whitespace following '(' */
			while (STlength(parser) > 0 && CMwhite(parser))
				CMnext(parser);

			/* Save the name of the symbol to look up */
			defptr = defsym;
			while (STlength(parser) > 0 &&
				CMcmpcase(parser, ERx(")") ) != 0 &&
				!CMwhite(parser))
			{
				CMcpychar(parser, defptr);
				CMnext(parser);
				CMnext(defptr);
			}
			*defptr = EOS;

			/* Try and find the ending ')' */
			while (STlength(parser) > 0 &&
				CMcmpcase(parser, ERx(")") ) != 0)
				CMnext(parser);

			/* Skip over the closed parenthesis, ) */
			if (STlength(parser) != 0)
				CMnext(parser);

			/* Make sure there was something in the parenthesis */
			if (STlength(defsym) == 0)
			{
				SIfprintf( stderr, E_YAPP001 );
				SIfprintf( stderr, E_YAPP013 );
				yydump();
			}
			boolval[curval++] = (is_defined(defsym, NULL) == OK);
		}

		/* Thats all we know how to parse, gotta bail out */
		else
		{
			SIfprintf( stderr, E_YAPP001 );
			SIfprintf( stderr, E_YAPP014 );
			yydump();
		}
	}

	/* Did we ultimately fail to evaluate the expression? */
	if (*goal == EOS && goalfound == FALSE)
	{
		SIfprintf( stderr, E_YAPP001 );
		SIfprintf( stderr, E_YAPP015 );
		yydump();
	}

	/* Now make sure something was specified in the current expression */
	if (curval == 0)
	{
		SIfprintf( stderr, E_YAPP001 );
		SIfprintf( stderr, E_YAPP016 );
		yydump();

	}

	/* If an operator is found make sure it had an object to operate on */
	if (oper != OPER_NONE && curval <= maxval)	
	{
		SIfprintf( stderr, E_YAPP001 );
		SIfprintf( stderr, E_YAPP017 );
		yydump();
	}

	/* Save the current location in parse string */
	*strptr = parser;

	/* Resolve the highest precedence NOT operators */
	if (curval > 0 && notval[0] == 1)
		boolval[0] = !boolval[0];
	if (curval > 1 && notval[1] == 1)
		boolval[1] = !boolval[1];

	/* Resolve the final expression */
	switch (oper)
	{
		case OPER_OR:
			rtn = boolval[0] || boolval[1];
			break;

		case OPER_AND:
			rtn = boolval[0] && boolval[1];
			break;

		default: 
			rtn = boolval[0]; 
			break;
	}
	return rtn;
}
예제 #6
0
static u_i4 
pp_directive( FILE *input, STACK_FRAME *stack , bool ifdef )
{
	i4 n, len;
	char *words[ MAX_LINE / 2 ], *temp, *p;
	char *parse_val, *parse_end;
	STACK_FRAME stack_frame;
	bool def_dir;
	u_i4 rtn = NONE;

	stack_frame.prev = stack;
	stack_frame.display_mode = TRUE;

	p = temp = STalloc( infile->yytext );
	CMnext( p );
	n = sizeof( words );
	STgetwords( p, &n, words ); 

	/* process the directive, watch out for the empty directive */
	if (n == 0)
	{
		;       /* empty directive */
	}
	else if( STequal( words[ 0 ], ERx( "define" ) ) != 0 )
	{
		/* If a symbol was specified look for the value to give it */
		if (n > 1) 
		{
			/* Scan for the 'define' keyword */
			parse_val = infile->yytext;
			CMnext(parse_val);         /* Skip over the '#' */
			while (CMwhite(parse_val))
				CMnext(parse_val);

			/* Scan past the 'define' keyword */
			while (!CMwhite(parse_val))
				CMnext(parse_val);

			/* Scan over white space separating 'define' */
			/* keyword and the specified symbol name */
			while (CMwhite(parse_val))
				CMnext(parse_val);

			/* Skip over the symbol name */
			while (!CMwhite(parse_val))
				CMnext(parse_val);

			/* Skip over white space after the symbol name */
			while (CMwhite(parse_val))
				CMnext(parse_val);

			/* At this point we have scanned to the beginning */
			/* of the defined value for the symbol, Trim off */
			/* any trailing white space */
			STtrmwhite(parse_val);

			/* Define value found, could be the empty string, "" */
			if( active( &stack_frame ) )
			{
				define( words[ 1 ], parse_val, FALSE );
			}
		}
		rtn = DEFINE;
	}

	else if( active( &stack_frame ) &&
		STequal( words[ 0 ], ERx( "undef" ) ) != 0 )
	{
		if (n > 1)
		{
			undefine( words[ 1 ] );
		}
		rtn = UNDEF;
	}

	else if( STequal( words[ 0 ], ERx( "if" ) ) != 0 )
	{
		/* If an expression was specified look for its evaluation */
		if (n > 1) 
		{
			/* Scan for the 'if' keyword */
			parse_val = infile->yytext;
			CMnext(parse_val);         /* Skip over the '#' */
			while (CMwhite(parse_val))
				CMnext(parse_val);

			/* Scan past the 'if' keyword */
			while (!CMwhite(parse_val))
				CMnext(parse_val);

			/* Scan over white space separating 'if' */
			/* keyword and the expression */
			while (CMwhite(parse_val))
				CMnext(parse_val);

			/* At this point we have scanned to the beginning */
			/* of the expression.*/
			if( active( &stack_frame ) )
			{
				/* Evaluate boolean expression found */
				stack_frame.display_mode = 
					pp_eval_boolexp( &parse_val, ERx("") );
			}
			(void) pp_input( input, &stack_frame, TRUE );
		}
		rtn = IF;
	}

	else if( STequal( words[ 0 ], ERx( "ifdef" ) ) != 0 )
	{
		if( active(&stack_frame) && is_defined(words[1], NULL) == OK)
		{
			stack_frame.display_mode = TRUE;
		}
		else
			stack_frame.display_mode = FALSE;
		(void) pp_input( input, &stack_frame, TRUE );
		rtn = IFDEF;
	}

	else if( STequal( words[ 0 ], ERx( "ifndef" ) ) != 0 )
	{
		if( active(&stack_frame) && is_defined(words[1], NULL) != OK)
		{
			stack_frame.display_mode = TRUE;
		}
		else
			stack_frame.display_mode = FALSE;
		(void) pp_input( input, &stack_frame, TRUE );
		rtn = IFNDEF;
	}

	else if( STequal( words[ 0 ], ERx( "else" ) ) != 0 )
	{
		if( !ifdef )
		{
			SIfprintf( stderr, E_YAPP007 );
			yydump();
		}
		stack_frame.prev->display_mode =
			( stack_frame.prev->display_mode == TRUE ) ?
			FALSE : TRUE;
		rtn = ELSE;
	}

	else if( STequal( words[ 0 ], ERx( "endif" ) ) != 0 )
	{
		rtn = ENDIF;
	}

	else if( STequal( words[ 0 ], ERx( "include" ) ) != 0 )
	{
		/* Look for the include filename */
		if (n > 1) 
		{
			/* Scan for the 'include' keyword */
			parse_val = infile->yytext;
			CMnext(parse_val);         /* Skip over the '#' */
			while (CMwhite(parse_val))
				CMnext(parse_val);

			/* Scan past the include keyword */
			while (!CMwhite(parse_val))
				CMnext(parse_val);

			/* Scan over white space separating 'include' */
			/* keyword and the specified filename */
			while (CMwhite(parse_val))
				CMnext(parse_val);

			/* At this point were expecting "file" or <file> */
			/* remember the character which ends the filename */
			def_dir = TRUE;
			if (CMcmpcase(parse_val, ERx("\"")) == 0)
			{
				parse_end = ERx("\"");
			}
			else if (CMcmpcase(parse_val, ERx("<")) == 0)
			{
				parse_end = ERx(">");
				def_dir = FALSE;
			}
			else
			{
				parse_end = ERx("");
			}

			/* Save the include file name in the temp string. */
			/* Note, this overwrites the parsed words of the  */
			/* record since but these are no longer needed.   */
			p = temp;
			CMnext(parse_val);
			while (*parse_val != EOS)
			{
				if (CMcmpcase(parse_val, parse_end) == 0) 
				{
					/* Terminate the file name and call */
					/* pp_file to process the file. */
					STcopy(ERx(""), p);
					pp_file(stack, temp, def_dir);
					break;
				}
				CMcpychar(parse_val, p);
				CMnext(parse_val);
				CMnext(p);
			}
		}
		rtn = DEFINE;
	}

	/* display everthing but legal directives */ 
	if (rtn == NONE && active( &stack_frame ) )
		yyputline( infile->yytext );

	MEfree( temp );
	return( rtn );
}
예제 #7
0
static STATUS
yygetline( FILE *input )
{
	char *read_buf = infile->yytext, *p, *psave;
	i4  linelen = 0;
	STATUS rtn;
	bool still_reading = TRUE;

/*
** If a line exists in the "unget" cache, just return success.
*/
	if( infile->yyline_cache )
	{
		infile->yyline_cache = FALSE;
		return( OK );
	}

/*
** Read lines from the input file until a non-continuation line is hit
** or the EOF is reached.
*/
	else while (still_reading == TRUE)
	{
		/* Assume the line is not a continuation and read a line */
		still_reading = FALSE;
		rtn = SIgetrec(read_buf, (i4)(MAX_LINE - linelen), input);

		/* Check for a continuation line */
		if (rtn == OK) 
		{
			++infile->yylineno; /* Increment files line counter */

			linelen = STlength(read_buf);

			/* Was the last character a continuation indicator? */
			p = STrchr(read_buf, '\\');
			if (p != NULL)
			{
				psave = p;
				CMnext(p);
#ifdef VMS
				if (*p == EOS || CMcmpcase(p, ERx("\n")) == 0)
#else
				if (CMcmpcase(p, ERx("\n")) == 0)
#endif
				{
					/* At this point we determined the */
					/* line is continued. */
					still_reading = TRUE;
					read_buf = psave;
					STcopy(ERx(""), psave);
				}
			}
		}
	}

	/* Special condition exception: If the EOF was hit after an some */
	/* data has already been read and we were still looking for      */
	/* non-continuation lines, just return back the data we have.    */
	if (OK != rtn && linelen > 0)
		return (OK);
	else
		return (rtn);
}
예제 #8
0
i4
Is_it_If_statement(FILE *testFile,i4 *counter,bool Ignore_it)
{
    char                  *cp1 = NULL ;
    char                  *cp2 = NULL ;
    i4                     cmd ;
    bool                   yes_its_if = FALSE ;
    bool                   yes_its_tc = FALSE ;

    cmd = 0;
    if ((!shellMode)&&(SEP_CMstlen(lineTokens[0],0) > 1)&&
	(CMcmpcase(lineTokens[0],ERx(".")) == 0))
    {
	cp1 = buffer_1 ;		/* Fix the ".if" statement. */
	cp2 = buffer_2 ;

	STcopy(buffer_1, holdBuf);
	CMcpyinc(cp1,cp2);
	CMcpychar(ERx(" "),cp2);
	CMnext(cp2);
	STcopy(cp1, cp2);
	STcopy(buffer_2, buffer_1);
	break_line(buffer_2, counter, lineTokens);
    }

    cmd = classify_cmmd(sepcmmds, lineTokens[1]);
    if (cmd == IF_CMMD || cmd == ELSE_CMMD || cmd == ENDIF_CMMD)
    {
	yes_its_if = TRUE;
    }
    else if (cmd == TEST_CASE_CMMD || cmd == TEST_CASE_END_CMMD)
    {
	yes_its_tc = TRUE;
    }

    if (yes_its_if || yes_its_tc)
    {
	append_line(holdBuf, 0);

	if (Ignore_it)
	    ignore_silent == TRUE;

	if (yes_its_if)
	{
	    process_if(testFile, lineTokens, cmd);
	}
	else if (yes_its_tc)
	{
	    if (cmd == TEST_CASE_CMMD)
	    {
		testcase_start(&lineTokens[1]);
	    }
	    else if (cmd == TEST_CASE_END_CMMD)
	    {
		testcase_end(FALSE);
	    }
	}

	if (Ignore_it)
	    ignore_silent == FALSE;
    }
    else
    {
	cmd = 0;
    }

    return (cmd);
}
예제 #9
0
i4
STxcompare(
	char	*a_ptr,
	size_t	a_len,
	char	*b_ptr,
	size_t	b_len,
	bool	ic,
	bool	sb)
{
	unsigned char		*ap;
	unsigned char		*bp;
	register size_t	al;
	register size_t	bl;
	i4		ret_val = -2;
	i4		cmp;


	ap = (unsigned char *) a_ptr;
	bp = (unsigned char *) b_ptr;
	al = a_len;

	if (al == 0)
		al = MAXI2;

	bl = b_len;

	if (bl == 0)
		bl = MAXI2;

	if (CMGETDBL)
	{
	    while (ret_val == -2)
	    {
		/* supress blanks in both strings */

		if (sb)
		{
			while (al > 0 && CMspace(ap))
			{
				al -= CMbytecnt(ap);
				CMnext(ap);
			}

			while (bl > 0 && CMspace(bp))
			{
				bl -= CMbytecnt(bp);
				CMnext(bp);
			}
		}


		if (al <= 0)
			ap = (unsigned char *) "";

		if (bl <= 0)
			bp = (unsigned char *) "";

		/* do inequality tests */

		if (ic)
			cmp = CMcmpnocase(ap,bp);
		else
			cmp = CMcmpcase(ap,bp);

		if (cmp < 0)
			ret_val = -1;
		else if (cmp > 0)
			ret_val = 1;
		else if (*ap == '\0')
			ret_val = 0;
		else
		{
			/* go on to the next character */

			al -= CMbytecnt(ap);
			CMnext(ap);
			bl -= CMbytecnt(bp);
			CMnext(bp);
		}
	    }
	}
	else
	{
	    while (ret_val == -2)
	    {
		/* supress blanks in both strings */

		if (sb)
		{
			while (al > 0 && CMspace_SB(ap))
			{
				al -= CMbytecnt_SB(ap);
				CMnext_SB(ap);
			}

			while (bl > 0 && CMspace_SB(bp))
			{
				bl -= CMbytecnt_SB(bp);
				CMnext_SB(bp);
			}
		}


		if (al <= 0)
			ap = (unsigned char *) "";

		if (bl <= 0)
			bp = (unsigned char *) "";

		/* do inequality tests */

		if (ic)
			cmp = CMcmpnocase_SB(ap,bp);
		else
			cmp = CMcmpcase_SB(ap,bp);

		if (cmp < 0)
			ret_val = -1;
		else if (cmp > 0)
			ret_val = 1;
		else if (*ap == '\0')
			ret_val = 0;
		else
		{
			/* go on to the next character */

			al -= CMbytecnt_SB(ap);
			CMnext_SB(ap);
			bl -= CMbytecnt_SB(bp);
			CMnext_SB(bp);
		}
	    }
	}

	return(ret_val);
}
예제 #10
0
VOID
get_string(WINDOW *wndow,char *question,char *ansbuff)
{
    char                  *prompt = NULL ;
    char                   tempBuffer [TERM_LINE] ;
    char                  *cp = ansbuff ;
    char                  *cptr = NULL ;
    i4                     clen ;
    register i4            i ;

    prompt = SEP_MEalloc(SEP_ME_TAG_NODEL, STlength(question)+5, TRUE,
			 (STATUS *) NULL);

    STprintf(prompt, ERx("%s "), question);
    put_message(wndow, prompt);    
    getstr(wndow, tempBuffer, FALSE);

    /* check if continuation character was entered */

    cptr = SEP_CMlastchar(tempBuffer,0);

    if (CMcmpcase(cptr,cont_char) == 0)
    {
	*cptr = EOS;
	STcopy(tempBuffer,cp);

	clen = SEP_CMstlen(tempBuffer,0);
	for (i=0; i<clen; i++)
	    CMnext(cp);

	TDerase(wndow);
	STprintf(tempBuffer, ERx("%s%s"), prompt, ansbuff);
	SEPprintw(wndow, PROMPT_ROW - 1, PROMPT_COL, tempBuffer);
	STprintf(prompt, ERx("%s%s"), question, cont_char);
	SEPprintw(wndow, PROMPT_ROW, PROMPT_COL, prompt);
	TDrefresh(wndow);
	getstr(wndow,tempBuffer,FALSE);

	/* check if continuation character was entered */

	cptr = SEP_CMlastchar(tempBuffer,0);

	if (CMcmpcase(cptr,cont_char) == 0)
	{
	    i4	    temp;

	    *cptr = EOS;
	    STprintf(prompt, ERx("%s %s"), question, tempBuffer);
	    SEPprintw(wndow, PROMPT_ROW, PROMPT_COL, prompt);
	    STcopy(tempBuffer, cp);

	    STprintf(prompt, ERx("%s%s"), question, cont_char);
	    SEPprintw(wndow, PROMPT_ROW + 1, PROMPT_COL, prompt);
	    /*
	    **	ugly fix to prevent the screen from scrolling when
	    **	typing to the last line of the screen. It will hopefully
	    **	be changed in the future for a more elegant solution
	    */
	    temp = LINES;
	    LINES++;
	    TDrefresh(wndow);
	    getstr(wndow, tempBuffer, FALSE);
	    disp_prompt((char *)NULLSTR, (char *)NULL, (char *)NULL);
	    LINES = temp;
	}
    }
    MEfree(prompt);
    STcopy(tempBuffer, cp);
    TDerase(wndow);
    TDrefresh(wndow);
}
예제 #11
0
/*{
** Name: adt_compare() - Compare 2 data values.
**
** Description:
**	This routine compares two data values.  This will tell the caller if the
**	supplied values are equal, or if not, which one is "greater than" the
**	other.
**
**	This routine exists as a performance boost for DMF.  DMF is not allowed
**	to know how to compare data values for the various datatypes.
**	Therefore, if this routine did not exist, DMF would have to make a
**	function call to "adc_compare()" for every attribute in the tuples
**	being compared.  Even though tuples are constructs that seem a level
**	above what ADF logically handles, the performance improvement in this
**	case justifies this routine.
**
**	To avoid the overhead of an adc_compare call,
**	this routine has built into it the semantics for
**	comparing several of the most common datatypes supported by INGRES.
**
**	If the routine does run across a datatype that is not in this list, it
**	will call the general routine "adc_compare()", thereby guaranteeing
**	that it will function (perhaps slower), for ALL datatypes, even future
**	user defined ADTs.
**
**	When NULL values are involved, this routine will use the same semantics
**	that "adc_compare()" uses:  a NULL value will be considered greater
**	than any other value, and equal to another NULL value.
**
**	PLEASE NOTE:  As with "adc_compare()", no pattern matching for
**	-----------   the string datatypes is done within this routine.
**
**
** Inputs:
**	adf_scb				Pointer to an ADF session control block.
**	    .adf_errcb			ADF_ERROR struct.
**		.ad_ebuflen		The length, in bytes, of the buffer
**					pointed to by ad_errmsgp.
**		.ad_errmsgp		Pointer to a buffer to put formatted
**					error message in, if necessary.
**      atr                             Pointer to DB_ATTR.
**      d1                        	Pointer to first value.
**      d2                              Pointer to second value.
**
** Outputs:
**	adf_scb				Pointer to an ADF session control block.
**	    .adf_errcb			ADF_ERROR struct.  If an
**					error occurs the following fields will
**					be set.  NOTE: if .ad_ebuflen = 0 or
**					.ad_errmsgp = NULL, no error message
**					will be formatted.
**		.ad_errcode		ADF error code for the error.
**		.ad_errclass		Signifies the ADF error class.
**		.ad_usererr		If .ad_errclass is ADF_USER_ERROR,
**					this field is set to the corresponding
**					user error which will either map to
**					an ADF error code or a user-error code.
**		.ad_emsglen		The length, in bytes, of the resulting
**					formatted error message.
**		.adf_errmsgp		Pointer to the formatted error message.
**      status                          Status returned from
**					adc_compare(), if called.
**	
**	    The following DB_STATUS codes may be returned by adc_compare():
**	    E_DB_OK, E_DB_WARN, E_DB_ERROR, E_DB_SEVERE, E_DB_FATAL
**
**	    If a DB_STATUS code other than E_DB_OK is returned, the caller
**	    can look in the field adf_scb.adf_errcb.ad_errcode to determine
**	    the ADF error code.  The following is a list of possible ADF error
**	    codes that can be returned by this routine:
**
**          E_AD0000_OK                 Operation succeeded.
**          E_AD2004_BAD_DTID           Datatype id unknown to ADF.
**          E_AD2005_BAD_DTLEN          Internal length is illegal for
**					the given datatype.
**		(Others not yet defined)
**
** Returns:
**      i4  < 0   if 1st < 2nd
**          = 0   if 1st = 2nd
**          > 0   if 1st > 2nd
**
** Exceptions:
**       none
**
** Side Effects:
**       none
**
** History:
**      10-Feb-86 (thurston)
**          Initial creation.
**	03-apr-86 (thurston)
**	    Initial coding.  Also, added two more return statuses (stati?):
**          E_AD2004_BAD_DTID and E_AD2005_BAD_DTLEN.
**      11-jun-86 (jennifer)
**          Fixed bug compare result asigned to adt_cmp_result instead
**          of indirect through this pointer, i.e. *adt_cmp_result.
**      11-jun-86 (jennifer)
**	    Fixed bug where the first entry of attribute array (0)
**          was being used.  This entry is always garbage since 
**          attributes are numbered from 1.
**      27-jul-86 (ericj)
**	    Converted for new ADF error handling.
**	19-nov-86 (thurston)
**	    Fixed the comparison for text.
**	22-sep-88 (thurston)
**	    Added bit representation check as a first pass on each attr.  Also,
**	    added code to deal with nullable types here ... this could be a big
**	    win, since all nullable types were going through adc_compare(), now
**	    they need not.  Also, added cases for CHAR and VARCHAR.
**	21-oct-88 (thurston)
**	    Got rid of all of the `#ifdef BYTE_ALIGN' stuff by using the
**	    appropriate [I2,I4,F4,F8]ASSIGN_MACROs.  This also avoids a bunch
**	    of MEcopy() calls on BYTE_ALIGN machines.
**	21-Apr-89 (anton)
**	    Added local collation support
**	17-Jun-89 (anton)
**	    Moved local collation routines to ADU from CL
**	25-jul-89 (jrb)
**	    Added support for decimal datatype.
**	02-jan-90 (jrb)
**	    Fix alignment problem.
**	08-aug-91 (seg)
**	    "d1" and "d2" are dereferenced too often with the assumption
**	    that (PTR) == (char *) to fix.  Made them (char *).
**	28-mar-2001 (abbjo03)
**	    Add support for DB_NCHR_TYPE and DB_NVCHR_TYPE.
**	16-dec-04 (inkdo01)
**	    Add collation ID parm to aduucmp() calls.
**	02-Feb-2005 (jenjo02)
**	    Consolidated from the nine adt functions which duplicated
**	    this "compare" code. Runs the most optimal compare
**	    based on datatype for a single attribute.
**
**	    Optimized CHA/VCH compares to use MEcmp rather than
**	    CMcmpcase loop when possible.
**
**	    Replace giant switch statement with if-then-else
**	    ordered most likely to least likely, more or less.
**	    The switch was consuming 27% of the CPU used by this
**	    function.
**
**	    Added DB_STATUS *status as a function parameter so
**	    if adc_compare returns an error, it will be returned
**	    to the caller rather than as a bogus compare "result".
**	27-Apr-2005 (jenjo02 for stial01)
**	    Replaced computing compare value using arithmetic
**	    (d1 - d2) with logical compares ( d1 < d2...) as
**	    the arithmetic may over/underflow and return the
**	    wrong result.
**	13-May-2005 (thaju02)
**	    For differing length vchar, return value based on 
**	    comparison of longer length vchar to blank. (B114514)
**	19-Jun-2006 (gupsh01)
**	    Added support for new date/time types.
**	3-may-2007 (dougi)
**	    Tweak slightly to allow MEcmp() on collation/double byte
**	    if they're bytewise equal.
**	10-may-2007 (dougi)
**	    Add logic to handle ordering of c/text/char/varchar in UTF8
**	    server.
**	25-jul-2007 (gupsh01)	
**	    Although UTF8 is multibyte it is meant to be processed through
**	    UTF8 comparison code utilizing unicode comparison.
**	17-Aug-2007 (gupsh01)
**	    Fix the UTF8 handling.
*/
i4
adt_compare(
ADF_CB		    *adf_scb,
DB_ATTS		    *atr,		/* Attribute in question */
char		    *d1,		/* Ptr to 1st value */
char		    *d2,		/* Ptr to 2nd value */
DB_STATUS	    *status)		/* Status from adc_compare */

{
    i4			cur_cmp;	/* Result of latest attr cmp */
    i4			vi1, vi2;	/* Temp i4's used to cmp ints */
    i8			lli1, lli2;	/* Compare i8's */
    f8			vf1, vf2;	/* Temp f8's used to cmp flts */
    u_char	        *lc1, *lc2;
    u_char	        blank;
    i4			atr_bdt;	/* Base datatype of attr */
    i2			atr_len;	/* Length of cur attribute */
    i4			d1_isnull, d2_isnull;
    DB_DATA_VALUE	dv1, dv2;	/* Data value structs for call
					** to adc_compare(), if that is
					** necessary.
					*/
    u_char		*tc1, *tc2;	/* Temps used for string compare */
    u_char		*endtc1, *endtc2;
    UCS2		*tn1, *tn2;	/* Temps used for Nstring compare */
    UCS2		*endtn1, *endtn2;
	/*
	**  The following four lines provide temp storage to solve
	**  byte allignment problems on some archictectures.
	*/
    i2			i2_t1, i2_t2;
    i4			i4_t1, i4_t2;
    f4			f4_t1, f4_t2;
    f8			f8_t1, f8_t2;

#define	ADT_LT	(i4)-1
#define ADT_EQ	(i4)0
#define	ADT_GT	(i4)1

    *status = E_DB_OK;

    atr_len = atr->length;

    if ( (atr_bdt = atr->type) < 0 )
    {
	/* Nullable datatype */

	d1_isnull = (*((char *)d1 + atr_len - 1) & ADF_NVL_BIT);
	d2_isnull = (*((char *)d2 + atr_len - 1) & ADF_NVL_BIT);

	if ( !d1_isnull && !d2_isnull )
	{
	    /* Neither is the Null value, look at data */
	    atr_bdt = -atr_bdt;
	    atr_len--;
	}
	else if (d1_isnull && d2_isnull)
	    return(ADT_EQ);   /* both are Null values; 1st = 2nd */
	else if (d1_isnull)
	    return(ADT_GT);   /* 1st is Null value; 1st > 2nd */
	else
	    return(ADT_LT);  /* 2nd is Null value; 1st < 2nd */
    }

    /* "if then else" consumes ~27% less CPU than "switch" */

    if ( atr_bdt == DB_INT_TYPE )
    {
	/* If both operands aligned... */
	/* Extra casts to shut up compilers -- only care about low bits */
	if ( (((i4)(SCALARP)d1 | (i4)(SCALARP)d2) & atr_len-1) == 0 )
	{
	    if ( atr_len == 4 )
	    {
		if      (*(i4*)d1 < *(i4*)d2)	return(ADT_LT);
		else if (*(i4*)d1 > *(i4*)d2)	return(ADT_GT);
		else			  	return(ADT_EQ);
	    }
	    if ( atr_len == 8 )
	    {
		if      (*(i8*)d1 < *(i8*)d2)	return(ADT_LT);
		else if (*(i8*)d1 > *(i8*)d2)	return(ADT_GT);
		else			  	return(ADT_EQ);
	    }
	    if ( atr_len == 2 )
	    {
		if      (*(i2*)d1 < *(i2*)d2)	return(ADT_LT);
		else if (*(i2*)d1 > *(i2*)d2)	return(ADT_GT);
		else			  	return(ADT_EQ);
	    }
	
	    if      (*(i1*)d1 < *(i1*)d2)	return(ADT_LT);
	    else if (*(i1*)d1 > *(i1*)d2)	return(ADT_GT);
	    else			  	return(ADT_EQ);
	}
	/* One or both not aligned... */
	if (atr_len == 4)
	{
	    I4ASSIGN_MACRO(*d1, i4_t1);
	    I4ASSIGN_MACRO(*d2, i4_t2);
	    if      (i4_t1 < i4_t2)	return(ADT_LT);
	    else if (i4_t1 > i4_t2)	return(ADT_GT);
	    else			return(ADT_EQ);
	}
	if (atr_len == 8)
	{
	    I8ASSIGN_MACRO(*d1, lli1);
	    I8ASSIGN_MACRO(*d2, lli2);
	    if      (lli1 < lli2)	return(ADT_LT);
	    else if (lli1 > lli2)	return(ADT_GT);
	    else		  	return(ADT_EQ);
	}
	if (atr_len == 2)
	{
	    I2ASSIGN_MACRO(*d1, i2_t1);
	    I2ASSIGN_MACRO(*d2, i2_t2);
	    if      (i2_t1 < i2_t2)	return(ADT_LT);
	    else if (i2_t1 > i2_t2)	return(ADT_GT);
	    else			return(ADT_EQ);
	}
	if      (*(i1*)d1 < *(i1*)d2)	return(ADT_LT);
	else if (*(i1*)d1 > *(i1*)d2)	return(ADT_GT);
	else			  	return(ADT_EQ);
    }

    if ( atr_bdt == DB_FLT_TYPE || atr_bdt == DB_MNY_TYPE )
    {
	/* If both operands aligned... */
	/* Extra casts to shut up compilers, only care about low bits */
	if ( (((i4)(SCALARP)d1 | (i4)(SCALARP)d2) & atr_len-1) == 0 )
	{
	    if ( atr_len == 8 )
	    {
		if      (*(f8*)d1 < *(f8*)d2) return(ADT_LT);
		else if (*(f8*)d1 > *(f8*)d2) return(ADT_GT);
		else                  	  return(ADT_EQ);
	    }
	    if      (*(f4*)d1 < *(f4*)d2) return(ADT_LT);
	    else if (*(f4*)d1 > *(f4*)d2) return(ADT_GT);
	    else                  	  return(ADT_EQ);
	}

	/* One or both not aligned... */
	if ( atr_len == 8 )
	{
	    F8ASSIGN_MACRO(*d1, f8_t1);
	    F8ASSIGN_MACRO(*d2, f8_t2);
	    if      (f8_t1 < f8_t2) return(ADT_LT);
	    else if (f8_t1 > f8_t2) return(ADT_GT);
	    else   		    return(ADT_EQ);
	}
	F4ASSIGN_MACRO(*d1, f4_t1);
	F4ASSIGN_MACRO(*d2, f4_t2);
	if      (f4_t1 < f4_t2) return(ADT_LT);
	else if (f4_t1 > f4_t2) return(ADT_GT);
	else   		        return(ADT_EQ);
    }

    if ( atr_bdt == DB_BYTE_TYPE || atr_bdt == DB_TABKEY_TYPE ||
	      atr_bdt == DB_LOGKEY_TYPE )
    {
	return(MEcmp(d1, d2, atr_len));
    }

    if ( atr_bdt == DB_CHA_TYPE || atr_bdt == DB_VCH_TYPE )
    {
	if ( atr_bdt == DB_CHA_TYPE )
	{
	    /* Try the turbo compare. */
	    cur_cmp = MEcmp(d1, d2, atr_len);

	    /* If not equal and UTF8-enabled ... */
	    if (cur_cmp && (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED))
		return(adt_utf8comp(adf_scb, atr, atr_bdt, atr_len, 
							d1, d2, status));

	    /* If neither collation nor doublebyte or if byte-wise equal ... */
	    if ( !(adf_scb->adf_collation || 
		   Adf_globs->Adi_status & ADI_DBLBYTE) || cur_cmp == 0)
	    {
		return(cur_cmp);
	    }

	    tc1    = (u_char *) d1;
	    tc2    = (u_char *) d2;
	    endtc1 = tc1 + atr_len;
	    endtc2 = tc2 + atr_len;
	}
	else
	{
	    I2ASSIGN_MACRO(((DB_TEXT_STRING *)d1)->db_t_count, i2_t1);
	    I2ASSIGN_MACRO(((DB_TEXT_STRING *)d2)->db_t_count, i2_t2);
	    tc1 = (u_char *)d1 + DB_CNTSIZE;
	    tc2 = (u_char *)d2 + DB_CNTSIZE;

	    /* Try the turbo compare on the prefix. */
	    cur_cmp = MEcmp((char *)tc1, (char *)tc2, min(i2_t1, i2_t2));

	    /* If neither collation nor doublebyte... */
	    if ( !(adf_scb->adf_collation || 
		   Adf_globs->Adi_status & ADI_DBLBYTE) || 
			(adf_scb->adf_utf8_flag & AD_UTF8_ENABLED))
	    {
		i2	diff = i2_t1 - i2_t2;
	    
		/* If not equal or lengths differ and UTF8-enabled ... */
		if ((diff || cur_cmp) && 
			(adf_scb->adf_utf8_flag & AD_UTF8_ENABLED))
		    return(adt_utf8comp(adf_scb, atr, atr_bdt, atr_len, 
							d1, d2, status));

		/* If short compare produces inequality or lengths are
		** the same ... */
		if ( cur_cmp || diff == 0 )
		{
		    return(cur_cmp);
		}

		/*
		** Equal for shorter length.
		** If longer trails all blanks, they're equal
		*/
		if ( diff > 0 )
		{
		    /* tc1 is longer */
		    tc1 += i2_t2;
		    while ( *(tc1++) == MIN_CHAR && --diff > 0 );

		    if (!diff)
			return( ADT_EQ );
		    else
		    {
			tc1--;
			if (*tc1 > MIN_CHAR)
			    return(ADT_GT);
			else
			    return(ADT_LT);
		    }
		}
		else
		{
		    /* tc2 is longer */
		    tc2 += i2_t1;
		    while ( *(tc2++) == MIN_CHAR && ++diff < 0 );

		    if (!diff)
			return( ADT_EQ );
		    else
		    {
			tc2--;
			if (MIN_CHAR > *tc2)
			    return(ADT_GT);
			else 
			    return(ADT_LT);
		    }
		}

	    }
	    else if (i2_t1 == i2_t2 && cur_cmp == 0)
		return(cur_cmp);	/* byte wise compare returns "=" */

	    endtc1 = tc1 + i2_t1;
	    endtc2 = tc2 + i2_t2;
	}

	if (adf_scb->adf_collation)
	    return(adugcmp((ADULTABLE *)adf_scb->adf_collation,
			 ADUL_BLANKPAD, tc1, endtc1, tc2, endtc2));

	/* Doublebyte is rather more tedious */
	blank = (u_char)MIN_CHAR;
	cur_cmp = ADT_EQ;
	
	while ( cur_cmp == ADT_EQ )
	{
	    if (tc1 < endtc1)
	    {
		lc1 = tc1;
		CMnext(tc1);
	    }
	    else
	    {
		lc1 = &blank;
	    }
	    
	    if (tc2 < endtc2)
	    {
		lc2 = tc2;
		CMnext(tc2);
	    }
	    else
	    {
		lc2 = &blank;
	    }
	    
	    /* if both pointing to blank or we happen to be comparing
	    ** a string to itself then break
	    */
	    if (lc1 == lc2)
		break;
	    
	    cur_cmp = CMcmpcase(lc1, lc2);
	}
	return(cur_cmp);
    }

    if ( atr_bdt == DB_NCHR_TYPE || atr_bdt == DB_NVCHR_TYPE )
    {
	if ( atr_bdt == DB_NCHR_TYPE )
	{
	    tn1 = (UCS2 *)d1;
	    tn2 = (UCS2 *)d2;
	    endtn1 = tn1 + atr_len / sizeof(UCS2);
	    endtn2 = tn2 + atr_len / sizeof(UCS2);
	}
	else
	{
	    tn1 = ((DB_NVCHR_STRING *)d1)->element_array;
	    tn2 = ((DB_NVCHR_STRING *)d2)->element_array;
	    I2ASSIGN_MACRO(((DB_NVCHR_STRING *)d1)->count, i2_t1);
	    I2ASSIGN_MACRO(((DB_NVCHR_STRING *)d2)->count, i2_t2);
	    endtn1 = tn1 + i2_t1;
	    endtn2 = tn2 + i2_t2;
	}
      
	*status = aduucmp(adf_scb, ADUL_BLANKPAD,
	    tn1, endtn1, tn2, endtn2, &cur_cmp, atr->collID);
	return (cur_cmp);
    }

    if ( atr_bdt == DB_CHR_TYPE )
    {
	if (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED)
	    return(adt_utf8comp(adf_scb, atr, atr_bdt, atr_len, 
							d1, d2, status));

	if (adf_scb->adf_collation)
	    return(adugcmp((ADULTABLE *)adf_scb->adf_collation,
			     ADUL_SKIPBLANK, (u_char *)d1,
			     atr_len + (u_char *)d1, (u_char *)d2,
			     atr_len + (u_char *)d2));
	return(STscompare((char *)d1, atr_len, (char *)d2, atr_len));
    }

    if ( atr_bdt == DB_TXT_TYPE )
    {
	if (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED)
	    return(adt_utf8comp(adf_scb, atr, atr_bdt, atr_len, 
							d1, d2, status));

	I2ASSIGN_MACRO(((DB_TEXT_STRING *)d1)->db_t_count, i2_t1);
	I2ASSIGN_MACRO(((DB_TEXT_STRING *)d2)->db_t_count, i2_t2);
	tc1 = (u_char *)d1 + DB_CNTSIZE;
	tc2 = (u_char *)d2 + DB_CNTSIZE;
	endtc1 = tc1 + i2_t1;
	endtc2 = tc2 + i2_t2;

	if (adf_scb->adf_collation)
	    return(adugcmp((ADULTABLE *)adf_scb->adf_collation,
			     0, tc1, endtc1, tc2, endtc2));

	cur_cmp = ADT_EQ;
	while (cur_cmp == ADT_EQ && tc1 < endtc1  &&  tc2 < endtc2)
	{
	    if ( (cur_cmp = CMcmpcase(tc1, tc2)) == ADT_EQ )
	    {
		CMnext(tc1);
		CMnext(tc2);
	    }
	}
	
	/* If equal up to shorter, short strings < long */
	return( (cur_cmp) ? cur_cmp : (endtc1 - tc1) - (endtc2 - tc2) );
    }

    if ( atr_bdt == DB_DEC_TYPE )
    {
	/*  See if the bit representation is identical. */
	if ( MEcmp(d1, d2, atr_len) )
	{
	    i4	    pr;
	    i4	    sc;

	    pr = DB_P_DECODE_MACRO(atr->precision);
	    sc = DB_S_DECODE_MACRO(atr->precision);
	    return(MHpkcmp((PTR)d1, pr, sc, (PTR)d2, pr, sc));
	}
	return(ADT_EQ);
    }

    /* Bit-equivalent dates we can handle here */
    if (( atr_bdt == DB_DTE_TYPE || 
	 atr_bdt == DB_ADTE_TYPE ||
	 atr_bdt == DB_TMWO_TYPE ||
	 atr_bdt == DB_TMW_TYPE ||
	 atr_bdt == DB_TME_TYPE ||
	 atr_bdt == DB_TSWO_TYPE ||
	 atr_bdt == DB_TSW_TYPE ||
	 atr_bdt == DB_TSTMP_TYPE ||
	 atr_bdt == DB_INYM_TYPE ||
	 atr_bdt == DB_INDS_TYPE ) &&
	MEcmp(d1, d2, (u_i2)atr_len) == 0 )
    {
	return(ADT_EQ);
    }

    /* Will have to do it the slow way */
    dv1.db_datatype = dv2.db_datatype = (DB_DT_ID)atr_bdt;
    dv1.db_prec = dv2.db_prec = atr->precision;
    dv1.db_length = dv2.db_length = atr_len;
    dv1.db_collID = dv2.db_collID = atr->collID;
    dv1.db_data = d1;
    dv2.db_data = d2;
    *status = adc_compare(adf_scb, &dv1, &dv2, &cur_cmp);

    return(cur_cmp);
}
예제 #12
0
/*{
** Name: psq_rptqry_text - add a piece of text to the text chain for a repeat
**			   query
**
** Description: Add a piece of text to the text chain for a repeat query.  It is
**		imperative that text of all repeat queries be stored in a
**		uniform fashion so that comparing two stored query texts would
**		serve as a reliable indicator of their sameness.  Each piece
**		will be preceeded with a blank except for a PERIOD.  Neither the
**		piece consisting of PERIOD nor the following piece will be
**		preceeded with a blank.
**
** Inputs:
**      header                          Pointer to chain header
**	piece				Pointer to piece of text
**	size				Size of piece
**	result				Place to put pointer to new piece
**	err_blk				Filled in if an error happens
**
** Outputs:
**      result                          Filled in with pointer to chain element
**	err_blk				Filled in if an error happens
**	Returns:
**	    E_DB_OK			Success
**	    E_DB_ERROR			Non-catastrophic failure
**	    E_DB_FATAL			Catastrophic failure
**	Exceptions:
**	    none
**
** Side Effects:
**	    Allocates memory
**
** History:
**      24-jan-90 (andre)
**          Plagiarized from psq_tadd().
**	28-jan-91 (andre)
**	    Do not insert a space if a piece is immediately following a piece
**	    consisting of a $.
*/
DB_STATUS
psq_rptqry_text(
	PTR                header,
	u_char		   *piece,
	i4		   size,
	PTR		   *result,
	DB_ERROR	   *err_blk)
{
    PSQ_THEAD           *hp = (PSQ_THEAD *) header;
    PSQ_TEXT		*tp;
    i4		err_code;
    bool		leading_blank;
    char		*txt;
    DB_STATUS		status;

    /*
    ** Allocate enough space for PSQ_TEXT structure containing piece:
    ** all pieces will be preceeded with a blank with the following exceptions:
    **	- piece consisting of PERIOD will not be preceeeded with a blank;
    **	- piece which immediately follows a piece consisting of PERIOD;
    **	- piece starting with a "white" character will not be preceeded with a
    **	  blank;
    **	- piece which immediately follows a piece consisting of $ (preceeded by
    **	  a blank which was inserted by this function)
    */

    if (   size == CMbytecnt(".") && !CMcmpcase(piece, ".")
	|| CMwhite(piece))
    {
	/*
	** piece consists of a period or starts with a "white" character - no
	** leading blanks will be added
	*/
	leading_blank = FALSE;
    }
    else if (   hp->psq_last != (PSQ_TEXT *) NULL
	     && ((   hp->psq_last->psq_psize == CMbytecnt(".")
		  && !CMcmpcase(hp->psq_last->psq_tval, ".")
		 )
		 ||
		 (   hp->psq_last->psq_psize == CMbytecnt(" ") + CMbytecnt("$")
		  && !CMcmpcase(hp->psq_last->psq_tval, " ")
		  && !CMcmpcase((hp->psq_last->psq_tval + CMbytecnt(" ")), "$")
		 )
	        )
	    )
    {
	/*
	** previous piece consists of a period or of a $ preceeded by a blank
	** inserted by this function - no leading blanks will be added
	*/
	leading_blank = FALSE;
    }
    else
    {
	/* insert a blank before the piece */
	leading_blank = TRUE;
    }

    hp->psq_tmem.ulm_psize = (leading_blank)
	? size + sizeof(PSQ_TEXT) - 1 + CMbytecnt(" ")
	: size + sizeof(PSQ_TEXT) - 1;

    if ((status = ulm_palloc(&hp->psq_tmem)) != E_DB_OK)
    {
	if (hp->psq_tmem.ulm_error.err_code == E_UL0005_NOMEM)
	{
	    (VOID) psf_error(E_PS0F02_MEMORY_FULL, 0L, PSF_CALLERR, 
		&err_code, err_blk, 0);
	}
	else
	{
	    (VOID) psf_error(E_PS0371_ALLOC_TEXT_CHAIN,
		hp->psq_tmem.ulm_error.err_code, PSF_INTERR, &err_code, err_blk,
		0);
	}

	return (status);
    }

    *result = hp->psq_tmem.ulm_pptr;
    tp	    = (PSQ_TEXT*) *result;

    /* Fill in text piece */
    txt = (char *) tp->psq_tval;

    /* insert a leading blank if necessary */
    if (leading_blank)
    {
	CMcpychar(" ", txt);
	txt += CMbytecnt(" ");
    }
	
    MEcopy((char *) piece, size, txt);
    tp->psq_psize = (leading_blank) ? size + CMbytecnt(" ") : size;

    /* Hook it up to the chain */
    tp->psq_next = (PSQ_TEXT *) NULL;
    if (hp->psq_last != (PSQ_TEXT *) NULL)
    {
	hp->psq_last->psq_next = tp;
	tp->psq_prev = hp->psq_last;
    }
    else
    {
	tp->psq_prev = NULL;
    }
    hp->psq_last = tp;
    if (hp->psq_first == (PSQ_TEXT *) NULL)
	hp->psq_first = tp;

    /* Add in the length to the total for the chain */
    hp->psq_tsize += tp->psq_psize;

    return (E_DB_OK);
}
예제 #13
0
STATUS
getLocation(char *string,char *newstr,LOCTYPE *typeOfLoc)
{
    STATUS                 ret_val ;
    LOCATION               aLoc ;
    LOCATION               bLoc ;

    LOCATION              *Locptr1 = NULL ;
    LOCATION              *Locptr2 = NULL ;
    LOCATION              *Locptr3 = NULL ;

    char                  *cptr    = NULL ;
    char                  *cptr2   = NULL ;
    char                  *next    = NULL ;
    char                  *start   = NULL ;
    char                  *tmpBuf  = NULL ;
    char                  *tmpBuf2 = NULL ;
    char                  *gl_dev  = NULL ;
    char                  *gl_path [128] ;
    char                  *gl_file = NULL ;
    char                  *resultPtr = NULL ;
    char                  *tmpaLocStr = NULL ;
    char                  *tmpbLocStr = NULL ;

    i4                     i ;

    ret_val = OK;
    for ( i=0; i<128; i++)
	gl_path[i] = NULL;

    tmpaLocStr = SEP_MEalloc(SEP_ME_TAG_GETLOC, MAX_LOC+1, TRUE, (STATUS *)NULL);
    tmpbLocStr = SEP_MEalloc(SEP_ME_TAG_GETLOC, MAX_LOC+1, TRUE, (STATUS *)NULL);

    LOfroms(FILENAME & PATH, tmpaLocStr, &aLoc);
    LOfroms(FILENAME & PATH, tmpbLocStr, &bLoc);

    if (tracing&TRACE_PARM)
    {
	SIfprintf(traceptr, ERx("getLocation00> string = %s\n"), string);
	SIfprintf(traceptr, ERx("getLocation01> newstr = %s\n"), newstr);
    }

    tmpBuf   = SEP_MEalloc(SEP_ME_TAG_GETLOC, MAX_LOC+1, TRUE, (STATUS *)NULL);
    STcopy(string, tmpBuf);

    if (!(start = STindex(tmpBuf, ERx("("), 0)))
    {
	MEtfree(SEP_ME_TAG_GETLOC);
	return(FAIL);
    }

    MEfree(tmpaLocStr);
    MEfree(tmpbLocStr);

    aLoc.string = SEP_MEalloc(SEP_ME_TAG_GETLOC, MAX_LOC+1, TRUE, (STATUS *)NULL);
    bLoc.string = SEP_MEalloc(SEP_ME_TAG_GETLOC, MAX_LOC+1, TRUE, (STATUS *)NULL);

    next = start;
    CMnext(next);
    if (typeOfLoc)
	*typeOfLoc = NULL;

    if (CMcmpcase(next, ERx(",")))
    {
	/* There's a device specification */

	cptr = next;
	if ((next = STindex(cptr, ERx(","), 0)) == NULL)
	{
	    if ((next = STindex(cptr, ERx(")"), 0)) == NULL)
		ret_val = FAIL;
	    else
	    {	/*
		** This is really a file name in the form, @file(filename.type)
		*/
		*next = EOS;
		gl_file = SEP_MEalloc(SEP_ME_TAG_GETLOC, ((i4)(next-cptr))+2,
				      TRUE, (STATUS *)NULL);
		STcopy(cptr, gl_file);

		if (tracing&TRACE_PARM)
		    SIfprintf(traceptr, ERx("getLocation02> file = %s\n"),
			      gl_file);
		if (typeOfLoc)
		    *typeOfLoc = FILENAME;
	    }
	}
	else
	{
	    *next = EOS;
	    gl_dev = SEP_MEalloc(SEP_ME_TAG_GETLOC, ((i4)(next-cptr))+2, TRUE,
				 (STATUS *)NULL);
#ifdef UNIX
	    STpolycat(2,ERx("$"),cptr, gl_dev);

	    cptr2 = gl_dev;
	    SEP_NMgtAt(CMnext(cptr2), &tmpBuf2, SEP_ME_TAG_GETLOC);
	    if ((tmpBuf2 == NULL)||(*tmpBuf2 == EOS))
	    {
		switch (i = SEP_CMwhatcase(cptr2))
		{
		   case  0: break;
		   case  1: for (cptr2 = gl_dev; *cptr2 != EOS; CMnext(cptr2))
				CMtolower(cptr2,cptr2);
			    break;
		   case -1: for (cptr2 = gl_dev; *cptr2 != EOS; CMnext(cptr2))
				CMtoupper(cptr2,cptr2);
			    break;
		}
		if (i != 0)
		{
		    cptr2 = gl_dev;
		    SEP_NMgtAt(CMnext(cptr2), &tmpBuf2, SEP_ME_TAG_GETLOC);
		}
	    }

	    if (tmpBuf2 != NULL)
		if (*tmpBuf2 != EOS)
		{
		    MEfree(gl_dev);
		    gl_dev = SEP_MEalloc(SEP_ME_TAG_GETLOC,
					 (STlength(tmpBuf2)*2)+2,
					 TRUE,(STATUS *)NULL);
		    STcopy(tmpBuf2,gl_dev);
		}
#else
#ifdef MPE
            STpolycat(2,ERx("!"),cptr, gl_dev);
            for (cptr2 = gl_dev; *cptr2 != EOS; CMnext(cptr2))
                CMtoupper(cptr2,cptr2);
#else
	    /* Probably VMS */

	    STcopy(cptr, gl_dev);
#endif
#endif
	    if (tracing&TRACE_PARM)
		SIfprintf(traceptr, ERx("getLocation03> dev = %s\n"), gl_dev);
	    if (typeOfLoc)
		*typeOfLoc = PATH;
	}

    }

    cptr = CMnext(next);
    next = STindex(cptr, ERx(","), 0);

    for (i = 0; next; ) /* do the paths */
    {
	*next = EOS;
	gl_path[i] = SEP_MEalloc(SEP_ME_TAG_GETLOC, (int)(next-cptr+2), TRUE,
				 (STATUS *)NULL);
	STcopy(cptr, gl_path[i]);
	if (tracing&TRACE_PARM)
	    SIfprintf(traceptr, ERx("getLocation04> path = %s\n"), gl_path[i]);

	if (typeOfLoc)
	    *typeOfLoc = PATH;

	cptr = CMnext(next);
	next = STindex(cptr, ERx(","), 0);
	i++;
    }
    gl_path[i] = NULL;

    Locptr1 = &aLoc;
    Locptr2 = &bLoc;


#ifndef MPE
    if (gl_dev || gl_path[0])
    {
	if (tracing&TRACE_PARM)
	    SIfprintf(traceptr, ERx("getLocation05> SEP_LOcompose()\n"));

	ret_val = SEP_LOcompose(gl_dev, gl_path[0], NULL, NULL, NULL, Locptr1);
#ifdef UNIX
	cptr2 = SEP_CMlastchar(Locptr1->string,0);
	if (*cptr2 == '/') *cptr2 = EOS;
	Locptr1->path = Locptr1->string;
#endif
    }

    for (i=1; (gl_path[i] != NULL)&&(ret_val == OK); i++)
    {
	if (tracing&TRACE_PARM)
	    SIfprintf(traceptr, ERx("getLocation06> LOfaddpath()\n"));

	if ((ret_val = LOfaddpath(Locptr1, gl_path[i], Locptr2)) != OK)
	    continue;

	Locptr3 = Locptr1;
	Locptr1 = Locptr2;
	Locptr2 = Locptr3;
    }
#endif

    if ((gl_file != NULL)&&(ret_val == OK))
    {
	/*
	** This first case catches the instance of: @file(filenane.type).
	** This was caught above in looking for a device (gl_dev).
	*/
	if (tracing&TRACE_PARM)
	    SIfprintf(traceptr, ERx("getLocation07> LOfroms()\n"));

	ret_val = LOfroms( FILENAME, gl_file, Locptr1);
    }
    else
    if ((CMcmpcase(cptr, ERx(")")) != 0)&&(ret_val == OK))
    {
	/* There is a filename */

	next = STindex(cptr, ERx(")"), 0);

	*next = EOS;
	gl_file = SEP_MEalloc(SEP_ME_TAG_GETLOC, (int)(next-cptr+2), TRUE,
			      (STATUS *)NULL);
	STcopy(cptr, gl_file);
	if (tracing&TRACE_PARM)
	    SIfprintf(traceptr, ERx("getLocation08> file = %s\n"), gl_file);
	if (typeOfLoc)
	    *typeOfLoc = PATH & FILENAME;
	if (gl_dev || gl_path[0])
	{
#ifdef MPE
	    if (gl_dev)
	    {
		if (tracing&TRACE_PARM)
		    SIfprintf(traceptr, ERx("getLocation09> MPE's LOfroms ()\n"));

	        char *tmpMPE = NULL ;

		tmpMPE = SEP_MEalloc(SEP_ME_TAG_GETLOC,
				     (STlength(gl_file)+STlength(gl_dev)+1)*2,
				     TRUE, (STATUS *)NULL);

		STpolycat(3, gl_file, ERx("."), gl_dev, tmpMPE);
		LOfroms(FILENAME & PATH, tmpMPE, Locptr1);
	    }
#else
	    if (tracing&TRACE_PARM)
		SIfprintf(traceptr, ERx("getLocation09> LOfstfile()\n"));

	    LOfstfile(gl_file, Locptr1);
#endif
	}
	else
	{
	    if (tracing&TRACE_PARM)
		SIfprintf(traceptr, ERx("getLocation10> LOfroms()\n"));

	    LOfroms( FILENAME, gl_file, Locptr1);
	}
    }

    if (ret_val == OK)
    {
	if (tracing&TRACE_PARM)
	    SIfprintf(traceptr, ERx("getLocation11> LOtos()\n"));

	LOtos(Locptr1, &resultPtr);
	STcopy(resultPtr, newstr);
    }
    MEtfree(SEP_ME_TAG_GETLOC);

    if (tracing&TRACE_PARM)
    {
	if (ret_val != OK)
	    SIfprintf(traceptr,ERx("getLocation12> ret_val = %d\n"),ret_val);
	else
	    SIfprintf(traceptr,ERx("getLocation13> newstr = %s\n"),newstr);
    }

    return(ret_val);
}
예제 #14
0
STATUS
Trans_SEPfile(char **Token,LOCTYPE *typeOfLoc,bool Dont_free,i2 ME_tag)
{
    STATUS                 syserr ;
    char                  *newstr = NULL ;
    char                  *temp_ptr = NULL ;
    char                  *tmp_buffer1 = NULL ;
    char                  *tmp_buffer2 = NULL ;
    char                  *tmp_ptr1 = NULL ;
    char                  *tmp_ptr2 = NULL ;
    char                  *tmp_ptr3 = NULL ;
    char                  *token_ptr = NULL ;
    char                  *tmp_token = NULL ;

    if (ME_tag == SEP_ME_TAG_NODEL && Dont_free != TRUE)
	Dont_free = TRUE;

    if (tracing&TRACE_PARM)
    {
	SIfprintf(traceptr,ERx("Trans_SEPfile> *Token = %s\n"),*Token);
	if (Dont_free)
	    SIfprintf(traceptr,ERx("                Dont_free = TRUE\n"));
	else
	    SIfprintf(traceptr,ERx("                Dont_free = FALSE\n"));
    }

    tmp_token = *Token;
    if ((token_ptr = FIND_SEPstring(tmp_token,ERx("@FILE("))) == NULL)
    {
	if (tracing&TRACE_PARM)
	    SIfprintf(traceptr,ERx("Trans_SEPfile> FIND_SEPstring is FALSE\n"));

	return (FALSE);
    }
    if (tracing&TRACE_PARM)
        SIfprintf(traceptr,ERx("Trans_SEPfile> FIND_SEPstring is TRUE\n"));

    tmp_buffer1 = SEP_MEalloc(SEP_ME_TAG_MISC, 128, TRUE, (STATUS *) NULL);
    tmp_buffer2 = SEP_MEalloc(SEP_ME_TAG_MISC, 128, TRUE, (STATUS *) NULL);

    if (token_ptr != tmp_token)
    {
	for (tmp_ptr1 = tmp_buffer1, tmp_ptr2 = tmp_token;
	     tmp_ptr2 != token_ptr; )
	    CMcpyinc(tmp_ptr2,tmp_ptr1);
    }
    else
    {
	tmp_ptr2 = token_ptr;
    }

    for (tmp_ptr3 = tmp_buffer2; CMcmpcase(tmp_ptr2,ERx(")")); )
	CMcpyinc(tmp_ptr2,tmp_ptr3);

    CMcpychar(tmp_ptr2,tmp_ptr3);
    CMnext(tmp_ptr2);
    newstr = SEP_MEalloc(SEP_ME_TAG_MISC, 128, TRUE, (STATUS *) NULL);

    if ((syserr = getLocation(tmp_buffer2,newstr,typeOfLoc)) == OK)
    {
	if (tracing&TRACE_PARM)
	{
	    SIfprintf(traceptr,ERx("Trans_SEPfile> newstr = %s\n"),newstr);
	    SIfprintf(traceptr,ERx("Trans_SEPfile> tmp_buffer1 = %s\n"),
                      tmp_buffer1);
            SIfprintf(traceptr,ERx("Trans_SEPfile> tmp_buffer2 = %s\n"),
                      tmp_buffer2);
	}
	STcat(tmp_buffer1, newstr);
	STcat(tmp_buffer1, tmp_ptr2);

        if (tracing&TRACE_PARM)
            SIfprintf(traceptr,ERx("Trans_SEPfile> tmp_buffer1 = %s\n"),
                      tmp_buffer1);

	temp_ptr = *Token;
	*Token = STtalloc(ME_tag,tmp_buffer1);
        if (Dont_free != TRUE)
	    MEfree(temp_ptr);
    }
    MEfree(tmp_buffer1);
    MEfree(tmp_buffer2);
    MEfree(newstr);

    if (tracing&TRACE_PARM)
        SIfprintf(traceptr,ERx("Trans_SEPfile> *Token = %s\n"),*Token);
 
    return (syserr);
}
예제 #15
0
/*{
** Name:	RPedit_name - edit an Ingres name
**
** Description:
**	Edit an Ingres name as specified.  The edited name is placed in a
**	global buffer.
**
** Inputs:
**	edit_type	- edit type
**			  EDNM_ALPHA	- replace special chars with '_'.
**			  EDNM_DELIMIT	- Ingres delimited name.
**			  EDNM_SLITERAL	- SQL single quoted string.
**			  else		- no edit
**	name		- name to edit
**
** Outputs:
**	edited_name	- if supplied, this buffer is filled with the edited
**			  name;  if NULL, a global buffer is used and the
**			  caller should do an STcopy() upon return.
**
** Returns:
**	pointer to the edited name
**/
char *
RPedit_name(
i4	edit_type,
char	*name,
char	*edited_name)
{
	char	tmp_name[DB_MAXNAME*2+3];
	char	*t = tmp_name;
	char	*en;
	char	*n;

	if (edited_name != NULL)
		en = edited_name;
	else
		en = Edited_Name_Buf;

	switch (edit_type)
	{
	case EDNM_ALPHA:		/* alphanumeric */
		for (n = name; *n != EOS; CMnext(n))
		{
			if (CMalpha(n) || (n != name && CMdigit(n)))
				CMcpychar(n, t);
			else
				CMcpychar(ERx("_"), t);
			CMnext(t);
		}
		*t = EOS;
		break;

	case EDNM_DELIMIT:		/* delimited */
		CMcpychar(ERx("\""), t);
		CMnext(t);
		for (n = name; *n != EOS; CMnext(n))
		{
			CMcpychar(n, t);
			if (!CMcmpcase(t, ERx("\"")))
			{
				CMnext(t);
				CMcpychar(ERx("\""), t);
			}
			CMnext(t);
		}
		CMcpychar(ERx("\""), t);
		CMnext(t);
		*t = EOS;
		break;

	case EDNM_SLITERAL:		/* SQL quoted */
		CMcpychar(ERx("'"), t);
		CMnext(t);
		for (n = name; *n != EOS; CMnext(n))
		{
			if (!CMcmpcase(n, ERx("'")))
			{
				CMcpychar(ERx("'"), t);
				CMnext(t);
			}
			CMcpychar(n, t);
			CMnext(t);
		}
		CMcpychar(ERx("'"), t);
		CMnext(t);
		*t = EOS;
		break;

	default:			/* no edit */
		t = name;
		break;
	}

	STcopy(tmp_name, en);
	return (en);
}