AkelPad Forum Index AkelPad
Support forum
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Decode/encode .macro files

 
Post new topic   Reply to topic    AkelPad Forum Index -> Plugins
View previous topic :: View next topic  
Author Message
tmsg



Joined: 21 Aug 2012
Posts: 35
Location: UK

PostPosted: Mon Sep 24, 2012 10:22 am    Post subject: Decode/encode .macro files Reply with quote

The attached C program decodes and encodes .macro files as used by the Macro plugin. This can be used to edit or clean-up .macro files.

First decode the file with
Code:
readMacro -decode c:\AkelPad\Plugs\Macros\some.macro c:\put\output\here.txt

then edit the resulting text file and finally encode it back with
Code:
readMacro -encode c:\put\output\here.txt c:\AkelPad\Plugs\Macros\someother.macro


This was a simple and rather quick-and-dirty attempt but it seems to do its job well enough. I can also upload a compiled version if someone points me to an appropriate upload location. In the long run (very long, perhaps;-)) I might try to add this capability to the Macro plugin, in the form of separate Import and Export commands.

It is certainly possible to write new keyboard macros from scratch but unless you know a few things about how Windows keypress messages work it's probably best to start with already recorded and working (!) macros.

If something's not working or if there are suggestions please notify me.

TM

readMacro.c
Code:

/*
**  readMacro converts binary AkelPad .macro files to editable text files and vice versa.
**  Version 0.1_2012-09-23. This file and the code it contains are in the public domain.
**
**  readMacro takes three or four arguments: readMacro mode [infile] [outfile]
**  mode is either -decode (from .macro file to text) or -encode (text to .macro).
**
**  In decoding mode infile is a .macro file and outfile (optional) is the output
**  textfile (if no outfile is given, readMacro writes to stdout).
**
**  If encoding infile (optional) is a textfile, outfile is the output .macro file
**  (if no infile is given, readMacro reads from stdin).
**
**  Decoding a .macro into a text file and encoding this back into a .macro file
**  should produce identical files.
*/

#include <malloc.h>
#include <stdio.h>
#include <string.h>

typedef struct _KEYACT {
   unsigned char bVk;
   unsigned int dwFlags;
} KEYACT;

#define VK_MAX  0x92
char *VKs[VK_MAX]={0};
char *flags[5]={"d",       // KEYDOWN
                "dx",      // KEYDOWN and EXTENDED
                "u",       // KEYUP
                "ux",      // KEYUP and EXTENDED
                "0x%04x"   // undefined
               };

int error(char *err) {
   fprintf(stderr,"%s\n",err);
   return -1;
}

