Secrets of the PeopleCode

http://www.vijaymukhi.com


Coded Practices

 How many twins do you know? At least a couple? Even with the most identical twins, there is usually some distinguishing character that sets one apart from the other. And it is this craze of being different that causes computer languages also to come out in different flavours. Each language is more distinct or unique when it has an identity of its own. Looking at the past and the many different languages that have been released, one finds that the smaller the team of authors, the stronger is the ‘character’ of the language and consequently, it is more popular with individuals too. Such languages are written for specific purposes and take ages to fade away as the scope broadens.

 C is a very good example of this. Written originally by K&R to make programs portable over Unix systems, it got quickly accepted by the programming community at large. C by itself is distinctive, but keeps getting added on with programmers wanting to give their own twist to the way things have to be done. Good old K&R could be damned and doubly damned as programmers fight with each other on silly issues of formatting and code writing style. Even though C is not likely to win the Nobel Peace prize, it is popular with a broad set of programmers. The average user would hardly bother about these issues.

 

Contrast this with another language — COBOL. The COmmon Business Oriented Language was written by a committee. Everything about the language is rather straight-faced and consequently very boring. There is no two ways about formatting code. The style and syntax is carefully defined. Break a rule and you will get an error message appear. The language is popular simply because it fits in with the corporate structure and more importantly, is used by many large corporations that cannot be bothered about individual style and appearance of the program. The program must work today, tomorrow and the days after that too. One cannot spend time admiring how well the last programmer laid out the code and the rest. This is exactly the same corporate scenario that PeopleSoft’s PeopleCode falls into.

 

It has taken bits and pieces from other languages to make a new straight-faced office/corporate programming language, that is more likely than not designed to get older programmers throw fits. No matter what you do in PeopleCode, as soon as one saves the code, all lines will be reformatted according to the rules defined internally in PeopleSoft. Two programmers with different styles could spend hours keying in exactly the same program, and at the end the result will be the same. The only formatting allowed in PeopleCode is what is defined at PeopleSoft.

 

Unlike C, PeopleCode is a strong contender for the Nobel Peace prize as it brings many individuals down to a common denominator. Users and programmers can get as mad as they wish but the result will always be the same — the PeopleSoft way. Everything follows the Precise PeopleSoft Panel Programming Pattern. P5 is the only way to go. And strangely enough, there PeopleSoft itself stores nothing. All code and other rules are stuffed into tables or records somewhere deep in the database.

 

What’s this chapter about

This chapter attempts to look behind the scenes. It is just like when you look behind the scenes in a horror movie and know how the monster was created. The movie somehow is no longer that scary but you still enjoy it because you now know what really happened when the scene was shot. If you ever worked with DOS and worse still programmed for it, you will understand why DOS programmers were held in awe. Windows programmers, on the other hand, had almost everything served to them on a platter. Discovering secrets is fun and it also makes life easier as one finds little tricks that help one work better. Go under the hood, dig a bit deeper in any of these environments, and suddenly you have a better understand of why you should use different functions for different tasks, even though a single function may be able to do more than one task. Programmers who write viruses or VxDs (about the same as viruses) in Windows, can do so only because they understand how Windows operates internally. These programmers are able to tap on other resources that are not usually specified in the manual.

 

After all, which programmer would really be bothered that Bill Gates knew Monica Lewinsky? It only helps paint a picture of Bill as a fun-loving guy. This may help in understanding why there are so many secrets in Windows possibly — a reason to hide and conceal. It may also clarify terms like Browse her, oops! Browser, the software tool used to move around on the world wide web. Most programs and applications have a little or lot of the people who developed them hidden in them. You find Easter Eggs that pop up to let you know who the programming team was, or just a happy tune being played. Something that makes the software unique.

 

After spending a considerable amount of time in trying to convince the John, Mary and James in PeopleSoft, that we would like to have more information about the insides of PeopleSoft, we came up with zilch. No matter what we told them, we could not get any information out of them. Nothing on what happens to the code when it is saved, or how it is placed in a table; or if some of the words were replaced by others; or if a pre-compiler was automatically run — nothing. We suspect strongly even they did not know. DO understand however, all this is not rocket science. It is there because it help in understanding PeopleSoft better. This chapter is not the last word on the subject as we have not yet had any confirmation from the powers that be at PeopleSoft. Our friends John, Mary and James are still busy with Jill, Tom and Macy, but not necessarily in that order. We have therefore taken it upon ourselves to find out a bit more about PeopleCode and the manner in which it is stored in the table.

 

Whichever way you look at it, this section will show you step by step how to dig deeper into PeopleSoft. It will help you understand not only PeopleSoft but the programming people at PeopleSoft better.

 

Pieces of PeopleCode

If you have used any visual programming environment before, you will know by now that there is no longer any concept of a single long program that does everything. Programs are now a set or collection of little sub-programs or routines that all work together. Further, these sub-routines do not just hang in the middle of nowhere, but get attached to some event, object or happening in the complete application. PeopleCode follows the same rules. For instance, you can attach code to record fields or menu fields placed on panels. There are fewer objects here to worry about that in DOS or Windows. Pre-programmed routines take care of much of the standard operations. All that you will be concerned about in the next few pages is writing code and seeing how it is stored.

 

By now, you know how to create fields, records, panels and menus. Hence, we will not spend time on this. Create your set of fields, records and panels, so that you can place code in some record field event. All you have to remember is the record field name and the event that you placed the code in.

 Start by opening a project with File | Open | Project. Now move to a record field and enter the following in the code window for an event

 &ii = 3 ;

 winmessage ( ‘No’ ) ;

 If this a terrible way to write code, you could be right. C programmers, however would consider it style. Which ever camp you belong to makes no difference to PeopleSoft. Save the file and you will see what we mean. Did you get an error? If you entered the code exactly, PeopleSoft would not have reported any error at all. Not even if you entered the code in the following fashion. Try

&ii =

5

;

 

winmessage

(

"Hello"

)

;

If you guessed that the result would be the same, you guessed right. Both entries land up with the exactly the same result. You can key in code in any manner, the result will still be the same. The only chance of getting an error is if you separate the & from the variable name. This is because PeopleSoft is not sure about what you want to do and hence, flags an error. Try the above in any combination, and you will still end up with exactly the same result. PeopleSoft brings all programmers down to a same common denominator which makes it easy for anyone else reading PeopleCode to understand what it is all about.

