home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 20 / AACD20.BIN / AACD / Programming / AmIDE / developer / example / sasc.module.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-04  |  19.6 KB  |  766 lines

  1. /*
  2. **  $Id: sasc.module.c,v 1.3 2001/03/04 18:56:04 damato Exp $
  3. **
  4. **  AmIDE - Amiga Integrated Development Environment
  5. **          API Functions
  6. **
  7. **  Copyright (C) 1998-2001 by
  8. **
  9. **  LightSpeed Communications GbR
  10. **
  11. **  Jens Langner                        Jens Troeger
  12. **  Bergstrasse 68                      i4/182 Dornoch Tce
  13. **  01069 Dresden                       Highgate Hill, QLD, 4101
  14. **  Germany                             Australia
  15. **  <damato@light-speed.de>             <savage@light-speed.de>
  16. **
  17. **  This program is free software; you can redistribute it and/or modify
  18. **  it under the terms of the GNU General Public License as published by
  19. **  the Free Software Foundation; either version 2 of the License, or
  20. **  any later version.
  21. **
  22. **  This program is distributed in the hope that it will be useful,
  23. **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25. **  GNU General Public License for more details.
  26. **
  27. **  You should have received a copy of the GNU General Public License
  28. **  along with this program; if not, write to the Free Software
  29. **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  30. **
  31. */
  32.  
  33. #define __USE_SYSBASE        // perhaps only recognized by SAS/C
  34.  
  35. #include <clib/alib_protos.h>
  36. #include <dos/dostags.h>
  37. #include <exec/types.h>
  38. #include <exec/memory.h>
  39. #include <utility/hooks.h>
  40. #include <proto/utility.h>
  41. #include <proto/dos.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <clib/debug_protos.h>
  45. #include <string.h>
  46.  
  47. #ifdef __MAXON__
  48. #include <clib/exec_protos.h>
  49. #include <clib/intuition_protos.h>
  50. #else
  51. #include <proto/exec.h>
  52. #include <proto/intuition.h>
  53. #include <intuition/intuition.h>
  54. #endif
  55.  
  56. #include <proto/exec.h>
  57.  
  58. #include "compiler.h"
  59. #include "sasc.module.h"
  60.  
  61. #include <amide/amide_api.h>
  62. #include <clib/savage_protos.h>
  63.  
  64. /*
  65. ** Global variables
  66. */
  67.  
  68. struct IClass *cl = 0;
  69.  
  70. #ifdef DEBUG
  71. static const char *id="@(#) $Id: sasc.module.c,v 1.3 2001/03/04 18:56:04 damato Exp $";
  72. #endif
  73.  
  74. /*
  75. ** AmIDE_API_GetClass
  76. **
  77. ** This is the only public function of the shared library
  78. ** It should only return the created class from the LibInit.c
  79. **
  80. ** parameters:
  81. ** ~~~~~~~~~~~
  82. ** void
  83. **
  84. ** Rückgabewerte:
  85. ** ~~~~~~~~~~~~~
  86. ** struct IClass *: Pointer to the created Class
  87. */
  88.  
  89. SAVEDS ASM struct IClass *AmIDE_API_GetClass(void)
  90. {
  91.   return(cl);
  92. }
  93.  
  94. /***************************************************************************************
  95. **
  96. ** Here follows the internal Methods and dispatcher function
  97. **
  98. */
  99.  
  100. /*
  101. ** AmIDE_API_New
  102. **
  103. ** Method to create the object
  104. **
  105. ** Übergabeparameter:
  106. ** ~~~~~~~~~~~~~~~~~
  107. ** Class *:  Die aufrufende Klasse
  108. ** Object *: Das Objekt
  109. ** struct opSet *: Die Message
  110. **
  111. ** Rückgabewerte:
  112. ** ~~~~~~~~~~~~~
  113. ** METHOD: Das neue Objekt
  114. */
  115.  
  116. METHOD MODULE_New(Class *cl, Object *obj, struct opSet *msg)
  117. {
  118.   struct MODS_InstData *Data;
  119.  
  120.   Object *newobj;
  121.  
  122.   #ifdef DEBUG
  123.   DEBUG_MAKRO
  124.   #endif
  125.  
  126.   if(newobj = (Object *)DoSuperMethodA(cl, obj, (Msg) msg))
  127.   {
  128.     // get the InstData
  129.     Data  = INST_DATA(cl, newobj);
  130.  
  131.     // get the attributes from the NewObject() call
  132.     Data->parent_obj = (Object *)GetTagData(AmIDEA_API_parentObj, NULL, msg->ops_AttrList);
  133.   }
  134.  
  135.   return((ULONG)newobj);
  136. }
  137.  
  138. /*
  139. ** AmIDE_API_Get
  140. **
  141. ** Method to get attributes of an object
  142. **
  143. ** parameters:
  144. ** ~~~~~~~~~~
  145. ** Class *        : The created class
  146. ** Object *       : The object
  147. ** struct opGet * : The opGet Message
  148. **
  149. ** return-values:
  150. ** ~~~~~~~~~~~~~~
  151. ** METHOD: 0 at sucess
  152. */
  153.  
  154. METHOD MODULE_Get(Class *cl, Object *obj, struct opGet *msg)
  155. {
  156.   #ifdef DEBUG
  157.   DEBUG_MAKRO
  158.   #endif
  159.  
  160.   switch (msg->opg_AttrID)
  161.   {
  162.     case AmIDEA_API_author:   { *(msg -> opg_Storage) = (ULONG)AUTHOR;          } break;
  163.     case AmIDEA_API_api_vers: { *(msg -> opg_Storage) = (ULONG)API_VERS;        } break;
  164.     case AmIDEA_API_lib_vers: { *(msg -> opg_Storage) = (ULONG)LIBNAME LIBVER;  } break;
  165.     case AmIDEA_API_compiler: { *(msg -> opg_Storage) = (ULONG)COMPILER;        } break;
  166.  
  167.     default: { DoSuperMethodA(cl, obj, (Msg) msg); break; };
  168.   }
  169.  
  170.   return(0);
  171. }
  172.  
  173. /*
  174. ** AmIDE_API__Set
  175. ** The OM_SET Method of the object
  176. ** With this method all attributes will be set
  177. **
  178. ** parameters:
  179. ** ~~~~~~~~~~
  180. ** Class *        : The created class
  181. ** Object *       : The object
  182. ** struct opSet * : The opSet Message structure
  183. **
  184. ** return values:
  185. ** ~~~~~~~~~~~~~
  186. ** 0
  187. */
  188.  
  189. METHOD MODULE_Set(Class *cl, Object *obj, struct opSet *msg)
  190. {
  191.   struct MODS_InstData *Data = INST_DATA(cl, obj);
  192.   struct TagItem *newdata;
  193.  
  194.   #ifdef DEBUG
  195.   DEBUG_MAKRO
  196.   #endif
  197.  
  198.   // find the TagItem and set the variable
  199.   if (newdata = FindTagItem(AmIDEA_API_parentObj, msg -> ops_AttrList))
  200.   {
  201.     Data->parent_obj = (Object *)(newdata->ti_Data);
  202.   }
  203.  
  204.   // All other item are not belonging to us
  205.   DoSuperMethodA(cl, obj, (Msg) msg);
  206.  
  207.   return(0);
  208. }
  209.  
  210. /*
  211. ** AmIDE_API_compile
  212. **
  213. ** This method is the MAIN Method of this shared-library.
  214. ** It handles all the compilation stuff. Will start the compiler with the correct options
  215. ** and also returns the compiler messages by calling a AmIDE Method.
  216. ** It should also preparse the messages and insert standard MUI-NList styles to the
  217. ** message
  218. **
  219. ** parameters:
  220. ** ~~~~~~~~~~
  221. ** Class *  : The created class
  222. ** Object * : The object
  223. ** Msg      : The Message
  224. **
  225. ** return-values:
  226. ** ~~~~~~~~~~~~~~
  227. ** METHOD: 0 at sucess
  228. */
  229.  
  230. METHOD MODULE_Compile(Class *cl, Object *obj, struct AmIDEP_API_compile_Message *msg)
  231. {
  232.   struct MODS_InstData *Data = INST_DATA(cl, obj);
  233.  
  234.   char command[256];
  235.   BPTR fh, nil;
  236.  
  237.   #ifdef DEBUG
  238.   DEBUG_MAKRO
  239.   #endif
  240.  
  241.   // Set log position to zero
  242.   Data->log_position = 0;
  243.  
  244.   // create logfile-name
  245.   sprintf(Data->logfile, "T:AmIDE-%s-compile.log", FilePart(msg->filename));
  246.  
  247.   // delete existing log-file
  248.   DeleteFile(Data->logfile);
  249.  
  250.   fh = Open(Data->logfile, MODE_READWRITE);
  251.   nil = Open("NIL:", MODE_OLDFILE);
  252.  
  253.   if(fh)
  254.   {
  255.     BOOL rc;
  256.  
  257.     // create the execute command
  258.     sprintf(command, "sc:c/sc %s VERBOSE", msg->filename);
  259.  
  260.     rc = SystemTags(  command,
  261.                       SYS_Input,      nil,
  262.                       SYS_Output,     fh,
  263.                       SYS_Asynch,     TRUE,
  264.                       SYS_UserShell,  TRUE,
  265.                       NP_Priority,    0,
  266.                       NP_Error,       fh,
  267.                       NP_WindowPtr,   NULL,
  268.                       NP_Cli,         TRUE,
  269.                       TAG_DONE);
  270.  
  271.     if(!rc)
  272.     {
  273.       BPTR lock;
  274.  
  275.       while(!(lock = Lock(Data->logfile, ACCESS_WRITE)))
  276.       {
  277.         // Das Logfile einlesen
  278.         DoMethod(obj, MODM_Logfile_Read, TAG_DONE);
  279.       }
  280.       if(lock) UnLock(lock);
  281.  
  282.       // if there are something left in the logfile
  283.       while(Data->log_position != sav_FileSize(Data->logfile)) DoMethod(obj, MODM_Logfile_Read, TAG_DONE);
  284.  
  285.     }
  286.  
  287.   }
  288.  
  289.   return(0);
  290. }
  291.  
  292. /*
  293. ** MODULE_Link
  294. ** Method to link all files passed in the message
  295. **
  296. ** parameters:
  297. ** ~~~~~~~~~~~
  298. ** Class * : the class itself
  299. ** Object *: the object
  300. ** Msg     : the AmIDEP_API_link_Message
  301. **
  302. ** return-values:
  303. ** ~~~~~~~~~~~~~~
  304. ** METHOD: The new object or NULL
  305. */
  306.  
  307. METHOD MODULE_Link(Class *cl, Object *obj, struct AmIDEP_API_link_Message *msg)
  308. {
  309.   struct MODS_InstData *Data = INST_DATA(cl, obj);
  310.  
  311.   STRPTR *file_array = msg->file_array;
  312.   STRPTR exe_name    = msg->exe_name;
  313.  
  314.   char obj_list[1024] = "";
  315.   char lib_list[1024] = "";
  316.   char command[256];
  317.   BOOL rc;
  318.   BPTR lock;
  319.   BPTR fh, nil;
  320.   LONG i;
  321.  
  322.   #ifdef DEBUG
  323.   DEBUG_MAKRO
  324.   #endif
  325.  
  326.   // Now we have to create the temporary WITH file
  327.   for(i=0; file_array[i]; i++)
  328.   {
  329.     // Now we search for .lib files so that this one will be linked together with the other object files
  330.     if(sav_MatchPatternNoCase("#?.lib", file_array[i]))
  331.     {
  332.       strcat(lib_list, file_array[i]);
  333.       strcat(lib_list, " ");
  334.  
  335.     }else
  336.     {
  337.       strcat(obj_list, file_array[i]);
  338.       strcat(obj_list, " ");
  339.     }
  340.   }
  341.  
  342.   if(fh = Open("T:AmIDE.tmp", MODE_NEWFILE))
  343.   {
  344.     FPrintf(fh, "VERBOSE\n");
  345.     FPrintf(fh, "TO %s\n", exe_name);
  346.     FPrintf(fh, "FROM %s\n", obj_list);
  347.     FPrintf(fh, "LIBRARY %s\n", lib_list);
  348.  
  349.     Close(fh);
  350.   }
  351.  
  352.   strcpy(command, "sc:c/slink WITH T:AmIDE.tmp");
  353.  
  354.   // first we set the log position to zero
  355.   Data->log_position = 0;
  356.  
  357.   // create logfile-name
  358.   strcpy(Data->logfile, "T:AmIDE-link.log");
  359.  
  360.   // delete a existing log file first
  361.   DeleteFile(Data->logfile);
  362.  
  363.   fh = Open(Data->logfile, MODE_READWRITE);
  364.   nil = Open("NIL:", MODE_OLDFILE);
  365.  
  366.   if(fh)
  367.   {
  368.     rc = SystemTags(  command,
  369.                       SYS_Input,      nil,
  370.                       SYS_Output,     fh,
  371.                       SYS_Asynch,     TRUE,
  372.                       SYS_UserShell,  TRUE,
  373.                       NP_Priority,    0,
  374.                       NP_Error,       fh,
  375.                       NP_WindowPtr,   NULL,
  376.                       NP_Cli,         TRUE,
  377.                       TAG_DONE);
  378.  
  379.     if(!rc)
  380.     {
  381.  
  382.       while(!(lock = Lock(Data->logfile, ACCESS_WRITE)))
  383.       {
  384.         // read the logfile now
  385.         DoMethod(obj, MODM_Logfile_Read, TAG_DONE);
  386.       }
  387.       if(lock) UnLock(lock);
  388.  
  389.       // check if there is something left in the logfile and read the rest again
  390.       while(Data->log_position != sav_FileSize(Data->logfile)) DoMethod(obj, MODM_Logfile_Read, TAG_DONE);
  391.     }
  392.  
  393.   }
  394.  
  395.   return(0);
  396. }
  397.  
  398. /*
  399. ** MODULE_Log_Read
  400. ** Method for reading the logfile and parsing it step by step
  401. **
  402. ** parameters:
  403. ** ~~~~~~~~~~~
  404. ** Class * : the class itself
  405. ** Object *: the object
  406. ** Msg     : the Message
  407. **
  408. ** return-values:
  409. ** ~~~~~~~~~~~~~~
  410. ** METHOD: NULL
  411. */
  412.  
  413. METHOD MODULE_Log_Read(Class *cl, Object *obj, Msg msg)
  414. {
  415.   struct MODS_InstData *Data = INST_DATA(cl, obj);
  416.  
  417.   STRPTR  buffer, endstring;
  418.   BPTR    mfile;
  419.   ULONG   size = Data->log_position;
  420.   ULONG   newsize;
  421.   APTR    tmpbuf;
  422.  
  423.   #ifdef DEBUG
  424.   DEBUG_MAKRO
  425.   #endif
  426.  
  427.   newsize = sav_FileSize(Data->logfile);
  428.  
  429.   if(size != newsize && newsize > 0)
  430.   {
  431.     if(mfile = Open(Data->logfile, MODE_OLDFILE))
  432.     {
  433.         buffer = tmpbuf = sav_AllocVec(((newsize-size)+1) * sizeof(char), MEMF_ANY);
  434.  
  435.         if(!buffer || !tmpbuf)
  436.         {
  437.           Close(mfile);
  438.           return(0);
  439.         }
  440.  
  441.         Seek(mfile, size, OFFSET_BEGINNING);
  442.         FRead(mfile, buffer, 1, (newsize-size));
  443.         Close(mfile);
  444.  
  445.         while(endstring = strchr(buffer, '\n'))
  446.         {
  447.             *endstring = 0;
  448.             Data->msg_text = buffer;
  449.             DoMethod(obj, MODM_Msg_Parse, 0);
  450.             buffer = endstring + 1;
  451.         }
  452.  
  453.         // If there is already a string
  454.         if(strlen(buffer) > 0)
  455.         {
  456.           Data->msg_text = buffer;
  457.           DoMethod(obj, MODM_Msg_Parse, 0);
  458.           newsize = newsize + 1;
  459.         }
  460.  
  461.         // set the position to which we parsed the logfile yet
  462.         Data->log_position = newsize;
  463.  
  464.         sav_FreeVec(tmpbuf);
  465.     }
  466.   }
  467.  
  468.   return(0);
  469. }
  470.  
  471. /*
  472. ** MODULE_Msg_Parse
  473. ** Method to parse the strings from the logfile and modify them to get it back to AmIDE
  474. **
  475. ** parameters:
  476. ** ~~~~~~~~~~~
  477. ** Class * : the class itself
  478. ** Object *: the object
  479. ** Msg     : the Message
  480. **
  481. ** return-values:
  482. ** ~~~~~~~~~~~~~~
  483. ** METHOD: the new object or NULL
  484. */
  485.  
  486. METHOD MODULE_Msg_Parse(Class *cl, Object *obj, Msg msg)
  487. {
  488.   struct MODS_InstData *Data = INST_DATA(cl, obj);
  489.  
  490.   #ifdef DEBUG
  491.   DEBUG_MAKRO
  492.   #endif
  493.  
  494.   /*
  495.   ** messages that we ignore and don`t want to be displayed in AmIDE
  496.   */
  497.  
  498.   if(strlen(Data->msg_text) < 4)                          return(0);
  499.   if(strstr(Data->msg_text, "Using options file"))        return(0);
  500.   if(strstr(Data->msg_text, "Pass1 for"))                 return(0);
  501.   if(strstr(Data->msg_text, "Pass2 for"))                 return(0);
  502.   if(strstr(Data->msg_text, "\033[F"))                    return(0);
  503.   if(strstr(Data->msg_text, "\033[K"))                    return(0);
  504.   if(strstr(Data->msg_text, "Slink -"))                   return(0);
  505.  
  506.   /*
  507.   ** The following messages are relevant ones so we insert them with MODM_Msg_Insert into the AmIDE MsgBrowser
  508.   */
  509.  
  510.   if(strcmp(Data->msg_text, "====================") == 0) { return(DoMethod(obj, MODM_Msg_Insert, MODA_MSG_BAR,         TAG_DONE));  };
  511.   if(strstr(Data->msg_text, " Warning "))                 { return(DoMethod(obj, MODM_Msg_Insert, MODA_MSG_WARNING,     TAG_DONE));  };
  512.   if(strstr(Data->msg_text, " Note "))                    { return(DoMethod(obj, MODM_Msg_Insert, MODA_MSG_NOTE,        TAG_DONE));  };
  513.   if(strstr(Data->msg_text, "\033[33;7m"))                { return(DoMethod(obj, MODM_Msg_Insert, MODA_MSG_WARNING_TXT, TAG_DONE));  };
  514.   if(strstr(Data->msg_text, " Error "))                   { return(DoMethod(obj, MODM_Msg_Insert, MODA_MSG_ERROR,       TAG_DONE));  };
  515.   if(strstr(Data->msg_text, "Compiler Phase 1"))          { return(DoMethod(obj, MODM_Msg_Insert, MODA_MSG_COMPILER_P1, TAG_DONE));  };
  516.   if(strstr(Data->msg_text, "Compiler Phase 2"))          { return(DoMethod(obj, MODM_Msg_Insert, MODA_MSG_COMPILER_P2, TAG_DONE));  };
  517.   if(strstr(Data->msg_text, "Global Optimizer"))          { return(DoMethod(obj, MODM_Msg_Insert, MODA_MSG_OPTIMIZER,   TAG_DONE));  };
  518.  
  519.  
  520.   return(DoMethod(obj, MODM_Msg_Insert, MODA_MSG_DEFAULT, TAG_DONE));
  521. }
  522.  
  523. /*
  524. ** MODULE_Msg_Insert
  525. ** Method to send the parsed strings to AmIDE in the correct format
  526. **
  527. ** parameters:
  528. ** ~~~~~~~~~~~
  529. ** Class * : the class itself
  530. ** Object *: the object
  531. ** Msg     : the MODS_Msg_Insert Message
  532. **
  533. ** return-values:
  534. ** ~~~~~~~~~~~~~~
  535. ** METHOD: The new object or NULL
  536. */
  537.  
  538. METHOD MODULE_Msg_Insert(Class *cl, Object *obj, struct MODS_Msg_Insert *msg)
  539. {
  540.   struct MODS_InstData *Data = INST_DATA(cl, obj);
  541.  
  542.   // First we allocate memory for a message
  543.   struct AmIDES_message *message = sav_AllocVec(sizeof(struct AmIDES_message), MEMF_ANY);
  544.  
  545.   #ifdef DEBUG
  546.   DEBUG_MAKRO
  547.   #endif
  548.  
  549.   if(!message) return(0);
  550.  
  551.   // fill it with some standard values
  552.   message->errnr = -1;
  553.   message->line  = -1;
  554.   message->text  = NULL;
  555.  
  556.   // Depending on the message type we are going to modify it different and send it to AmIDE
  557.   switch(msg->msg_type)
  558.   {
  559.     //
  560.     // If this is a BAR we send a MUI BAR string
  561.     //
  562.     case MODA_MSG_BAR:
  563.     {
  564.       message->text = sav_AllocVec((strlen(AmIDE_MSG_STYLE_BAR)+10)*sizeof(char), MEMF_ANY);
  565.       if(!message->text) return(0);
  566.  
  567.       strcpy(message->text, AmIDE_MSG_STYLE_BAR);
  568.  
  569.       message->type = AmIDE_MSG_DEFAULT;
  570.     }
  571.     break;
  572.  
  573.     //
  574.     // If this is a NOTE/EROOR or WARNING we do the following
  575.     //
  576.     case MODA_MSG_NOTE:
  577.     case MODA_MSG_ERROR:
  578.     case MODA_MSG_WARNING:
  579.     {
  580.       int    pos;
  581.       char   tmp_str2[256];
  582.       char   tmp_type[256];
  583.       STRPTR tmp_errnr;
  584.       STRPTR tmp_line;
  585.       STRPTR tmp_str;
  586.  
  587.       //
  588.       // Now we parse the string and get out error-number and line-number
  589.  
  590.       // read the message text
  591.       tmp_str = strstr(Data->msg_text, ": ")+2;
  592.  
  593.       message->text = sav_AllocVec((strlen(tmp_str)+1)*sizeof(char), MEMF_ANY);
  594.       if(!message->text) return(0);
  595.       strcpy(message->text, tmp_str);
  596.  
  597.       // now we get the error/warning number out of the string
  598.       pos = strlen(Data->msg_text)-strlen(tmp_str)-2;
  599.       strncpy(tmp_str2, Data->msg_text, pos);
  600.       tmp_str2[pos] = '\0';
  601.       tmp_errnr = strrchr(tmp_str2, ' ')+1;
  602.  
  603.       message->errnr = atol(tmp_errnr);
  604.  
  605.       // now lets get the line number
  606.       tmp_str2[strlen(tmp_str2)-strlen(tmp_errnr)-1] = '\0';
  607.       strcpy(tmp_type, strrchr(tmp_str2, ' ')+1);
  608.       tmp_str2[strlen(tmp_str2)-strlen(tmp_type)-1] = '\0';
  609.       tmp_line = strrchr(tmp_str2, ' ')+1;
  610.  
  611.       message->line = atol(tmp_line);
  612.  
  613.       switch(msg->msg_type)
  614.       {
  615.         case MODA_MSG_NOTE:     { message->type = AmIDE_MSG_NOTE;     } break;
  616.         case MODA_MSG_ERROR:    { message->type = AmIDE_MSG_ERROR;    } break;
  617.         case MODA_MSG_WARNING:  { message->type = AmIDE_MSG_WARNING;  } break;
  618.       }
  619.     }
  620.     break;
  621.  
  622.     //
  623.     // If this is the text of a warning message
  624.     //
  625.     case MODA_MSG_WARNING_TXT:
  626.     {
  627.       LONG tmp;
  628.       STRPTR tmp_str = Data->msg_text;
  629.  
  630.       message->text = sav_AllocVec(256*sizeof(char),  MEMF_ANY);
  631.       if(!message->text) return(0);
  632.  
  633.       // Now we copy everything in front of the ANSI characters
  634.       tmp = (strlen(tmp_str)-strlen(strstr(tmp_str, "\033[33;7m")));
  635.       strncpy(message->text, tmp_str, tmp);
  636.  
  637.       // Now insert some ESC sequences for MUI
  638.       strcat(message->text, AmIDE_MSG_STYLE_TXT_START);
  639.  
  640.       // Now we copy the text in between of the ANSI chars.
  641.       tmp_str += (tmp+7);
  642.  
  643.       tmp =  (strlen(tmp_str)-strlen(strstr(tmp_str, "\033[0m")));
  644.       strncat(message->text, tmp_str, tmp);
  645.  
  646.       // and again we append some ESC sequeneces
  647.       strcat(message->text, AmIDE_MSG_STYLE_TXT_STOP);
  648.  
  649.       // and don`t forget the rest of the text
  650.       tmp_str += (tmp+4);
  651.       strcat(message->text, tmp_str);
  652.  
  653.       message->type = AmIDE_MSG_WARNING;
  654.     }
  655.     break;
  656.  
  657.     //
  658.     // For Compiler-Phase1 messages of SAS/C
  659.     //
  660.     case MODA_MSG_COMPILER_P1:
  661.     {
  662.       message->status = "compiling phase1...";
  663.  
  664.       message->text = sav_AllocVec((strlen(AmIDE_MSG_STYLE_PHASES "Compiler Phase 1:")+1)*sizeof(char), MEMF_ANY);
  665.       strcpy(message->text, AmIDE_MSG_STYLE_PHASES "Compiler Phase 1:");
  666.  
  667.       message->type = AmIDE_MSG_DEFAULT;
  668.     }
  669.     break;
  670.  
  671.     //
  672.     // For Compiler-Phase2 messages of SAS/C
  673.     //
  674.     case MODA_MSG_COMPILER_P2:
  675.     {
  676.       message->status = "compiling phase2...";
  677.  
  678.       message->text = sav_AllocVec((strlen(AmIDE_MSG_STYLE_PHASES "Compiler Phase 2:")+1)*sizeof(char), MEMF_ANY);
  679.       strcpy(message->text, AmIDE_MSG_STYLE_PHASES "Compiler Phase 2:");
  680.  
  681.       message->type = AmIDE_MSG_DEFAULT;
  682.     }
  683.     break;
  684.  
  685.     //
  686.     // For Global-Optimizer messages
  687.     //
  688.     case MODA_MSG_OPTIMIZER:
  689.     {
  690.       message->status = "global optimizing...";
  691.  
  692.       message->text = sav_AllocVec((strlen(AmIDE_MSG_STYLE_PHASES "Global Optimizer:")+1)*sizeof(char), MEMF_ANY);
  693.       strcpy(message->text, AmIDE_MSG_STYLE_PHASES "Global Optimizer:");
  694.  
  695.       message->type = AmIDE_MSG_DEFAULT;
  696.     }
  697.     break;
  698.  
  699.     //
  700.     // For default messages we just send the whole string
  701.     //
  702.     case MODA_MSG_DEFAULT:
  703.     {
  704.       message->text = sav_AllocVec((strlen(Data->msg_text)+1)*sizeof(char),   MEMF_ANY);
  705.       strcpy(message->text, Data->msg_text);
  706.  
  707.       message->type = AmIDE_MSG_DEFAULT;
  708.     }
  709.     break;
  710.   }
  711.  
  712.   // main method call to insert the message into AmIDE
  713.   DoMethod(Data->parent_obj, AmIDEM_msginsert, message, TAG_DONE);
  714.  
  715.   // Now lets free the allocated stuff
  716.   if(message->text)   sav_FreeVec(message->text);
  717.   if(message)         sav_FreeVec(message);
  718.  
  719.   return(0);
  720. }
  721.  
  722.  
  723. /*
  724. ** MODULE_Dispatcher
  725. **
  726. ** This is the dispatcher for the module library
  727. **
  728. ** parameters
  729. ** ~~~~~~~~~~
  730. ** Class *    (a0): the class of the object
  731. ** Object *   (a2): the object
  732. ** Msg        (a1): the message (METHOD_IDs)
  733. **
  734. ** return-values:
  735. ** ~~~~~~~~~~~~~~
  736. ** ULONG: the new object
  737. */
  738.  
  739. SAVEDS ASM ULONG MODULE_Dispatcher(REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) Msg msg)
  740. {
  741.   #ifdef DEBUG
  742.   DEBUG_MAKRO
  743.   #endif
  744.  
  745.   switch (msg->MethodID)
  746.   {
  747.     // public Methods (defined in the API)
  748.     case OM_NEW                     : return(MODULE_New         (cl, obj, (APTR)msg));
  749.     case OM_GET                     : return(MODULE_Get         (cl, obj, (APTR)msg));
  750.     case OM_SET                     : return(MODULE_Set         (cl, obj, (APTR)msg));
  751.     case AmIDEM_API_compile         : return(MODULE_Compile     (cl, obj, (APTR)msg));
  752.     case AmIDEM_API_link            : return(MODULE_Link        (cl, obj, (APTR)msg));
  753.  
  754. // Not implemented yet:
  755. //    case AmIDEM_API_break           : return(MODULE_break       (cl, obj, (APTR)msg));
  756. //    case AmIDEM_API_prefs           : return(MODULE_prefs       (cl, obj, (APTR)msg));
  757.  
  758.     // private Methods (only for internal module use)
  759.     case MODM_Logfile_Read          : return(MODULE_Log_Read    (cl, obj, (APTR)msg));
  760.     case MODM_Msg_Parse             : return(MODULE_Msg_Parse   (cl, obj, (APTR)msg));
  761.     case MODM_Msg_Insert            : return(MODULE_Msg_Insert  (cl, obj, (APTR)msg));
  762.   }
  763.  
  764.   return (DoSuperMethodA(cl, obj, msg));
  765. }
  766.