int main(int argc, char **argv) {
   FILE *infile,*outfile;
   VKs[0x08]="back";
   VKs[0x09]="tab";
   VKs[0x0C]="clear";
   VKs[0x0D]="return";
   VKs[0x10]="shift";
   VKs[0x11]="control";
   VKs[0x12]="menu";
   VKs[0x13]="pause";
   VKs[0x14]="capital";
   VKs[0x15]="kana";
   VKs[0x17]="junja";
   VKs[0x18]="final";
   VKs[0x19]="hanja";
   VKs[0x19]="kanji";
   VKs[0x1B]="escape";
   VKs[0x1C]="convert";
   VKs[0x1D]="nonconvert";
   VKs[0x1E]="accept";
   VKs[0x1F]="modechange";
   VKs[0x20]="space";
   VKs[0x21]="prior";
   VKs[0x22]="next";
   VKs[0x23]="end";
   VKs[0x24]="home";
   VKs[0x25]="left";
   VKs[0x26]="up";
   VKs[0x27]="right";
   VKs[0x28]="down";
   VKs[0x29]="select";
   VKs[0x2A]="print";
   VKs[0x2B]="execute";
   VKs[0x2C]="snapshot";
   VKs[0x2D]="insert";
   VKs[0x2E]="delete";
   VKs[0x2F]="help";
   VKs[0x30]="0";
   VKs[0x31]="1";
   VKs[0x32]="2";
   VKs[0x33]="3";
   VKs[0x34]="4";
   VKs[0x35]="5";
   VKs[0x36]="6";
   VKs[0x37]="7";
   VKs[0x38]="8";
   VKs[0x39]="9";
   VKs[0x41]="a";
   VKs[0x42]="b";
   VKs[0x43]="c";
   VKs[0x44]="d";
   VKs[0x45]="e";
   VKs[0x46]="f";
   VKs[0x47]="g";
   VKs[0x48]="h";
   VKs[0x49]="i";
   VKs[0x4A]="j";
   VKs[0x4B]="k";
   VKs[0x4C]="l";
   VKs[0x4D]="m";
   VKs[0x4E]="n";
   VKs[0x4F]="o";
   VKs[0x50]="p";
   VKs[0x51]="q";
   VKs[0x52]="r";
   VKs[0x53]="s";
   VKs[0x54]="t";
   VKs[0x55]="u";
   VKs[0x56]="v";
   VKs[0x57]="w";
   VKs[0x58]="x";
   VKs[0x59]="y";
   VKs[0x5A]="z";
   VKs[0x5B]="lwin";
   VKs[0x5C]="rwin";
   VKs[0x5D]="apps";
   VKs[0x5F]="sleep";
   VKs[0x60]="numpad0";
   VKs[0x61]="numpad1";
   VKs[0x62]="numpad2";
   VKs[0x63]="numpad3";
   VKs[0x64]="numpad4";
   VKs[0x65]="numpad5";
   VKs[0x66]="numpad6";
   VKs[0x67]="numpad7";
   VKs[0x68]="numpad8";
   VKs[0x69]="numpad9";
   VKs[0x6A]="multiply";
   VKs[0x6B]="add";
   VKs[0x6C]="separator";
   VKs[0x6D]="subtract";
   VKs[0x6E]="decimal";
   VKs[0x6F]="divide";
   VKs[0x70]="f1";
   VKs[0x71]="f2";
   VKs[0x72]="f3";
   VKs[0x73]="f4";
   VKs[0x74]="f5";
   VKs[0x75]="f6";
   VKs[0x76]="f7";
   VKs[0x77]="f8";
   VKs[0x78]="f9";
   VKs[0x79]="f10";
   VKs[0x7A]="f11";
   VKs[0x7B]="f12";
   VKs[0x7C]="f13";
   VKs[0x7D]="f14";
   VKs[0x7E]="f15";
   VKs[0x7F]="f16";
   VKs[0x80]="f17";
   VKs[0x81]="f18";
   VKs[0x82]="f19";
   VKs[0x83]="f20";
   VKs[0x84]="f21";
   VKs[0x85]="f22";
   VKs[0x86]="f23";
   VKs[0x87]="f24";
   VKs[0x90]="numlock";
   VKs[0x91]="scroll";
  // If adding further elements change VK_MAX!

   if (argc<3||argc>4) return error("Wrong number of arguments: mode [infile] [outfile]\n"
                                    "  mode is either -decode (from .macro file to text) or -encode (text to .macro).\n"
                                    "  If decoding infile is a .macro file, outfile (optional) is the output textfile\n"
                                    "  (if no outfile is given, readMacro writes to stdout).\n"
                                    "  If encoding infile (optional) is a textfile, outfile is the output .macro file\n"
                                    "  (if no infile us given, readMacro reads from stdin).\n");
   if (!stricmp(argv[1],"-decode")) {
      unsigned long fileLen,n=0;
      char flag[16];
      KEYACT *ka;
      if (!(infile=fopen(argv[2],"rb"))) return error("Unable to open infile");
      fseek(infile,0,SEEK_END);
      fileLen=ftell(infile);
      fseek(infile,0,SEEK_SET);
      ka=(KEYACT *)malloc(fileLen);
      if (!ka) {
         fclose(infile);
         return error("Memory allocation failed");
      }
      fread(ka,fileLen,1,infile);
      fclose(infile);
      if (argc==3) outfile=stdout;
      else if (!(outfile=fopen(argv[3],"w+"))) return error("Unable to open outfile");
      while (n<fileLen) {
         if (ka->dwFlags>3) sprintf(flag,flags[4],ka->dwFlags);
         else strcpy(flag,flags[ka->dwFlags]);
         if (VKs[ka->bVk]&&ka->dwFlags<4) fprintf(outfile,"%s %s\n",VKs[ka->bVk],flag);
         else fprintf(outfile,"# %i %s\n",ka->bVk,flag);
         ka++;
         n=n+sizeof(KEYACT);
      }
      if (argc==4) fclose(outfile);
      free(ka);
      fprintf(stderr,"Conversion successful, %i items converted.\n",n/sizeof(KEYACT));
   }
   else if (!stricmp(argv[1],"-encode")) {
      char buf[64];
      KEYACT ka;
      int j=0;
      if (argc==3) infile=stdin;
      else if (!(infile=fopen(argv[2],"r"))) return error("Unable to open infile");
      if (!(outfile=fopen(argv[argc-1],"wb"))) {
         fclose(infile);
         return error("Unable to open outfile");
      }
      while (fgets(buf,sizeof(buf),infile)) {
         char *delim=strchr(buf,'\n');
         int i;
         if (buf[0]=='#') continue;
         if (delim) *delim=0;
         if (!(delim=strchr(buf,' '))) {
            printf("warning: unrecognised input\n");
            continue;
         }
         *delim=0;
         delim++;
         memset(&ka,0,sizeof(ka));
         if (!stricmp(delim,flags[0])) ka.dwFlags=0;
         else if (!stricmp(delim,flags[1])) ka.dwFlags=1;
         else if (!stricmp(delim,flags[2])) ka.dwFlags=2;
         else if (!stricmp(delim,flags[3])) ka.dwFlags=3;
         else {
            printf("warning: unrecognised flag, entry skipped\n");
            continue;
         }
         ka.bVk=255;
         for (i=0;i<VK_MAX;i++) {
            if (VKs[i]&&(!stricmp(buf,VKs[i]))) {
               ka.bVk=(unsigned char)i;
               break;
            }
         }
         if (ka.bVk==255) {
            printf("warning: unrecognised VK, entry skipped\n");
            continue;
         }
         printf("%08x %08x\n",ka.bVk,ka.dwFlags);
         if (fwrite(&ka,sizeof(ka),1,outfile)!=1) {
            fclose(infile);
            fclose(outfile);
            error("Error while writing outfile");
         }
         j++;
      }
      if (argc==4) fclose(infile);
      fclose(outfile);
      fprintf(stderr,"Conversion successful, %i items converted.\n",j);

   }
   else return error("Unrecognised mode switch, use either -decode or -encode");
   return 1;
}
Back to top
View user's profile Send private message
Surveyor



