improved by Scott Bronson
authorbela <bela@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 17 Oct 2003 10:53:22 +0000 (10:53 +0000)
committerbela <bela@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 17 Oct 2003 10:53:22 +0000 (10:53 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2951 4a8a32a2-be11-0410-ad9d-d568d2c75423

support/scripts/keil2sdcc.pl

index 6a8b327344d1ee1cb70fea3f01e378001a08a290..07a982d3084a3a51acda2bc324757644aad7d4ad 100755 (executable)
-#!/usr/bin/perl
-# keil2sdcc.pl
-# converts Keil compatible header files to sdcc-compatible format
-# call (path)/keil2sdcc.pl keil_file_name sdcc_file_name
-#
-# Bela Torok - bela.torok@kssg.ch
-# Version: June 2001
-#
-# Limitation: Keil-style sfr and sbit definitions should begin 
-# in the first column! 
-#
-
-$keil_file = $ARGV[0];
-$sdcc_file = $ARGV[1];
+#!/usr/bin/perl -w
 
-if (open (KEIL_FILE , "<" . $keil_file)) {  
-#  printf("Opening file: %s for output!\n", $keil_file);
-} else {
-  printf("Cannot open file: %s !\n", $keil_file);
-  exit (0);
-}
+# keil2sdcc.pl
+# Scott Bronson
+# 22 June 2003
 
-if (open (SDCC_FILE ,">" . $sdcc_file)) {  
-#  printf("Opening file: %s for output!\n", $sdcc_file);
-} else {
-  printf("Cannot open file: %s !\n", $sdcc_file);
-  exit (0);
-}
 
-while ($input_buffer = <KEIL_FILE>) {
-
-  if( substr($input_buffer, 0, 3) eq 'sfr') 
-    {
-      &convert( substr($input_buffer, 4) );
-      print SDCC_FILE "sfr at", $value, " ", $name, ";", $comment;
-    }
-  elsif( substr($input_buffer, 0, 4) eq 'sbit') 
-    {
-      &convert( substr($input_buffer, 5) );
-      print SDCC_FILE "sbit at", $value, " ", $name, ";", $comment;
-    }
-  else {
-    print SDCC_FILE $input_buffer;
-  }
+# usage:
+#    perl keilconv.pl < keil_header.h > sdcc_header.h
+# or
+#    perl keilconv.pl keil_header.h > sdcc_header.h
+#
+# keil_header.h and sdcc_header.h must not be the same file since
+# most shells overwrite the output file before opening the input file.
 
-}
 
-close (KEIL_FILE);
-close (SDCC_FILE);
-exit (0);
+# This script converts Keil-style header files to SDCC.  It tries to
+# be pedantic so don't be surprised if you need to munge it a bit to
+# get it to work.  On the other hand, it doesn't fully parse the C
+# file (for obvious reasons).
 
-sub convert
-{
-    local($arg) = @_;
+# It takes the Keil header file either as an argument or on
+# stdin and it produces the output on stdout.
 
-    ($command, $comment) = split(';' , $arg);
+# This script is inspired by keil2sdcc.pl by Bela Torok but a lot
+# more pedantic.
 
-    ($name, $value) = split('=' , $command);
+use strict;
 
+while(<>) 
+{
+       s/\r//g;        # remove DOS line endings if necessary
+
+       # external register (kind of a weird format)
+       #
+       # in:  EXTERN xdata volatile BYTE GPIF_WAVE_DATA _AT_ 0xE400;
+       # out: EXTERN xdata at 0xE400 volatile BYTE GPIF_WAVE_DATA;
+       # $1: leading whitespace
+       # $2: variable name
+       # $3: variable location
+       # $4: trailing comments, etc.
+
+       if(/^(\s*)EXTERN\s*xdata\s*volatile\s*BYTE\s*(\w+(?:\s*\[\s*\d+\s*\])?)\s+_AT_\s*([^;]+);(.*)$/) {
+               print "$1EXTERN xdata at $3 volatile BYTE $2;$4\n";
+               next;
+       }
+
+       # sfr statement
+       #
+       # in:  sfr IOA = 0x80;
+       # out: sfr at 0x80 IOA;
+       # $1: leading whitespace
+       # $2: variable name
+       # $3: variable location
+       # $4: trailing comments, etc.
+
+       if(/^(\s*)sfr\s*(\w+)\s*=\s*([^;]+);(.*)$/) {
+               print "$1sfr at $3 $2;$4\n";
+               next;
+       }
+
+       # sbit statement
+       #
+       # in:  sbit SEL = 0x86+0;
+       # out: sbit at 0x86+0 SEL;
+       # $1: leading whitespace
+       # $2: variable name
+       # $3: variable location
+       # $4: trailing comments, etc.
+
+       if(/^(\s*)sbit\s*(\w+)\s*=\s*([^;]+);(.*)$/) {
+               print "$1sbit at $3 $2;$4\n";
+               next;
+       }
+
+
+
+       # entire line is a C++ comment, output it unchanged.
+       if(/^(\s*)\/\/(.*)$/) {
+               print "$1//$2\n";
+               next;
+       }
+
+       # C comment, slurp lines until the close comment and output it unchanged.
+       if(/^(\s*)\/\*(.*)$/) {
+               my($ws,$cmt) = ($1,"$2\n");
+               $cmt .= <> while $cmt !~ /\*\/\s*$/;
+               $cmt =~ s/\r//g;
+               print "$ws/*$cmt";
+               next;
+       }
+
+       # preprocessor statement (whitespace followed by '#'), don't change
+       if(/^(\s*)\#(.*)$/) {
+               print "$1#$2\n";
+               next;
+       }
+
+       # blank line, don't change
+       if(/^(\s*)$/) {
+               print "\n";
+               next;
+       }
+
+       chomp;
+       die "Unconvertable line: \"$_\"\n";
 }
 
-
-
-
-
-
-
-
-
-
-
-