For the next few examples, you will just have to trust the result displayed. You will get a chance to check this out for yourself a little later. Start with writing the smallest possible routine. Just a semicolon.

;

 

The result is as follows:

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

2

0

0

0

0

 

 

 

 

 

 

 

 

 

 

 

10

0

0

0

0

0

0

0

0

0

0

 

 

 

 

 

 

 

 

 

 

 

20

0

0

0

0

0

0

0

0

0

0

 

 

 

 

 

 

 

 

 

 

 

30

0

0

0

4

0

0

0

21

7

 

 

 

 

 

 

 

 

 

;

EOC

 

 

The first task is to locate the code. As we have stated before, everything in PeopleSoft is placed somewhere in some table. Remove the tables and PeopleSoft is nothing. Attempting to search the database would be like searching for the proverbial needle in the haystack. You could search all day long and still not find a thing. This is because the database is huge. There are too many records or tables to go through. We have done part of the work by tracking down the table in which the code is stored. In the table PSPCMPROG, there is a field PROGTXT that is listed as CHAR. Query the database and you will find this is true. You will also find that there are a few million fields to go through. Worse still, although the field appears to be defined as CHAR, one cannot see the characters in it. This is because CHAR really does not mean much. This is different from the CHAR that was used to define Character fields. You will notice there is no length specified for the field.

 PeopleSoft stores data in this field as binary. No matter what the label is on the outside, a binary field is one where data is just a long series of bytes. None of which the RDBMS really understands. We wrote a C program to quietly get into the contents of the code field. Later, we will share the program with you so that you can also try and verify all that appears here. But for right now, you will have to take our word.

That single semi-colon really did not leave us much to go on. Place another and then save the file once one. What is stored this time is as shown below.

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

3

0

0

0

0

 

 

 

 

 

 

 

 

 

 

 

10

0

0

0

0

0

0

0

0

0

0

 

 

 

 

 

 

 

 

 

 

 

20

0

0

0

0

0

0

0

0

0

0

 

 

 

 

 

 

 

 

 

 

 

30

0

0

0

4

0

0

0

21

21

7

 

 

 

 

 

 

 

 

;

;

EOC

A number of things have remained constant. The most obvious is the starting byte which is still 31. Since this is program code, it is only fair to assume that this byte 31 indicates the beginning of program code. Every program code field you see here starts with 31. It could also be 31 0 0 0 0. At this point, we are not sure why exactly 31 was chosen to represent the beginning of the code field. We cannot even tell you why the four zeroes follow. The 31 could be because PeopleSoft is superstitious and so did not want to use 13, hence interchanged the digits. It could be that 31 people started PeopleSoft, or this was the 31st attempt in writing a sensible language (though we have reservations about this). However, it is a fair assumption as just like the signature value that other program files take, PeopleSoft code must also have a signature byte. Open an .EXE file in a hex editor, and the first two bytes are MZ, signifying that it is an executable file. The first byte of a dBase database is 03. Java code developers being a little more human and open with their thoughts, put in a special magic number. Since they liked the coffee house (or maybe the waitresses) across the road so much, Java code files start with CA FE BA BE.

Again PeopleSoft code all appear to have the same bytes in the beginning. In the first 37 bytes only one value changed in byte 6. The value 31 at the start has nothing to do with the fact that the program actually starts at the 38th byte. If you count the number of bytes in the first example, you will find that they total 39 — that is 37 plus 2. In all the examples that follow, you will find that the code actually begins at the 38th byte. This byte has a value of 21 and 21 in ASCII is a semi-colon. The 39th byte is the last byte of the code and since this too remains constant, we assume the value 7 to be the End of code marker. You can refer to the table for all these values. This is confirmed in the second example, where there are now 40 bytes totally, with 3 bytes of code.

Try another program:

&I = 10;

If PeopleSoft followed the same pattern as the last example, then logic demands that the resulting code should be 45. That is 37 plus 8, (or 6 if one leaves out the spaces). However, what you must remember is that numerals are never stored individually. Hence, it would be fair to assume that the introduction of a number will change the maths done. And this is true. The output for this code is as follows.

1

2

3

4

5

6

7

8

9

10

31

0

0

0

0

22

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

1

38

73

Var

&

I

40

0

6

17

0

0

0

0

10

0

0

Nul

=

Num

10

50

0

0

0

0

0

0

0

21

7

;

EOC

This time the 38th byte is 1. Except for the 6th byte, the first 37 bytes have remained the same. Since this is the first time that a variable has been used, one must assume the value 1 defines a variable. This is PeopleSoft notation that a variable follows. The 38 in 39th byte is ASCII for & and 73 is the letter I. A fair deal of code has been borrowed from C. Since a variable name could be a byte or 250 bytes long, it is difficult to predict the space required. Hence, strings are usually Nul terminated or the end marked by a 0. This happens here too.

Like in C, spaces have no value (unless they form a part of a text string). The 6 represents the equals sign. 17 0 0 0 0 indicates that the next ten bytes that follow are to be treated as a numeral. Here too, there is no conclusive proof that the other bytes are not used. We are not sure if 17 or 17 0 0 0 or 17 0 0 0 0 means numeral follows. But through all the examples this pattern holds good. The value assigned to the variable &I was 10, therefore the fifth byte after 17 is 10. This is followed by nine zeroes. The 21 represents the semi-colon at the end of the line.

The next program and resultant field value confirm both these points — that numbers are still stored with the low byte first followed by the high byte. Again, spaces do not appear anywhere in the code and the number still takes 10 bytes.

&I = 10;

&J = 20;

&K = 300;

Note, the value assigned to &I occupies the first byte out of the 10 bytes assigned to store the number and is 20. The value for the second, &J occupies the 5th byte after the value 17, and 20 is stored in it. The last variable &K has 44 1 stored in the 5th and 6th byte after 17. Each byte counts to the value of 256. Hence, while storing a value — just like in decimal counting system — the first byte is ones. The next byte stores 256s, the following 65536s and so on. The total therefore is 1 x 44 + 256 x 1 = 300.

 

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

64

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

1

38

73

 

 

 

 

 

 

 

 

Var

&

I

