/*!================================================================
 module:    vpc14Fetch.c

 responsible: ThomasS
 
 special area:   
 
 description: Stueckweises Lesen von Long-Spalten
 
 see:  
 



    ========== 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                                                        *
 *==================================================================*/

#define PREPSTMT
#include "vpc14Fetch.h"
#include "gpc001.h" 

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

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

void p10rmspace (tpc_partbuffer*, char, char, tsp00_Int4, tsp00_Int4,
		 tsp00_Int4*, tsp00_Int4*);

void p19sqlfaallocate (tsp00_Int2*);

void p10getkeyword (tpc_globals*, tpc_partbuffer*, int*);

void p14bcusearch (tpc_globals*, tpc_partbuffer*, int);

void p14getname (void (*next_symbol) (tpc_globals*, tpc_partbuffer*,
				     int),
		 tpc_globals*, tsp00_KnlIdentifier, int*, tsp00_Int2*,
		 tsp00_Int2*);

void p14_add_prind (tpc_globals*, int*, tsp00_Int2*);

void p14_hostv_get (void (*next_symbol) (tpc_globals*, tpc_partbuffer*,
				     int),
		    tpc_globals*, tsp00_Int2*, tsp00_Int2*);

void p05inttochr12 (int, tsp00_C12);

void p11wrerrorlisting (tpc_globals*, tpc_pre_errors);

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

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

