Any modula programmers in the house?I need to convert a modula pgm into Java

Dear Experts,


I am a java programmer.
I need to convert a program written in modula into java.
I tried to understand the logic,but i found it difficult.

Could anybody help?

Latha
slathakamatchiAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mlmccCommented:
Post the code and we'll see.

Please explain wha the program is supposed to do.

mlmcc
0
slathakamatchiAuthor Commented:
Dear experts,

My application needs to read the licence information before allowing the user to login.

The licence information would be in a text file with a extention .dat.
Here is the content of that licence file (license.dat).

MUL12181
B3-2E-38-13-6A-52
2
******** D E M O  L I C E N S E ******** 2  clients

SNTH



In that file the string in the first line is serial number.
Second line has the licence key value.
Third line specifies the no of users allowed
Fourth line is the customer name.
Fifth line may have either version information or it can be empty.
6th line has the options allowed in this application.
7th line may be empty or can have expiry date.

My application has to do the following things abt licence.
1.Read the licence.dat file.
2.Check its in the valid format
      2.1.It should have min 8 lines.
      2.2.The serial no is of length 8
      2.3.The licene key is of length 17.
      2.4.The customer name should not be empty.
3.Then it has to use the logic as in the modula pgm (coming later of this post) to generate a magic no and compares it with the licence key.If they are same,The licence is

valid.i.e The License Key should be equal (Strings) to the Calculated License Key.


Here is the contents of LICENCE.DEF file.
----------------------------------------------------------------
DEFINITION MODULE License;

TYPE
  LicenseStatusT = (LicOK,LicIllegal,LicExpired);
  LicenseInfoPT = POINTER TO LicenseInfoT;
  LicenseInfoT =
      RECORD
        SerieNr    : ARRAY [0..10] OF CHAR;
        NrStations : ARRAY [0..10] OF CHAR;
        Customer   : ARRAY [0..79] OF CHAR;
        License    : ARRAY [0..17] OF CHAR;
        Version    : ARRAY [0..5] OF CHAR;
        Option     : ARRAY [0..16] OF CHAR;
        ExpDate    : ARRAY [0..10] OF CHAR;
      END;


PROCEDURE PutLicense(Directory    : ARRAY OF CHAR;
                     LicFile      : ARRAY OF CHAR;
                   LicenseInfoP : LicenseInfoPT);

PROCEDURE GetLicense(LoadDir      : ARRAY OF CHAR;
                     LicenseInfoP : LicenseInfoPT): BOOLEAN;
 
PROCEDURE CheckLicense(VAR NrOfStations : CARDINAL;
                       VAR LicenseP     : LicenseInfoPT;
                       VAR DemoArr      : ARRAY OF CHAR):LicenseStatusT;

PROCEDURE CreateLicense(LicenseInfoP : LicenseInfoPT;
                    VAR LicenseStr   : ARRAY OF CHAR);

END License.
----------------------------------------------------------------

The following is the contents of LICENCE.MOD file.

-------------------------------------------------------------
IMPLEMENTATION MODULE License;

FROM ConvNumb IMPORT NumToString,StringToNum,ConvStatusT,CardToString,StringToCard;
FROM StringsP IMPORT CopyString,AppendString,AssignString,StringLength,
                     EqualStrings,ClearString,CompareStringsNoCase,
                     CompareResult,InsertString;
FROM FileProc IMPORT OpenTextFile,CloseTextFile, AccessT, TextFile, ReadLine,
                 EndOfTextFile,CreateTextFile,WriteLine,DeleteFile;
FROM DirFiles IMPORT AppendFileName,FileExist;

FROM Bios     IMPORT Shift,LOR,LAND,XOR;
FROM Environ  IMPORT GetDate;

CONST  
  LicFileName = "License.dat";
  LicenseErrorStr = "****   No license file present   ****";
  IllegalErrorStr = "****   License expired  ****";

TYPE
 
  LicenseT = RECORD
            CASE Tag: CARDINAL OF
            1 :
                String : ARRAY [0..199] OF CHAR;
            | 2 :
                CardArr : ARRAY [0..99] OF CARDINAL;
            ELSE
            END;
          END;

PROCEDURE CheckLicense(VAR NrOfStations : CARDINAL;
                   VAR LicenseP     : LicenseInfoPT;
                       VAR DemoArr      : ARRAY OF CHAR): LicenseStatusT;
VAR
  LicenseStr  : ARRAY [0..17] OF CHAR;
  ConvStatus  : ConvStatusT;
  StringsOK   : BOOLEAN;
  IntYear,
  Year,
  Month,
  Day         : CARDINAL;
  WeekDay,
  String1,
  String2,
  String      : ARRAY [0..10] OF CHAR;
  LicStatus   : LicenseStatusT;
  ConvStat    : ConvStatusT;