40

0

6

17

0

0

0

0

10

0

0

 

Nul

=

Num

 

 

 

 

10

 

 

50

0

0

0

0

0

0

0

21

1

38

 

 

 

 

 

 

 

 

;

Var

&

60

74

0

6

17

0

0

0

0

20

0

 

J

Nul

=

Num

 

 

 

 

20

 

70

0

0

0

0

0

0

0

0

21

1

 

 

 

 

 

 

 

 

 

;

Var

80

38

75

0

6

17

0

0

0

0

44

 

&

K

Nul

=

Val

 

 

 

 

44

90

1

0

0

0

0

0

0

0

0

21

 

256

 

 

 

 

 

 

 

 

;

100

7

 

 

 

 

 

 

 

 

 

 

EOC

 

 

 

 

 

 

 

 

 

If you paid close attention to the 6th byte, you will noticed it changed again. This value is the total length of the field minus the header which is 37 bytes long. In the first example this was 2 as the code only contained two bytes — the semi-colon (21) and the end-of-file marker (7). In the next example, the code was 22 bytes long. The variable name occupied 4; the assignment 16 (equals and 15 bytes for the number); The last two bytes are the semi-colon (21) and end-of-file marker (7).

The rules change slightly for a string value. Character variables are defined in the same way as their numeric counterparts. The only change here is that a CHAR value does not have a fixed length, so a byte (22) signifies its start and the end is marked with a Nul terminator. For example the routine

&I = ‘A’;

will store code in the following manner

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

10

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

1

38

73

 

 

 

 

 

 

 

 

Var

&

I

40

0

6

22

65

0

21

7

 

 

 

 

Nul

=

Str

A

Nul

;

EOC

 

 

 

 

The code is 10 bytes long as indicated by the 6th byte. As before, 1 represents a variable defined. From PeopleSoft point of view, there is no difference — a variable is a variable. There is no difference in the definition, though the assignment is different. 1 38 73 0 defines the variable &I. The value 6 is the equals sign. To indicate that text or a string literal follows, PeopleSoft uses the value 22, which is followed by 65 — the ASCII value for A. You will notice that this string is null terminated, or in simple terms it means that zero signifies the end of the string. The last two bytes need no further explanation. Although every other character is stored in the code, even assignment characters like the equals sign, the quotation marks for the string literal are not stored. Strings are correctly deciphered according to the term that precedes it. PeopleCode knows what is a variable name and what is a string literal. The quotation marks appear automatically when the code is displayed again.

Just to confirm

&I = ‘A’;

&J = ‘B’;

 

results in the following

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

19

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

1

38

73

 

 

 

 

 

 

 

 

Var

&

I

40

0

6

22

65

0

21

1

38

74

0

 

Nul

=

Str

A

Nul

;

Var

&

J

Nul

50

6

22

66

0

21

7

 

 

 

 

 

=

Str

B

Nul

;

EOC

 

 

 

 

 

Close this field and open it and there will still be quote marks around the A and B, while I and J remain unchanged.

Try just one more variable — Boolean values, that is True or False. Since the variable name by itself does not indicate the contents of a field, True and False need to be represented by some value. Usually the values assigned to True and False are 0 and 1. However, this is not the case here. Like all other variables, there is a special values assigned to indicate Boolean numbers. A 47 defines True, while 48 is False. This can be seen in the case of the following example.

&I = True;

&J = False;

These values come as close to following Boolean rules as possible by occupying only a single byte.

 

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

15

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

1

38

73

 

 

 

 

 

 

 

 

Var

&

I

40

0

6

47

21

1

38

73

0

6

48

 

Nul

=

True

;

Var

&

J

Nul

=

False

50

21

7

 

 

 

 

 

 

 

 

 

;

EOC

 

 

 

 

 

 

 

 

It is difficult to understand how exactly PeopleSoft goes about making sense of all this code. But this partially optimised code seems to work well. It ensures that the code can be recreated without any problem. There are a number of distinct advantages that this method of coding has over others. The most important feature is that there can be no runtime error. This is because the code is reformatted before being saved. This step therefore has to check that all the command and functions used are actually available to the program. Further, as the code is also parsed and in some sort of order, execution is faster as the compiler does not have spend time in making sense of bits and pieces. Finally, this ‘compiled’ code can be used to get the original code back.

The next example proves that the code is not fully optimised as in the case of a C. Compiled C code is also optimised and hence statements that are redundant are automatically removed or compressed. Only calculations and computations that have to be done at runtime are retained, all other operations that can be completed before are done in the compilation stage.

&I = 10 + 20;

In such an assignment, it would obviously make sense to store the sum in the variable &I. However, in doing so, it would also be impossible for PeopleSoft to correctly recreate the original code after it is saved.

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

38

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

1

38

73

 

 

 

 

 

 

 

 

Var

&

I

40

0

6

17

0

0

0

0

10

0

0

 

Nul

=

Num

 

 

 

 

10

 

 

50

0

0

0

0

0

0

0

19

17

0

 

 

 

 

 

 

 

 

+

Num

 

60

0

0

0

20

0

0

0

0

0

0

 

 

 

 

20

 

 

 

 

 

 

70

0

0

0

21

7

 

 

 

 

 

 

 

 

 

;

EOC

 

 

 

 

 

 

The only value that separates the two numbers is 19 and this one has to assume is the plus character (+). You will find that all other rules that you learned so far have been obeyed. There is no change in the pattern followed. The 6th byte is still the length of the code, the last two bytes are still 21 7.

From this point on, only the new items will be pointed out to you. Most of these will point out the value assigned to different keywords in PeopleCode. You will notice functions are spelt out in PeopleCode, whereas keywords like If, For, are simply represented by a single value. Try a function first.

WinMessage("hi",64);

This function uses two parameters that you are already familiar with — a string and a numeric. Try figuring out how the code will be represented before looking at the output below. Since function names are spelt out, there has to be some sort of flag that differentiates a function from a string.

 

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

36

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

10

87

105

 

 

 

 

 

 

 

 

Func

W

i

40

110

77

101

115

115

97

103

101

0

11

 

n

M

e

s

s

a

g

e

Nul

