home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
fed0217s.zip
/
source
/
profile.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2001-10-29
|
22KB
|
668 lines
/*
** Module :PROFILE.CPP
** Abstract :FED profile (FED.INI) reader/parser
**
** Copyright (C) Sergey I. Yevtushenko
**
** Log: Wed 17/03/1998 Created
*/
#include <string.h>
#define INCL_DOS
#include <os2.h>
#include <boxcoll.h>
#include <fio.h>
#include <version.h>
#define P_INT 1
#define P_CHAR 2
#define P_PSZ 3
struct stPairDef;
typedef struct stPairDef* PPairDef;
struct stPairDef
{
char *index;
int type;
void *value;
};
stPairDef ProfileDef[]=
{
{"color.app.default" , P_CHAR, app_pal + CL_APPLICATION_START+CL_DEFAULT },
{"color.app.status" , P_CHAR, app_pal + CL_APPLICATION_START+CL_STATUSLINE },
{"color.dialog.default" , P_CHAR, app_pal + CL_DIALOG_START+CL_DEFAULT },
{"color.dialog.hilite" , P_CHAR, app_pal + CL_DIALOG_START+CL_BORDER },
{"color.edit.comment" , P_CHAR, app_pal + CL_EDITBOX_START+CL_COMMENT },
{"color.edit.const" , P_CHAR, app_pal + CL_EDITBOX_START+CL_CONST },
{"color.edit.default" , P_CHAR, app_pal + CL_EDITBOX_START+CL_DEFAULT },
{"color.edit.eof" , P_CHAR, app_pal + CL_EDITBOX_START+CL_EOF },
{"color.edit.function" , P_CHAR, app_pal + CL_EDITBOX_START+CL_FUNCTION },
{"color.edit.ident" , P_CHAR, app_pal + CL_EDITBOX_START+CL_IDENT },
{"color.edit.number" , P_CHAR, app_pal + CL_EDITBOX_START+CL_NUMBER },
{"color.edit.preproc" , P_CHAR, app_pal + CL_EDITBOX_START+CL_PREPROC },
{"color.edit.selection" , P_CHAR, app_pal + CL_EDITBOX_START+CL_SELECTION },
{"color.edit.semicol" , P_CHAR, app_pal + CL_EDITBOX_START+CL_SEMICOL },
{"color.edit.stdword" , P_CHAR, app_pal + CL_EDITBOX_START+CL_STDWORD },
{"color.edit.xnumber" , P_CHAR, app_pal + CL_EDITBOX_START+CL_XNUMBER },
{"color.line.active.comment" , P_CHAR, app_pal + CL_EDITLINE_ACTIVE+CL_COMMENT },
{"color.line.active.const" , P_CHAR, app_pal + CL_EDITLINE_ACTIVE+CL_CONST },
{"color.line.active.default" , P_CHAR, app_pal + CL_EDITLINE_ACTIVE+CL_DEFAULT },
{"color.line.active.eof" , P_CHAR, app_pal + CL_EDITLINE_ACTIVE+CL_EOF },
{"color.line.active.function" , P_CHAR, app_pal + CL_EDITLINE_ACTIVE+CL_FUNCTION },
{"color.line.active.ident" , P_CHAR, app_pal + CL_EDITLINE_ACTIVE+CL_IDENT },
{"color.line.active.number" , P_CHAR, app_pal + CL_EDITLINE_ACTIVE+CL_NUMBER },
{"color.line.active.preproc" , P_CHAR, app_pal + CL_EDITLINE_ACTIVE+CL_PREPROC },
{"color.line.active.selection" , P_CHAR, app_pal + CL_EDITLINE_ACTIVE+CL_SELECTION },
{"color.line.active.semicol" , P_CHAR, app_pal + CL_EDITLINE_ACTIVE+CL_SEMICOL },
{"color.line.active.stdword" , P_CHAR, app_pal + CL_EDITLINE_ACTIVE+CL_STDWORD },
{"color.line.active.xnumber" , P_CHAR, app_pal + CL_EDITLINE_ACTIVE+CL_XNUMBER },
{"color.line.inactive.comment" , P_CHAR, app_pal + CL_EDITLINE_INACTIVE+CL_COMMENT },
{"color.line.inactive.const" , P_CHAR, app_pal + CL_EDITLINE_INACTIVE+CL_CONST },
{"color.line.inactive.default" , P_CHAR, app_pal + CL_EDITLINE_INACTIVE+CL_DEFAULT },
{"color.line.inactive.eof" , P_CHAR, app_pal + CL_EDITLINE_INACTIVE+CL_EOF },
{"color.line.inactive.function" , P_CHAR, app_pal + CL_EDITLINE_INACTIVE+CL_FUNCTION },
{"color.line.inactive.ident" , P_CHAR, app_pal + CL_EDITLINE_INACTIVE+CL_IDENT },
{"color.line.inactive.number" , P_CHAR, app_pal + CL_EDITLINE_INACTIVE+CL_NUMBER },
{"color.line.inactive.preproc" , P_CHAR, app_pal + CL_EDITLINE_INACTIVE+CL_PREPROC },
{"color.line.inactive.selection" , P_CHAR, app_pal + CL_EDITLINE_INACTIVE+CL_SELECTION },
{"color.line.inactive.semicol" , P_CHAR, app_pal + CL_EDITLINE_INACTIVE+CL_SEMICOL },
{"color.line.inactive.stdword" , P_CHAR, app_pal + CL_EDITLINE_INACTIVE+CL_STDWORD },
{"color.line.inactive.xnumber" , P_CHAR, app_pal + CL_EDITLINE_INACTIVE+CL_XNUMBER },
{"color.list.active.current" , P_CHAR, app_pal + CL_LISTBOX_ACTIVE+CL_CURRENT },
{"color.list.active.currsel" , P_CHAR, app_pal + CL_LISTBOX_ACTIVE+CL_CURRSEL },
{"color.list.active.default" , P_CHAR, app_pal + CL_LISTBOX_ACTIVE+CL_DEFAULT },
{"color.list.active.selection" , P_CHAR, app_pal + CL_LISTBOX_ACTIVE+CL_SELECTION },
{"color.list.inactive.current" , P_CHAR, app_pal + CL_LISTBOX_INACTIVE+CL_CURRENT },
{"color.list.inactive.currsel" , P_CHAR, app_pal + CL_LISTBOX_INACTIVE+CL_CURRSEL },
{"color.list.inactive.default" , P_CHAR, app_pal + CL_LISTBOX_INACTIVE+CL_DEFAULT },
{"color.list.inactive.selection" , P_CHAR, app_pal + CL_LISTBOX_INACTIVE+CL_SELECTION },
{"color.menu.active.current" , P_CHAR, app_pal + CL_MENU+CL_CURRENT },
{"color.menu.active.currsel" , P_CHAR, app_pal + CL_MENU+CL_CURRSEL },
{"color.menu.active.default" , P_CHAR, app_pal + CL_MENU+CL_DEFAULT },
{"color.menu.active.selection" , P_CHAR, app_pal + CL_MENU+CL_SELECTION },
{"color.static.default" , P_CHAR, app_pal + CL_STEXT_START+CL_DEFAULT },
{"color.static.hilite" , P_CHAR, app_pal + CL_STEXT_START+CL_HILITE },
{"cursor.shape.insert" , P_INT , iShape + 0},
{"cursor.shape.overwrite" , P_INT , iShape + 1},
{"editor.ctrlbreak.action" , P_INT , &iCtrlBrk},
{"editor.default.format" , P_INT , &iDefType},
{"editor.helptext" , P_PSZ , &help_text},
{"editor.no.ea" , P_INT , &iNoEA},
{"editor.statusline" , P_PSZ , &statusline},
{"editor.statuspos" , P_INT , &iUpperStatus},
{"editor.syntax" , P_PSZ , &hi_map},
{"editor.syntax.save.mode" , P_INT , &iSaveSyntax},
{"editor.tabwidth" , P_INT , &iTabWidth},
{"editor.default.wordwrap.state" , P_INT , &iWWDef},
{"editor.default.wordwrap.margin", P_INT , &iDefWidth},
{"editor.untitled" , P_PSZ , &untitled},
{"editor.verbose.search" , P_INT , &iVSearch},
{"editor.file.name.reduce" , P_INT , &iFileName},
{"mouse.event.mask" , P_INT , &iMouseMask},
{"mouse.sense.shift" , P_INT , &iSenseShift}
};
ProfileDictionary::ProfileDictionary():Dictionary(1, 0, 0)
{
for(int i = 0; i < sizeof(ProfileDef)/sizeof(ProfileDef[0]); i++)
{
//printf("init: %s=%08x\n", ProfileDef[i].index, ProfileDef[i].value);
Add(&ProfileDef[i]);
}
}
int get_ini_name(char *cProgName, char *ini_ext)
{
char* lastdot;
char* lastslash;
strcpy(cProgName, _cFedPATH);
lastdot = strrchr(cProgName, '.');
lastslash = strrchr(cProgName, '\\');
if(lastdot > lastslash) //dot really in extension, not in path
strcpy(lastdot, ini_ext);
else
strcat(cProgName, ini_ext);
return 0;
}
void EditBoxCollection::load_profile(int mode)
{
char cProgName[FED_MAXPATH];
if(!mode)
{
if(get_ini_name(cProgName, ".ini"))
return;
}
else
{
strcpy(cProgName, "fed.ini");
}
load_profile_file(cProgName);
}
static char* skip_to_eol(char* ptr)
{
while(*ptr && *ptr != '\n')
ptr++;
return ptr;
}
void EditBoxCollection::load_profile_file(char* cFile)
{
char *orig_file = _ld_file(cFile);
if(orig_file)
load_profile(orig_file);
_fr_file(orig_file);
}
void EditBoxCollection::load_profile(char* orig_file)
{
char *ptr;
char *str;
for(ptr = str = orig_file; *ptr;)
{
int j = 0;
//Skip whitespaces
//Skip empty lines
while(__issp(*ptr))
ptr++;
// Ignore comments
if(*ptr == ':' || *ptr == '#' || (ptr[0] == '/' && ptr[1] == '/'))
{
ptr = skip_to_eol(ptr);
continue;
}
if(*ptr == '@') // '@' - commands
{
char cCmd[32];
int i;
ptr++;
while(__isic(ptr[j]) || ptr[j] == '.')
j++;
if(j == 0 || j >= sizeof(cCmd)) /* something wrong, wkip line */
{
ptr = skip_to_eol(ptr);
continue;
}
for(i = 0; i < j; i++)
cCmd[i] = __to_lower(ptr[i]);
cCmd[i] = 0;
ptr += j;
while(__issp(*ptr))
ptr++;
if(!strcmp(cCmd, "include")) //@include "some.file"
{
char cProgName[FED_MAXPATH];
do
{
int iDelim = *ptr;
if(iDelim != '\'' && iDelim != '"')
{
ptr = skip_to_eol(ptr);
break;
}
ptr++;
str = ptr;
while(*ptr && *ptr != iDelim && *ptr != '\r' && *ptr != '\n')
ptr++;
if(*ptr != iDelim)
{
if(*ptr != '\n')
ptr = skip_to_eol(ptr);
break;
}
int iSz = (ptr - str);
if(iSz <= 0 || iSz >= sizeof(cProgName))
{
ptr = skip_to_eol(ptr);
break;
}
memcpy(cProgName, str, iSz);
cProgName[iSz] = 0;
load_profile_file(cProgName);
ptr = skip_to_eol(ptr);
}
while(0);
}
else if(!strcmp(cCmd, "mode"))
{
do
{
j = 0;
while(__isic(ptr[j]) || ptr[j] == '+')
j++;
if(j == 0 || j >= sizeof(cCmd)) /* something wrong, wkip line */
{
ptr = skip_to_eol(ptr);
break;
}
for(i = 0; i < j; i++)
cCmd[i] = ptr[i];
cCmd[i] = 0;
ptr += j;
while(__issp(*ptr))
ptr++;
if(*ptr != '{')
{
ptr = skip_to_eol(ptr);
break;
}
ptr++;
str = ptr;
while(*ptr)
{
while(*ptr && *ptr != '}')
ptr++;
if(!*ptr)
break;
char* tmp = ptr + 1;
while(__issp(*tmp) && *tmp != '\n') //skip trailing spaces
tmp++;
if(*ptr == '}' && *tmp == '\n') //at the end of line!
break;
ptr++;
}
if(*ptr && *ptr != '}')
{
ptr = skip_to_eol(ptr);
break;
}
int iSz = (ptr - str);
char* compile = new char[iSz + 1];
for(i = 0; str < ptr; i++)
compile[i] = *str++;
compile[i] = 0;
//Parse it using recursive call to ourselves
//load_profile(compile, cCmd);
delete compile;
}
while(0);
}
else
ptr = skip_to_eol(ptr);
continue;
}
// Look for variable name
while(__isic(ptr[j]) || ptr[j] == '.')
j++;
if(j == 0) /* something wrong, wkip line */
{
ptr = skip_to_eol(ptr);
continue;
}
PPairDef pProf;
pProf = (PPairDef) prof_keys.IsIn(ptr, j, 0);
if(pProf)
{
//Process lines
//Skip everything up to first non-space character after delimiter
ptr += j;
while(__issp(*ptr))
ptr++;
if(*ptr != ':' && *ptr != '=')
{
ptr = skip_to_eol(ptr);
continue;
}
ptr++;
while(__issp(*ptr))
ptr++;
switch(pProf->type)
{
case P_INT:
case P_CHAR:
{
int iSign = 0;
int iValue = 0;
int iValid = 0;
if(*ptr == '-')
{
iSign = 1;
ptr++;
}
else
if(*ptr == '+')
{
iSign = 0;
ptr++;
}
if(ptr[0] == '0' && __to_upper(ptr[1]) == 'X')
{
ptr += 2;
while(__ishd(*ptr))
{
iValue <<= 4;
if(__to_upper(*ptr) > '9')
iValue |= __to_upper(*ptr) - 'A' + 0x0A;
else
iValue |= *ptr - '0';
ptr++;
iValid = 1;
}
}
else
{
while(__isdd(*ptr))
{
iValue *= 10;
iValue += *ptr - '0';
ptr++;
iValid = 1;
}
}
if(iValid)
{
if(iSign)
iValue = -iValue;
if(pProf->value)
{
if(pProf->type == P_CHAR)
*((char *)pProf->value) = (char)iValue;
if(pProf->type == P_INT)
*((int *)pProf->value) = (int)iValue;
}
}
ptr = skip_to_eol(ptr);
}
break;
case P_PSZ:
{
int iDelim = ptr[0];
char *pEOL = 0;
if(iDelim != '\'' && iDelim != '"')
{
//Ignore definition
ptr = skip_to_eol(ptr);
break;
}
//First pass - calculate length
int iLen = 0;
int iInside = 0;
str = ptr;
while(*ptr && !pEOL)
{
if(!iInside)
{
if(*ptr == '\'' || *ptr == '"')
{
iDelim = *ptr;
iInside = 1;
ptr++;
continue;
}
if(ptr[0] == ',' &&
(ptr[1] == '\r' || ptr[1] == '\n'))
{
//Include next line too
ptr++;
while(__issp(*ptr))
ptr++;
continue;
}
if(*ptr == '\n')
{
pEOL = ptr;
break;
}
ptr++;
continue;
}
if(*ptr == iDelim)
{
iInside = 0;
ptr++;
continue;
}
iLen++;
//Inside string
if(*ptr == '\\')
ptr++;
ptr++;
}
if(!pEOL)
pEOL = ptr;
//Second pass - copy string
char* pOut = new char[iLen + 1];
ptr = str;
str = pOut;
iInside = 0;
while(ptr != pEOL)
{
if(!iInside)
{
if(*ptr == '\'' || *ptr == '"')
{
iDelim = *ptr;
iInside = 1;
ptr++;
continue;
}
ptr++;
continue;
}
if(*ptr == iDelim)
{
iInside = 0;
ptr++;
continue;
}
//Inside string
if(*ptr == '\\')
{
ptr++;
char chr = *ptr;
if(chr == 'b') chr = '\b';
if(chr == 't') chr = '\t';
if(chr == 'n') chr = '\n';
if(chr == 'r') chr = '\r';
*str++ = chr;
ptr++;
continue;
}
*str++ = *ptr++;
}
*str = 0;
*(char **)(pProf->value) = pOut;
}
break;
}
continue;
}
if(__to_upper(ptr[0]) == 'K' &&
__to_upper(ptr[1]) == 'B' &&
j < KEY_NAME_LEN)
{
//Process keydef
str = ptr;
ptr += j;
while(__issp(*ptr))
ptr++;
if(*ptr != ':' && *ptr != '=')
{
ptr = skip_to_eol(ptr);
continue;
}
ptr++;
while(__issp(*ptr))
ptr++;
if(*ptr == '{') // REXX macro
{
while(*ptr)
{
while(*ptr && *ptr != '}')
ptr++;
if(!*ptr)
break;
char* tmp = ptr + 1;
while(__issp(*tmp) && *tmp != '\n') //skip trailing spaces
tmp++;
if(*ptr == '}' && *tmp == '\n') //at the end of line!
break;
ptr++;
}
}
else //Ordinary keydef
{
while(*ptr)
{
if(ptr[0] == ',' &&
(ptr[1] == '\r' || ptr[1] == '\n'))
{
//Include next line too
ptr++;
while(__issp(*ptr))
ptr++;
continue;
}
if(*ptr == '\n')
break;
ptr++;
}
}
if(*ptr)
{
*ptr = 0;
ptr++;
}
keys.InsKey(str, j);
continue;
}
//Ignore unrecognized line
ptr = skip_to_eol(ptr);
}
if(iUpperStatus != 0)
iUpperStatus = 1;
}