Joined: 08 Feb 2008
Posts: 146
Location: British Columbia, Canada

PostPosted: Mon Sep 24, 2012 3:09 pm    Post subject: MacTool Reply with quote

Please see here. Compiler is complete - decompiler works - but only back to keystrokes, not to "source" language. Got little/no reponse to post, so decompiler may wait...
Back to top
View user's profile Send private message Send e-mail
tmsg



Joined: 21 Aug 2012
Posts: 35
Location: UK

PostPosted: Mon Sep 24, 2012 4:05 pm    Post subject: Re: MacTool Reply with quote

Surveyor wrote:
Please see here. Compiler is complete - decompiler works - but only back to keystrokes, not to "source" language. Got little/no reponse to post, so decompiler may wait...

Well... I did search the forum for something like this but found nothing:-/.

I agree that keyboard macros, if done well, are extremely flexible and often underrated. (In the old DOS days I used an editor with absolutely perfect record/replay capabilities... I've never found a macro-capable editor that good later on.)

Anyway, your attempt seems much more ambitious and more complete than my q-n-d fix. I'll have a look.

TM
Back to top
View user's profile Send private message
Surveyor



Joined: 08 Feb 2008
Posts: 146
Location: British Columbia, Canada

PostPosted: Mon Sep 24, 2012 6:44 pm    Post subject: Reply with quote

tmsg wrote:
I'll have a look.
I would greatly appreciate any/all comments or criticisms about MacTool, if you get a chance to look at it. The "normal decompile" (to source) is actually started, but needs some more work - hopefully, when done, it will generate at least strings, keypresses (and compound kepresses) from macros. Detection of REPEAT loops and SNIPPETs may come later, but this may not be necessary. The real power comes from just using a source language instead of memorization from the keyboard. MacTool source code is freely available on request, but it is written in Pascal (I am an OLD Dos Pascal programmer!).

In the Dos days, I used Turbo Pascal (3.0 and 5.5) a lot - they both had editors which responded to Wordstar commands, which I found very quick. For macros, I also used something called QEdit (by Semware?) which had great macro capability, but only with keyboard memorization, I think (at least that's all I used).

BTW, MacTool is a command-line app, but does a sort of drag-and-drop emulaton which is quite a bit easier than running from the command prompt. It's in the help file...

Cheers from Canada!
- Surveyor
Back to top
View user's profile Send private message Send e-mail
ps281



Joined: 14 Jan 2014
Posts: 1

PostPosted: Tue Jan 14, 2014 10:07 pm    Post subject: Re: MacTool Reply with quote

Surveyor wrote:
Please see here. Compiler is complete - decompiler works - but only back to keystrokes, not to "source" language. Got little/no reponse to post, so decompiler may wait...you may have to check here later.


So decompiler does work but not to source language?
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AkelPad Forum Index -> Plugins All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


SourceForge.net Logo Powered by phpBB © 2001, 2005 phpBB Group