From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 14-JUN-1989 20:06
To:	MRGATE::"ARISIA::EVERHART"
Subj:	Termcap to Termtable Conversion Program (2 of 3)

Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Wed, 14 JUN 89 15:45:04 PDT
Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Wed, 14 Jun 89 15:18:22 PDT
Received: by ucbvax.Berkeley.EDU (5.61/1.36)
	id AA21244; Wed, 14 Jun 89 15:05:00 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 14 Jun 89 19:06:13 GMT
From: mtxinu!sybase!forrest%sybase.com@ucbvax.Berkeley.EDU
Organization: Sybase, Inc.
Subject: Termcap to Termtable Conversion Program (2 of 3)
Message-Id: <4670@sybase.sybase.com>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com


+-+-+-+ Beginning of part 2 +-+-+-+
X`009`125
X`009if ((ofp = fopen("termtable.txt","w")) == NULL)
X`009`123
X`009`009perror("termtable.txt");
X`009`009exit(1);
X`009`125
X`009if ((efp = fopen(ERRLOG,"w")) == NULL)
X`009`123
X`009`009perror(ERRLOG);
X`009`009exit(1);
X`009`125
X
X`009while (do_entry(ifp, input_line1, NO_TC) != EOF);
X`009if (do_end)
X`009`009fprintf(ofp,"END\n");
X`009fclose(ifp);
X`009fclose(ofp);
X`009fclose(efp);
X`009if (tcfp != NULL)
X`009`009fclose(tcfp);
X`125
X
X/*
X** Process an entry for a terminal in termcap. This might be because
X** we're processing a new entry or because we're looking for a terminal
X** specified in a tc capability. The actual purpose is shown in the
X** third argument.
X*/
X
Xdo_entry(ifp, input_line, purpose)
X`009FILE *ifp;
X`009char *input_line;
X`009int purpose;
X`123
X`009register char *beg_cap;
X`009register struct table_item *t_ptr;
X`009char curr_term_name[TERMNAME_LEN];
X`009char *get_next_cap();
X`009struct table_item *binary();
X
X`009for (;;)
X`009`123
X`009`009if (fgets(input_line, LINE_LEN, ifp) == NULL)
X`009`009`009return(EOF);
X
X`009`009/* ignore comment lines */
X`009`009if (*input_line == '#')
X`009`009`009continue;
X
X`009`009beg_cap = input_line;
X
X`009`009/*
X`009`009** If we're not finding a terminal as a result of a
X`009`009** tc command and we're at the first line in an entry
X`009`009*/
X
X`009`009if ((purpose != TC) && (!isspace(*beg_cap)))
X`009`009`123
X`009`009`009char *curr_ptr, *term_ptr;
X`009`009`009int did_dash, did_plus;
X
X`009`009`009if (do_end)
X`009`009`009`009fprintf(ofp,"END\n");
X
X`009`009`009/* get the terminal name */
X`009`009`009get_term_name(beg_cap,curr_term_name,LONGNAME);
X`009`009`009curr_ptr = curr_term_name;
X`009`009`009term_ptr = term_name;
X`009`009`009did_dash = did_plus = 0;
X`009`009`009while (*curr_ptr)
X`009`009`009`009switch (*curr_ptr)
X`009`009`009`009`123
X`009`009`009`009case '-':
X`009`009`009`009`009curr_ptr++;
X`009`009`009`009`009*term_ptr++ = '_';
X`009`009`009`009`009if (did_dash == 0)
X`009`009`009`009`009`123
V`009`009`009`009`009`009fprintf(efp,"%s : Changed dash(s) to '_'\n",curr_term
X_name);
X`009`009`009`009`009`009did_dash = 1;
X`009`009`009`009`009`125
X`009`009`009`009`009break;
X`009`009`009`009case '+':
X`009`009`009`009`009curr_ptr++;
X`009`009`009`009`009*term_ptr++ = 'p';
X`009`009`009`009`009*term_ptr++ = 'l';
X`009`009`009`009`009*term_ptr++ = 'u';
X`009`009`009`009`009*term_ptr++ = 's';
X`009`009`009`009`009if (did_plus == 0)
X`009`009`009`009`009`123
V`009`009`009`009`009`009fprintf(efp,"%s : Changed + to plus\n",curr_term_name
X);
X`009`009`009`009`009`009did_plus = 1;
X`009`009`009`009`009`125
X`009`009`009`009`009break;
X`009`009`009`009default:
X`009`009`009`009`009*term_ptr++ = *curr_ptr++;
X`009`009`009`009`009break;
X`009`009`009`009`125
X`009`009`009*term_ptr = '\0';
X
X`009`009`009fprintf(ofp,"NAME = \"%s\"\n",term_name);
X`009`009`009do_end = 1;
X`009`009`125
X
X`009`009/* get next cap on the line, if any left */
X`009`009while ((beg_cap = get_next_cap(beg_cap)) != EOL)
X`009`009`123
X`009`009`009/*
X`009`009`009** If the cap is a "tc" then we have to
X`009`009`009** recursively call do_entry to put together
X`009`009`009** all the information for the original term
X`009`009`009*/
X
X`009`009`009if (strncmp(beg_cap,"tc",2) == 0)
X`009`009`009`123
X`009`009`009`009if (find_term(beg_cap) == FOUND)
X`009`009`009`009`009do_entry(tcfp, input_line2, TC);
X`009`009`009`009else
X`009`009`009`009`009fprintf(efp,"%s : No entry found for tc\n",term_name);
X`009`009`009`125
X`009`009`009else
X`009`009`009`123
X`009`009`009`009/* look up the cap in the list */
X`009`009`009`009t_ptr = binary(beg_cap);
X`009`009`009`009if (t_ptr != ((struct table_item *)0))
X`009`009`009`009`009do_cap(beg_cap, t_ptr);
X`009`009`009`125
X`009`009`125
X`009`009if (purpose == TC)
X`009`009`009return((int)EOL);
X`009`125
X`125
X
X/*
X** Reads the first line in a terminal entry and fills in term_name
X** with the terminal name found. since there can be many different
X** terminal names, the one to use is in which_name. For example,
X** if which_name is 2 this means to use the second terminal name found.
X** If successful, returns which_name, otherwise returns NULL.
X*/
X
Xget_term_name(c_ptr,term_name,which_name)
X`009register char *c_ptr;
X`009char term_name[];
X`009int which_name;
X`123
X`009register int i;
X
X`009for (i = 1; i < which_name; i++)
X`009`123
X`009`009c_ptr = strchr(c_ptr,'`124');
X`009`009if (c_ptr == NULL)
X`009`009`009return (NULL);
X`009`009c_ptr++;
X`009`125
X
X`009/* now c_ptr points to the which_name'th terminal name */
X`009for (i = 0;(i < TERMNAME_LEN) && (*c_ptr != '`124') && (*c_ptr != ':');)
X`009`009term_name[i++] = *c_ptr++;
X`009if (i == TERMNAME_LEN)
X`009`123
X`009`009term_name[i - 1] = '\0';
X`009`009fprintf(efp,"Term name starting with \"%s\" too long\n",
X`009`009`009term_name);
X`009`009exit(0);
X`009`125
X`009term_name[i] = '\0';
X`009return(which_name);
X`125
X
Xchar *
Xget_next_cap(beg_cap)
X`009register char *beg_cap;
X`123
X`009beg_cap = strchr(beg_cap,':');
X
X`009if (beg_cap == NULL)
X`009`009return(EOL);
X`009else
X`009`123
X`009`009beg_cap++;
X`009`009if ((*beg_cap == '\\') `124`124 (*beg_cap == '\n'))
X`009`009`009return(EOL);
X`009`009else
X`009`009`009return(beg_cap);
X`009`125
X`125
X
Xdo_cap(beg_cap, t_ptr)
X`009char *beg_cap;
X`009struct table_item *t_ptr;
X`123
X`009int arg_num = 1;
X`009int inc_amount = 1;
X`009int reverse = 0;
X`009char *cap_begin;
X
X`009if (*t_ptr->vms_name == '\0')
X`009`123
V`009`009fprintf(efp,"%s : No SMG translation for %s\n",term_name,t_ptr->unix_
Xname);
X`009`009return;
X`009`125
X`009cap_begin = beg_cap;
X
X`009/* move past the capability name */
X`009beg_cap++;
X`009beg_cap++;
X`009if (*beg_cap == '@')
X`009`009return;
X
X`009switch(t_ptr->type)
X`009`123
X`009case BOOL:
X`009`009fprintf(ofp,"BOOLEAN %s = 1\n",t_ptr->vms_name);
X`009`009break;
X`009case STR:
X`009`009if (*beg_cap != '=')
X`009`009`123
V`009`009`009fprintf(efp,"%s : missing equal char in capability %.2s\n",term_n
Xame,cap_begin);
X`009`009`009break;
X`009`009`125
X`009`009beg_cap++;
X
X`009`009fprintf(ofp,"STRING %s = \"",t_ptr->vms_name);
X
X`009`009/* skip padding values and asteric */
V`009`009while (isdigit(*beg_cap) `124`124 (*beg_cap == '*') `124`124 (*beg_ca
Xp == '.'))
X`009`009`009beg_cap++;
X
X`009`009/* go through all characters in string */
X`009`009while (*beg_cap != ':')
X`009`009`123
X`009`009`009switch (*beg_cap)
X`009`009`009`123
X`009`009`009case '\n':
X`009`009`009`009
V`009`009`009`009fprintf(efp,"%s : missing ending colon in capability %.2s\n",
Xterm_name,cap_begin);
X`009`009`009`009return;
X`009`009`009case '\\':
X`009`009`009`009beg_cap++;
X`009`009`009`009switch (*beg_cap)
X`009`009`009`009`123
X`009`009`009`009case 'E':`009`009/* escape */
X`009`009`009`009`009fputc('$',ofp);
X`009`009`009`009`009break;
X`009`009`009`009case 'n':`009`009/* newline */
X`009`009`009`009`009fprintf(ofp,"`094j");
X`009`009`009`009`009break;
X`009`009`009`009case 'r':`009`009/* carriage return */
X`009`009`009`009`009fprintf(ofp,"`094m");
X`009`009`009`009`009break;
X`009`009`009`009case 't':`009`009/* horizontal tab */
X`009`009`009`009`009fprintf(ofp,"`094i");
X`009`009`009`009`009break;
X`009`009`009`009case 'b':`009`009/* backspace */
X`009`009`009`009`009fprintf(ofp,"`094h");
X`009`009`009`009`009break;
X`009`009`009`009case 'f':`009`009/* form feed */
X`009`009`009`009`009fprintf(ofp,"`094l");
X`009`009`009`009`009break;
X`009`009`009`009case '`094':`009`009/* caret */
X`009`009`009`009`009fprintf(ofp,"_`094");
X`009`009`009`009`009break;
X`009`009`009`009case '\\':`009`009/* backslash */
X`009`009`009`009`009fputc('\\',ofp);
X`009`009`009`009`009break;
X`009`009`009`009case '0':
X`009`009`009`009`009if (strncmp(beg_cap,"072",3) == 0)
X`009`009`009`009`009`123
X`009`009`009`009`009`009fputc(':',ofp);
X`009`009`009`009`009`009beg_cap++;
X`009`009`009`009`009`009beg_cap++;
X`009`009`009`009`009`125
X`009`009`009`009`009else
X`009`009`009`009`009`123
X`009`009`009`009`009`009/* better be just 3 digits */
X`009`009`009`009`009`009fputc(*beg_cap++,ofp);
X`009`009`009`009`009`009fputc(*beg_cap++,ofp);
X`009`009`009`009`009`009fputc(*beg_cap,ofp);
X`009`009`009`009`009`125
X`009`009`009`009`009break;
X`009`009`009`009`125;
X`009`009`009`009beg_cap++;
X`009`009`009`009break;
X`009`009`009case '`094':`009`009`009/* control */
X`009`009`009`009fputc(*beg_cap++,ofp);
X`009`009`009`009fputc(*beg_cap++,ofp);
X`009`009`009`009break;
X`009`009`009case '%':
X`009`009`009`009/* missing %> */
X`009`009`009`009beg_cap++;
X`009`009`009`009switch (*beg_cap)
X`009`009`009`009`123
X`009`009`009`009case 'n':
X`009`009`009`009case 'B':
X`009`009`009`009case 'D':
X`009`009`009`009case '>':
V`009`009`009`009`009fprintf(efp,"%s : cursor addressing mode %%%c not support
Xed\n",term_name,*beg_cap);
X`009`009`009`009`009break;
X`009`009`009`009case '%':
X`009`009`009`009`009fputc('%',ofp);
X`009`009`009`009`009break;
X`009`009`009`009case '+':
X`009`009`009`009case 'c':
X`009`009`009`009case '.':
X`009`009`009`009`009fprintf(ofp,"(%%%d",arg_num);
X`009`009`009`009`009if (*beg_cap++ == '+')
X`009`009`009`009`009`123
X`009`009`009`009`009`009fprintf(ofp,"+%d)",*beg_cap - 1);
X`009`009`009`009`009`009beg_cap++;
X`009`009`009`009`009`125
X`009`009`009`009`009else
X`009`009`009`009`009`009fputc(')',ofp);
X`009`009`009`009`009if (reverse)
X`009`009`009`009`009`009arg_num--;
X`009`009`009`009`009else
X`009`009`009`009`009`009arg_num++;
X`009`009`009`009`009break;
X`009`009`009`009case 'i':
X`009`009`009`009`009beg_cap++;
X`009`009`009`009`009inc_amount = 0;
X`009`009`009`009`009break;
X`009`009`009`009case 'r':
X`009`009`009`009`009reverse = 1;
X`009`009`009`009`009arg_num = 2;
X`009`009`009`009`009beg_cap++;
X`009`009`009`009`009break;
X`009`009`009`009/* convert to ASCII */
X`009`009`009`009case 'd':
X`009`009`009`009case '2':
X`009`009`009`009case '3':
X`009`009`009`009`009if (inc_amount)
X`009`009`009`009`009`123
X`009`009`009`009`009`009fprintf(ofp,"(%%%d-%d)",arg_num,inc_amount);
X`009`009`009`009`009`009if (reverse)
X`009`009`009`009`009`009`009arg_num--;
X`009`009`009`009`009`009else
X`009`009`009`009`009`009`009arg_num++;
X`009`009`009`009`009`125
X`009`009`009`009`009else
X`009`009`009`009`009`123
X`009`009`009`009`009`009/* the 2 or 3 isn't valid
X`009`009`009`009`009`009if (*beg_cap == 'd')
X`009`009`009`009`009`009`009fprintf(ofp,"!UL");
X`009`009`009`009`009`009else
X`009`009`009`009`009`009`009fprintf(ofp,"!%cUL",*beg_cap);
X`009`009`009`009`009`009*/
X`009`009`009`009`009`009if (*beg_cap != 'd')
V`009`009`009`009`009`009`009fprintf(efp,"%s : %cdchanged to !UL\n",term_name,
X*beg_cap);
X`009`009`009`009`009`009fprintf(ofp,"!UL");
X`009`009`009`009`009`125
X`009`009`009`009`009beg_cap++;
X`009`009`009`009`009break;
X`009`009`009`009`125
X`009`009`009`009break;
X
X`009`009`009/* characters that must be escaped */
X`009`009`009case '&':
X`009`009`009case '\'':
X`009`009`009case '@':
X`009`009`009case '"':
X`009`009`009case '$':
X`009`009`009case '!':
X`009`009`009case '(':
X`009`009`009case '_':
X`009`009`009case '+':
X`009`009`009case '-':
X`009`009`009case '*':
X`009`009`009case '/':
X`009`009`009`009fputc('_',ofp);
X`009`009`009`009fputc(*beg_cap++,ofp);
X`009`009`009`009break;
X`009`009`009`009
X`009`009`009default:
X`009`009`009`009fputc(*beg_cap++,ofp);
X`009`009`009`009break;
X`009`009`009`125
X`009`009`125
X`009`009fprintf(ofp,"\"\n");
X`009`009break;
X`009case NUM:
X`009`009fprintf(ofp,"NUMERIC %s = ",t_ptr->vms_name);
X`009`009while (*beg_cap++ != '#');
X`009`009while(isdigit(*beg_cap))
X`009`009`009fputc(*beg_cap++,ofp);
X`009`009fputc('\n',ofp);
X`009`009break;
X`009`125;
X`009return;
X`125
X
Xstruct table_item *
Xbinary (cap)
X`009char *cap;
X`123
X`009int cond;
X`009register struct table_item *low = &table[0];
V`009register struct table_item *high = &table[(sizeof table / sizeof (struct
X table_item)) - 1];
X`009register struct table_item *mid;
X
X`009while (low <= high)
X`009`123
X`009`009mid = low + (high - low) / 2;
X`009`009if ((cond = strncmp(cap, mid->unix_name, 2)) < 0)
X`009`009`009high = mid - 1;
X`009`009else
X`009`009`009if (cond > 0)
X`009`009`009`009low = mid + 1;
X`009`009`009else
X`009`009`009`009return(mid);
X`009`125
X`009return(NULL);
X`125
X
X/*
X** given the address of a tc entry, find the full entry for
X** the terminal given in the tc entry. When this routine returns
X** tcfp will be positioned to the first line of the entry.
X*/
X
Xfind_term(char_ptr)
X`009register char *char_ptr;
X`123
X`009char *temp_ptr;
X`009long start_pos;
X`009int term_num;
X`009char t_name[TERMNAME_LEN];
X
X`009/* move over to the terminal name */
X`009char_ptr++;
X`009char_ptr++;
X`009char_ptr++;
X
V`009/* look for the end of the tc cap terminal name and terminate with null *
X/
X`009temp_ptr = char_ptr;
X`009while((*temp_ptr != ':') && (*temp_ptr != '\n'))
X`009`009temp_ptr++;
X`009*temp_ptr = '\0';
X
X`009/* char_ptr now points to the terminal name to find */
X`009if (tcfp == NULL)
X`009`009tcfp = fopen(TERMCAP,"r");
X`009else
X`009`009rewind(tcfp);
X
X`009for(;;)
X`009`123
X`009`009if (fgets(input_line2, LINE_LEN, tcfp) == NULL)
X`009`009`009return(NULL);
X
X`009`009/* point to the beginning of the line */
X`009`009temp_ptr = input_line2;
X
X`009`009if ((*temp_ptr == '#') `124`124 (isspace(*temp_ptr)))
X`009`009`009continue;
X
X`009`009start_pos = ftell(tcfp);
X
X`009`009term_num = 1;
X`009`009while (get_term_name(temp_ptr, t_name, term_num))
X`009`009`123
X`009`009`009if (strcmp(char_ptr, t_name) == 0)
X`009`009`009`123
X`009`009`009`009fseek(tcfp, start_pos, 0);
X`009`009`009`009move_over(tcfp);
X`009`009`009`009return(FOUND);
X`009`009`009`125
X`009`009`009else
X`009`009`009`123
X`009`009`009`009term_num++;
X`009`009`009`009continue;
X`009`009`009`125
X`009`009`125
X`009`009continue;
X`009`125
X`125
X
Xmove_over(tcfp)
X`009FILE *tcfp;
X`123
X`009int in_char;
X
X`009/* read over all terminal names */
X`009for (;;)
X`009`123
X`009`009in_char = fgetc(tcfp);
X`009`009if ((in_char != ':') && (in_char != '\\'))
X`009`009`009continue;
X
X`009`009/* Now we're either at ':' or the '\'.
X`009`009** If at ':' then the next char is either '\',
X`009`009** meaning more lines are coming, or another cap.
X`009`009** It had better not be '\n' because this means that
X`009`009** a line consisting of only a terminal name was given.
X`009`009** If at '\' the line is missing the ':' and the next char
X`009`009** is '\n' followed by at least one continuation line.
X`009`009*/
X
X`009`009if (in_char == ':')
X`009`009`123
X`009`009`009in_char = fgetc(tcfp);
X`009`009`009if (in_char == '\\')
X`009`009`009`009while(isspace(in_char = fgetc(tcfp)));
X`009`009`125
X`009`009else
X`009`009`123
X`009`009`009while(isspace(fgetc(tcfp)));
X`009`009`125
X
X`009`009/* in either case, restore the character just read */
-+-+-+-+-+ End of part 2 +-+-+-+-+-
Jon Forrest
forrest@sybase.com
{pacbell,sun,{uunet,ucbvax}!mtxinu}!sybase!forrest
415-596-3422

