(* *****************************************************************
** File    : C_tools.PAS
** Created : 07.05.00
** Author  :
**
** Macro for FoldMaster
**
** Installation of this file
**   This macro module is intended to be started at start-up
**   of FoldMaster. Therfore use the automation/modules dialog
**   to include this file to the list of macro- modules.
**   Then simply mark the option run on start-up for this file.
**   That's all. The next time FoldMaster is started this macro is
**   executed automatically at start-up making the key definitions
**   available
**
** Following functions will be available
** F12 : Add_End_of
**   Takes selection or current word and searches for the next
**   open brace and the corresponding closing brace.
**   Sets cursor behind closing Brace and deletes to the end of the line
**   then adds "/* end of", the selection and a closing " */".
** SHIFT- F12 : Make_Extern_Definition
**   Takes current selection and generates an extern definition
**   in the include file.
**   In the include file it searches for a fold with the word
**   extern in its title.
**   The definition will be added at the end of this fold.
**   If the fold is not found it will be creted.
**
********************************************************************
** Version     Date      Change
** 1.46        07.05.00  Creation
** **************************************************************-**)
PROGRAM C_tools;

const
   (*{{{  Key Definitions*)
   VK_BACK           = $08;
   VK_TAB            = $09;

   VK_CLEAR          = $0C;
   VK_RETURN         = $0D;

   VK_SHIFT          = $10;
   VK_CONTROL        = $11;
   VK_MENU           = $12;
   VK_PAUSE          = $13;
   VK_CAPITAL        = $14;

   VK_ESCAPE         = $1B;

   VK_SPACE          = $20;
   VK_PRIOR          = $21;      { Page UP }
   VK_NEXT           = $22;      { Page Down }
   VK_END            = $23;
   VK_HOME           = $24;
   VK_LEFT           = $25;
   VK_UP             = $26;
   VK_RIGHT          = $27;
   VK_DOWN           = $28;
   VK_SELECT         = $29;
   VK_PRINT          = $2A;
   VK_EXECUTE        = $2B;
   VK_SNAPSHOT       = $2C;
   VK_INSERT         = $2D;
   VK_DELETE         = $2E;
   VK_HELP           = $2F;

   { VK_0 thru VK_9 are the same as ASCII '0' thru '9' ($30 - $39) }
   { VK_A thru VK_Z are the same as ASCII '0' thru ASCII 'A' thru 'Z' ($41 - $5A) }

   VK_LWIN           = $5B;
   VK_RWIN           = $5C;
   VK_APPS           = $5D;

   VK_NUMPAD0        = $60;
   VK_NUMPAD1        = $61;
   VK_NUMPAD2        = $62;
   VK_NUMPAD3        = $63;
   VK_NUMPAD4        = $64;
   VK_NUMPAD5        = $65;
   VK_NUMPAD6        = $66;
   VK_NUMPAD7        = $67;
   VK_NUMPAD8        = $68;
   VK_NUMPAD9        = $69;
   VK_MULTIPLY       = $6A;
   VK_ADD            = $6B;
   VK_SEPARATOR      = $6C;
   VK_SUBTRACT       = $6D;
   VK_DECIMAL        = $6E;
   VK_DIVIDE         = $6F;
   VK_F1             = $70;
   VK_F2             = $71;
   VK_F3             = $72;
   VK_F4             = $73;
   VK_F5             = $74;
   VK_F6             = $75;
   VK_F7             = $76;
   VK_F8             = $77;
   VK_F9             = $78;
   VK_F10            = $79;
   VK_F11            = $7A;
   VK_F12            = $7B;
   VK_F13            = $7C;
   VK_F14            = $7D;
   VK_F15            = $7E;
   VK_F16            = $7F;
   VK_F17            = $80;
   VK_F18            = $81;
   VK_F19            = $82;
   VK_F20            = $83;
   VK_F21            = $84;
   VK_F22            = $85;
   VK_F23            = $86;
   VK_F24            = $87;

   VK_NUMLOCK        = $90;
   VK_SCROLL         = $91;

   (*}}}*)
   (*{{{  Modifiers*)
   SHIFT   = $01;   { combination with M_CTRL, M_SHIFT and M_ALT allowed }
   CTRL    = $02;
   ALT     = $04;
   CTRL_K  = $08;   { only useable as long as CTRL+K is not replaced }
   CTRL_Q  = $09;   { only useable as long as CTRL+Q is not replaced }

   { Options }
   EXTSEL  = $10;   { indicating commands used to extend selection e.g.:
                      Shift+ArrowKeys.}
   (*}}}*)