(

50

22

104

105

0

3

17

0

0

0

0

 

Str

h

i

Nul

,

Num

 

 

 

 

60

64

0

0

0

0

0

0

0

0

0

 

64

 

 

 

 

 

 

 

 

 

70

20

21

7

 

 

 

 

 

 

 

 

)

;

EOC

 

 

 

 

 

 

 

 

To quickly go over this, start with the length of the code, which is 36 bytes long, as represented in the 6th byte. The 38th byte from the beginning is 10. This must indicate the start of a function as there is no other code before this and the WinMessage function’s ASCII values follow in the subsequent bytes. The Nul terminates the character string as expected. Another standard coding practice that is used by many programming languages is the use of parenthesis, which mark the start and end of the function’s parameters. This is represented by 11 and is closed by the value 20, which is the third last byte. Breaking up the other parts of the code, you will find that the two parameters are separated by a byte whose value is 3. This is the comma. This is easily identifiable because the first parameter is a string literal and the second is a number.

By now, you should be very comfortable with reading these outputs by yourself. As you go on, you will find that you begin to understand more and more, the internal workings of PeopleSoft and will be more comfortable with working on PeopleSoft.

&I = 10;

If (&I = 10) Then

WinMessage("i10");

End-If;

 

The If is a reserved word in PeopleSoft. It is therefore treated a bit differently from functions like WinMessage. You will find that this keyword like others that are done in later examples, are represented by single values in the stored code.

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

68

0

0

0

0

10

0

0

 

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

0

4

0

0

1

38

73

 

 

 

 

 

 

 

 

Var

&

I

40

0

6

17

0

0

0

0

10

0

0

 

Nul

=

Num

 

 

 

 

10

 

 

50

0

0

0

0

0

0

0

21

28

11

 

 

 

 

 

 

 

 

;

If

(

60

1

38

73

0

6

17

0

0

0

0

 

Var

&

I

Nul

=

Num

 

 

 

 

70

10

0

0

0

0

0

0

0

0

0

 

10

 

 

 

 

 

 

 

 

 

80

20

31

10

87

105

110

77

101

115

115

 

)

Then

Func

W

i

n

M

e

s

s

90

97

103

101

0

11

22

105

49

48

0

 

a

g

e

Nul

(

Str

i

1

0

Nul

100

20

21

26

21

7

 

 

 

 

 

 

)

;

End-If

;

EOC

 

 

 

 

 

 

Taking this apart, you will see If is represented by the value 28. Right after this, the variable &I is defined. Note also that the equals sign does not change in value although it is used for comparison the second time. Skip along to the right past the bracket close which is 20, and you will find that a function definition starts (10). You used this function in the last example. The complimentary keyword to If is Then. This is represented by 31 in byte 82. If, as you will also find with For has also to have a corresponding close value. In the last five bytes (20 21 26 21 7), there is an End-If (26) which matches the If. These last five values represent the following — close bracket, semi-colon, End-If, semi-colon and end-of-code. You now know how the If, Then, End-If is stored in the record.

The next example is a small revision on the last. It introduces the Else clause.

If (&I = 10) Then

WinMessage("i10");

Else

WinMessage("hi");

End-If;

All that has been added to this example is another WinMessage function that will be called if the condition is not fulfilled. Examine the code stored in the PROG.TXT field and you will see the following.

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

67

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

28

11

1

 

 

 

 

 

 

 

 

If

(

Var

40

38

73

0

6

17

0

0

0

0

10

 

&

I

Nul

=

Num

 

 

 

 

10

50

0

0

0

0

0

0

0

0

0

20

 

 

 

 

 

 

 

 

 

 

)

60

31

10

87

105

110

77

101

115

115

97

 

Then

Func

W

i

n

M

e

s

s

a

70

103

101

0

11

22

105

49

48

0

20

 

g

e

Nul

(

Str

i

1

0

Nul

)

80

21

25

10

87

105

110

77

101

115

115

 

;

Else

Func

W

i

n

M

e

s

s

90

97

103

101

0

11

22

104

105

0

20

 

a

g

e

Nul

(

Str

h

i

Nul

)

100

21

26

21

7

 

 

 

 

 

 

 

;

End-If

;

EOC

 

 

 

 

 

 

C programmers and other programming professionals will notice that the function appears twice. Optimising compilers usually define functions only once and the same function is called as many times as required using reference points. However, this is not the case in PeopleSoft. Only standard keywords are substituted by values from a look up table. Functions are spelt out and get repeated as many times as they appear in the code.

 

Obviously, this method does not increase the execution speed, but it does allow PeopleSoft to recreate the original code completely. Another difference between this and C programs, is the fact that one could call a function in C many times, without it actually being there. The compiler would go through the process of optimising the code, and using references without checking for the function. Ultimately, at runtime the error will be discovered. This is never the case in PeopleCode as all keywords and functions are checked before the code is saved to disk. If you change WinMessage to SinMessage in the DLL, **********, then when trying to save the above code you would automatically get an error message as WinMessage will no longer be found.

In the above example, the only new value that appears in 25, which stands for Else. The other code is the same as what was there earlier.

Just a couple more examples to ensure you have understood all this well. Writing a disassembler is not an easy task. This is because one has to figure out a pattern from the compiled code. Translating this pattern into something meaningful is not easy, unless one has written the compiler or knows how the compiled code is saved. The more cryptic the code gets, (or the closer the compiled code is to machine language) the faster it executes. This, however, make it even more difficult to reconstruct the original code.

Java, for instance, is a perfect example of an impossible task. Any program that is finally run on a computer does so because the code is understood by the microprocessor. Java runs on a hypothetical microprocessor, or rather is compiled for a processor that does not exist. The final compiled code that executes is a layer below that is created by the Operating System — that runs a Java Virtual Machine. Trying to make sense of this would be close to impossible as something or the other will definitely be lost in the translation. The big plus for Java is that because of its design, it can work on any system — any system that supports a Java Virtual Machine.

What it loses on speed, it makes up on platforms. PeopleSoft happens to have a similar approach. The code is not designed to run at top speed but for increased readability and simplicity in modification. Performance benefits can only come from better coding practices. And this will only happen when one understands how the code is actually saved.

This next example shows the For function applied.

For &I = 1 To 10

WinMessage("hi");

End-For;

The pattern is exactly the same as with the If statement. The only change is For has a value of 41; To the value 42; and the increment counter or ‘step’ the value 43 (which is not seen in this example as the default increment is 1).

 

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