BEGIN
    LicStatus := LicOK;
    StringsOK := ( (StringLength(LicenseP^.Customer) # 0) AND
               (StringLength(LicenseP^.SerieNr) = 8) AND
               (StringLength(LicenseP^.License) = 17));
    CardToString(NrOfStations,0,LicenseP^.NrStations);
    CreateLicense(LicenseP,LicenseStr);

    IF (LicStatus = LicOK) AND
       (StringLength(LicenseP^.ExpDate) <> 0) THEN
      GetDate(Year,Month,Day,WeekDay,String);
      String1:=LicenseP^.ExpDate;
      IF StringLength(LicenseP^.ExpDate) = 8 THEN
        CopyString(LicenseP^.ExpDate,0,2,String2);
        IntYear:=StringToCard(String2,ConvStat);
        IF IntYear > 80 THEN
          InsertString("19",0,String1);
        ELSE
          InsertString("20",0,String1);
        END;
      END;
      IF CompareStringsNoCase(String1,String) = Less THEN
        LicStatus := LicExpired;
        NrOfStations := 0;
        AssignString(IllegalErrorStr,LicenseP^.Customer);
      END;
    END;

    IF (LicStatus = LicOK) AND
       ((NOT StringsOK) OR
       (NOT EqualStrings(LicenseStr,LicenseP^.License)) OR
       (NrOfStations = 0)) THEN
      LicStatus := LicIllegal;
      NrOfStations := 0;
      ClearString(LicenseP^.SerieNr);
    END;
  RETURN LicStatus;
END CheckLicense;


PROCEDURE CalculateLicense(String : ARRAY OF CHAR): CARDINAL;

VAR
  Check   : CARDINAL;
  License : LicenseT;
  i,j     : CARDINAL;
  Len     : CARDINAL;

BEGIN
  Len := StringLength(String);
  AssignString(String,License.String);
(* Fill with zero until the end of the string *)  
FOR i:=Len TO 199 DO
    License.String[i] := 0C;
  END;
(* Calculate on the mapped word array *)
  Len := Len DIV 2;
  WITH License DO
    Check := CardArr[0];            (* Start with the first word value *)
    FOR j:=1 TO Len DO
      i := j-1;
      IF CardArr[j] # CardArr[i] THEN
      Check := XOR(Check,CardArr[j]);              (* Exclusive OR *)
      Check := LOR(Shift(Check,-1),               (* Logical OR and shift one bit to left *)
               LAND(XOR(Shift(CardArr[j],5),Shift(CardArr[j],2)),1));                    
      END;
    END;
  END;
  RETURN Check;
END CalculateLicense;

(* This procedure creates a License Key string *)
PROCEDURE CreateLicense(LicenseInfoP : LicenseInfoPT;
                VAR String       : ARRAY OF CHAR);

VAR  
  Cust      : ARRAY [0..4] OF CHAR;
  Stat      : ARRAY [0..4] OF CHAR;
  TmpString : ARRAY [0..200] OF CHAR;
  Part      : ARRAY [0..2] OF CHAR;
  i         : CARDINAL;
BEGIN
  WITH LicenseInfoP^ DO
 (* Concatenate the fields to a temporary string *)
    AssignString(Customer,TmpString);  
    AppendString(NrStations,TmpString);
    AppendString(SerieNr,TmpString);  
    AppendString(Version,TmpString);  
    AppendString(Option,TmpString);  
    AppendString(ExpDate,TmpString);  
 (* Calculate the magic number *)
    i := CalculateLicense(TmpString);
  (* Convert the magic number to hexadecimal 4 characters*)
    NumToString(i,16,4,Cust);
   (* Split the Hexadecimal string and Create the output string *)
    CopyString(Cust,0,2,Part);
    AssignString(Part,String);
    AppendString("-",String);
    CopyString(Cust,2,2,Part);
    AppendString(Part,String);
 
  (* Concatenate the fields to a temporary string *)
    AssignString(SerieNr,TmpString);  
    AppendString(NrStations,TmpString);
    AppendString(Customer,TmpString);  
    (* Calculate the magic number *)
    i := CalculateLicense(TmpString);
    (* Convert the magic number to hexadecimal 4 characters*)
    NumToString(i,16,4,Stat);
 (* Split the Hexadecimal string and append to the output string *)
    AppendString("-",String);
    CopyString(Stat,0,2,Part);
    AppendString(Part,String);
    AppendString("-",String);
    CopyString(Stat,2,2,Part);
    AppendString(Part,String);
 
 (* Concatenate the fields to a temporary string *)
    AssignString(Cust,TmpString);
    AppendString(Stat,TmpString);
(* Calculate the magic number *)
    i := CalculateLicense(TmpString);

    (* Convert the magic number to hexadecimal 4 characters*)
    NumToString(i,16,4,TmpString);
     (* Split the Hexadecimal string and append to the output string *)
    AppendString("-",String);
    CopyString(TmpString,0,2,Part);
    AppendString(Part,String);
    AppendString("-",String);
    CopyString(TmpString,2,2,Part);
    AppendString(Part,String);
  END;
END CreateLicense;


(* The String will be mapped to an array of integers (Word) and
leading characters will be filled with zero.*)

(*The following functions will be used:
Shift(Word,NrOfShifts):Returns Word
The function shifts the word a number of bits to the left (negative)
or to the right
XOR(Word1,Word2):Returns Word
The Exclusive OR bitwise operand
LAND(Word1,Word2):Returns Word
The Logical AND function
LOR(Word1,Word2):Returns Word
The Logical OR function*)



PROCEDURE PutLicense(Directory    : ARRAY OF CHAR;
                     LicFile      : ARRAY OF CHAR;
                   LicenseInfoP : LicenseInfoPT);
VAR
  FileName  : ARRAY [0..128] OF CHAR;
  f         : TextFile;
BEGIN
  AssignString(Directory,FileName);
  AppendFileName(LicFile,FileName);
  IF FileExist(FileName) THEN
    DeleteFile(FileName);
  END;
  CreateTextFile(FileName,f);
  WITH LicenseInfoP^ DO
    WriteLine(f,SerieNr);
    WriteLine(f,License);
    WriteLine(f,NrStations);
    WriteLine(f,Customer);
    WriteLine(f,Version);
    WriteLine(f,Option);
    WriteLine(f,ExpDate);
  END;
  CloseTextFile(f);
END PutLicense;

PROCEDURE GetLicense(LoadDir      : ARRAY OF CHAR;
                     LicenseInfoP : LicenseInfoPT):BOOLEAN;
 
  VAR
    FileName  : ARRAY [0..128] OF CHAR;
    f         : TextFile;
    Line      : ARRAY [0..255] OF CHAR;
    NrChar    : CARDINAL;
    LineLen   : CARDINAL;
    ConvStatus : ConvStatusT;
    OK        : BOOLEAN;
  BEGIN
    WITH LicenseInfoP^ DO
      ClearString(Customer);
      ClearString(SerieNr);
      ClearString(NrStations);
      ClearString(License);
      ClearString(Version);
      ClearString(Option);
      ClearString(ExpDate);
      AssignString(LoadDir,FileName);
      AppendFileName(LicFileName,FileName);
      IF FileExist(FileName) THEN
        OK := TRUE;
        OpenTextFile(FileName,ReadOnly,f);
      IF NOT EndOfTextFile(f) THEN
        ReadLine(f,Line,NrChar);
        AssignString(Line,SerieNr);
      END;
      IF NOT EndOfTextFile(f) THEN
        ReadLine(f,Line,NrChar);
        AssignString(Line,License);
      END;
      IF NOT EndOfTextFile(f) THEN
        ReadLine(f,Line,NrChar);
        AssignString(Line,NrStations);
      END;
      IF NOT EndOfTextFile(f) THEN
        ReadLine(f,Line,NrChar);
        AssignString(Line,Customer);
      END;
      IF NOT EndOfTextFile(f) THEN
        ReadLine(f,Line,NrChar);
          AssignString(Line,Version);
      END;
      IF NOT EndOfTextFile(f) THEN
        ReadLine(f,Line,NrChar);
          AssignString(Line,Option);
        ELSE
          ClearString(NrStations);
        END;
      IF NOT EndOfTextFile(f) THEN
        ReadLine(f,Line,NrChar);
          AssignString(Line,ExpDate);
        ELSE
          ClearString(NrStations);
      END;
      CloseTextFile(f);
      ELSE
        OK := FALSE;
        AssignString(LicenseErrorStr,Customer);
      END;
    END;
  RETURN OK;
END GetLicense;

END License.
--------------------------------------------------------------

In the above pgm,I can understatnd the CheckLicence() method.The PutLicence() and GetLicence() methods are also managable though I canot understand much abt the

pointer.But I can understand the logic.

My biggest plm is with CreateLicence() and CalculateLicence() methods.
The CalculateLicence() method uses the CardArr array.but i donot know where it gets its value.
And I am very much uncertain abt the WORD concept.

Could you plz,explain with the possible output of each step.and let me allocate some more points to your valuable help.

Thanks and expecting a guidence
Latha
0
For-SoftCommented:
Pointer is a variable holding an memory adress.

TYPE LicenseInfoPT = POINTER TO LicenseInfoT;

VAR LicenseP     : LicenseInfoPT;

LicenseInfoPT is a pointer type. Variable LicenseP holds an adress to LicenseInfoT record structure.

To access the data stored at the adress pointed by LicenseP it is necesary to use statement: LicenseP^

LicenseP^.ExpDate is ExpDate field of LicenseInfoT type record pointed by adress stored in LicenseP variable.

To access the adress value stored in a pointer variable use LicenseP. To access the data stored at adress stored in a pointer use LicenseP^.


WITH LicenseInfoP^ DO
    ClearString(Customer);
  END;

equals

ClearString(LicenseInfoP^.Customer);

Statement WITH is used to simplify some statements.
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

For-SoftCommented:
CardArr is a variable from LicenseT record structure pointed by License pointer.

LicenseT record can accessed in 2 ways.
- by a character table String
- by a cardinal table CardArr

Both variables String and CardArr are operating on the same data. So assigning a value to String variable assigns a value to CardArr variable also. And it is made in:

(* Fill with zero until the end of the string *)  
FOR i:=Len TO 199 DO
    License.String[i] := 0C;
  END;
0
For-SoftCommented:
TYPE
 
  LicenseT = RECORD
           CASE Tag: CARDINAL OF
          1 :
                String : ARRAY [0..199] OF CHAR;
           | 2 :
                CardArr : ARRAY [0..99] OF CARDINAL;
           ELSE
           END;
         END;

Cardinal is a WORD. It contains 2 bytes. In this case it contains 2 1byte characters. So it's clearly a 16bit code.
0
slathakamatchiAuthor Commented:
Hi For-Soft,

Thanx for the guidence.
Hope you can wait till i go thro the points

Be back soon

Latha
0
slathakamatchiAuthor Commented:
For-Soft,

Yes...I can understand the CalculateLicence function.

you say,any String (array of characters) can be mapped to a Cardinal array.
As a cordinal can have 2 bytes, we use size of 100 cardinal array to map a string of length 200.Is it right?

if I have string

s="Abc"
bin value for A - 0100 0001 (65)
bin value for b - 0110 0010 (98)
bin value for c - 0110 0011 (99)

then how would be the word i.e Cardinal array look like.

cardArr[0] = ?
cardArr[1] = ?

could you plz explain this?

And one more doubt..

You have the Cardinal type that can be matched to a string.

But in Java, I can split a string into individual single bytes (String.getBytes()).
How can I get the WORD representation .i.e, how can I split them into a 2 byte values?

Latha
0
For-SoftCommented:
Pascal and Modula languages are relatively low level languages, so it is necesary to understand how the code will look like in assembler to understand what compiler will do with the code.

Your Abc string will be stored in memory in following way:
65,98,99,00,...
so cardinal array will look like:
(65,98),(99,00),...
Every cardinal word takes 2 bytes of memory, but values stored in memory by procesor have reversed order. The low byte goes first, then the high byte. So procesor will retrieve following cardinal data from memory:
(98*256+65),(99)

I can't tell you how to change string array to cardinal array in Java, because i don't know Java at all. You can always to split the string into bytes, and then to calculace cardinal values.
0
slathakamatchiAuthor Commented:
For-soft,

I try doing split the string into bytes.

but what do this LAND,LOR functions mean?
Are they same like the ones && and ||.if so, they would return either 1 or 0.

In my pgm,is there possibility to get different string?
0
For-SoftCommented:
LAND LOR are related to assembly AND and OR procesor commands.
So it is not a boolean operator
True OR False = True
It is bitwise operator.
00100001 AND 10010001 = 10110001

I don't know what "&& and ||" operators are for.
0
slathakamatchiAuthor Commented:
Hi For-soft,

Yes...I understand.One last issue..I know left shift and right shift operators in java.

I use them with an positive integer that specifies  the no of places to be shifted.

but what does the -1 in Shift(Check,-1) mean?
0
slathakamatchiAuthor Commented:
does that mean left shift?
0
For-SoftCommented:
Last time I used Modula about 12 years ago. I'm a pascal programmer ever since. So I'm not entirely sure. The only logical explanation for Shift(Check,-1) is a left shift. I'm not sure if it is a shift including Carry Flag or not. I do not know Bios library used here.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Pascal

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.