|
|
1.1 ! root 1: .\" Copyright (c) 1980 Regents of the University of California. ! 2: .\" All rights reserved. The Berkeley software License Agreement ! 3: .\" specifies the terms and conditions for redistribution. ! 4: .\" ! 5: .\" @(#)puman2.n 6.2 (Berkeley) 5/7/86 ! 6: .\" ! 7: .if !\n(xx \{\ ! 8: .so tmac.p \} ! 9: 'if n 'ND ! 10: .nr H1 1 ! 11: .NH ! 12: Basic UNIX Pascal ! 13: .PP ! 14: The following sections ! 15: explain the basics of using ! 16: .UP . ! 17: In examples here we use the text editor ! 18: .I ex ! 19: (1). ! 20: Users of the text editor ! 21: .I ed ! 22: should have little trouble following these examples, ! 23: as ! 24: .I ex ! 25: is similar to ! 26: .I ed . ! 27: We use ! 28: .I ex ! 29: because it ! 30: allows us to make clearer examples.\(dg ! 31: .FS ! 32: \(dg Users with \s-2CRT\s0 terminals should find the editor ! 33: .I vi ! 34: more pleasant to use; ! 35: we do not show its use here because its display oriented nature ! 36: makes it difficult to illustrate. ! 37: .FE ! 38: The new ! 39: .UX ! 40: user will find it helpful to read one of the text editor documents ! 41: described in section 1.4 before continuing with this section. ! 42: .NH 2 ! 43: A first program ! 44: .PP ! 45: To prepare a program for ! 46: .UP ! 47: we first need to have an account on ! 48: .UX ! 49: and to `login' ! 50: to the system on this account. ! 51: These procedures are described in the documents ! 52: .I "Communicating with UNIX" ! 53: and ! 54: .I "UNIX for Beginners". ! 55: .PP ! 56: Once we are logged in we need to choose a name for our program; ! 57: let us call it `first' as this is the first example. ! 58: We must also choose a name for the file in which the program will be stored. ! 59: The ! 60: .UP ! 61: system requires that programs reside in files which have names ending with ! 62: the sequence `.p' so we will call our file `first.p'. ! 63: .PP ! 64: A sample editing session to create this file would begin: ! 65: .LS ! 66: % \*bex first.p\fR ! 67: "first.p" [New file] ! 68: : ! 69: .LE ! 70: We didn't expect the file to exist, so the error diagnostic doesn't ! 71: bother us. ! 72: The editor now knows the name of the file we are creating. ! 73: The `:' prompt indicates that it is ready for command input. ! 74: We can add the text for our program using the `append' ! 75: command as follows. ! 76: .LS ! 77: :\*bappend\fR ! 78: .B ! 79: program first(output) ! 80: begin ! 81: writeln('Hello, world!') ! 82: end. ! 83: \&. ! 84: .R ! 85: : ! 86: .LE ! 87: The line containing the single `\*b.\fR' character here indicated ! 88: the end of the appended text. ! 89: The `:' prompt indicates that ! 90: .I ex ! 91: is ready for another command. ! 92: As the editor operates in a temporary work space we must now store the contents ! 93: of this work space in the file `first.p' ! 94: so we can use the Pascal ! 95: translator and executor ! 96: .IX ! 97: on it. ! 98: .LS ! 99: :\*bwrite\fR ! 100: "first.p" [New file] 4 lines, 59 characters ! 101: :\*bquit\fR ! 102: % ! 103: .LE ! 104: We wrote out the file from the edit buffer here with the ! 105: `write' ! 106: command, and ! 107: .I ex ! 108: indicated the number of lines and characters written. ! 109: We then quit the editor, and now have a prompt from the shell.\(dd ! 110: .FS ! 111: \(dd Our examples here assume you are using ! 112: .I csh. ! 113: .FE ! 114: .KS ! 115: .PP ! 116: We are ready to try ! 117: to translate and execute our program. ! 118: .DS ! 119: .tr '\(aa^\(ua ! 120: % \*bpix first.p\fR ! 121: .so firstout ! 122: .tr ''^^ ! 123: % ! 124: .DE ! 125: .KE ! 126: .PP ! 127: The translator first printed a syntax error diagnostic. ! 128: The number 2 here indicates that the rest of the line is an image ! 129: of the second line of our program. ! 130: The translator is saying that it expected to find a `;' before the ! 131: keyword ! 132: .B begin ! 133: on this line. ! 134: If we look at the Pascal syntax charts in the Jensen-Wirth ! 135: .I "User Manual" , ! 136: or at some of the sample programs therein, we will see that ! 137: we have omitted the terminating `;' of the ! 138: .B program ! 139: statement on the first ! 140: line of our program. ! 141: .PP ! 142: One other thing to notice about the error diagnostic is the letter `e' ! 143: at the beginning. ! 144: It stands for `error', ! 145: indicating that our input was not legal Pascal. ! 146: The fact that it is an `e' rather than an `E' ! 147: indicates that the translator managed to recover from this error well ! 148: enough that generation of code and execution could take place. ! 149: Execution is possible whenever no fatal `E' errors ! 150: occur during translation. ! 151: The other classes of diagnostics are `w' warnings, ! 152: which do not necessarily indicate errors in the program, ! 153: but point out inconsistencies which are likely to be due to program bugs, ! 154: and `s' standard-Pascal violations.\*(dg ! 155: .FS ! 156: \*(dgThe standard Pascal warnings occur only when the associated ! 157: .B s ! 158: translator option is enabled. ! 159: The ! 160: .B s ! 161: option is discussed in sections 5.1 and A.6 below. ! 162: Warning diagnostics are discussed at the end of section 3.2, ! 163: the associated ! 164: .B w ! 165: option is described in section 5.2. ! 166: .FE ! 167: .PP ! 168: After completing the translation of the program to interpretive code, ! 169: the Pascal system indicates that execution of the translated program began. ! 170: The output from the execution of the program then appeared. ! 171: At program termination, the Pascal runtime system indicated the ! 172: number of statements executed, and the amount of cpu time ! 173: used, with the resolution of the latter being 1/60'th of a second. ! 174: .PP ! 175: Let us now fix the error in the program and translate it to a permanent ! 176: object code file ! 177: .I obj ! 178: using ! 179: .PI . ! 180: The program ! 181: .PI ! 182: translates Pascal programs but stores the object code instead of executing it\*(dd. ! 183: .FS ! 184: \*(ddThis script indicates some other useful approaches to debugging ! 185: Pascal programs. ! 186: As in ! 187: .I ed ! 188: we can shorten commands in ! 189: .I ex ! 190: to an initial prefix of the command name as we did ! 191: with the ! 192: .I substitute ! 193: command here. ! 194: We have also used the `!' shell escape command here to execute other ! 195: commands with a shell without leaving the editor. ! 196: .FE ! 197: .LS ! 198: % \*bex first.p\fR ! 199: "first.p" 4 lines, 59 characters ! 200: :\*b1 print\fR ! 201: program first(output) ! 202: :\*bs/$/;\fR ! 203: program first(output); ! 204: :\*bwrite\fR ! 205: "first.p" 4 lines, 60 characters ! 206: :\*bquit\fR ! 207: % \*bpi first.p\fR ! 208: % ! 209: .LE ! 210: If we now use the ! 211: .UX ! 212: .I ls ! 213: list files command we can see what files we have: ! 214: .LS ! 215: % \*bls\fR ! 216: first.p ! 217: obj ! 218: % ! 219: .LE ! 220: The file `obj' here contains the Pascal interpreter code. ! 221: We can execute this by typing: ! 222: .LS ! 223: % \*bpx obj\fR ! 224: .so firstobjout ! 225: % ! 226: .LE ! 227: Alternatively, the command: ! 228: .LS ! 229: % \*bobj\fR ! 230: .LE ! 231: will have the same effect. ! 232: Some examples of different ways to execute the program follow. ! 233: .LS ! 234: % \*bpx\fR ! 235: .so firstobjout ! 236: % \*bpi -p first.p\fR ! 237: % \*bpx obj\fR ! 238: .so firstobjout2 ! 239: % \*bpix -p first.p\fR ! 240: .so firstobjout2 ! 241: % ! 242: .LE ! 243: .PP ! 244: Note that ! 245: .I px ! 246: will assume that `obj' is the file we wish to execute ! 247: if we don't tell it otherwise. ! 248: The last two translations use the ! 249: .B \-p ! 250: no-post-mortem option to eliminate ! 251: execution statistics and ! 252: `Execution begins' ! 253: and ! 254: `Execution terminated' ! 255: messages. ! 256: See section 5.2 for more details. ! 257: If we now look at the files in our directory we will see: ! 258: .LS ! 259: % \*bls\fR ! 260: first.p ! 261: obj ! 262: % ! 263: .LE ! 264: We can give our object program a name other than `obj' by using the move ! 265: command ! 266: .I mv ! 267: (1). ! 268: Thus to name our program `hello': ! 269: .LS ! 270: % \*bmv obj hello\fR ! 271: % \*bhello\fR ! 272: Hello, world! ! 273: % \*bls\fR ! 274: first.p ! 275: hello ! 276: % ! 277: .LE ! 278: Finally we can get rid of the Pascal object code by using the ! 279: .I rm ! 280: (1) remove file command, e.g.: ! 281: .LS ! 282: % \*brm hello\fR ! 283: % \*bls\fR ! 284: first.p ! 285: % ! 286: .LE ! 287: .PP ! 288: For small programs which are being developed ! 289: .IX ! 290: tends to be more convenient to use than ! 291: .PI ! 292: and ! 293: .X . ! 294: Except for absence of the ! 295: .I obj ! 296: file after a ! 297: .IX ! 298: run, ! 299: a ! 300: .IX ! 301: command is equivalent to a ! 302: .PI ! 303: command followed by a ! 304: .X ! 305: command. ! 306: For larger programs, ! 307: where a number of runs testing different parts of the program are ! 308: to be made, ! 309: .PI ! 310: is useful as this ! 311: .I obj ! 312: file can be executed any desired number of times. ! 313: .. >>> INSERT SECTION FOR PC <<< ! 314: .NH 2 ! 315: A larger program ! 316: .PP ! 317: Suppose that we have used the editor to put a larger program ! 318: in the file `bigger.p'. ! 319: We can list this program with line numbers by using the program ! 320: .I cat -n ! 321: i.e.: ! 322: .LS ! 323: % \*bcat -n bigger.p\fR ! 324: .so bigger3.p ! 325: % ! 326: .LE ! 327: This program is similar to program 4.9 on page 30 of the ! 328: Jensen-Wirth ! 329: .I "User Manual" . ! 330: A number of problems have been introduced into this example for ! 331: pedagogical reasons. ! 332: .br ! 333: .PP ! 334: If we attempt to translate and execute the program using ! 335: .IX ! 336: we get the following response: ! 337: .LS ! 338: % \*bpix bigger.p\fR ! 339: .so bigout1 ! 340: % ! 341: .LE ! 342: .PP ! 343: Since there were fatal `E' errors in our program, ! 344: no code was generated and execution was necessarily suppressed. ! 345: One thing which would be useful at this point is a listing of the ! 346: program with the error messages. ! 347: We can get this by using the command: ! 348: .LS ! 349: % \*bpi -l bigger.p\fR ! 350: .LE ! 351: There is no point in using ! 352: .IX ! 353: here, since we know there are fatal errors in the program. ! 354: This command will produce the output at our terminal. ! 355: If we are at a terminal which does not produce a hard copy ! 356: we may wish to print this ! 357: listing off-line on a line printer. ! 358: We can do this with the command: ! 359: .LS ! 360: % \*bpi -l bigger.p | lpr\fR ! 361: .LE ! 362: .PP ! 363: In the next few sections we will illustrate various aspects of the ! 364: Berkeley ! 365: Pascal system by correcting this program. ! 366: .NH 2 ! 367: Correcting the first errors ! 368: .PP ! 369: Most of the errors which occurred in this program were ! 370: .I syntactic ! 371: errors, those in the format and structure of the program rather than ! 372: its content. ! 373: Syntax errors are flagged by printing the offending line, and then a line ! 374: which flags the location at which an error was detected. ! 375: The flag line also gives an explanation ! 376: stating either a possible cause of the error, ! 377: a simple action which can be taken to recover from the error so ! 378: as to be able to continue the analysis, ! 379: a symbol which was expected at the point of error, ! 380: or an indication that the input was `malformed'. ! 381: In the last case, the recovery may skip ahead in the input ! 382: to a point where analysis of the program can continue. ! 383: .PP ! 384: In this example, ! 385: the first error diagnostic indicates that the translator detected ! 386: a comment within a comment. ! 387: While this is not considered an error in `standard' ! 388: Pascal, it usually corresponds to an error in the program which ! 389: is being translated. ! 390: In this case, we have accidentally omitted the trailing `*)' of the comment ! 391: on line 8. ! 392: We can begin an editor session to correct this problem by doing: ! 393: .LS ! 394: % \*bex bigger.p\fR ! 395: "bigger.p" 24 lines, 512 characters ! 396: :\*b8s/$/ *)\fR ! 397: s = 32; (* 32 character width for interval [x, x+1] *) ! 398: : ! 399: .LE ! 400: .PP ! 401: The second diagnostic, given after line 16, ! 402: indicates that the keyword ! 403: .B do ! 404: was expected before the keyword ! 405: .B begin ! 406: in the ! 407: .B for ! 408: statement. ! 409: If we examine the ! 410: .I statement ! 411: syntax chart on page 118 of the ! 412: Jensen-Wirth ! 413: .I "User Manual" ! 414: we will discover that ! 415: .B do ! 416: is a necessary part of the ! 417: .B for ! 418: statement. ! 419: Similarly, we could have referred to section C.3 of the ! 420: Jensen-Wirth ! 421: .I "User Manual" ! 422: to learn about the ! 423: .B for ! 424: statement and gotten the same information there. ! 425: It is often useful to refer to these syntax charts and to the ! 426: relevant sections of this book. ! 427: .PP ! 428: We can correct this problem by first scanning for the keyword ! 429: .B for ! 430: in the file and then substituting the keyword ! 431: .B do ! 432: to appear in front of the keyword ! 433: .B begin ! 434: there. ! 435: Thus: ! 436: .LS ! 437: :\*b/for\fR ! 438: for i := 0 to lim begin ! 439: :\*bs/begin/do &\fR ! 440: for i := 0 to lim do begin ! 441: : ! 442: .LE ! 443: The next error in the program is easy to pinpoint. ! 444: On line 18, we didn't hit the shift key and got a `9' ! 445: instead of a `)'. ! 446: The translator diagnosed that `x9' ! 447: was an undefined variable and, later, ! 448: that a `)' was missing in the statement. ! 449: It should be stressed that ! 450: .PI ! 451: is not suggesting that you should insert a `)' before the `;'. ! 452: It is only indicating that making this change will help it to be able to ! 453: continue analyzing the program so as to be able to diagnose further ! 454: errors. ! 455: You must then determine the true cause of the error and make the ! 456: appropriate correction to the source text. ! 457: .PP ! 458: This error also illustrates the fact that one error in the input may lead ! 459: to multiple error diagnostics. ! 460: .I Pi ! 461: attempts ! 462: to give only one diagnostic for each error, ! 463: but single errors in the input sometimes appear to be more than ! 464: one error. ! 465: It is also the case that ! 466: .PI ! 467: may not detect an error when it occurs, but may detect it later in ! 468: the input. ! 469: This would have happened ! 470: in this example if we had typed `x' instead of `x9'. ! 471: .PP ! 472: The translator next detected, on line 19, that the function ! 473: .I Round ! 474: and the variable ! 475: .I h ! 476: were undefined. ! 477: It does not know about ! 478: .I Round ! 479: because ! 480: .UP ! 481: normally distinguishes between upper and lower case.\*(dg ! 482: .FS ! 483: \*(dgIn ``standard'' Pascal no distinction is made based on case. ! 484: .FE ! 485: On ! 486: .UX ! 487: lower-case is preferred\*(dd, ! 488: .FS ! 489: \*(ddOne good reason for using lower-case is that it is easier to type. ! 490: .FE ! 491: and all keywords and built-in ! 492: .B procedure ! 493: and ! 494: .B function ! 495: names are composed of lower-case letters, ! 496: just as they are in the Jensen-Wirth ! 497: .I "Pascal Report" . ! 498: Thus we need to use the function ! 499: .I round ! 500: here. ! 501: As far as ! 502: .I h ! 503: is concerned, ! 504: we can see why it is undefined if we look back to line 9 ! 505: and note that its definition was lost in the non-terminated ! 506: comment. ! 507: This diagnostic need not, therefore, concern us. ! 508: .PP ! 509: The next error which occurred in the program caused the translator ! 510: to insert a `;' before the statement calling ! 511: .I writeln ! 512: on line 23. ! 513: If we examine the program around the point of error we will see ! 514: that the actual error is that the keyword ! 515: .B until ! 516: and an associated expression have been omitted here. ! 517: Note that the diagnostic from the translator does not indicate the actual ! 518: error, and is somewhat misleading. ! 519: The translator made the correction which seemed to be most plausible. ! 520: As the omission of a `;' character is a common mistake, ! 521: the translator chose to indicate this as a possible fix here. ! 522: It later detected that the keyword ! 523: .B until ! 524: was missing, but not until it saw the keyword ! 525: .B end ! 526: on line 24. ! 527: The combination of these diagnostics indicate to us the true problem. ! 528: .PP ! 529: The final syntactic error message indicates that the translator needed an ! 530: .B end ! 531: keyword to match the ! 532: .B begin ! 533: at line 15. ! 534: Since the ! 535: .B end ! 536: at line 24 is supposed to match this ! 537: .B begin , ! 538: we can infer that another ! 539: .B begin ! 540: must have been mismatched, and have matched this ! 541: .B end . ! 542: Thus we see that we need an ! 543: .B end ! 544: to match the ! 545: .B begin ! 546: at line 16, ! 547: and to appear before the final ! 548: .B end . ! 549: We can make these corrections: ! 550: .LS ! 551: :\*b/x9/s//x)\fR ! 552: y := exp(-x) * sin(i * x); ! 553: :\*b+s/Round/round\fR ! 554: n := round(s * y) + h; ! 555: :\*b/write\fR ! 556: write(' '); ! 557: :\*b/\fR ! 558: writeln('*') ! 559: :\*binsert\fR ! 560: \*buntil n = 0;\fR ! 561: \&\*b.\fR ! 562: :\*b$\fR ! 563: end. ! 564: :\*binsert\fR ! 565: \*bend\fR ! 566: \&\*b.\fR ! 567: : ! 568: .LE ! 569: .PP ! 570: At the end of each ! 571: .B procedure ! 572: or ! 573: .B function ! 574: and the end of the ! 575: .B program ! 576: the translator summarizes references to undefined variables ! 577: and improper usages of variables. ! 578: It also gives ! 579: warnings about potential errors. ! 580: In our program, the summary errors do not indicate any further problems ! 581: but the warning that ! 582: .I c ! 583: is unused is somewhat suspicious. ! 584: Examining the program we see that the constant was intended ! 585: to be used in the expression which is an argument to ! 586: .I sin , ! 587: so we can correct this expression, and translate the program. ! 588: We have now made a correction for each diagnosed error ! 589: in our program. ! 590: .LS ! 591: :\*b?i ?s//c /\fR ! 592: y := exp(-x) * sin(c * x); ! 593: :\*bwrite\fR ! 594: "bigger.p" 26 lines, 538 characters ! 595: :\*bquit\fR ! 596: % \*bpi bigger.p\fR ! 597: % ! 598: .LE ! 599: It should be noted that the translator suppresses warning ! 600: diagnostics for a particular ! 601: .B procedure , ! 602: .B function ! 603: or the main ! 604: .B program ! 605: when it finds severe syntax errors in that part of the source ! 606: text. ! 607: This is to prevent possibly confusing and ! 608: incorrect warning diagnostics from being produced. ! 609: Thus these warning diagnostics may not appear in a program with ! 610: bad syntax errors until these errors are corrected. ! 611: .KS ! 612: .PP ! 613: We are now ready to execute our program for the first ! 614: time. ! 615: We will do so in the next section after giving a listing ! 616: of the corrected program for reference purposes. ! 617: .LS ! 618: % \*bcat -n bigger.p\fR ! 619: .so bigger6.p ! 620: % ! 621: .LE ! 622: .NH 2 ! 623: Executing the second example ! 624: .PP ! 625: We are now ready to execute the second example. ! 626: The following output was produced by our first run. ! 627: .LS ! 628: % \*bpx\fR ! 629: .so bigout2 ! 630: % ! 631: .LE ! 632: Here the interpreter is presenting us with a runtime error diagnostic. ! 633: It detected a `division by zero' at line 17. ! 634: Examining line 17, we see that we have written ! 635: the statement `x := d / i' instead of `x := d * i'. ! 636: We can correct this and rerun the program: ! 637: .LS ! 638: % \*bex bigger.p\fR ! 639: "bigger.p" 26 lines, 538 characters ! 640: :\*b17\fR ! 641: x := d / i ! 642: :\*bs'/'*\fR ! 643: x := d * i ! 644: :\*bwrite\fR ! 645: "bigger.p" 26 lines, 538 characters ! 646: :\*bq\fR ! 647: % \*bpix bigger.p\fR ! 648: .so bigout3 ! 649: % ! 650: .LE ! 651: .KS ! 652: .PP ! 653: This appears to be the output we wanted. ! 654: We could now save the output in a file if we wished by using the shell ! 655: to redirect the output: ! 656: .LS ! 657: % \*bpx > graph\fR ! 658: .LE ! 659: .KE ! 660: We can use ! 661: .I cat ! 662: (1) to see the contents of the file graph. ! 663: We can also make a listing of the graph on the line printer without ! 664: putting it into a file, e.g. ! 665: .LS ! 666: % \*bpx | lpr\fR ! 667: .so bigout4 ! 668: % ! 669: .LE ! 670: Note here that the statistics lines came out on our terminal. ! 671: The statistics line comes out on the diagnostic output (unit 2.) ! 672: There are two ways to get rid of the statistics line. ! 673: We can redirect the statistics message to the printer using the ! 674: syntax `|\|&' to the shell rather than `|', i.e.: ! 675: .LS ! 676: % \*bpx |\|& lpr\fR ! 677: % ! 678: .LE ! 679: or we can translate the program with the ! 680: .B p ! 681: option disabled on the command line as we did above. ! 682: This will disable all post-mortem dumping including the statistics line, ! 683: thus: ! 684: .LS ! 685: % \*bpi -p bigger.p\fR ! 686: % \*bpx | lpr\fR ! 687: % ! 688: .LE ! 689: This option also disables the statement limit which normally guards ! 690: against infinite looping. ! 691: You should not use it until your program is debugged. ! 692: Also if ! 693: .B p ! 694: is specified and an error occurs, you will ! 695: not get run time diagnostic information to help you ! 696: determine what the problem is. ! 697: .NH 2 ! 698: Formatting the program listing ! 699: .PP ! 700: It is possible to use special lines within the source text of a program ! 701: to format the program listing. ! 702: An empty line (one with no characters on it) corresponds to a ! 703: `space' macro in an assembler, leaving a completely blank line ! 704: without a line number. ! 705: A line containing only a control-l (form-feed) character ! 706: will cause a page eject in the listing with the corresponding line number ! 707: suppressed. ! 708: This corresponds to an `eject' pseudo-instruction. ! 709: See also section 5.2 for details on the ! 710: .B n ! 711: and ! 712: .B i ! 713: options of ! 714: .PI . ! 715: .NH 2 ! 716: Execution profiling ! 717: .PP ! 718: An execution profile consists of a structured listing of (all or part of) ! 719: a program with information about the number of times each statement in ! 720: the program was executed for a particular run of the program. ! 721: These profiles can be used for several purposes. ! 722: In a program which was abnormally terminated due to excessive looping ! 723: or recursion or by a program fault, the counts can facilitate location ! 724: of the error. ! 725: Zero counts mark portions of the program which were not executed; ! 726: during the early debugging stages they should prompt new test data or ! 727: a re-examination of the program logic. ! 728: The profile is perhaps most valuable, however, in drawing ! 729: attention to the (typically small) ! 730: portions of the program that dominate execution time. ! 731: This information can be used for source level optimization. ! 732: .SH ! 733: An example ! 734: .PP ! 735: A prime number is a number which is divisible only by itself and the ! 736: number one. ! 737: The program ! 738: .I primes , ! 739: written by Niklaus Wirth, ! 740: determines the first few prime numbers. ! 741: In translating the program we have specified the ! 742: .B z ! 743: option to ! 744: .IX . ! 745: This option causes the translator to generate counters and count instructions ! 746: sufficient in number to determine the number of times each statement in the ! 747: program was executed.\*(dg ! 748: .FS ! 749: \*(dgThe counts ! 750: are completely accurate only in the absence of runtime errors and nonlocal ! 751: .B goto ! 752: statements. ! 753: This is not generally a problem, however, as in structured programs ! 754: nonlocal ! 755: .B goto ! 756: statements occur infrequently, ! 757: and counts are incorrect after abnormal termination only when the ! 758: .I "upward look" ! 759: described below to get a count passes a suspended call point. ! 760: .FE ! 761: When execution of the program completes, either normally or abnormally, ! 762: this count data is written to the file ! 763: .I pmon.out ! 764: in the current directory.\*(dd ! 765: .FS ! 766: \*(dd\c ! 767: .I Pmon.out ! 768: has a name similar to ! 769: .I mon.out ! 770: the monitor file produced by the profiling facility of the C compiler ! 771: .I cc ! 772: (1). ! 773: See ! 774: .I prof ! 775: (1) for a discussion of the C compiler profiling facilities. ! 776: .FE ! 777: It is then possible to prepare an execution profile by giving ! 778: .XP ! 779: the name of the file associated with this data, as was done in the following ! 780: example. ! 781: .LS ! 782: % \*bpix -l -z primes.p\fR ! 783: .so primeout1 ! 784: % ! 785: .LE ! 786: .SH ! 787: Discussion ! 788: .PP ! 789: The header lines of the outputs of ! 790: .IX ! 791: and ! 792: .XP ! 793: in this example indicate the version of the translator and execution ! 794: profiler in use at the time this example was prepared. ! 795: The time given with the file name (also on the header line) ! 796: indicates the time of last modification of the program source file. ! 797: This time serves to ! 798: .I "version stamp" ! 799: the input program. ! 800: .I Pxp ! 801: also indicates the time at which the profile data was gathered. ! 802: .LS ! 803: % \*bpxp -z primes.p\fR ! 804: .so primeout2 ! 805: % ! 806: .LE ! 807: .KE ! 808: .PP ! 809: To determine the number of times a statement was executed, ! 810: one looks to the left of the statement and finds the corresponding ! 811: vertical bar `|'. ! 812: If this vertical bar is labelled with a count then that count gives the ! 813: number of times the statement was executed. ! 814: If the bar is not labelled, we look up in the listing to find the first ! 815: `|' which directly above the original one which has a count and that ! 816: is the answer. ! 817: Thus, in our example, ! 818: .I k ! 819: was incremented 157 times on line 18, ! 820: while the ! 821: .I write ! 822: procedure call on line 24 was executed 48 times as given by the count ! 823: on the ! 824: .B repeat . ! 825: .PP ! 826: More information on ! 827: .I pxp ! 828: can be found in its manual section ! 829: .XP ! 830: (1) ! 831: and in sections 5.4, 5.5 and 5.10.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.