60

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

41

1

38

 

 

 

 

 

 

 

 

For

Var

&

40

73

0

6

17

0

0

0

0

1

0

 

I

Nul

=

Num

 

 

 

 

1

 

50

0

0

0

0

0

0

0

0

42

17

 

 

 

 

 

 

 

 

 

To

Num

60

0

0

0

0

10

0

0

0

0

0

 

 

 

 

 

10

 

 

 

 

 

70

0

0

0

0

45

10

87

105

110

77

 

 

 

 

 

Code St

Func

W

i

n

M

80

101

115

115

97

103

101

0

11

22

104

 

e

s

s

a

g

e

Nul

(

Str

h

90

105

0

20

21

44

21

7

 

 

 

 

i

Nul

)

;

EndFor

;

EOC

 

 

 

 

The For keyword and a few others that you will use shortly, always enclose a group of statements. To signify the start of such a set of statements the value 45 is placed. Like the value 6, which represents the equals sign and can be used for assignment or comparison, this value 45 can mean different things. You will see this later. Right now, it marks the beginning of code (Code St) and 44 (the third last byte) closes the set (End-For).

Use both the If and the For statements together as in the follows and the result is clear enough to understand.

For &I = 1 To 10 If (&I = 2) Then

WinMessage("hi");

End-If;

End-For;

Pay attention to the end-markers. Remember there are two parts to the For. First the keyword and the condition to be tested is defined and then, just after this there must be a point where the commands to be repeated start. The If, on the other hand, executes the command set only once. Therefore, there are two entry points for a For statement, but only one end. An If has only a single start and end. Incidentally, the values given to the If and For are not machine code bytes. Hence, one can be sure that this code is not optimised at all.

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

86

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

41

1

38

 

 

 

 

 

 

 

 

For

Var

&

40

73

0

6

17

0

0

0

0

1

0

 

I

Nul

=

Num

 

 

 

 

1

 

50

0

0

0

0

0

0

0

0

42

17

 

 

 

 

 

 

 

 

 

To

Num

60

0

0

0

0

10

0

0

0

0

0

 

 

 

 

 

10

 

 

 

 

 

70

0

0

0

0

45

28

11

1

38

73

 

 

 

 

 

Code St

 

 

Var

&

I

80

0

6

17

0

0

0

0

2

0

0

 

Nul

=

Num

 

 

 

 

2

 

 

90

0

0

0

0

0

0

0

20

31

10

 

 

 

 

 

 

 

 

)

Then

Func

100

87

105

110

77

101

115

115

97

103

101

 

W

i

n

M

e

s

S

a

g

e

110

0

11

22

104

105

0

20

21

26

21

 

Nul

(

Str

h

i

Nul

)

;

End-If

;

120

44

21

7

 

 

 

 

 

 

 

 

End-For

;

EOC

 

 

 

 

 

 

 

What you have to bear in mind, is that all this is calculated guesses on how PeopleSoft stores code. The definitions for the values used may change along the way.

Try another code segment. This time initialise a variable to a field. Field names are only unique when part of a table. Two fields from different tables could use exactly the same name. The only way to tell two fields apart, would be to append the table name to the field. This is done automatically when working with most RDBMS’. To check how PeopleSoft handles record fields when storing, try out the next example. Remember that only a record field can be used to store code in. Fields themselves are never used except when they are defined in the beginning.

There are many details stored with fields. There is the Long name, the Short name, the data type, the size etc. If each time a field was referenced or used, all this information was stored, the code size would grow tremendously. In the next examples, you will find that PeopleSoft has its own method of recalling fields used in the code. This method of storing record fields saves bytes.

This line of code was written in the table REC1 and under the field R1:

&I = REC1.R1;

R1 is a record field in the table REC1, which is being assigned to the variable &I. Saving this entry, the code segment automatically changes to

&I = R1;

PeopleSoft first removes the redundant REC1 as the code appears in the field itself. Examine also how PeopleSoft saves the code in the binary table.

 

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

10

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

1

38

73

 

 

 

 

 

 

 

 

Var

&

I

40

0

6

33

0

0

21

7

 

 

 

 

Nul

=

Field

 

 

;

EOC

 

 

 

 

The total code saved is 47 bytes long with the actual code portion occupying only 10 bytes. The starting 37 bytes have not changed. A variable &I is declared with 1 and terminated by zero. Equals is 6. Now comes the change. The field name is not stored directly, but is referred to by PeopleCode. The new value 33 appears to be the field entry point and holds a reference to where the actual field (and its contents) can be found. It would be impossible to assign a value to &I as one will not know until runtime what value will be in record field R1. This value could change depending upon the row that is currently being pointed to.

We can only assume bytes 44 and 45 after the value 33, which are 0 0 indicate the first entry on some table that keeps track of the fields used in the program. This is confirmed later. Using a reference point is a simpler method of assigning a value as this ensures a couple of things. One, that always the current value stored in field F1 is assigned to the variable &I during execution. Secondly, that no space is wasted in reserving bytes for unknown field sizes.

How exactly the fields are referenced or whether the format actually makes complete sense is up for discussion. Unfortunately, whether this is good or bad there is no escaping the fact that one will have to live with it. PeopleSoft will not be allowed to change this or else code that worked for so long will cease to function. This is similar to why COBOL is still around.

Try assigning another field from the same table REC1 to the variable &I. Delete the first line so that there is no confusion.

&I = R2;

Check the binary code that is stored for this entry changes slightly giving us a clue as to what goes on.

 

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

10

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

1

38

73

 

 

 

 

 

 

 

 

Var

&

I

40

0

6

33

1

0

21

7

 

 

 

 

Nul

=

Field

Index

 

;

EOC

 

 

 

The value after the equals sign is 33 1 0. We know the 33 signifies a field assignment follows and 1 0 is the index number for the field that is being referenced. Two questions that should come to mind are — why is the index value not 0 0? And what happens if a record field is referenced from another event in the same field? Quite obviously, as you will see later on, the reference value 0 0 is reserved for calls to the field from within itself. Any other field is indexed in order starting from 1 0. Further examples will show that the reference values are assigned on a first-appear-first-assigned basis.

