/***************************************************************/
/* module   : array.c                                          */
/* date     : 28/07/92                                         */
/* auteurs  : RENAUD & VENOT & PITON                           */
/***************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <varargs.h>

#include PAT_H
#include "libpat_l.h"


/* ###--------------------------------------------------------------### */
/* function     : ARRAY                                                 */
/* description  : Create a PAGRP structure and the referenced PAIOL	*/
/* called func. : Erreur, SplitIdent, KillEsp, CheckIdent, TraiterChaine*/
/*          CheckWidth, FindIdent, EmpileParam, CheckSeparate, 		*/
/*          CheckFormat, CheckType, DefileParam, DupPaiol, CreatePagrp	*/
/* ###--------------------------------------------------------------### */


void ARRAY (va_alist)
va_dcl
{
va_list pa;
char    *param;
char     buffer [80];
char     buffer_anx [64];
char     name [64];
char     blk;
char     base;
char     i_o;
short    dim;
int      tmp_ind_paiol;
struct   alpha_num decomp;

    if (racine_paseq == NULL)
      Erreur ("ARRAY must declare output file's name first\n");

    if (GNP_TAB_PAIOL_CREE == GNP_ACTIF)
      Erreur ("ARRAY already in descriptive part\n");

    va_start(pa);

    param = va_arg(pa, char *);
    if (param == NULL) 
       Erreur ("ARRAY needs any parameters\n");
    strcpy (buffer,param);
    KillEsp (buffer);

    if (*buffer == ':')
      Erreur ("ARRAY must have an element at least\n");
 
    sp_pile_param = 0;
    while ( *buffer != ':') 
    {
        strcpy     (buffer,param);
        SplitIdent (buffer,buffer_anx);
        CheckIdent (buffer);
        if (strlen (buffer_anx) != 0) 
        {
            TraiterChaine (buffer_anx, &decomp);
            CheckWidth (&decomp);
            if (strlen(decomp.alpha) ==0) 
                sprintf(buffer,"%s %s",buffer,decomp.gauche);
            else 
                Erreur ("ARRAY must separate each element of a vector\n");
        }
        else 
            if  ( FindIdent (buffer,hash_pagrp) != -1) 
                Erreur ("ARRAY yet declared identifier as a pagrp\n");
        EmpileParam(param);


        param = va_arg(pa, char *);
        if (param == NULL) 
           Erreur ("ARRAY needs more parameters\n");
        strcpy (buffer,param);
        KillEsp (buffer);
    }

    blk = CheckSeparate(buffer);

    dim = sp_pile_param;

    param = va_arg(pa, char *);
    if (param == NULL) 
      Erreur ("ARRAY needs more parameters\n");
    strcpy (buffer,param);
    base = CheckFormat (buffer);

    param     = va_arg(pa, char *);
    if (param == NULL) 
      Erreur ("ARRAY needs more parameters\n");
    strcpy (buffer,param);
    i_o = CheckType (buffer);

    param = va_arg(pa, char *);
    if (param == NULL) 
      Erreur ("ARRAY needs group name\n");
    strcpy (name,param);
    if  ( FindIdent (name,hash_paiol) != -1) 
        Erreur ("ARRAY duplicate declared identifier\n");
    if  ( FindIdent (name,hash_pagrp) != -1) 
        Erreur ("ARRAY yet declared identifier as a pagrp\n");

    param = va_arg(pa, char *);
    if (param != NULL) 
        Erreur ("ARRAY NULL parameter expected\n");

    va_end (pa);

    sp_file_param = 0;

/* test si les parametres sont de meme mode 'O', 'R', 'S' ou non declares */
    while (sp_file_param < sp_pile_param) 
    {
        param = DefileParam();
	strcpy      (buffer_anx,param);
	SplitIdent  (buffer_anx,buffer);
	KillEsp     (buffer_anx);

        sprintf (buffer, "%s %d", name, GNP_PARAM_COURANT);

        switch (i_o) 
        {
          case 'I': case 'T' : 
          {
             if  ( FindIdent (buffer_anx,hash_paiol) != -1) 
                 Erreur ("ARRAY duplicate declared identifier\n");
             DupPaiol (-1,base,buffer_anx,buffer,i_o,blk);
             break;
          }
          case 'O': case 'R': case 'S' : 
          {
             tmp_ind_paiol = FindIdent (buffer_anx,hash_paiol);
             if  ( tmp_ind_paiol == -1)
                  DupPaiol (-1,base,buffer_anx,buffer,i_o,blk);
             else 
             {
               if (((struct paiol*)tab_ident[tmp_ind_paiol].pointeur)->MODE != i_o) 
                  Erreur ("ARRAY /port mode not matched\n");
               DupPaiol (tmp_ind_paiol,base,buffer_anx,buffer,i_o,blk);
               break;
             }
          }
        }
    }
    CreatePagrp (name,dim,-1,GNP_VECTEUR_VIRTUEL);
}
