-+-+-+-+-+-+-+-+ START OF PART 2 -+-+-+-+-+-+-+-+ 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`091TERMNAME_LEN`093; 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 X`009`009`009`009`009`009fprintf(efp,"%s : Changed dash(s) to '_'\n",curr_ter Vm_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 X`009`009`009`009`009`009fprintf(efp,"%s : Changed + to plus\n",curr_term_nam Ve); 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`091`093; 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`091i++`093 = *c_ptr++; X`009if (i == TERMNAME_LEN) X`009`123 X`009`009term_name`091i - 1`093 = '\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`091i`093 = '\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 X`009`009fprintf(efp,"%s : No SMG translation for %s\n",term_name,t_ptr->unix V_name); 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 X`009`009`009fprintf(efp,"%s : missing equal char in capability %.2s\n",term_ Vname,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 */ X`009`009while (isdigit(*beg_cap) `124`124 (*beg_cap == '*') `124`124 (*beg_c Vap == '.')) 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 X`009`009`009`009fprintf(efp,"%s : missing ending colon in capability %.2s\n" V,term_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 '>': X`009`009`009`009`009fprintf(efp,"%s : cursor addressing mode %%%c not suppor Vted\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') X`009`009`009`009`009`009`009fprintf(efp,"%s : %cdchanged to !UL\n",term_name V,*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`0910`093; X`009register struct table_item *high = &table`091(sizeof table / sizeof (str Vuct table_item)) - 1`093; 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`091TERMNAME_LEN`093; X X`009/* move over to the terminal name */ X`009char_ptr++; X`009char_ptr++; X`009char_ptr++; X X`009/* look for the end of the tc cap terminal name and terminate with null V */ 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 +-+-+-+-+-+-+-+-