.ad 8
.bm 8
.fm 4
.bt $Copyright by   SAP AG, 1997$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $TOOL$add keywords$VTT01c$
.tt 2 $$$
.tt 3 $G.Grossmann$Tool$1997-10-21$
***********************************************************
.nf


    ========== licence begin  GPL
    Copyright (C) 2001 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

.fo
.nf
.sp
Module  : kw
=========
.sp
Purpose :
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :

.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :

.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :

.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : G.Grossmann
.sp
.cp 3
Created : 1997-10-21
.sp
.cp 3
Version : 1997-10-21
.sp
.cp 3
Release :  6.2 	 Date : 1997-10-21
.br
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:

.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:

.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:

.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :

#define mx_line    132
#define MAX_KW_LENGTH 18
#include <string.h>
#include <memory.h>
#include <stdio.h>
#include <fcntl.h>

FILE *INPUT;
FILE *OUTPUT;

char kw_no    [] = "cak_i_no_keyword";
char kw_max   [] = "cak_maxkeyword";
char kw_prefix[] = "cak_i_";

int  to_ebcdic[] = {0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37,
                    11, 12, 13, 14, 15, 16, 17, 18, 19, 60,
                    61, 50, 38, 24, 25, 63, 39, 28, 29, 30,
                    31, 64, 90,127,123, 91,108, 80,125, 77,
                    93, 92, 78,107, 96, 75, 97,240,241,242,
                   243,244,245,246,247,248,249,122, 94, 76,
                   126,110,111,124,193,194,195,196,197,198,
                   199,200,201,209,210,211,212,213,214,215, 
                   216,217,226,227,228,229,230,231,232,233,
                   186,224,187,176,109,121,129,130,131,132,
                   133,134,135,136,137,145,146,147,148,149,
                   150,151,152,153,162,163,164,165,166,167,
                   168,169,192, 79,208,161,  7,  4,  6,  8,
                     9, 10, 20, 21, 23, 26, 27, 32, 33, 34,
                    35, 36, 40, 41, 42, 43, 44, 48, 49, 51,
                    52, 53, 54, 56, 57, 58, 59, 62,255, 65,
                   170, 74,177,159,178,106,181,189,180,154,
                   138, 95,202,175,188,144,143,234,250,190,
                   160,182,179,157,218,155,139,183,184,185,
                   171,100,101, 98,102, 99,103,158,104,116,
                   113,114,115,120,117,118,119,172,105,237,
                   238,235,239,236,191,128,253,254,251,252,
                   173,174, 89, 68, 69, 66, 70, 67, 71,156,
                    72, 84, 81, 82, 83, 88, 85, 86, 87,140,
                    73,205,206,203,207,204,225,112,221,222,
                   219,220,141,142,223};

int toebcdic (c)
    char c;
{
 return (to_ebcdic[c]);
}

int read_line (ln)
    char *ln;
{
 int   c, len;
 char *p;
 len = 0;
 p   = ln;
 while ((len < mx_line) && ((c = getc (INPUT)) != EOF) && (c != '\n'))
   {
    *ln = (char) c;
    ln++;
    len++;
   }
 if (len == mx_line)
   {
    fprintf (stderr, "too long line");
    len = 0;
   }
 else
   if (c == '\n')
     {
      *ln = '\n';
      len++;
     }
   else
     len = 0;
 return (len);
}

int error_line (errmsg, errorline)
    char *errmsg;
    char *errorline;
{
 fprintf (stderr, "%s", errmsg);
 while (*errorline != '\n')
    fprintf (stderr, "%c", *errorline++);
 fprintf (stderr, "\n");
 exit (-1);
}

int put_line (line)
    char *line;
{
 while (*line != '\n')
     putc (*line++, OUTPUT);
 putc ('\n', OUTPUT);
}

