|
|
DataMuseum.dkPresents historical artifacts from the history of: Regnecentalen RC-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Regnecentalen RC-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T U m
Length: 16819 (0x41b3)
Types: TextFile
Notes: UNIX file
Names: »mre_db.c«
└─⟦a85bd4a7c⟧ Bits:30004636/disk2.imd INTERACTIVE Motif Environment Development System
└─⟦a85bd4a7c⟧ UNIX Filesystem
└─⟦this⟧ »xt/new/usr/lib/X11/examples/mre/mre_db.c«
#ifdef REV_INFO
#ifndef lint
static char SCCSID[] = "OSF/Motif: @(#)mre_db.c 1.1 - 89/08/30 - 12:00:46";
#endif /* lint */
#endif /* REV_INFO */
/*
** mre_db.c - Motif Resource Editor Line Information Handling
** Copyright (c) 1989, Open Software Foundation, Inc.
** ALL RIGHTS RESERVED.
**
** Functions in this file maintain mre's internal database connecting
** lines in the users' resource file with mre's listbox display
**
** Revision history:
** created July 1989 Mitch Trachtenberg
**
*/
#include "mre.h"
extern stricmp();
extern char *skip_to_value();
extern char *skip_to_resource();
static LineInfo li[500];
static int lc;
static TypeInfo typed_resources[100];
static int num_typed_resources;
static EnumInfo enumerations[100];
static int num_enumerations;
static TypeInfo mre_type_descriptions[]={
{MRE_TYPE_DELETED, 0,"DELETED"},
{MRE_TYPE_DONT_SHOW, 0,"DONT_SHOW"},
{MRE_TYPE_MISC, 0,"MISC"},
{MRE_TYPE_COLOR, 0,"COLOR"},
{MRE_TYPE_FONT, 0,"FONT"},
{MRE_TYPE_BOOLEAN, 0,"BOOLEAN"},
{MRE_TYPE_FILE, 0,"FILE"},
{MRE_TYPE_TRANSLATION, 0,"TRANSLATION"},
{MRE_TYPE_ENUM, 0,"ENUMERATED"}
};
static TypeInfo hardcoded_typed_resources[]={
{MRE_TYPE_COLOR,0,"foreground$"},
{MRE_TYPE_COLOR,0,"background$"},
{MRE_TYPE_COLOR,0,"fg"},
{MRE_TYPE_COLOR,0,"bg"},
{MRE_TYPE_FONT,0,"font$"},
{MRE_TYPE_FONT,0,"fontList$"},
{MRE_TYPE_BOOLEAN,0,"traversalOn$"},
{MRE_TYPE_FILE,0,"windowManagerName$"},
{MRE_TYPE_FILE,0,"terminalEmulatorName$"}
};
static TypeInfo value_determiners[]={
{MRE_TYPE_BOOLEAN,0,"on"},
{MRE_TYPE_BOOLEAN,0,"off"},
{MRE_TYPE_BOOLEAN,0,"true"},
{MRE_TYPE_BOOLEAN,0,"false"},
{MRE_TYPE_COLOR,0,"red"},
{MRE_TYPE_COLOR,0,"green"},
{MRE_TYPE_COLOR,0,"blue"}
};
/* if an external file containing resource type information exists, load it */
void load_mre_type_file(name)
char *name;
{
FILE *f;
char buf[MAX_ENTRY_SIZE];
char *type_string;
int n;
if(!(f = fopen(name,"r"))){
fetch_message_printf("fail_cant_read",name);
return;
}
while(fgets(buf,MAX_ENTRY_SIZE,f)){
type_string=strtok(buf," \t\n");
if(type_string==NULL)break;
/* check to see if you are defining an enumeration */
if(!stricmp(type_string,"DEFINE")){
enumerations[num_enumerations].enum_label = strdup(strtok(NULL," \t\n"));
enumerations[num_enumerations].enum_choices = strdup(strtok(NULL,"\n"));
++num_enumerations;
continue;
}
/* find the type description string matching the line's first component */
/* and set the type of the line's remainder to the matching MRE_TYPE */
for(n=0;n<XtNumber(mre_type_descriptions);n++){
if(!stricmp(type_string,mre_type_descriptions[n].type_string)){
char *resource_string;
resource_string = strtok(NULL,"\n");
if(resource_string==NULL){
fetch_message_printf("fail_resource_string");
continue;
}
typed_resources[num_typed_resources].type_string =
strdup(resource_string);
typed_resources[num_typed_resources].type_flag =
mre_type_descriptions[n].type_flag;
num_typed_resources++;
}
}
/* if the search for a defined type didn't work, check for an enum */
for(n=0;n<num_enumerations;n++){
if(!stricmp(type_string,enumerations[n].enum_label)){
char *resource_string;
resource_string = strtok(NULL,"\n");
if(resource_string==NULL){
fetch_message_printf("fail_resource_string");
continue;
}
typed_resources[num_typed_resources].type_string =
strdup(resource_string);
typed_resources[num_typed_resources].type_flag = MRE_TYPE_ENUM;
typed_resources[num_typed_resources].enum_type = n;
num_typed_resources++;
}
}
}
return;
}
/* reset the list; called by file_new_proc */
clear_li()
{
int n;
for(n=0;n<lc;n++)
if(li[lc].line_contents)free(li[lc].line_contents);
lc = 0;
}
/* this function reads a resource file into the li line information array */
read_into_li(f)
FILE *f;
{
int n;
int listbox_index;
int saved_lc;
char buf[MAX_ENTRY_SIZE];
for(listbox_index=1,lc=0;fgets(buf,MAX_ENTRY_SIZE,f);lc++){
int length;
length = strlen(buf);
/* clip terminal newlines, spaces */
while(length>1 &&
(buf[length-1]=='\n' ||
buf[length-1]=='\t' ||
buf[length-1]==' ')){
buf[length-1]='\0';
length--;
}
/* make ss8 listbox XmString routines happy */
if(*buf=='\0')strcpy(buf,"!");
/* allow for multiple calls to this function; free and zero resources*/
if(li[lc].line_contents)
free(li[lc].line_contents);
li[lc].continuation = li[lc].listbox_index = 0;
li[lc].resource_type = MRE_TYPE_DONT_SHOW;
li[lc].line_number = lc;
li[lc].line_contents = strdup(buf);
saved_lc = lc;
while(ends_in_slash(buf)){
fgets(buf,MAX_ENTRY_SIZE,f);
length = strlen(buf);
/* clip terminal newline */
if(buf[length-1]=='\n')
buf[length-1]='\0';
else
length++;
lc++;
li[lc].line_number = lc;
li[lc].continues_line = saved_lc;
li[lc].line_contents = (char *)calloc(length,sizeof(char));
strcpy(li[lc].line_contents,buf);
}
if(has_colon(li[saved_lc].line_contents)
&& !is_comment(li[saved_lc].line_contents)
&& !is_hash(li[saved_lc].line_contents)
&& !is_blank(li[saved_lc].line_contents)) {
int cont;
li[saved_lc].resource_type =
resource_type(li[saved_lc].line_contents);
if(li[saved_lc].resource_type == MRE_TYPE_ENUM)
li[saved_lc].enum_type = get_enumerated_type();
for(cont=0;saved_lc<=lc;cont++,saved_lc++){
li[saved_lc].listbox_index = listbox_index;
li[saved_lc].continuation = cont;
}
listbox_index++;
}
else li[saved_lc].resource_type = MRE_TYPE_DONT_SHOW;
}
}
static int global_enumerated_type;
set_enumerated_type(val)
{
global_enumerated_type = val;
}
get_enumerated_type()
{
return global_enumerated_type;
}
/* the type of a given resource is determined by comparing the resource */
/* against hard-coded and externally loaded regular expressions; */
/* then checking the resource's value against hard-coded strings; */
/* then searching for special characters in the resource value. */
resource_type(s)
char *s;
{
char buf[MAX_ENTRY_SIZE];
char *res;
char *val;
int hyphens;
int n;
int good;
res = skip_to_resource(s);
for(n=0;(buf[n]=(*res))!=':';n++,res++);
buf[n]='\0';
#ifdef USE_RE_COMP
for(n=0;n<XtNumber(hardcoded_typed_resources);n++){
re_comp(hardcoded_typed_resources[n].type_string);
if(1==re_exec(buf)){
if(hardcoded_typed_resources[n].type_flag == MRE_TYPE_ENUM)
set_enumerated_type(hardcoded_typed_resources[n].enum_type);
return(hardcoded_typed_resources[n].type_flag);
}
}
#else
for(n=0;n<XtNumber(hardcoded_typed_resources);n++){
char *ptr;
ptr = NULL;
ptr=(char *)regcmp(hardcoded_typed_resources[n].type_string,NULL);
if(regex(ptr,buf)){
if(ptr)free(ptr);
if(hardcoded_typed_resources[n].type_flag == MRE_TYPE_ENUM)
set_enumerated_type(hardcoded_typed_resources[n].enum_type);
return(hardcoded_typed_resources[n].type_flag);
}
if(ptr)free(ptr);
}
#endif /* USE_RE_COMP */
/* if not, check to see if it matches one from the mre_type_file */
#ifdef USE_RE_COMP
for(n=0;n<num_typed_resources;n++){
re_comp(typed_resources[n].type_string);
if(1==re_exec(buf)){
if(typed_resources[n].type_flag == MRE_TYPE_ENUM)
set_enumerated_type(typed_resources[n].enum_type);
return(typed_resources[n].type_flag);
}
}
#else
for(n=0;n<num_typed_resources;n++){
char *ptr;
ptr = NULL;
ptr=(char *)regcmp(typed_resources[n].type_string,NULL);
if(regex(ptr,buf)){
if(ptr)free(ptr);
if(typed_resources[n].type_flag == MRE_TYPE_ENUM)
set_enumerated_type(typed_resources[n].enum_type);
return(typed_resources[n].type_flag);
}
if(ptr)free(ptr);
}
#endif /* USE_RE_COMP */
/* if not, check to see if value matches a hard-coded string */
val = skip_to_value(s);
strcpy(buf,val);
for(n = strlen(buf) - 1;n>0 && isspace(buf[n]);n--)
buf[n]='\0';
for(n=0;n<XtNumber(value_determiners);n++)
if(!stricmp(buf,value_determiners[n].type_string))
return(value_determiners[n].type_flag);
/* check to see if value "looks like" a font specification */
/* (does it have >5 hyphens?) */
for(n=0,hyphens=0;buf[n];n++)
if(buf[n]=='-')
hyphens++;
if(hyphens>5)
return(MRE_TYPE_FONT);
/* check to see if value "looks like" a file specification */
/* (does it have a forwardslash?) */
for(n=0;buf[n];n++)
if(buf[n]=='/' || buf[n]=='.')
return(MRE_TYPE_FILE);
/* check to see if value "looks like" a xlat specification */
/* (does it have a "<> */
/* NOTE THIS MUST PRECEDE CHECK FOR COLOR SHARP SIGN */
for(n=0;buf[n];n++)
if(buf[n]=='<' || buf[n]=='>')
return(MRE_TYPE_TRANSLATION);
/* check to see if value "looks like" a color specification */
/* (does it begin with a hash and have hex digits?) */
/* (does it match an entry in the rgb.txt file?) */
good = 1;
if(*buf!='#')good = 0;
else {
for(n=1;buf[n];n++)
if(!isxdigit(buf[n]))
good=0;
}
if(good)return(MRE_TYPE_COLOR);
return(MRE_TYPE_MISC);
}
/* this function determines whether to allow a given line in the li array */
/* to be entered and displayed in the main listbox */
allow_entry(t,f)
int t, f;
{
int n;
/* never allow entry of deleted or dontshow types */
if(t<0)return(0);
/* allow entry for a type if that type's bit is set in the type_flag */
for(n=1;n<7;n++){
if(t==n && f&(1<<(n-1)))return(1);
}
/* allow entry for miscellaneous if allow_misc bit is set */
if(t==MRE_TYPE_MISC && f&0x20)
return(1);
/* dont allow anything else */
return(0);
}
/* routine to perform string compares on the value part of line infos */
int valstrcmp(lip1,lip2)
LIP lip1,lip2;
{
char *s1, *s2;
s1 = lip1->line_contents;
s2 = lip2->line_contents;
if(!(s1 = skip_to_value(s1)))
return(1);
if(!(s2 = skip_to_value(s2)))
return(-1);
return(stricmp(s1,s2));
}
/* opposite of above */
int revvalstrcmp(lip1,lip2)
LIP lip1,lip2;
{
return(-valstrcmp(lip1,lip2));
}
/* routine to perform string compares on the resource part of line infos */
int resstrcmp(lip1,lip2)
LIP lip1, lip2;
{
char *s1, *s2;
s1 = lip1->line_contents;
s2 = lip2->line_contents;
if(!(s1 = skip_to_resource(s1)))
return(1);
if(!(s2 = skip_to_resource(s2)))
return(-1);
return(stricmp(s1,s2));
}
/* opposite of above */
int revresstrcmp(lip1,lip2)
LIP lip1,lip2;
{
return(-resstrcmp(lip1,lip2));
}
/* routine to perform string compares on the line contents of line infos */
int lipstrcmp(lip1,lip2)
LIP lip1, lip2;
{
char *s1, *s2;
s1 = lip1->line_contents;
s2 = lip2->line_contents;
return(stricmp(s1,s2));
}
/* opposite of above */
int revstrcmp(lip1,lip2)
LIP lip1,lip2;
{
return(-lipstrcmp(lip1,lip2));
}
/* function to give to qsort to sort a line info array back to file order */
cmplinenums(lip1,lip2)
LIP lip1, lip2;
{
return(lip1->line_number - lip2->line_number);
}
sort_li_array(method)
int method;
{
static int (*compar[])()={
lipstrcmp,
lipstrcmp,
valstrcmp,
resstrcmp,
revstrcmp,
revvalstrcmp,
revresstrcmp
};
int n;
int indx;
qsort(li,lc,sizeof(LineInfo),compar[method]);
/* now walk sorted array, setting non-zero listbox_indices in sequence */
indx = 1;
for(n=0;n<lc;n++){
if(li[n].listbox_index)li[n].listbox_index=indx++;
}
}
/* this function builds a new item array for the main selection listbox */
/* based on the current state of the line_info array */
gen_new_list(type_flag)
int type_flag;
{
int n;
int listbox_index = 1;
int item_count;
Widget list;
Arg arg[2];
XmString *items;
for(n=0;n<lc;n++){
if(allow_entry(li[n].resource_type,type_flag)){
if(!li[n].continuation){
li[n].listbox_index = listbox_index++;
}
}
else if(li[n].resource_type>=0){
li[n].listbox_index = 0;
}
}
/* calloc an item array of listbox_index (less one) items; */
/* fill it with compound strings generated from list,*/
/* and set the main listbox to that array and item count */
item_count = listbox_index - 1;
items = (XmString *)calloc(item_count,sizeof(XmString));
for(listbox_index=n=0;listbox_index<item_count;n++){
char buf[MAX_ENTRY_SIZE];
if(allow_entry(li[n].resource_type,type_flag)){
if(!li[n].continuation){
if(ends_in_slash(li[n].line_contents)){
strcpy(buf,li[n].line_contents);
replace_slash_with_ellipsis(buf);
items[listbox_index++] = XmStringDefCreate(buf);
}
else{
int m;
strcpy(buf,li[n].line_contents);
for(m=0;buf[m];m++)if(buf[m]=='\t')buf[m]=' ';
items[listbox_index++] = XmStringDefCreate(buf);
}
}
/* should these compound strings be freed? */
}
}
n = 0;
XtSetArg(arg[n],XmNitemCount,item_count);n++;
XtSetArg(arg[n],XmNitems,items);n++;
XtSetValues(list=XmSelectionBoxGetChild(main_selection_box_id,XmDIALOG_LIST),
arg,n);
/* now, if item_count>0, get selectedItemCount and, if 0, select item 1 */
if(item_count>0){
XtSetArg(arg[0],XmNselectedItemCount,&item_count);
XtSetArg(arg[1],XmNselectedItems,items);
XtGetValues(list,arg,2);
if(item_count==0 || !XmListItemExists(list,*items))
XmListSelectPos(list,1,1);
}
}
delete_line_item(indx)
int indx;
{
int n;
for(n=0;n<lc;n++){
if(li[n].listbox_index==indx){
li[n].listbox_index=0;
li[n].resource_type= MRE_TYPE_DELETED; /*deleted*/
}
if(li[n].listbox_index &&
li[n].listbox_index>indx)li[n].listbox_index--;
}
/* DONT lower lc; the deleted item is still in the array */
}
char *enumeration_choices(line)
int line;
{
int n;
for(n=0;n<lc;n++){
if(li[n].line_number==line){
return(enumerations[li[n].enum_type].enum_choices);
}
}
return(NULL);
}
linenum_from_listindex(listbox_index)
int listbox_index;
{
int n;
for(n=0;n<lc;n++)
if(li[n].listbox_index == listbox_index)
return(li[n].line_number);
/* -1 is impossible line number */
return(-1);
}
listindex_from_linenum(line_number)
int line_number;
{
int n;
for(n=0;n<lc;n++)
if(li[n].line_number == line_number)
return(li[n].listbox_index);
/* 0 indicates line not in listbox */
return(0);
}
add_line_item(s,indx)
char *s;
int indx;
{
int n;
char *dup;
for(n=0;n<lc;n++){
if(li[n].listbox_index &&
li[n].listbox_index>=indx)li[n].listbox_index++;
}
/* and create an entry in the li array for the new item */
li[lc].line_number=lc;
li[lc].resource_type=resource_type(s);
if(li[lc].resource_type == MRE_TYPE_ENUM)
li[lc].enum_type = get_enumerated_type();
li[lc].listbox_index=indx;
li[lc].continuation=0;
/* ss8 listboxes die when fed zero length XmStrings */
if(!strlen(s)){
dup = (char *)calloc(2,sizeof(char));
strcpy(dup,"!");
}
else{
dup=strdup(s);
}
li[lc].line_contents=dup;
/*increment top of sort flag */
lc++;
}
set_values_in_database(s,item_to_adjust)
char *s;
int item_to_adjust;
{
char buf[MAX_ENTRY_SIZE];
char *colon;
int n;
int found_match=0;
/* search for non-continuation line with line_number==item_to_adjust */
for(n=0;n<lc;n++){
if (!(li[n].continuation) && li[n].line_number==item_to_adjust){
found_match=1;
strcpy(buf,li[n].line_contents);
break;/* to prevent n increment */
}
}
if(!found_match)
return;
/* s contains rhs of spec */
if(colon=strchr(buf,':')){
colon++;
while(*colon==' ')colon++;
*colon='\0';
strcat(buf,s);
free(li[n].line_contents);
li[n].line_contents = strdup(buf);
}
}
write_db(f)
FILE *f;
{
int n;
qsort(li,lc,sizeof(LineInfo),cmplinenums);
for(n=0;n<lc;n++)
if(li[n].resource_type != MRE_TYPE_DELETED)
fprintf(f,"%s\n",li[n].line_contents);
}
void dump_db()
{
int n;
qsort(li,lc,sizeof(LineInfo),cmplinenums);
for(n=0;n<lc;n++)
printf("LINE %d TYPE %d ENUM %d LISTBOX %d CONT %d TEXT %s\n",
li[n].line_number,
li[n].resource_type,
li[n].enum_type,
li[n].listbox_index,
li[n].continuation,
li[n].line_contents);
}
has_colon(s)
char *s;
{
if(strchr(s,':'))return(1);
return(0);
}
is_comment(s)
char *s;
{
while(isspace(*s))s++;
return(*s == '!' ? 1 : 0);
}
is_hash(s)
char *s;
{
while(isspace(*s))s++;
return(*s == '#' ? 1 : 0);
}
is_blank(s)
char *s;
{
while(isspace(*s))s++;
return(*s ? 0 : 1);
}
ends_in_slash(s)
char *s;
{
int length;
length = strlen(s);
if(s[length-1]=='\\')
return(1);
else return(0);
}
/* WARNING -- buffer passed to this function must accomodate ellipsis */
replace_slash_with_ellipsis(s)
char *s;
{
int length;
length = strlen(s);
s[length-1]='\0';
strcat(s,"...");
}