Again, each code segment that is keyed in each field event is stored separately. Hence, counters for each individual code segment always start from 1 each time. There is no overlap at all. We will use the Application Designer once more to look at a couple of PeopleSoft tables that show the references made.

But before doing that, try initialising two variable &I and &J to two fields in any event of record field R1.

&I = R2;

&J = R1;

The output will not be 33 0 0 and 33 1 0. Look at what will be saved in the PROG.TXT field.

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

19

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

1

38

73

 

 

 

 

 

 

 

 

Var

&

I

40

0

6

33

1

0

21

1

38

74

0

 

Nul

=

Field

Index

 

;

Var

&

J

Nul

50

6

33

0

0

21

7

 

 

 

 

 

=

Field

Index

 

;

EOC

 

 

 

 

Although &J = R1; appears second, the value stored is still 33 0 0, while the entry before this is 33 1 0. Just to make this a little clearer, try the following.

Start the Application Designer by clicking Go | PeopleTools | Application Designer. Create a couple of fields R1 and R2. The size or type of the field is not really important at this point, so set it to whatever you want. Create a record called REC1 and place the two field created in this record. Do not forget to Build the record else you will get an error.

First, verify that there is no code stored for this record. Using the Query module, check the internal table PSPCMNAME, which has the following fields — PROGNAME, NAMENUM, RECNAME and REFNAME for any reference to the fields. To do this, perform the following steps. Click Go | PeopleTools | Query. Click the Database panel on the left and locate PSPCMNAME. Double-clicking this entry will move the record to the Query panel as shown in fig.1. Double click to select every field for display. A short list of all the fields appears on the panel on the right.

Before running the query, (which you could attempt and have a few thousand record displayed) set a search criteria by right-clicking on RECNAME in the left panel. Select Criteria in the pop-up that appears. The Criteria panel in the right shows up and you must fill in a value for the search. Enter REC1 in the Expression field. Click the Execute button on the button bar and wait. You could wait till eternity and still not have anything appear in the right panel because at this point there is no code written for any of the fields of table Rec1.

Fig.1: Querying the table PSPCMNAME for code

Switch to the Application Designer and select the first record field — R1. Right-click the object and select View PeopleCode as shown fig.2. When the code window opens, enter a single semi-colon (;). This is only required for the purpose of testing and to make sure that the query works. You could experiment a while later, but for now stay with the example or the results you see may be different from what is shown here. Save the record once more so the change is reflected in the database.

Fig.2: Enter some code in the field R1

As far as PeopleSoft is concerned the ; signifies that there is code placed in the field. You, however, know that there is no code at all, but then, you are not important. No assignment statements or functions have been used. At best, one can say that the only reference made would be to an event in a field. In this case, it is the FieldChange, the first event in the event list.

Switch to the Query application once more and run the same query. This time there is an entry listed in the columns on the right. The line displayed in the right panel displays the Prog Name, Name Nb, Record and Ref Name. Prog Name is a unique name created by PeopleSoft as it stores the code you entered somewhere. The code that you keyed in is not stored in this table but in another which we will come to shortly. This table only keeps track of the code references. The program name displayed in fig.4 may not be the same displayed on your terminal. Name Nb or Name Number is 1. We have assumed this to be the reference to the field itself. The Record field shows REC1, as this is the table we are looking for. Ref Name R1 identifies the record field in which the code was entered.

Fig.4: Querying PSPCMNAME once more

Take a closer look at the left panel. There is a short explanatory note that appears with the table PSPCMNAME, which states PeopleCode Reference. In short, this is the table where PeopleSoft stores references to objects used. (The PS beginning means that it is internal to PeopleSoft.) As there is only a single reference at this point to the current field, you have only a single line in the query.

This will not change even if an assignment statement is added, as long as the field reference is the local one. Hence, if you change the code in the field R1 to read

&I = R1;

and run the query once more, there will be no change in the references made. The entry that appeared will still be exactly the same. This is because at this point there is no change in the field referenced. To examine the code, we need to query the table PSPCMPROG. Note the program name that appears in Prog Name as it will be required for the query. Use Query once more and locate the table PSPCMPROG in the Database panel. Double-click and move the table to the Query panel. The last field is the one to examine — PROGTXT. This field contains the program code of all programs in PeopleSoft. Add it to the right panel by double clicking on it. Set the search criteria to match the program name that appeared in the last query. The result will show that there is only one entry for this query. Although you can see the field, you will not be able to see its contents. To be able to do this, use our C program or some other hex editor to extract the bytes stored here. The actual bytes of this stored program were shown earlier. If you examine the bytes, you will find that the field assignment is set to 33 0 0.

Make a small change to the program code in record field R1. This time assign another field other than the current one to the variable, like

&I = R2;

Fig.10: Assigning any other field within a field, returns two reference points

Save this change and now run the same query on PSPCMNAME. This time the query returns two records as you can see in fig.10. You will notice that the program name is the same for both entries. Hence, this same piece of code is making two references. The first which has Name Nb equal 1, refers to the field itself as this is where the code lies. The second with Name Nb 2 is a reference to another field. The last column shows Ref Name is R2. Each time another field is referenced the Name Nb increases by 1. In this query list however, the reserved reference for the field itself is 1. Any other field is sequentially reference as it appears starting with a value of 2.

What is not explained so far, is why the reference values stored differ from that shown in the query. Another thing not explained is the reference to the field itself. As we have seen earlier, an assignment made to another field from within a field appears as 33 1 0. However, there is no reference 33 0 0 in the stored code, as would be indicated from the query that we have just seen. There is obviously more to this and we hope that it will make some sense along the way.

Try this out by creating another record, REC2 with two more fields R3 and R4. Change the line of code once more, this time to read

&I = REC2.R3;

as you can see in fig.11

Fig.11: Assignments can be made to any field, any record

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

10

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

1

38

73

 

 

 

 

 

 

 

 

Var

&

I

40

0

6

33

1

0

21

7

 

 

 

 

Nul

=

Field

Index

 

;

EOC

 

 

 

Do not hit the panic button if when you run the query again you find only one record referenced. This happens because the search criterion has been set to look only for record REC1. To locate all references, you will have to broaden the search parameters to look at both REC1 and REC 2. Do this by changing the Operator to In List and then specifying REC1 and REC2 in the Expression column. Fig.13 shows how.

