/*!**************************************************************************

  module      : vpc16c.c

  -------------------------------------------------------------------------

  responsible : BurkhardD

  special area:
  description : Code Analyse and generation of FETCH Commands
                Contains functions old Ascii functionality only used
                by the Precompiler

  last changed:
  see also    :

  change history :

        D025086 07-12-2000 Created for UNICODE Support. New parser etc.

  -------------------------------------------------------------------------





    ========== licence begin  GPL
    Copyright (c) 2000-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end




*****************************************************************************/

/*==================================================================*
 *  INCLUDES                                                        *
 *==================================================================*/

#include "gpr00.h"
#include "gpr05.h"
#include "vpr01SQL.h"
#include "vpr01Cursor.h"

/*==================================================================*
 *  DECLARATIONS                                                    *
 *==================================================================*/

/*==================================================================*
 *  EXTERNAL PROTOTYPES                                             *
 *==================================================================*/

/*==================================================================*
 *  EXPORTED FUNCTIONS                                              *
 *==================================================================*/

/*==================================================================*
 *  FUNCTION PROTOTYPES                                             *
 *==================================================================*/

/*==================================================================*
 *  CODE                                                            *
 *==================================================================*/

void pc16cSearchFetch(sqlcatype *sqlca, sqlxatype *sqlxa, sqlgaentry *ga, tsp00_KnlIdentifier ergn, BOOLEAN *descr, int *intopos)
{
  int pos;
  int posi;
  tsp00_Int4 sympos;
  tsp00_Int4 symlen;
  int len;
  int anf;
  int cnt;
  int plus;
  tpr00_Symbol symb;
  tpr_macroline mline;
  tsp1_part_ptr part_ptr;
  int macrono;
  p03find_part((*sqlca).sqlrap , 3 , &part_ptr);
  *descr = 0;
  memset(ergn, ' ', sizeof(tsp00_KnlIdentifier));
  *intopos = 0;
  (*sqlca).sqlcxap->xacfetspec = CPR_FE_EMPTY;
  if (part_ptr != NULL) {
    tsp00_Uint1 *sp1p_buf_F = part_ptr->sp1p_buf;
    tsp1_part_header *sp1p_part_header_F = &part_ptr->sp1p_part_header;
    sqlratype *sqlrap = sqlca->sqlrap;;
    if (sp1p_part_header_F->sp1p_buf_len > 0) {
      pos = 1;
      p05nextsymbol((char*)sp1p_buf_F , sp1p_part_header_F->sp1p_buf_len , pos , &sympos , &symlen , &symb);
      if (p05eq((unsigned char*)"FETCH " , (char*)sp1p_buf_F , sympos , 6)
	  || p05eq((unsigned char*)"MFETCH " , (char*)sp1p_buf_F , sympos , 7)
	  && sqlrap->ralang == CPR_LA_CALL) {
	sqlcxatype *sqlcxap = sqlca->sqlcxap;
	sqlcxap->xacfetspec = CPR_FE_FETCH;
	pos = sympos + symlen;
	p05nextsymbol((char*)sp1p_buf_F , sp1p_part_header_F->sp1p_buf_len , pos , &sympos , &symlen , &symb);
	switch (sp1p_buf_F[sympos-1]) {
	case 'F' :
	case 'f' :
	  if (p05eq((unsigned char*)"FIRST ", (char*)sp1p_buf_F , sympos , 6)) {
	    sqlcxap->xacfetspec = CPR_FE_FIRST;
	    pos = sympos + symlen;
	    p05nextsymbol((char*)sp1p_buf_F , sp1p_part_header_F->sp1p_buf_len , pos , &sympos , &symlen , &symb);
	  }
	  break;
	case 'L' :
	case 'l' :
	  if (p05eq((unsigned char*)"LAST ", (char*)sp1p_buf_F , sympos , 5)) {
	    sqlcxap->xacfetspec = CPR_FE_LAST;
	    pos = sympos + symlen;
	    p05nextsymbol((char*)sp1p_buf_F , sp1p_part_header_F->sp1p_buf_len , pos , &sympos , &symlen , &symb);
	  }
	  break;
	case 'N' :
	case 'n' :
	  if (p05eq((unsigned char*)"NEXT ", (char*)sp1p_buf_F , sympos , 5)) {
	    sqlca->sqlcxap->xacfetspec = CPR_FE_NEXT;
	    pos = sympos + symlen;
	    p05nextsymbol((char*)sp1p_buf_F , sp1p_part_header_F->sp1p_buf_len , pos , &sympos , &symlen , &symb);
	  }
	  break;
	case 'S' :
	case 's' :
	  if (p05eq((unsigned char*)"SAME ", (char*)sp1p_buf_F , sympos , 5)) {
	    sqlcxap->xacfetspec = CPR_FE_SAME;
	    pos = sympos + symlen;
	    p05nextsymbol((char*)sp1p_buf_F , sp1p_part_header_F->sp1p_buf_len , pos , &sympos , &symlen , &symb);
	  }
	  break;
	case 82 :
	case 114 :
	case 65 :
	case 97 :
	  if (p05eq((unsigned char*)"RELATIVE ", (char*)sp1p_buf_F , sympos , 9)
	      || p05eq((unsigned char*)"ABSOLUTE ", (char*)sp1p_buf_F , sympos , 9)) {
	    sqlcxap->xacfetspec = CPR_FE_POSC;
	    pos = sympos + symlen;
	    while ( sp1p_buf_F[pos-1] == ' ')
	      pos = pos + 1;
	    if (sp1p_buf_F[pos-1] == '(') {
	      cnt = 0;
	      do {
		if (sp1p_buf_F[pos-1] == '(') {
		  cnt = cnt + 1;
		}
		else {
		  if (sp1p_buf_F[pos-1] == ')') {
		    cnt = cnt + -1;
		  }
		  else {
		    if (sp1p_buf_F[pos-1] == CPR_PARAMCHR
			|| sp1p_buf_F[pos-1] == CPR_PREPARECHR) {
		      sqlcxap->xacfetspec = CPR_FE_POSV;
		    }
		  }
		}
		pos = pos + 1;
	      }
	      while (!(cnt == 0 || pos >= sp1p_part_header_F->sp1p_buf_len));
	      p05nextsymbol((char*)sp1p_buf_F , sp1p_part_header_F->sp1p_buf_len , pos , &sympos , &symlen , &symb);
	    }
	    else {
	      p05nextsymbol((char*)sp1p_buf_F , sp1p_part_header_F->sp1p_buf_len , pos , &sympos , &symlen , &symb);
	      if (symb == CPR_S_PARAMETER_NAME) {
		pos = sympos + symlen;
		sqlcxap->xacfetspec = CPR_FE_POSV;
		p05nextsymbol((char*)sp1p_buf_F , sp1p_part_header_F->sp1p_buf_len , pos , &sympos , &symlen , &symb);
	      }
	      else {
		if (symb == CPR_S_PLUS
		    || symb == CPR_S_MINUS) {
		  pos = sympos + symlen;
		  p05nextsymbol((char*)sp1p_buf_F , sp1p_part_header_F->sp1p_buf_len , pos , &sympos , &symlen , &symb);
		}
		if ((int ) symb == CPR_S_UNSIGNED_INTEGER) {
		  pos = sympos + symlen;
		  p05nextsymbol((char*)sp1p_buf_F , sp1p_part_header_F->sp1p_buf_len , pos , &sympos , &symlen , &symb);
		}
	      }
	    }
	  }
	  break;
	case 'P' :
	case 'p' :
	  if (p05eq((unsigned char*)"PREV ", (char*)sp1p_buf_F, sympos, 5)) {
	    sqlcxap->xacfetspec = CPR_FE_PREV;
	    pos = sympos + symlen;
	    p05nextsymbol((char*)sp1p_buf_F, sp1p_part_header_F->sp1p_buf_len, pos, &sympos, &symlen, &symb);
	  }
	  else {
	    if (p05eq((unsigned char*)"POS ", (char*)sp1p_buf_F, sympos, 3) && symlen == 3) {
	      sqlca->sqlcxap->xacfetspec = CPR_FE_POSC;
	      pos = sympos + symlen;
	      while (sp1p_buf_F[pos-1] == bsp_c1)
		pos = pos + 1;
	      if (sp1p_buf_F[pos-1] == '(') {
		cnt = 0;
		do {
		  if (sp1p_buf_F[pos-1] == '(') {
		    cnt = cnt + 1;
		  }
		  else {
		    if (sp1p_buf_F[pos-1] == ')') {
		      cnt = cnt + -1;
		    }
		    else {
		      if (sp1p_buf_F[pos-1] == CPR_PARAMCHR
			  || sp1p_buf_F[pos-1] == CPR_PREPARECHR) {
			sqlcxap->xacfetspec = CPR_FE_POSV;
		      }
		    }
		  }
		  pos = pos + 1;
		} while (!(cnt == 0 || pos >= sp1p_part_header_F->sp1p_buf_len));
		p05nextsymbol((char*)sp1p_buf_F, sp1p_part_header_F->sp1p_buf_len, pos, &sympos, &symlen, &symb);
	      }
	    }
	  }
	  break;
	default :
	  break;
	}
	if (!p05eq((unsigned char*)"INTO ", (char*)sp1p_buf_F, sympos, 5)
	    && !p05eq((unsigned char*)"USING ", (char*)sp1p_buf_F, sympos, 6)) {
	  macrono = 0;
	  if (sp1p_buf_F[sympos-1] == CPR_MACROCHR
	      && sp1p_buf_F[sympos-2] != '"') {
	    sqlkaentry *ka = sqlxa->sqlkap+sqlxa->xakano-1;
	    anf = sympos;
	    posi = sympos;
	    p16macrosubstitution(sqlca, sqlxa, ga, &anf , &posi , &macrono , mline);
	    sympos = posi;
	    ka->kamacro = 1;
	    pos = sympos;
	    p05nextsymbol((char*)sp1p_buf_F, sp1p_part_header_F->sp1p_buf_len, pos, &sympos, &symlen, &symb);
	  }
	  len = 0;
	  pos = sympos;
	  if (memcmp(ga->gaxuserrec.xu_dblang, bsp_c64, sizeof(ga->gaxuserrec.xu_dblang)) == 0
	      && sp1p_buf_F[sympos-2] != '"'
	      && macrono == 0) {
	    p05up1casebuf(sp1p_buf_F, sympos, sympos+symlen);
	  }
	  do {
	    if (sp1p_buf_F[pos-1] == '"'
		&& sp1p_buf_F[pos] == '"') {
	      pos = pos + 1;
	    }
	    len = len + 1;
	    ergn[len-1] = sp1p_buf_F[pos-1];
	    pos = pos + 1;
	  } while (!(len >= sizeof(tsp00_KnlIdentifier)
		     || pos >= sympos + symlen));
	  if (ergn[0] == CPR_PARAMCHR) {
	    /* Cursorname kommt mit Hostvariable */
	    if (sqlxa->xaSQLDesc && sqlxa->xaSQLDesc->CursorDesc) {
	      tpr01_CursorDesc *CursorDesc = sqlxa->xaSQLDesc->CursorDesc;
	      if (CursorDesc) {
		tpr05_String tmpString;
		tmpString.allocationType = constant_epr05;
                pr05IfCom_String_InitString(&tmpString, (char*)ergn, sizeof(ergn), sp77encodingAscii, constant_epr05);
                pr05IfCom_String_Convert ( &tmpString, &(CursorDesc->CursorNameDesc.CursorName));
		len = tmpString.cbLen;
		tmpString.rawString[len+1]='\0';
		if (len > symlen) {
		  anf = sympos;
		  pos = sympos;
		  plus = len - symlen;
		  p16addspacevarpart(sqlca, sqlxa, ga, &anf , &pos , &plus);
		}
		else {
		  memset(&sp1p_buf_F[sympos-1], ' ', symlen);
		}
		memcpy(&sp1p_buf_F[sympos-1], ergn, len);
		symlen = len;
	      }
	    }
	  }
	  if (sp1p_buf_F[sympos-2] != '"' && macrono < 100) {
	    anf = sympos;
	    pos = sympos;
	    plus = 1;
	    p16addspacevarpart(sqlca, sqlxa, ga, &anf , &pos , &plus);
	    sp1p_buf_F[sympos-1] = (unsigned char)'"';
	    anf = sympos + symlen + 1;
	    pos = anf;
	    plus = 1;
	    p16addspacevarpart(sqlca, sqlxa, ga, &anf , &pos , &plus);
	    sp1p_buf_F[anf + -1] = (unsigned char)'"';
	  }
	  pos = sympos + symlen + 2;
	  p05nextsymbol((char*)sp1p_buf_F , sp1p_part_header_F->sp1p_buf_len , pos , &sympos , &symlen , &symb);
	}
	*intopos = sympos;
	if (p05eq((unsigned char*)"USING ", (char*)sp1p_buf_F, sympos, 6) ||
	    p05eq((unsigned char*)"INTO ", (char*)sp1p_buf_F, sympos, 5)) {
	  pos = sympos + symlen;
	  p05nextsymbol((char*)sp1p_buf_F, sp1p_part_header_F->sp1p_buf_len, pos, &sympos, &symlen, &symb);
	  if (p05eq((unsigned char*)"DESCRIPTOR  ", (char*)sp1p_buf_F, sympos, 10)) {
	    *descr = 1;
	  }
	}
      }
    }
  }
}