(*{{{  procedure Add_end_of;*)
{ Add_End_of
     Takes selection or current word searches for the next
     open brace and the corresponding closing brace.
     Sets cursor behind Closing Brace and deletes to end of line
     and add "/* end of", the selection and a closing " */".
}
procedure Add_end_of;
var s, l : string;
    p,p2 : integer;
begin
   TempPosSet(19);           // save current position
   Lock;                     // lock editor for faster processing
   s := GetLineSelection;    // get selection
   MatchPair('{', '}', '');  // search matching closing brace
   if (MatchPairFound) then begin
      // brace found text is marked
      EndOfSelection; Right; l := GetLine;
      if (pos('}' , l) > 0) then begin
         // test if end of comment already available
         p := pos('/* end', l);
         if (p > 0) then begin
            // replace it at the same string position
            // save additional comments behind it
            p2 := posx('*/',l,p);
            if (p2 > p) then begin
               delete(l, p, (p2-p)+2);
            end else begin
               delete(l,p,1000);
            end;
            Insert('/* end of '+ s+ ' */', l, p);
         end else begin
            // otherwise delete to end of line
            // and simply add the string
            l := l + ' /* end of '+ s+ ' */';
         end;
         // Replace the line and go back to first position
         ReplaceLine(l); TempPosGoto(19);
      end;
   end;
   UnLock;
end;
(*}}}*)

(*{{{  procedure Make_Extern_Definition*)
{ Make_Extern_Definition
    Takes current selection and generates a extern definition
    in the include file.
    IN the include file it searches for a fold with the word
    extern in its title.
    The definition will be added at the end within this fold.
    If the fold is not found in will be creted.
}
procedure Make_Extern_Definition;
var s  : string;
    fn : string;
begin
   fn := GetModuleName;  if (fn = '') then exit;
   TempstoreCopy(0);    // index 0 may be used without allocation

   (*{{{  Remember FileName and current position*)
   // Remember FileName and current position
   s  := GetModuleName;
   strupper(s);         // needs to be uppercase for some comparison
   TempPosSet(19);
   (*}}}*)
   // Open Includefile
   FileNameSetExt(fn, '.H'); // we are using .H files
   FileOpen(fn);
   If (IsModuleOpen(fn)) then begin
      SearchFold('extern', 'g');
      if (NOT FoldFound) then begin
         (*{{{  Not found so create the fold*)
         // Not found so create the fold
         StartOfText; MatchPair('#if', '#endif', '');
         if (MatchPairFound) then begin
            EndOfSelection; StartOfLine; InsertLine('');
         end else begin
            EndOfText;
         end;
         if (pos('.C', s) <> 0) then begin
            InsertLine('#ifdef __cplusplus');
            InsertLine('extern "C" {            /* Assume C declarations for C++ */');
            InsertLine('#endif /* __cplusplus */');
         end;
         FoldInsert('extern'); FoldHide; TempposSet(18);
         if (pos('.C', s) <> 0) then begin
            InsertLine('#ifdef __cplusplus');
            InsertLine('}                       /* End of extern "C" { */');
            InsertLine('#endif /* __cplusplus */');
         end;
         TempposGoto(18);
         FoldExpand;
         NewLine;     // add at least one empty line
         (*}}}*)
      end else begin
         FoldExpand;  // just expand the fold
      end;
      EndOfFold; StartOfLine;
      // Test if current line is empty otherwise add a new line
      if (NOT IsLineEmpty) then begin
         EndOfLine; NewLine;
      end;
      InsertText('extern ');
      TempStorePaste(0);
      InsertText(';'); NewLine;
   end;
   // go back to origin editpos
   FileOpen(s);  TempPosGoto(19);
end;
(*}}}*)


BEGIN
   KeyMapSetMacro('Add_End_Of', VK_F12, 0);
   KeyMapSetMacro('Make_Extern_Definition', VK_F12, SHIFT);
END.