Fig.13: Searching for references in a list of records

Fig.14 shows exactly where the references to the fields are. As usual the reference to a field within itself returns a reference value of 1. Since the reference is to another field, the index counter moves up by 1 and is set at 2. You will notice that Name Nb is set to 2 and it points to REC2 with Ref Name set at R3. Just to confirm that the references follow this pattern, change REC2.R3 to REC2.R4 in the program code, save and then re-run the query.

Fig.14: There are two reference points when looking at fields outside the current record

The binary code that is stored for this entry is as follows.

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

10

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

1

38

73

 

 

 

 

 

 

 

 

Var

&

I

40

0

6

33

1

0

21

7

 

 

 

 

Nul

=

Field

Index

 

;

EOC

 

 

 

 

It does not make a difference which field you call. In the code that is stored, 33 0 0 always represents the current field and 33 1 0, the first reference made to an outside field. Since there is no assignment actually made in the code to the current field, there is no 33 0 0. Again, whether the field is from the current record or from another record really does not make a difference to the index counter. This continues from 1 onward. If you add another line of code that assigns field R4 to variable &J, you will notice that the query will reference the current field only once. There is no second reference to the field itself ever.

&I = REC2.R3;

&J = REC2.R4;

Fig.17: Query shows that there are three references for two assignments

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

19

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

1

38

73

 

 

 

 

 

 

 

 

Var

&

I

40

0

6

33

1

0

21

1

38

74

0

 

Nul

=

Field

Index

 

;

Var

&

J

Nul

50

6

33

2

0

21

7

 

 

 

 

 

=

Field

Index

 

;

EOC

 

 

 

 

As seen in fig.17, there is a total of three entries. One is a reference point to the current field in which the code is stored in, the other two refer to the other fields assigned to variables. Change the assignment order around to

&I = REC2.R4;

&J = REC2.R3;

and you will find that the reference numbers in Name Nb do not change order. This is because PeopleSoft assigns objects on a first come basis. The first field that is referenced gets the value 33 1 0. The one after this 33 2 0 and so on.

Try just one more before moving on. Assign all the fields to variables. Since there are four fields, you will get four reference points. Other than the first entry (where Name Nb is 1) the other references will appear in order of the assignment. If therefore you entered and saved the following in a field,

&I = R1;

&J = R2;

&K = REC2.R3;

&H = REC2.R4;

The query result should be as shown in fig.19.

 

Fig.19: Four references for four fields

What we would like you to bear in mind, is that all this is exploratory work. The only people who know the real reasons behind what happens inside PeopleSoft are the programmers at PeopleSoft. This next example does not make any sense given the way we have looked at referencing in PeopleSoft. We have so far assumed that any reference to a field is stored in a table. This table has only one reserved value 0, which means a reference to the code field itself. From what we have seen so far, any other assignment to the current field uses the same reference point. It would then be logical to assume that this should hold good for all other field assignments as well. However, the next example when entered in field R1, proves this wrong.

&I = R2;

&J = R2;

&K = R2;

Logic would demand that all these assignments reference the same value, which should be 33 1 0 as 33 0 0 is reserved for R1. As you see in the output, you have 33 1 0, 33 2 0 and 33 3 0 stored in the binary file.

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

28

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

1

38

73

 

 

 

 

 

 

 

 

Var

&

I

40

0

6

33

1

0

21

1

38

74

0

 

Nul

=

Field

Index

 

;

Var

&

J

Nul

50

6

33

2

0

21

1

38

75

0

6

 

=

Field

Index

 

;

Var

&

K

Nul

=

60

33

3

0

21

7

 

 

 

 

 

 

Field

Index

 

;

EOC

 

 

 

 

 

At this point, we have to consider this as another ‘feature’ of PeopleSoft (as Microsoft popularly refers to such). These features unfortunately can never be removed, at least not in subsequent updates. Making changes in the core would render the program unusable to existing users, which is something that no software company can afford to do.

The Query application can be used to examine many other things. Right now, we will continue to delve into the workings of PeopleSoft by discovering how other functions are stored. Some thing that will become important as you go along is the manner in which functions are stored. Hence, the following examples look at code that have functions defined. The many lines of code that you write translate to few bytes saved in the code field.

Declare Function XXX PeopleCode F1 FieldFormula;

Again we go one step at a time to ensure that you do not get confused with too many terms introduced at once. This line declares that there is a function XXX that is written is available to PeopleCode. This function can be found in the field F1 under the event FieldFormula.

Examine the binary code stored. Byte 38 is the first code byte after the header. Keywords only occupy a byte. Declare is therefore represented by a value 49. The keyword Function is 50. The start of function names are marked by the value 10, which is the 40th byte and terminated with a Nul.

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

29

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

49

50

10

 

 

 

 

 

 

 

 

Declare

Function

Fn Name

40

88

88

88

0

58

33

0

0

64

70

 

X

X

X

Nul

PCode

Field

Index

 

Event

F

50

105

101

108

100

70

111

114

109

117

108

 

i

e

l

d

F

o

r

m

u

l

60

97

0

66

21

45

7

 

 

 

 

 

a

Nul

End Declare

;

Code St

EOC

 

 

 

 

The next byte 58 is the PeopleSoft shorthand for the word PeopleCode. The following three bytes 33 0 0 indicate a reference to the current field, F1. Since event names are not keywords and could be added to like functions, there has to be an identifier placed here to mark the start of the event name. This is 64, marking the start of an event — FieldFormula, which as usual is Nul terminated. The Declare needs a corresponding close and this is the value 66 is an End Declare.

Add another line to the last program. Having informed PeopleSoft where to find the function XXX, call the function.

Declare Function XXX PeopleCode F1 FieldFormula;

XXX();

In the last example, we ignored the second last byte. Here is where something else gets screwy. The 45 was supposed to signify the start of code. It may not seem so in the last example, but makes sense when another line of code appears. Take a look at the binary code output that is given below.

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

37

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

49

50

10

 

 

 

 

 

 

 

 

Declare

Function

Fn Name

40

88

88

88

0

58

33

0

0

64

70

 

X

X

X

Nul

PCode

Field

Index

 

Event

F

50

105

101

108

100

70

111

114

109

117

108

 

i

e

l

d

