home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $PROJECT: c.datatype
- **
- ** $VER: dispatch.c 39.4 (01.04.95)
- **
- ** by
- **
- ** Stefan Ruppert , Windthorststraße 5 , 65439 Flörsheim , GERMANY
- **
- ** (C) Copyright 1995
- ** All Rights Reserved !
- **
- ** $HISTORY:
- **
- ** 01.04.95 : 039.004 : added GLOBAL template
- ** 23.03.95 : 039.003 : added TEXT arg, now full tabs handling
- ** 13.03.95 : 039.002 : autodoc completed
- ** 06.03.95 : 039.001 : initial
- */
-
- /* ------------------------------- include -------------------------------- */
-
- #include "classbase.h"
-
- /* ------------------------------- autodoc -------------------------------- */
-
- /*FS*/ /*"AutoDoc"*/
-
- /*GB*** c.datatype/c.datatype ************************************************
- *
- * NAME
- * c.datatype - data type for any c source
- *
- * FUNCTION
- * This datatype is designed to display C and C++ source codes. It
- * display's different parts of the C source in different style and
- * color.At the moment these parts are :
- * STANDARD - any text which, doesn't match the following parts
- * COMMENT - any comment such like \* ... *\ and // ...
- * CPP - any C-PreProcessor keyword like "#define" or "#include"
- * KEYWORD - any C/C++ keyword, which isn't handled explicitly
- * STORAGE - extern,static,register,auto keywords
- * TYPES - basic type keywords like int,char,long etc.
- * TYPENAME - any name following a struct,union,class or enum
- * STRING - any string or char literal
- * NUMBER - any number constant decimal,hex
- *
- * It uses a parser generated by bison with my yacc grammer.Because it's
- * a parser, it may occur a parse error on some unusual source code. If
- * this happens please send me a description of this parse error and
- * maybe the input file. So I can fix this problem !
- *
- * PREFS
- * Env:DataTypes/c.prefs with the following two ReadArgs() templates :
- *
- * - CPART/A/K,PEN/N/K,R=RED/N/K,G=GREEN/N/K,B=BLUE/N/K,ITALIC/S,BOLD/S,
- * UNDERLINED/S,TEXT/S
- *
- * CPART is one of the explaned cpart names like COMMENT or CPP.
- * PEN assigns the color with the pen number to the specified part
- * R,G,B defines a new color for the specified part. This color is
- * allocated with ObtainBestPenA(...,OBP_Precision,
- * PRECISION_ICON);
- * ITALIC,BOLD,UNDERLINED specifies the font style for the part
- * TEXT treat this CPART as normal text
- *
- * - GLOBAL/A/S,TABLENGTH/N/K
- *
- * GLOBAL indicates, that this line is a global setting. Note: The
- * /A/S combination isn't supported from ReadArgs(), so I check
- * it manually !
- * TABLENGTH - number of spaces to use for a tab !
- *
- * AUTHOR
- * Stefan Ruppert
- * Windthorststrasse 5
- * 65439 Floersheim am Main
- * Germany
- * EMail: ruppert@vs3.informatik.fh-wiesbaden.de
- *
- * SEE ALSO
- * text.datatype
- *
- ******************************************************************************
- *
- */
-
- /*FE*/
-
- /* ------------------------------- defines -------------------------------- */
-
- #define PUDDLE_SIZE 2048
- #define G(o) ((struct Gadget *) (o))
-
- #define BUFFER_SIZE 1024
- #define EOS '\0'
-
- /* ------------------------ preference definition ------------------------- */
-
- /*FS*/ /*"Definitions"*/
- const STRPTR prefstemplate[] = {
- { "CPART/A/K,PEN/N/K,R=RED/N/K,G=GREEN/N/K,B=BLUE/N/K,"
- "ITALIC/S,BOLD/S,UNDERLINED/S,TEXT/S" },
- { "GLOBAL/S,TABLENGTH/N/K" D(",DEBUG/S") },
- { NULL }};
-
- D(extern int cdtparse_debug;)
-
- enum
- {
- TMPLT_CPART,
- TMPLT_GLOBAL
- };
-
- enum
- {
- CPARTARG_CSECTION,
- CPARTARG_PEN,
- CPARTARG_RED,
- CPARTARG_GREEN,
- CPARTARG_BLUE,
- CPARTARG_ITALIC,
- CPARTARG_BOLD,
- CPARTARG_UNDERLINED,
- CPARTARG_TEXT,
- CPARTARG_MAX
- };
-
- enum
- {
- GLOBALARG_GLOBAL,
- GLOBALARG_TABLENGTH,
- #ifdef DEBUG
- GLOBALARG_DEBUG,
- #endif
- };
-
- const STRPTR cparts[C_MAX] =
- {
- "STANDARD",
- "COMMENT",
- "CPP",
- "KEYWORD",
- "STORAGE",
- "TYPES",
- "TYPENAME",
- "STRING",
- "NUMBER"
- };
-
- const struct Style defstyle[C_MAX] =
- {
- {1,0,FS_NORMAL }, /* C_STANDARD */
- {1,0,FSF_ITALIC }, /* C_COMMENT */
- {1,0,FSF_BOLD | FSF_ITALIC }, /* C_CPP */
- {2,0,FSF_BOLD }, /* C_KEYWORD */
- {1,0,FSF_UNDERLINED }, /* C_STORAGE */
- {1,0,FSF_BOLD }, /* C_TYPES */
- {2,0,FS_NORMAL }, /* C_TYPENAME */
- {3,0,FS_NORMAL }, /* C_STRING */
- {3,0,FSF_BOLD } /* C_NUMBER */
- };
- /*FE*/
-
- /* ------------------------------ init class ------------------------------ */
-
- /*FS*/ LibCall Class *initClass(REGA6 struct ClassBase *cb)
- {
- Class *cl;
-
- if((cl = MakeClass(DATATYPENAME,TEXTDTCLASS,NULL,sizeof(struct CData ),0)))
- {
- cl->cl_Dispatcher.h_Entry = (HOOKFUNC) dispatch;
- cl->cl_UserData = (ULONG) cb;
-
- AddClass(cl);
- }
-
- return(cl);
- }
- /*FE*/
-
- /* ------------------------------ read prefs ------------------------------ */
-
- /*FS*/ BOOL readPrefs(struct ClassBase *cb,struct CData *cd,STRPTR file)
- {
- struct RDArgs *rdargs;
- struct RDArgs *args;
- BPTR fh;
-
- ENTERING;
-
- if((fh = Open(file,MODE_OLDFILE)))
- {
- UBYTE buf[256];
- ULONG para[CPARTARG_MAX];
- LONG i;
-
- DB(("def file %s opened\n",file));
-
- while(FGets(fh,buf,sizeof(buf)))
- {
- const STRPTR *tmplt = prefstemplate;
- ULONG tmpltnr = 0;
- DB(("line : %s",buf));
-
- while(*tmplt)
- {
- if((rdargs = (struct RDArgs *) AllocDosObject(DOS_RDARGS,NULL)))
- {
- rdargs->RDA_Source.CS_Buffer = buf;
- rdargs->RDA_Source.CS_Length = strlen(buf);
-
- for(i=0 ; i < (sizeof(para)/sizeof(LONG)) ; i++)
- para[i]=0;
-
- DB(("rdargs at : %lx\n",rdargs));
-
- if((args = ReadArgs(*tmplt,(LONG *) para,rdargs)))
- {
- DB(("args at %lx\n",args));
-
- switch(tmpltnr)
- {
- case TMPLT_CPART:
- for(i = C_MAX - 1; i >= 0 ; i--)
- if(!Stricmp((STRPTR) para[CPARTARG_CSECTION],(STRPTR) cparts[i]))
- {
- struct Style *style = &cd->cd_CStyle[i];
-
- if(para[CPARTARG_TEXT])
- style->Style = (UWORD) ~0;
- else
- {
- if(para[CPARTARG_PEN])
- style->FgPen = (UWORD) *((ULONG *) para[CPARTARG_PEN]);
- else if(para[CPARTARG_RED] || para[CPARTARG_GREEN] || para[CPARTARG_BLUE])
- {
- struct PenNode *pen;
- if((pen = AllocPooled(cd->cd_Pool,sizeof(struct PenNode))))
- {
- pen->pn_Section = i;
- pen->pn_Pen = -1;
-
- if(para[CPARTARG_RED])
- pen->pn_Red = (*((ULONG *) para[CPARTARG_RED])) << 24;
- if(para[CPARTARG_GREEN])
- pen->pn_Green = (*((ULONG *) para[CPARTARG_GREEN])) << 24;
- if(para[CPARTARG_BLUE])
- pen->pn_Blue = (*((ULONG *) para[CPARTARG_BLUE])) << 24;
-
- AddTail(&cd->cd_PenList,(struct Node *) pen);
- }
- }
-
- style->Style = FS_NORMAL;
- if(para[CPARTARG_ITALIC])
- style->Style |= FSF_ITALIC;
- if(para[CPARTARG_BOLD])
- style->Style |= FSF_BOLD;
- if(para[CPARTARG_UNDERLINED])
- style->Style |= FSF_UNDERLINED;
- }
- }
- break;
- case TMPLT_GLOBAL:
- if(para[GLOBALARG_GLOBAL])
- {
- if(para[GLOBALARG_TABLENGTH])
- cd->cd_TabLength = *((ULONG *) para[GLOBALARG_TABLENGTH]);
-
- D({
- if(para[GLOBALARG_DEBUG])
- cdtparse_debug = 1;
- bug("yydebug is : %ld\n",cdtparse_debug);
- });
- }
- break;
- }
- }
-
- FreeDosObject(DOS_RDARGS , rdargs);
- }
- tmpltnr++;
- tmplt++;
- }
- }
- Close(fh);
- }
-
- LEAVING;
-
- return((BOOL) (fh == NULL));
- }
- /*FE*/
-
- /* ---------------------------- notify object ----------------------------- */
-
- /*FS*/ ULONG notifyAttrChanges(Object * o, void * ginfo, ULONG flags, ULONG tag1,...)
- {
- return(DoMethod(o, OM_NOTIFY, &tag1, ginfo, flags));
- }
- /*FE*/
-
- /* --------------------------- class dispatcher --------------------------- */
-
- /*FS*/ ClassCall ULONG dispatch(REGA0 Class *cl,REGA2 Object *obj,REGA1 Msg msg)
- {
- struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
- struct CData *cd = INST_DATA(cl,obj);
- ULONG retval;
-
- switch(msg->MethodID)
- {
- case OM_NEW:
- {
- Object *newobj;
- if((newobj = (Object *) DoSuperMethodA(cl,obj,msg)))
- {
- cd = INST_DATA(cl,newobj);
-
- NewList(&cd->cd_PenList);
- cd->cd_TabLength = 8;
-
- if((cd->cd_Pool = CreatePool(MEMF_CLEAR | MEMF_ANY , PUDDLE_SIZE,PUDDLE_SIZE)))
- {
- STRPTR buffer = NULL;
- ULONG bufferlen = 0;
-
- if(GetDTAttrs(newobj,TDTA_Buffer ,&buffer,
- TDTA_BufferLen ,&bufferlen,
- TAG_DONE) == 2 && buffer && bufferlen)
- {
- int i;
-
- for(i = 0 ; i < C_MAX ; i++)
- cd->cd_CStyle[i] = defstyle[i];
-
- if(readPrefs(cb,cd,"PROGDIR:Prefs/DataTypes/c.prefs"))
- readPrefs(cb,cd,"Env:DataTypes/c.prefs");
-
- retval = (ULONG) newobj;
- } else
- SetIoErr(ERROR_REQUIRED_ARG_MISSING);
- }
- }
-
- if(!retval)
- {
- D(bug("c.datatype error : %ld\n",IoErr()));
- CoerceMethod(cl,(Object *) retval,OM_DISPOSE);
- }
- }
- break;
- case OM_DISPOSE:
- {
- struct List *linelist;
- struct PenNode *pen;
-
- if(GetDTAttrs(obj,TDTA_LineList,&linelist,TAG_DONE) && linelist)
- NewList(linelist);
-
- while((pen = (struct PenNode *) RemHead(&cd->cd_PenList)))
- if(pen->pn_Pen != -1)
- ReleasePen(cd->cd_ColorMap,pen->pn_Pen);
-
- if(cd->cd_Pool)
- DeletePool(cd->cd_Pool);
-
- retval = DoSuperMethodA(cl,obj,msg);
- }
- break;
- case OM_SET:
- case OM_UPDATE:
- /* Pass the attributes to the super class and force a refresh
- * if we need it */
- if((retval = DoSuperMethodA (cl, obj, msg)) && (OCLASS (obj) == cl))
- {
- struct RastPort *rp;
-
- /* Get a pointer to the rastport */
- if((rp = ObtainGIRPort (((struct opSet *) msg)->ops_GInfo)))
- {
- struct gpRender gpr;
-
- /* Force a redraw */
- gpr.MethodID = GM_RENDER;
- gpr.gpr_GInfo = ((struct opSet *) msg)->ops_GInfo;
- gpr.gpr_RPort = rp;
- gpr.gpr_Redraw = GREDRAW_UPDATE;
- DoMethodA (obj, (Msg) &gpr);
-
- /* Release the temporary rastport */
- ReleaseGIRPort (rp);
- }
- }
- break;
- case GM_LAYOUT:
- /* Tell everyone that we are busy doing things */
- notifyAttrChanges (obj, ((struct gpLayout *) msg)->gpl_GInfo, NULL,
- GA_ID, G(obj)->GadgetID,
- DTA_Busy, TRUE,
- TAG_DONE);
- /* Let the super-class partake */
- retval = DoSuperMethodA (cl, obj, msg);
-
- /* We need to do this one asynchronously */
- retval += DoAsyncLayout (obj, (struct gpLayout *) msg);
- break;
- case DTM_PROCLAYOUT:
- /* Tell everyone that we are busy doing things */
- notifyAttrChanges (obj, ((struct gpLayout *) msg)->gpl_GInfo, NULL,
- GA_ID, G(obj)->GadgetID,
- DTA_Busy, TRUE,
- TAG_DONE);
-
- /* Let the super-class partake and then fall through to our layout method */
- DoSuperMethodA (cl, obj, msg);
- case DTM_ASYNCLAYOUT:
- /* Layout the text */
- retval = layout(cb, cl, obj, (struct gpLayout *) msg);
- break;
- default:
- retval = DoSuperMethodA(cl,obj,msg);
- }
-
- return(retval);
- }
- /*FE*/
-
- /*FS*/ GetA4 ULONG layout(struct ClassBase *cb, Class * cl, Object * obj, struct gpLayout * gpl)
- {
- struct DTSpecialInfo *si = (struct DTSpecialInfo *) G(obj)->SpecialInfo;
- struct CData *cd = INST_DATA(cl,obj);
-
- struct CParse cparse;
- struct RastPort trp;
-
- ULONG visible;
- ULONG hunit;
-
- ULONG total = 0;
- ULONG bsig = 0;
-
- /* Attributes obtained from super-class */
- struct TextAttr *tattr;
- struct TextFont *font;
- struct List *linelist;
- ULONG bufferlen;
- STRPTR buffer;
-
- struct IBox *domain;
- STRPTR title;
-
- D(bug("layout !\n"));
-
- /* Get all the attributes that we are going to need for a successful layout */
- if(GetDTAttrs(obj,DTA_TextFont, (ULONG) &font,
- DTA_TextAttr, (ULONG) &tattr,
- DTA_Domain, (ULONG) &domain,
- DTA_ObjName, (ULONG) &title,
- TDTA_LineList, (ULONG) &linelist,
- TDTA_Buffer, (ULONG) &buffer,
- TDTA_BufferLen,(ULONG) &bufferlen,
- TAG_DONE) == 7)
- {
- ULONG maxwidth = 0;
-
- /* Lock the global object data so that nobody else can manipulate it */
- ObtainSemaphore (&(si->si_Lock));
-
- /* Make sure we have a buffer */
- if(buffer)
- {
- /* Initialize the temporary RastPort */
- InitRastPort (&trp);
- SetFont (&trp, font);
-
- /* We only need to perform layout if we are doing word wrap, or this
- * is the initial layout call */
- if (gpl->gpl_Initial)
- {
- struct PenNode *pen;
-
- if((cd->cd_ColorMap = gpl->gpl_GInfo->gi_Screen->ViewPort.ColorMap))
- {
- for(pen = (struct PenNode *) cd->cd_PenList.lh_Head ;
- pen->pn_Node.mln_Succ ;
- pen = (struct PenNode *) pen->pn_Node.mln_Succ)
- {
- pen->pn_Pen = ObtainBestPen(cd->cd_ColorMap,
- pen->pn_Red,pen->pn_Green,pen->pn_Blue,
- OBP_Precision , PRECISION_ICON,
- TAG_DONE);
- DB(("pen : %ld allocated for section %ld with RGB : %lx %lx %lx\n",
- pen->pn_Pen,pen->pn_Section,pen->pn_Red,pen->pn_Green,pen->pn_Blue));
-
- if(pen->pn_Pen != -1)
- cd->cd_CStyle[pen->pn_Section].FgPen = pen->pn_Pen;
- }
- }
-
- cparse.BegPtr = buffer;
- cparse.ActPtr = buffer;
- cparse.TxtPtr = buffer;
- cparse.SegPtr = buffer;
- cparse.EndPtr = buffer + bufferlen;
- cparse.TabWidth = TextLength(&trp," ",1);
- cparse.Mode = C_STANDARD;
-
- cparse.XOffset = 0;
- cparse.YOffset = 0;
- cparse.MaxWidth = 0;
-
- cparse.LineList = linelist;
- cparse.RPort = &trp;
- cparse.Data = cd;
-
- D({ BPTR fh;
- BPTR oldfh;
- if(cdtparse_debug)
- if((fh = Open("CON:////C-DataType YYDebug/WAIT/CLOSE",MODE_NEWFILE)))
- oldfh = SelectOutput(fh);
- );
-
- cdtparse_parse(cb,&cparse);
-
- cdtparse_free(cb,&cparse);
-
- D( if(fh && cdtparse_debug)
- {
- SelectOutput(oldfh);
- Close(fh);
- }
- }
- );
-
- total = cparse.YOffset / font->tf_YSize;
- maxwidth = cparse.MaxWidth;
- }
- else
- {
- /* No layout to perform */
- total = si->si_TotVert;
- maxwidth = si->si_TotHoriz;
- }
- }
-
- /* Compute the lines and columns type information */
- si->si_VertUnit = font->tf_YSize;
- si->si_VisVert = visible = domain->Height / si->si_VertUnit;
- si->si_TotVert = total;
-
- si->si_HorizUnit = hunit = 1;
- si->si_VisHoriz = (LONG) domain->Width / hunit;
- si->si_TotHoriz = maxwidth;
-
- /* Release the global data lock */
- ReleaseSemaphore(&si->si_Lock);
-
- /* Were we aborted? */
- if (bsig == 0)
- {
- /* Not aborted, so tell the world of our newest attributes */
- notifyAttrChanges (obj, gpl->gpl_GInfo, NULL,
- GA_ID, G(obj)->GadgetID,
-
- DTA_VisibleVert, visible,
- DTA_TotalVert, total,
- DTA_NominalVert, font->tf_YSize * 25,
- DTA_VertUnit, font->tf_YSize,
-
- DTA_VisibleHoriz, (ULONG) (domain->Width / hunit),
- DTA_TotalHoriz, maxwidth,
- DTA_NominalHoriz, font->tf_XSize * 80,
- DTA_HorizUnit, hunit,
-
- DTA_Title, title,
- DTA_Busy, FALSE,
- DTA_Sync, TRUE,
- TAG_DONE);
- }
- }
-
- return(total);
- }
- /*FE*/
-
-