int print_usage ()
{
 fprintf (stderr, "ikw -a <new keyword> : adds a new keyword\n");
 fprintf (stderr, "ikw -d <old keyword> : removes a keyword\n");
 fprintf (stderr, 
     "     <new keyword> ::= Identifier without cak_i_ prefix\n");
 fprintf (stderr, 
     "     <old keyword> ::= Identifier without cak_i_ prefix\n");
 fprintf (stderr, "vak00[1] at $OWN/sys/src/ak will be modified\n");
 exit (0);
}
                                  
char *getenv ();

int add_keyword (kw, kw_pos, eq_pos, kw_cnt)
                char *kw;
                int  kw_pos;
                int  eq_pos;
                int  *kw_cnt;
{     
 int  j;
 char new_line[mx_line];
 for (j = 0; j < mx_line; j++)
   new_line [j] = ' ';
 j = 0;
 while (*kw)
   new_line[kw_pos+j++] = *kw++;
 new_line[eq_pos] = '=';
 sprintf (&new_line[eq_pos+1], "%5d", ++(*kw_cnt));
 while (new_line[j] != '\0')
 j++;
 new_line[j++] = ';';
 new_line[j]   = '\n';
 put_line (new_line);
}

void main (argc, argv)
           int  argc;
           char **argv;
{
 extern char *optarg;
 char line [mx_line], in_path[mx_line], out_path[mx_line];
 char new_kw [22];
 char cmp_kw [MAX_KW_LENGTH];
 char curr_kw[22];
 char *p, *path;
 char *relver;
 int  explain;
 int  action;
 int  i, j, k, c, cnt, len, res, in_keywords, kw_cnt, max_kw;
 int  kw_found;
 int  inserted;
 int  deleted;
 int  kw_pos, eq_pos;
 int  mx_no_kw, mx_max_kw;

 if (argc != 3)
   print_usage ();

 if (0 == strcmp (argv[1], "-a"))
   {
   action  = 'a';
   }
 else 
   if (0 == strcmp (argv[1], "-d"))
     {
     action  = 'd';
     }
   else
     print_usage ();
     
 if ((len = strlen (argv[2])) > MAX_KW_LENGTH)
   {
   fprintf (stderr, "keyword too long\n");
   exit (-1);
   }
 else
   if (len == 0)
     {
     fprintf (stderr, "missing keyword\n");
     exit (-1);
     }
 strcpy (new_kw, "cak_i_");
 for (i = 0; i <= len; i++)
   {
   new_kw[i+6] = tolower (*argv[2]);
   cmp_kw[i  ] = toupper (*argv[2]++);
   }

 relver = getenv ("RELVER");
 if (relver == NULL)
   {
    fprintf (stderr, "$RELVER not found\n");
    exit (-1);
   }

 path = getenv ("OWN");
 if (path == NULL)
   {
    fprintf (stderr, "$OWN not found\n");
    exit (-1);
   }
 else
   {
    strcpy (in_path, path);

    if (strcmp (relver, "R72") >= 0)
      {
	strcat (in_path, "/sys/src/ak/vak001");
      } else {
	strcat (in_path, "/sys/src/ak/vak00");
      }

    if ((INPUT = fopen (in_path, "r")) == NULL)
      {
       fprintf (stderr, "%s not found\n", in_path);
       exit (-1);
      }
    strcpy (out_path, path);
    strcat (out_path, "/sys/src/ak/vak00.new");
    if ((OUTPUT = fopen (out_path, "w")) == NULL)
      {
       fprintf (stderr, "cannot create %s\n", out_path);
       exit (-1);
      }
   }
 mx_no_kw    = strlen (kw_no);
 mx_max_kw   = strlen (kw_max);
 kw_found    = 0;
 in_keywords = 0;
 kw_cnt      = 0;
 inserted    = 0;
 deleted     = 0;
 max_kw      = -1;
 k           = -1;
 while ((len = read_line (line)) != 0)
   {
    i   = 0;
    cnt = 0;
    if (line[0] != '&')
     {
      while (line[i] == ' ')
        {
         i++;
         cnt++;
        }
      if (!in_keywords)
        {
         if (i + mx_no_kw < len)
           if ((res = memcmp (&line[i], kw_no, mx_no_kw)) == 0) 
             {
              k           = -1;
              kw_cnt      = 0;
              in_keywords = 1;
              kw_found    = 1;
              kw_pos      = i;
              while (line[i++] != '=');        
              eq_pos = i - 1;
             }
        }
      else
        {
         if ((i + mx_max_kw < len) &&  
             ((res = memcmp (&line[i], kw_max, mx_max_kw)) == 0)) 
           in_keywords = 0;
         else
           if (kw_cnt == 0)
             {
              k++;
              if (k > 1)
                 error_line (
                    "unexpected keyword table structure ", line);
              else
                if (k == 1)
                  {
                   for (p = cmp_kw; (*p = toebcdic (*p)); p++);
                   inserted = 0;
                  }
             }
         if (in_keywords)
           if ((res = memcmp (&line[i], kw_prefix, 6)) != 0)
               error_line ("unexpected keyword : ", line);
           else
             if ((!inserted) && (action == 'a'))
              {
               p = curr_kw;
               i += 6;
               while ((*p++ = toupper(line[i++])) != ' ');
               p--;
               *p = '\0';
               if (k == 1)
                  for (p = curr_kw; (*p = toebcdic(*p)); p++);
               if ((strcmp (curr_kw, cmp_kw)) == 0)
                  error_line ("keyword already exists : ", line);
               if ((strcmp (curr_kw, cmp_kw)) > 0)
                 {
                  inserted = 1;
                  add_keyword (new_kw, kw_pos, eq_pos, &kw_cnt);
                 }
              } 
            else
              if (action == 'd')
                {
                 p = curr_kw;
                 while ((*p++ = line[i++]) != ' ');
                 p--;
                 *p = '\0';
                 if ((strcmp (curr_kw, new_kw)) == 0)
                   {
                    if (kw_cnt == 0)
                      k--;
                    deleted = 1;
                    continue;
                   }
                }
         while ((i < mx_line) && (line[i] != '='))
           i++; 
         if (i == mx_line)
           error_line ("= not found :", line);
         else
           if (i + 5 >= mx_line)
             error_line ("too long row : ", line);
         j = ++i;
         while (line[j] != '\n')
           line[j++] = ' ';  
         if (in_keywords)
           sprintf (&line[i], "%5d", ++kw_cnt);
         else
           sprintf (&line[i], "%5d", max_kw);
         if (kw_cnt > max_kw)
            max_kw = kw_cnt;
         while (line[i] != '\0')
           i++;
         line[i++] = ';';
         line[i]   = '\n';
        }
     }
   else
     {
      if ((in_keywords)  && (!inserted) &&
          (action == 'a') && (kw_cnt > 0))
         {
          inserted = 1;
          add_keyword (new_kw, kw_pos, eq_pos, &kw_cnt);
         }
      max_kw = kw_cnt;
      kw_cnt = 0;
     }
   put_line (line);
   }
 fclose (INPUT); 
 fclose (OUTPUT);
 if (!kw_found)
   fprintf (stderr, "invalid input file, no keyword found\n");
 else
   if ((action == 'd') && (!deleted))
     fprintf (stderr, "keyword %s not found\n", new_kw);
   else
     if ((action == 'a') && (!inserted))
       fprintf (stderr, "keyword %s not inserted\n", new_kw);
     else
       {
        if (action == 'a')
           fprintf (stderr, "keyword %s inserted\n", new_kw);
        else
           fprintf (stderr, "keyword %s removed\n", new_kw);
        if( unlink( in_path ) == -1 )
           fprintf( stderr, "Could not delete %s", in_path );        
        else if ( rename( out_path, in_path ) )
               fprintf (stderr, "could not rename file %s to %s\n", 
                 out_path, in_path);
       }
}

.CM *-END-* code ----------------------------------------
.SP 2
***********************************************************
.PA