F

o

r

m

u

l

60

97

0

66

21

45

10

88

88

88

0

 

a

Nul

End

;

Code St

Fn Name

X

X

X

Nul

70

11

20

21

7

 

 

 

 

 

 

 

(

)

;

EOC

 

 

 

 

 

 

You find 45 marks the start of a loop or set of code lines. It is only after this does function XXX get defined. The byte pair 11 20 is the open and close brackets that hold a function parameters. The rule on reference pointers still holds true here too. If you changed the F1 to F2, then as seen in the output below, you will find that the XX byte has changed from 0 to 1.

Declare Function XXX PeopleCode F2 FieldFormula;

XXX();

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

37

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

49

50

10

 

 

 

 

 

 

 

 

Declare

Function

Fn Name

40

88

88

88

0

58

33

1

0

64

70

 

X

X

X

Nul

PCode

Field

Index

 

Event

F

50

105

101

108

100

70

111

114

109

117

108

 

i

e

l

d

F

o

r

m

u

l

60

97

0

66

21

45

10

88

88

88

0

 

a

Nul

End

;

Code St

Fn Name

X

X

X

Nul

70

11

20

21

7

 

 

 

 

 

 

 

(

)

;

EOC

 

 

 

 

 

 

This is true even if you use a field that is not in the current table. The next example is only to prove this.

Declare Function XXX PeopleCode AR1.A1 FieldFormula;

XXX();

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

37

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

20

0

0

0

0

0

0

0

0

0

0

30

0

0

0

4

0

0

0

49

50

10

 

 

 

 

 

 

 

 

Declare

Function

Fn Name

40

88

88

88

0

58

33

1

0

64

70

 

X

X

X

Nul

PCode

Field

Index

 

Event

F

50

105

101

108

100

70

111

114

109

117

108

 

i

e

l

d

F

o

r

m

u

l

60

97

0

66

21

45

10

88

88

88

0

 

a

Nul

End

;

Loop

Fn Name

X

X

X

Nul

70

11

20

21

7

 

 

 

 

 

 

 

(

)

;

EOC

 

 

 

 

 

 

 

Looking deeper into functions, there is much that still has to be explained. Our next example defines a function. Do not ask why the rules of the game are not observed, but here a bit of what you know so far has been changed. As we had pointed out earlier, the biggest problem in developing software is that you must live with your mistakes. Once rules are defined, it is difficult to undefine them. Change the rules of the game, and you could lose all the business you have so far. Since we are guessing the rules here, we are not sure what PeopleSoft really wants to do. The pattern is still to become clear.

 Function XXX()

End-Function;

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

13

0

0

0

0

0

10

0

0

4

0

0

0

0

0

0

0

20

1

0

0

0

0

0

0

0

0

1

30

0

0

0

4

0

0

0

50

10

88

 

 

 

 

 

 

 

 

Function

Fn Name

X

40

88

88

0

11

20

45

55

21

45

7

 

X

X

Nul

(

)

Code St

End Fn

;

Code St

EOC

50

88

88

88

0

0

0

0

0

0

0

 

X

X

X

?

?

?

?

?

?

?

60

0

0

0

0

0

0

7

0

0

0

 

?

?

?

?

?

?

?

?

?

?

70

7

0

 

 

 

 

 

 

 

 

 

?

?

 

 

 

 

 

 

 

 

 

This stored code has broken a couple of rules. So far, recovering binary code from the field meant a sum of 37 bytes for the header, with the number of code bytes after the header indicated in byte 6. This has been accurate for all the examples and has always matched the field size that was stored with the entry. We know the C program that we used works flawlessly. It locates the number of bytes stored in the field from the table header, and then reads that many bytes from the start of the field.

 The current example is 22 bytes longer than what is indicated in byte 6. Yet the field size had been accurately read. These 22 bytes appear to have something to do with the function XXX that was defined. The second rule that was broken is that 7 is not the last of the code. Rather the value 7 that appears only marks the end of the code statements keyed into the field. There is obviously other bytes that are stored along with the code.

We will examine the last 22 bytes in depth with further examples. In the following example, you will notice though the function definition has changed, the bytes still remain exactly the same. Code for this function is once more preceded by a value of 45. There is no corresponding close other than the semi-colon.

Function XXX() WinMessage("HI");End-Function;

 

1

2

3

4

5

6

7

8

9

10

 

31

0

0

0

0

32

0

0

0

0

10

0

0

0

4

0

0

0

0

0

0

20

0

1

0

0

0

0

0

0

0

1

30

0

0

0

4

0

0

0

50

10

88

 

 

 

 

 

 

 

 

Function

Fn Name

X

40

88

88

0

11

20

45

10

87

105

110

 

X

X

Nul

(

)

Loop

Fn Name

W

i

n

50

77

101

115

115

97

103

101

0

11

22

 

M

e

s

s

a

g

e

Nul

(

Str

60

72

73

0

20

21

55

21

45

7

88

 

H

I

Nul

)

;

End Fn

;

Code St

EOC

X

70

88

88

0

0

0

0

0

0

0

0

 

X

X

?

?

?

?

?

?

?

?

80

0

0

0

0

0

7

0

0

0

7

 

?

?

?

?

?

?

?

?

?

?

90

0

 

 

 

 

 

 

 

 

 

 

?

 

 

 

 

 

 

 

 

 

So far, we have only covered a few of the statements that PeopleSoft inserts in the code field. There is a lot more ground to cover before it can all make sense together. Obviously, there will be questions galore. The most important is — how does all this help? When programming Windows it helps to know how functions and data is handled. Here too, as you understand how PeopleSoft puts its code together, it will become easier to understand some of the more difficult statements that will be covered in the later chapters. Since you know how the function gets stored, you will know why certain parameters have to be passed and why you will get vague errors at times. If all this seems like a far shot just now, read along it gets more interesting.

In another chapter we discuss the use of C and explain the sample C program we used to delve into the contents of the database. You will have to be content at this point to use the look up table for the values of the different keywords and objects used in PeopleCode. You will also learn where exactly you can find what in PeopleSoft, as it is easy to get lost in the many records that PeopleSoft creates. Another secret tool that comes along free with PeopleSoft, is the log file that one can examine to learn more about the different commands that PeopleSoft issues when performing any task.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值