void p14putval (void (*next_symbol) (tpc_globals* p1, tpc_partbuffer* p2,
				     int p3), 
		tpc_globals* apc, int* keyind, tsp00_Int4* pos) {
  int n;
  int f_pos;
  tsp00_Int4 stmlen;
  tsp00_Int2 macro;
  tsp00_Int2 param;
  tsp00_KnlIdentifier cursorn;
  int cursorl;
  tpr_scannertype rscan;
  tsp00_Int2 va1ix;
  tsp00_C12 ch12;
  int no;
  tsp00_Int2 CursorNameIndex;
  int prind;
  tsp00_Int2 paix;
  int ndcuindex;
 
  if (apc->sqlca.sqlrap->ralang == cpr_la_c) {
    /* if fuer umstellung next_symbol */
    while  ((apc->pcscan.symb != cpr_s_eof) && (apc->pcscan.symb != cpr_s_bufeof))
      (*next_symbol) (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
  }
  apc->pcscan.symb = cpr_s_unknown;
  apc->sqlxa.xadescpos = 0;
  apc->sqlxa.xadesclen = 0;
  *keyind = 0;
  f_pos = 0;
  apc->pcan.ancomtyp = cpr_com_sql_putval;
  p10rmspace (apc->pccmdpart.partbufp,  cpr_quotsym, cpr_quotsym,
	      1, apc->pccmdpart.part1len-1, &apc->pccmdpart.part1len, &stmlen);
  if (apc->sqlca.sqlrap->ralang != cpr_la_cobol)
    (*apc->pccmdpart.partbufp)[apc->pccmdpart.part1len-1] = '\0';
  /* fetch command */
  apc->pcscan.syposacc = 1;
  next_symbol (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
  p19sqlfaallocate (&apc->pcfa);
  /* fetch spec oder ergname */
  next_symbol (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
  p10getkeyword (apc, apc->pccmdpart.partbufp, keyind);
#ifndef PREPSTMT
  p14bcusearch (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
#endif
  if (*keyind == cpc_i_pos) {
    n = 0;
    do {
      (*next_symbol) (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
      if (apc->pcscan.symb == cpr_s_leftpar)
	n++;
      if (apc->pcscan.symb == cpr_s_parameter_name)
	f_pos = cpc_i_pos;
      if (apc->pcscan.symb == cpr_s_rightpar)
	n--;
    } while (!((n == 0) || (apc->pcscan.symb == cpr_s_eof) || 
	       (apc->pcscan.symb == cpr_s_bufeof)));
  }
  if ((*keyind != cpc_i_using) && (*keyind != cpc_i_into)) {
    /* ergname oder fetchspec */
    if ((*keyind != cpc_i_next) &&
	(*keyind != cpc_i_prev) &&
	(*keyind != cpc_i_last) &&
	(*keyind != cpc_i_first) &&
        (*keyind != cpc_i_pos)) {
      p14getname (next_symbol, apc, cursorn, &cursorl, &macro,
                  &param);
      paix = 0;
      p14_add_prind  (apc, &prind, &paix);
      apc->pcpr = prind;
      (*(apc->sqlxa).sqlprp)[apc->pcpr-1].prarea = cpr_in_sqlst;
      (*(apc->sqlxa).sqlprp)[apc->pcpr-1].prDescribe = cpr_is_false;
      if (param == cpr_is_true) {
	apc->pcan.ancomtyp = cpr_com_sql_putval;
	apc->pcan.ancheck = cpc_ch_no;
	apc->pcusage.uscom = cpc_usage_empty;
	rscan = apc->pcscan;
	p14_hostv_get (next_symbol, apc, &CursorNameIndex, &va1ix);
	no = va1ix;
	p05inttochr12 (no, ch12);
	memcpy (cursorn, bsp_knl_identifier, sizeof (bsp_knl_identifier)-1); /* PTS 1106786 */
	cursorn[0] = ':';
	memcpy (&cursorn[1], &ch12[1], 4);
	/* PTS 1104482 */
	ndcuindex = apc->pcsqlva.ndcnt;
	if (ndcuindex > 0) {
	  (*apc->pcsqlva.ndtabp)[ndcuindex-1].ndkano = apc->pcka+1;
	}
	apc->pcscan = rscan;
	memcpy ((*apc->sqlxa.sqlprp)[apc->pcpr-1].prCursorName, 
		cursorn, sizeof (cursorn));
	(*apc->sqlxa.sqlprp)[apc->pcpr-1].prCursorNameIndex = CursorNameIndex;
      } else {
	memcpy ((*apc->sqlxa.sqlprp)[apc->pcpr-1].prCursorName, 
		cursorn, sizeof (cursorn));
      }
      next_symbol (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
      p10getkeyword (apc, apc->pccmdpart.partbufp, keyind);
    } else {
      paix = 0;
      p14_add_prind  (apc, &prind, &paix);
      apc->pcpr = prind;
    }
    *pos = apc->pcscan.syposacc;
    if ((*keyind != cpc_i_using) && (*keyind != cpc_i_into)) {
      /*  using/ into    */
      next_symbol (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
      p10getkeyword (apc, apc->pccmdpart.partbufp, keyind);
    }
    if (*keyind != cpc_i_descriptor) {
      next_symbol (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
      p10getkeyword (apc, apc->pccmdpart.partbufp, keyind);
    }
    if (*keyind == cpc_i_descriptor) {
      /*        sqlprp^[pcpr].prDescribe := cpr_is_true; */
      if (f_pos == cpc_i_pos) {
	p11wrerrorlisting (apc, cpc_invalid_sql_command);
      } else {
	/* default :descriptor, delete ':' */
	n = apc->pcscan.syposacc;
	while ((*apc->pccmdpart.partbufp)[n-1] == bsp_c1) {
	  n = n + 1;
	}
	if ((*apc->pccmdpart.partbufp)[n-1] == cpr_paramchr) {
	  (*apc->pccmdpart.partbufp)[n-1] = bsp_c1;
	}
	apc->sqlxa.xadescpos = n;
	apc->sqlxa.xadesclen = apc->pccmdpart.part1len - apc->sqlxa.xadescpos;
      }
    }
    apc->pcscan.symb = cpr_s_eof;
    apc->pcscan.syposacc = 1;
    if ((apc->sqlca.sqlrap->rakamode == cpr_kind_internal) &&
	(apc->pccmdpart.part1len - n == 0)) {
      apc->sqlxa.xadescpos = -1;
    }
  } else {
    paix = 0;
    p14_add_prind  (apc, &prind, &paix);
    apc->pcpr = prind;
  }
}


void p14getval (void (*next_symbol) (tpc_globals* p1, tpc_partbuffer* p2,
				     int p3), 
		tpc_globals* apc, int* keyind, tsp00_Int4* pos) {
  int n;
  int f_pos;
  tsp00_Int4 stmlen;
  tsp00_Int2 macro;
  tsp00_Int2 param;
  tsp00_KnlIdentifier cursorn;
  int cursorl;
  tpr_scannertype rscan;
  tsp00_Int2 va1ix;
  tsp00_C12 ch12;
  int no;
  tsp00_Int2 CursorNameIndex;
  int prind;
  tsp00_Int2 paix;
  int ndcuindex;
 
  if (apc->sqlca.sqlrap->ralang == cpr_la_c) {
    /* if fuer umstellung next_symbol */
    while  ((apc->pcscan.symb != cpr_s_eof) && (apc->pcscan.symb != cpr_s_bufeof))
      (*next_symbol) (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
  }
  apc->pcscan.symb = cpr_s_unknown;
  apc->sqlxa.xadescpos = 0;
  apc->sqlxa.xadesclen = 0;
  *keyind = 0;
  f_pos = 0;
  apc->pcan.ancomtyp = cpr_com_sql_getval;
  p10rmspace (apc->pccmdpart.partbufp,  cpr_quotsym, cpr_quotsym,
	      1, apc->pccmdpart.part1len-1, &apc->pccmdpart.part1len, &stmlen);
  if (apc->sqlca.sqlrap->ralang != cpr_la_cobol)
    (*apc->pccmdpart.partbufp)[apc->pccmdpart.part1len-1] = '\0';
  /* fetch command */
  apc->pcscan.syposacc = 1;
  next_symbol (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
  p19sqlfaallocate (&apc->pcfa);
  /* fetch spec oder ergname */
  next_symbol (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
  p10getkeyword (apc, apc->pccmdpart.partbufp, keyind);
#ifndef PREPSTMT
  p14bcusearch (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
#endif
  if (*keyind == cpc_i_pos) {
    n = 0;
    do {
      (*next_symbol) (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
      if (apc->pcscan.symb == cpr_s_leftpar)
	n++;
      if (apc->pcscan.symb == cpr_s_parameter_name)
	f_pos = cpc_i_pos;
      if (apc->pcscan.symb == cpr_s_rightpar)
	n--;
    } while (!((n == 0) || (apc->pcscan.symb == cpr_s_eof) || 
	       (apc->pcscan.symb == cpr_s_bufeof)));
  }
  if ((*keyind != cpc_i_using) && (*keyind != cpc_i_into)) {
    /* ergname oder fetchspec */
    if ((*keyind != cpc_i_next) &&
	(*keyind != cpc_i_prev) &&
	(*keyind != cpc_i_last) &&
	(*keyind != cpc_i_first) &&
        (*keyind != cpc_i_pos)) {
      p14getname (next_symbol, apc, cursorn, &cursorl, &macro,
                  &param);
      paix = 0;
      p14_add_prind  (apc, &prind, &paix);
      apc->pcpr = prind;
      (*(apc->sqlxa).sqlprp)[apc->pcpr-1].prarea = cpr_in_sqlst;
      (*(apc->sqlxa).sqlprp)[apc->pcpr-1].prDescribe = cpr_is_false;
      if (param == cpr_is_true) {
	apc->pcan.ancomtyp = cpr_com_sql_getval;
	apc->pcan.ancheck = cpc_ch_no;
	apc->pcusage.uscom = cpc_usage_empty;
	rscan = apc->pcscan;
	p14_hostv_get (next_symbol, apc, &CursorNameIndex, &va1ix);
	no = va1ix;
	p05inttochr12 (no, ch12);
	memcpy (cursorn, bsp_knl_identifier, sizeof (bsp_knl_identifier)-1); /* PTS 1106786 */
	cursorn[0] = ':';
	memcpy (&cursorn[1], &ch12[1], 4);
	/* PTS 1104482 */
	ndcuindex = apc->pcsqlva.ndcnt;
	if (ndcuindex > 0) {
	  (*apc->pcsqlva.ndtabp)[ndcuindex-1].ndkano = apc->pcka+1;
	}
	apc->pcscan = rscan;
	memcpy ((*apc->sqlxa.sqlprp)[apc->pcpr-1].prCursorName, 
		cursorn, sizeof (cursorn));
	(*apc->sqlxa.sqlprp)[apc->pcpr-1].prCursorNameIndex = CursorNameIndex;
      } else {
	memcpy ((*apc->sqlxa.sqlprp)[apc->pcpr-1].prCursorName, 
		cursorn, sizeof (cursorn));
      }
      next_symbol (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
      p10getkeyword (apc, apc->pccmdpart.partbufp, keyind);
    } else {
      paix = 0;
      p14_add_prind  (apc, &prind, &paix);
      apc->pcpr = prind;
    }
    *pos = apc->pcscan.syposacc;
    if ((*keyind != cpc_i_using) && (*keyind != cpc_i_into)) {
      /*  using/ into    */
      next_symbol (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
      p10getkeyword (apc, apc->pccmdpart.partbufp, keyind);
    }
    if (*keyind != cpc_i_descriptor) {
      next_symbol (apc, apc->pccmdpart.partbufp, apc->pccmdpart.part1len);
      p10getkeyword (apc, apc->pccmdpart.partbufp, keyind);
    }
    if (*keyind == cpc_i_descriptor) {
      /*        sqlprp^[pcpr].prDescribe := cpr_is_true; */
      if (f_pos == cpc_i_pos) {
	p11wrerrorlisting (apc, cpc_invalid_sql_command);
      } else {
	/* default :descriptor, delete ':' */
	n = apc->pcscan.syposacc;
	while ((*apc->pccmdpart.partbufp)[n-1] == bsp_c1) {
	  n = n + 1;
	}
	if ((*apc->pccmdpart.partbufp)[n-1] == cpr_paramchr) {
	  (*apc->pccmdpart.partbufp)[n-1] = bsp_c1;
	}
	apc->sqlxa.xadescpos = n;
	apc->sqlxa.xadesclen = apc->pccmdpart.part1len - apc->sqlxa.xadescpos;
      }
    }
    apc->pcscan.symb = cpr_s_eof;
    apc->pcscan.syposacc = 1;
    if ((apc->sqlca.sqlrap->rakamode == cpr_kind_internal) &&
	(apc->pccmdpart.part1len - n == 0)) {
      apc->sqlxa.xadescpos = -1;
    }
  } else {
    paix = 0;
    p14_add_prind  (apc, &prind, &paix);
    apc->pcpr = prind;
  }
}



