home *** CD-ROM | disk | FTP | other *** search
/ ftp.robelle3000.ai 2014 / 2014.06.ftp.robelle3000.ai.tar / ftp.robelle3000.ai / papers / qxport.txt < prev    next >
Text File  |  1994-05-03  |  45KB  |  1,149 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.                     Porting Qedit from MPE to HP-UX
  11.  
  12.                            By David J. Greer
  13.  
  14.  
  15.  
  16.                                Abstract
  17.  
  18.    Robelle recently ported its Qedit full-screen editor from the MPE
  19.    environment to the HP-UX environment.  David Greer, manager of
  20.    software R&D at Robelle, headed up the team doing the migration.
  21.    This paper describes the problems they faced and the resulting
  22.    solutions.  Qedit is written in SPL and was ported to HP-UX using
  23.    the SPLash! compiler from SRN.  The paper covers both the gory
  24.    details of how Robelle does cross-development using SPLash! and
  25.    the theoretical problem of how to make UNIX look like MPE.  Most
  26.    of the Qedit source code is identical for the two systems, but
  27.    the MPE file system differs radically and is more complex than
  28.    the UNIX file system.
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.                         Robelle Consulting Ltd.
  45.                        Unit 201, 15399-102A Ave.
  46.                      Surrey, B.C.  Canada V3R 7K1
  47.                         Phone:  (604) 582-1700
  48.                          Fax:  (604) 582-1799
  49.  
  50.                     Email:  david_greer@robelle.com
  51.  
  52.  
  53.                 Copyright Robelle Consulting Ltd.  1994
  54.  
  55.  
  56.         Permission is granted to reprint this document (but not
  57.          for profit), provided that copyright notice is given.
  58.  
  59.  
  60.  
  61.  
  62.                     Porting Qedit from MPE to HP-UX
  63.  
  64.                            By David J. Greer
  65.  
  66.  
  67.  
  68.                              Introduction
  69.  
  70.  
  71.    Our Qedit full-screen text editor was first written in 1977 and
  72.    has been continually enhanced since then.  We recently ported
  73.    Qedit from MPE to HP-UX.  This paper discusses our research
  74.    strategy and the technical details of how we actually managed to
  75.    port approximately 100,000 lines of code that had been written
  76.    over the last fifteen years.
  77.  
  78.  
  79.    Original UNIX Goals
  80.  
  81.    For a few years, our customers (especially in Europe) had started
  82.    doing development on UNIX machines.  We didn't know anything
  83.    about UNIX, but we decided that we had better start learning.
  84.    Our goal was to learn as much as we could about UNIX by seeing
  85.    how much of our source code and programs we could convert to HP's
  86.    version of UNIX:  HP-UX.
  87.  
  88.  
  89.    Why HP-UX
  90.  
  91.    We decided on HP-UX for a couple of reasons:
  92.  
  93.    1. It was made by HP, so it was likely to be more familiar to us
  94.       than another vendor's UNIX (and at least the Response Center
  95.       telephone number would be the same).  Time and again, this
  96.       proved to be true and greatly helped our development effort.
  97.  
  98.    2. Qedit is written almost entirely in SPL/SPLash!.  Because of
  99.       our compiler technology, we wanted to focus on the HPPA RISC
  100.       architecture.  For this reason, we restricted our research to
  101.       HP's 700 and 800 series of computers (they have HPPA RISC
  102.       CPUs).
  103.  
  104.    3. We did not want to rewrite all of the source code into C (the
  105.       usual language of choice for UNIX programs).  We felt that
  106.       rewriting Qedit into C would be too large an R&D project for
  107.       Robelle.  Automated tools for doing the conversion were
  108.       reported to be ineffective.
  109.  
  110.  
  111.    Major R&D Phases
  112.  
  113.    Our HP-UX research was done in different phases.  We had a
  114.    short-term goal for each phase and worked towards completing this
  115.    goal in a reasonable time frame.  The major phases were as
  116.    follows:
  117.  
  118.    1. Basic Research.  In this phase we borrowed an HP-UX machine
  119.       and investigated HP-UX object-code and run-time libraries.
  120.  
  121.    2. MPE and Robelle Libraries.  Robelle's software development is
  122.       based on a concept of layers that build on each other.  This
  123.       phase involved getting our own machine, writing necessary MPE
  124.       replacement routines, and porting our fundamental subroutine
  125.       libraries.
  126.  
  127.    3. Rebuild Qedit.  Once the basic libraries were running we
  128.       needed to look at Qedit.  In this phase, we reengineered Qedit
  129.       so that it has little knowledge about which computer platform
  130.       it is running on.
  131.  
  132.    4. Polish and Release Qedit/UX.  After the first version of Qedit
  133.       was working on HP-UX, we needed to do a series of enhancements
  134.       to make Qedit work in a more UNIX-like manner.  We also needed
  135.       to complete all the details that turn an R&D project into a
  136.       product.
  137.  
  138.  
  139.    Personnel
  140.  
  141.    Three people worked on porting Qedit to HP-UX.
  142.  
  143.    Dave Lo          Dave was the general programmer's helper.  He
  144.                     was assigned specific research tasks (e.g., how
  145.                     to get the value of an environment variable in
  146.                     SPLash!).
  147.  
  148.    Robert Green     Bob is the original author and chief architect
  149.                     of Qedit.  His main job was to keep Dave's and
  150.                     David's spirits up and to reengineer Qedit so
  151.                     that it didn't depend on MPE any more.
  152.  
  153.    David Greer      I was the overall project leader.  I ported most
  154.                     of our subroutine libraries, learned everything
  155.                     I could about programming interfaces to HP-UX,
  156.                     and implemented all of the Qedit/UX operating
  157.                     system interface.
  158.  
  159.  
  160.    Development Diaries
  161.  
  162.    At Robelle, we keep a diary with summaries of each day's
  163.    development effort.  We kept a development diary for HP-UX --
  164.    much of the material in this paper is drawn from it.  It takes
  165.    work to keep these diaries up-to-date, but they pay off in the
  166.    long-term by saving useful information.
  167.  
  168.  
  169.    Time and Effort
  170.  
  171.    From first inception to delivering a production product took
  172.    about 20 months.  The work effort is estimated as 19
  173.    person-months.  We feel that this is incredibly fast for the
  174.    amount of work that needed to be done.  We could never have
  175.    achieved this if we had rewritten all of our software into a new
  176.    language as well as for a new operating system.
  177.  
  178.    We estimate that a complete rewrite of Qedit into C would have
  179.    taken at least twice the time (four years) and three times the
  180.    work effort (at least 60 person-months).  A rewrite goes against
  181.    our long-held belief in doing things in small incremental steps,
  182.    rather than striking out for the big win.
  183.  
  184.    Another disadvantage of rewriting Qedit into C was that we likely
  185.    could not have used the C version on Classic 3000s, due to poor C
  186.    compiler support on the Classic 3000.  However, we always try to
  187.    make available as many Qedit enhancements as possible to all of
  188.    our HP 3000 customers.  This is one reason why we have one set of
  189.    source code for all versions of Qedit.
  190.  
  191.  
  192.                     Software Development At Robelle
  193.  
  194.  
  195.    To understand how we ported Qedit from MPE to HP-UX, it is
  196.    important to understand how we develop software at Robelle.  Most
  197.    of our development, including Qedit, is done in SPL and SPLash!.
  198.    SPL was the original Systems Programming Language for the HP
  199.    3000.  The SPL compiler only produces object-code for Classic HP
  200.    3000s (you can also run this code in compatibility-mode on MPE/iX
  201.    machines).
  202.  
  203.    SPLash! is a compiler from Software Research Northwest
  204.    (206-463-3030) that translates SPL source code into HPPA RISC
  205.    object-code.  We use SPLash! on MPE/iX to produce the native-mode
  206.    version of Qedit.  There is no SPLash! compiler for HP-UX.
  207.  
  208.    SPL has no run-time library (which is similar to how the C
  209.    language works).  In Pascal, you would write something to the
  210.    screen as shown below:
  211.  
  212.         writeln('Hello, World!');
  213.  
  214.    In SPL, there is no language construct that will print a string
  215.    on your screen.  Instead, you move the string to a buffer and
  216.    then call a library routine to print the string:
  217.  
  218.         move outbuf := "Hello, World!";
  219.  
  220.         print(outbuf,-13,0);      ! print is a library routine
  221.  
  222.    The print routine displays the thirteen characters on the screen.
  223.    Print is a library routine that comes with MPE.
  224.  
  225.  
  226.    Subroutine Libraries
  227.  
  228.    Because SPL does not rely on a language-specific run-time
  229.    library, we thought it might be possible to port the SPLash!
  230.    object-code to HP-UX running on the HPPA RISC architecture.  The
  231.    only thing left would be to replace all of the subroutine
  232.    libraries on which Qedit depends.  Since Qedit depends on
  233.    hundreds of routines, that was still a lot of potential work.
  234.  
  235.    Qedit is built upon a series of subroutine libraries.  Each set
  236.    of libraries depends on other sets of libraries.  The libraries
  237.    look something like this:
  238.  
  239.  
  240.                                  Qedit
  241.  
  242.                              Qedit Library
  243.  
  244.                 Calculator, Qhelp, and Other Libraries
  245.  
  246.                        Low-level Robelle Library
  247.  
  248.                       MPE and Compiler Libraries
  249.  
  250.  
  251.                        View of Robelle Libraries
  252.  
  253.    While these libraries build on each other, libraries at the upper
  254.    levels can call libraries at any lower level.  For example, Qedit
  255.    makes many calls directly to the MPE library (e.g., readx, print,
  256.    fopen, fread, ...).  Similarly, the calculator makes calls to
  257.    both the Robelle low-level library and the MPE library.
  258.  
  259.  
  260.    Development Summary
  261.  
  262.    Because we use SPL and SPLash!, we needed to develop ideas that
  263.    would let us port object-code to HP-UX.  In order to port Qedit
  264.    from MPE to HP-UX, we would first need to port many of our own
  265.    libraries and investigate how many MPE library routines were
  266.    available on HP-UX.
  267.  
  268.  
  269.                       Phase One:  Basic Research
  270.  
  271.  
  272.    We wanted to start our research by doing two things:
  273.  
  274.    1. Learn more about HP-UX (e.g., how to log on!)
  275.  
  276.    2. Prove whether or not the object-code formats on MPE and HP-UX
  277.       were the same.
  278.  
  279.  
  280.    Get A Machine
  281.  
  282.    You can't make an omelet without breaking eggs, and it's hard to
  283.    learn about HP-UX without having access to a machine.  Because we
  284.    had no idea how successful our initial research would be, we
  285.    didn't want to purchase one.
  286.  
  287.    We asked HP if we could rent an HP-UX machine for a week, but HP
  288.    doesn't have short-term rentals.  Since we've had good relations
  289.    with HP/Canada, they arranged for us to have one of their demo
  290.    machines for a month.  It's a good thing we had the machine that
  291.    length of time, because it took us about three weeks to get it up
  292.    and running.
  293.  
  294.    We could tell HP-UX was made by HP.  When we first brought the
  295.    machine up, one of the first things it did was ask us if our
  296.    console was a 2392 or a 700/92.  We can't imagine any non-HP
  297.    machine asking this question.
  298.  
  299.  
  300.    Networking
  301.  
  302.    We learned a lot by just installing the borrowed HP-UX machine
  303.    and getting it connected to our network.  On our HP 3000
  304.    machines, we had HP's NS software and used Thinlan to connect all
  305.    of our machines together.  We lost a lot of time because the demo
  306.    HP-UX machine had a jumper switch on the network interface card
  307.    turned off.  It took us two weeks to figure out that it was a
  308.    hardware problem and not a configuration problem.
  309.  
  310.    By default, HP-UX is not able to communicate with MPE machines.
  311.    On MPE, we are used to having front-end software that handles
  312.    configuration (NMMGR being the one for configuring network
  313.    software in MPE).  In UNIX, it's common for configuration to be
  314.    done by changing scripts (although some common configuration
  315.    tasks can be done with HP's SAM tool).  Scripts are similar to
  316.    MPE/iX command files.  One of the files that is used to configure
  317.    networking is called /etc/netlinkrc.  By default, it contains a
  318.    line like this:
  319.  
  320.         /etc/lanconfig lan0 ether
  321.  
  322.    For HP-UX to communicate with MPE machines in the Thinlan/NS
  323.    environment, this line needs to be:
  324.  
  325.         /etc/lanconfig lan0 ether ieee
  326.  
  327.    Notice the addition of "ieee" to the end of the line.  We also
  328.    needed to the following:
  329.  
  330.    1. Fill in the DOMAIN and ORGANIZATION in /etc/netlinkrc.
  331.  
  332.    2. Add machine names and IP addresses to /etc/hosts.
  333.  
  334.    3. Reboot our machine for these changes to take effect.
  335.  
  336.    Since our machine had the NS software for HP-UX, we could now use
  337.    vt3k to log on to our MPE machines from HP-UX (vt3k provides
  338.    virtual terminal access from HP-UX to MPE).  After using NMMGR to
  339.    add our new HP-UX machine to our MPE configuration, we could also
  340.    use dscopy to copy files from MPE to HP-UX and vice versa.
  341.  
  342.  
  343.    Object-Code Format
  344.  
  345.    Our next major goal was to test our theory that object-code files
  346.    were the same on MPE/iX and HP-UX.  To show this was the case we
  347.    planned to compile a SPLash! program on MPE, copy the object-code
  348.    to HP-UX, link the object-code, and run the resulting program.
  349.  
  350.    One of the first programs we tried was written by Randy Medd of
  351.    Telamon (510-987-7700).  This program calls the HP-UX routines
  352.    puts (which writes a string to stdlist) and exit (which
  353.    terminates the program).  It looked like this:
  354.  
  355.         $native, nocc, unix
  356.         begin
  357.  
  358.         equate line'feed = 10;
  359.  
  360.         byte array buf(0:14);
  361.  
  362.         double procedure puts(buf);
  363.            virtual byte array buf;
  364.            option native, nocc, external;
  365.  
  366.         procedure exit(int);
  367.            value   int;
  368.            double  int;
  369.            option native, nocc, external;
  370.  
  371.         move buf :=  ("Hello, World!",line'feed,0);
  372.  
  373.         puts(buf);
  374.         exit(0);
  375.  
  376.         end.
  377.  
  378.  
  379.    Compiling and Linking
  380.  
  381.    We compiled the above program using SPLash! and copied the
  382.    resulting object-code to HP-UX with these commands:
  383.  
  384.          :splash testsrc,testobj
  385.          :dscopy testobj to /users/david/test.o:daffy[david:pass]
  386.  
  387.    The next part took about a week of work to figure out:  the exact
  388.    link command to use in HP-UX in order to have our SPLash! program
  389.    run.  The HP-UX command for linking is called ld.  To link our
  390.    example program, we used this ld command:
  391.  
  392.         ld /lib/crt0.o test.o /lib/libc.a
  393.  
  394.    This linked the three files /lib/crt0.o, test.o, and /lib/libc.a.
  395.    The first file is /lib/crt zero dot oh (don't mix up the zero and
  396.    the oh), which is the C run-time startup library.  The test.o
  397.    file is our SPLash! object-code that we generated on MPE.  The
  398.    /lib/libc.a file is one of the HP-UX run-time libraries.  Like
  399.    most HP-UX command names and commands, everything must be in
  400.    lower case.  The general form of the ld command is:
  401.  
  402.         ld /lib/crt0.o objfiles... /lib/libc.a
  403.            ^                       ^ C library
  404.            C run-time startup
  405.  
  406.  
  407.    Running Our Program
  408.  
  409.    By default, the ld command creates a program file called a.out.
  410.    To run this program, we only had to type its name (like using
  411.    implied run on MPE/iX).  We tried running the resulting program
  412.    and got:
  413.  
  414.         a.out             {run our sample program}
  415.         Hello, World!     {result of running a.out}
  416.  
  417.    This was exactly what we expected.  The buffer that we
  418.    initialized with "Hello, World!" was printed out on stdlist and
  419.    the program stopped.  We had now answered one of our most basic
  420.    questions -- we could compile programs on MPE, copy the
  421.    object-code to HP-UX, link the object-code into a program and run
  422.    it on HP-UX.
  423.  
  424.  
  425.    Run-Time Libraries
  426.  
  427.    Once our basic research question was answered, it was time to
  428.    start exploring more of HP-UX.  We had no idea how many of the
  429.    MPE routines that we needed were available on HP-UX.  We used two
  430.    HP-UX tools to search for routines:  man and nm.
  431.  
  432.  
  433.    Man Pages
  434.  
  435.    The man pages are similar to MPE's on-line help.  For example, if
  436.    you want to see if there is a description of a routine called
  437.    binary, you do the following:
  438.  
  439.         man binary
  440.  
  441.    Once done, you will see this:
  442.  
  443.         No manual entry for binary.
  444.  
  445.    Another way to search the man pages is to have the man utility
  446.    search a keyword index from all the man pages for a string (see
  447.    below for how to create the man page index file):
  448.  
  449.         man -k binary                {-k requests a keyword search}
  450.         .
  451.         .                            {many entries printed}
  452.         .
  453.  
  454.    There were many routines with a description that included the
  455.    word "binary", but none were similar to the MPE binary routine.
  456.    The man page index is in the file /usr/lib/whatis.  You can
  457.    rebuild this file by doing:
  458.  
  459.         catman -w
  460.  
  461.    You must be logged on as super user to run catman.  It takes
  462.    catman a long time to create the index, so we suggest that you
  463.    run it in the background or in a batch job.
  464.  
  465.  
  466.    Searching Object-Code
  467.  
  468.    Just because a routine is not documented doesn't mean that it
  469.    does not exist.  Many MPE compiler-library routines are available
  470.    in HP-UX, but not documented.  The tool to use for finding
  471.    symbolic names in object-code is nm.  The nm utility is similar
  472.    to the MPE/iX Linkedit Listobj command.  The nm output is similar
  473.    enough to the Linkedit listobj output to make MPE users feel at
  474.    home (another advantage of using HP-UX).  We combined nm with two
  475.    other HP-UX tools to search entire directories of files.  For
  476.    example, to search the directory /usr/lib/ for any files with a
  477.    symbolic entry for binary we did the following:
  478.  
  479.         cd /usr/lib
  480.         nm -r /usr/lib/* | grep binary | more
  481.  
  482.    If you do this on HP-UX, you get a large number of error messages
  483.    (not everything in /usr/lib is an object-code file) and the
  484.    following line is found:
  485.  
  486.         libnsfmt.a:binary   |1073789772|extern|data   |$SHORTDATA$
  487.  
  488.    Unfortunately, this is "data".  What we needed was "code" or
  489.    "entry".  Libraries on HP-UX are also stored in the directory
  490.    /lib, so we checked those libraries too:
  491.  
  492.         cd /lib
  493.         nm -r * | grep binary | more
  494.  
  495.    We did this search and still did not find any routine called
  496.    binary.  So it appears that there is no binary routine for HP-UX.
  497.    Since this routine is used everywhere in our tools, we ended up
  498.    writing our own "binary" routine in C (note that the HP-UX
  499.    routine atoi is not the same).
  500.  
  501.  
  502.    Floating-Point Numbers
  503.  
  504.    In MPE, we use the compiler-library routines hpinext and hpextin
  505.    to convert floating-point numbers from human-readable form to the
  506.    internal IEEE format and vice versa.  These routines have many
  507.    options and handle different sizes of floating-point numbers.
  508.    Rewriting these routines would be a lot of work.
  509.  
  510.    Qedit does not use floating-point numbers very often, except in
  511.    the calculator.  In order to implement the calculator, we would
  512.    need the functionality of the hpinext and hpextin routines.  A
  513.    search of the man pages revealed no documentation for either
  514.    routine, although there were other routines to handle
  515.    floating-point conversions.  All of our code assumes that hpinext
  516.    and hpextin are available.  So we searched for these routines
  517.    using nm:
  518.  
  519.         cd /usr/lib
  520.         nm -r * | grep hpinext | more
  521.  
  522.    The result of this search was as follows:
  523.  
  524.         libcl.a:hpinext     |     13836|extern|entry  |$CODE$
  525.         libcl.sl:hpinext    |    421568|extern|code   |$CODE$
  526.         libcl.sl:hpinext    |    421524|extern|entry  |
  527.         libf.a:hpinext      |     13836|extern|entry  |$CODE$
  528.         libf.sl:hpinext     |    421568|extern|code   |$CODE$
  529.         libf.sl:hpinext     |    421524|extern|entry  |
  530.  
  531.    Success!  We had found the hpinext routine.  We also found the
  532.    hpextin routine in the same libraries (using the same technique).
  533.    These routines were located in either the libcl.a or libf.a
  534.    library.  Once we started converting the calculator to work on
  535.    HP-UX, we had to change our ld command to include one of these
  536.    libraries:
  537.  
  538.         ld /lib/crt0.o test.o /usr/lib/libcl.a /lib/libc.a
  539.                                ^
  540.                                New run-time library
  541.  
  542.    This was one example of how familiar HP-UX is to MPE programmers.
  543.    It is highly unlikely that any other version of UNIX has the
  544.    hpinext or the hpextin routines.  Even if they did, they are
  545.    unlikely to have the same parameters and work the same way as the
  546.    HP version.
  547.  
  548.  
  549.    Phase One Summary
  550.  
  551.    We succeeded in our basic research goals.  We obtained access to
  552.    an HP-UX machine (due to the kind loan from HP) and we proved
  553.    that SPLash! code compiled on MPE could be linked and executed on
  554.    HP-UX.  The time that elapsed for this phase was about three
  555.    months (February to April).  The work time:
  556.  
  557.  
  558.     Dave Lo   One person-month.
  559.  
  560.     Bob Green Half person-month.
  561.  
  562.     David GreerOne person-month.
  563.  
  564.  
  565.                  Phase Two:  MPE and Robelle Libraries
  566.  
  567.  
  568.    The goals for phase two were:
  569.  
  570.    1. Obtain our own HP-UX machine.
  571.  
  572.    2. Learn more about HP-UX.
  573.  
  574.    3. Implement the necessary MPE routines on which we rely.
  575.  
  576.    4. Start porting the Robelle library to HP-UX.
  577.  
  578.  
  579.    Obtaining an HP-UX Machine
  580.  
  581.    After we had returned our demo machine to HP, we started work to
  582.    obtain our own HP-UX machine.  We did some investigation and
  583.    decided to rent a Series 705 workstation from HP, complete with
  584.    the necessary networking (NS) and development (C) tools (don't
  585.    attempt C development with the "free" C compiler that comes with
  586.    HP-UX).  Since Bob and I work at home most of the time, we really
  587.    planned on using the workstation as a server.  Because HP-UX is a
  588.    multi-user operating system, we decided that it would work just
  589.    fine as a development server.  Even today, our Series 705 is used
  590.    as a workstation by one user in the office and as our primary
  591.    development machine by those of us doing HP-UX program
  592.    development.
  593.  
  594.  
  595.    Implementing MPE Routines on HP-UX
  596.  
  597.    In phase one, we had already started implementing some common MPE
  598.    routines (binary, dbinary, ascii, and dascii were now done).  We
  599.    continued with other routines such as print, readx, ccode, and
  600.    hpsetccode.  Once these routines were completed we could start
  601.    porting our most fundamental library source modules.
  602.  
  603.  
  604.    Porting the Robelle Libraries
  605.  
  606.    With a basic set of MPE routines now available, several of our
  607.    source modules started working on HP-UX.  However, we would often
  608.    try to port a new Robelle library only to find that we needed to
  609.    implement additional MPE routines.  So the process went
  610.    back-and-forth between porting Robelle source modules and writing
  611.    new MPE replacement routines.  In total, we implemented about
  612.    twenty different MPE routines.
  613.  
  614.  
  615.    MPE File System Routines
  616.  
  617.    Things went well, until we had to port our first source module
  618.    that needed to access files.  Using sample code written by Stan
  619.    Sieler of Allegro Consultants, Inc.  (415-369-2303), we
  620.    investigated how difficult it would be to implement the MPE
  621.    fopen, fread, fwrite, and fclose routines.
  622.  
  623.    The HP-UX file system is simple compared to the MPE file system.
  624.    Files are collections of bytes.  There is no implied structure to
  625.    any file (although you may deduce the structure by examining the
  626.    filename extension or by looking at some of the data in the
  627.    file).  In MPE, we have fixed-length, variable-length, ascii
  628.    versus binary, record-length, blocking-factor, and many other
  629.    file attributes.
  630.  
  631.    Our software depends on a number of assertions that are provided
  632.    by MPE's file system routines.  For example, if you open a new
  633.    file with a filecode of 111 and a record size of 256 words, write
  634.    some records to it, close it, open the file again, then ask about
  635.    its structure, you expect to get a filecode of 111 and a record
  636.    size of 256 words.  In HP-UX, there is no place to store this
  637.    information (without using an auxiliary file).
  638.  
  639.    It was at this point that we made a pivotal decision about how we
  640.    would port our software.  We would not emulate the MPE file
  641.    system routines.  Instead, we would reengineer our products to
  642.    invoke an interface layer that would provide file system
  643.    functionality.  We would isolate the interface layer for each
  644.    module that needed file system access into a separate source file
  645.    (in object-oriented terminology this is called encapsulation).
  646.  
  647.  
  648.    Recognizing Qedit Files
  649.  
  650.    On MPE, Qedit files are easily recognized as those with a
  651.    filecode of 111 and a record length of 256 words.  But how were
  652.    we going to recognize Qedit files on HP-UX?  HP-UX doesn't have
  653.    filecodes or record lengths.  Bob and I designed a routine that
  654.    would examine the first 1024 bytes of an HP-UX file.  By looking
  655.    at various relationships in this file, we hoped that we could
  656.    determine if the file was a Qedit file or not.
  657.  
  658.    We managed to implement such a routine.  To test its
  659.    effectiveness, we used dscopy to copy one Qedit file from MPE to
  660.    HP-UX.  We wrote a test program that opened every file on our
  661.    Series 705 workstation and checked to see if it was a Qedit file.
  662.    Our first implementations found many HP-UX files that the routine
  663.    thought were Qedit files when they were not.  But our final
  664.    implementation found the one and only Qedit file that we had
  665.    copied from MPE.
  666.  
  667.  
  668.    Porting Qhelp to HP-UX
  669.  
  670.    Qhelp is the software that provides all of Robelle's on-line help
  671.    facilities.  Qhelp was nicely isolated into one source module.
  672.    It uses a Qedit file to store all of the help text and the help
  673.    keywords.  We decided that Qhelp would be our first HP-UX module
  674.    to use an interface layer to provide file system access on both
  675.    MPE and HP-UX.
  676.  
  677.  
  678.    File System Layer
  679.  
  680.    The MPE version of Qhelp invoked the MPE file system directly.
  681.    It looked basically like this:
  682.  
  683.  
  684.                                  Qhelp
  685.  
  686.                         MPE File System Library
  687.  
  688.  
  689.                             Original Qhelp
  690.  
  691.    We reengineered Qhelp to call an interface layer to provide all
  692.    file system functionality.  This interface layer would open a
  693.    file, let us know whether it was a Qedit file or not, read the
  694.    file, and close the file.  Once Qhelp called the interface layer,
  695.    it would no longer "know" whether it was running on MPE or on
  696.    HP-UX.
  697.  
  698.    The new Qhelp looked like:
  699.  
  700.  
  701.                                  Qhelp
  702.  
  703.                             Interface Layer
  704.  
  705.                         OS File System Library
  706.  
  707.  
  708.                         Revised Qhelp Structure
  709.  
  710.  
  711.    Implementing the Qhelp Interface Layer
  712.  
  713.    In our revised Qhelp diagram, we added an interface layer that is
  714.    not operating system specific.  The job of the interface layer is
  715.    to hide the details of the underlying operating system.  Each
  716.    interface layer has two implementations:  one for MPE and one for
  717.    HP-UX.  The MPE interface was written in SPL/SPLash! and the
  718.    HP-UX interface was written in C.
  719.  
  720.    A lot of research went into learning how to map parameters in SPL
  721.    to parameters in C.  We also had to learn all of the HP-UX file
  722.    system calls, how they worked, how to detect and report errors
  723.    and so on.  All of this took considerable time, but once we got
  724.    Qhelp working we knew that future rewriting of other modules
  725.    would be faster.
  726.  
  727.  
  728.    Phase Two Summary
  729.  
  730.    During this phase we made a lot of progress.  Approximately
  731.    20,000 lines of existing SPL source code were ported to HP-UX
  732.    (e.g., the calculator and Qhelp modules) and about 1,500 new
  733.    lines of C code were written.  This provided a strong foundation
  734.    to begin the port of Qedit to HP-UX.  The time that elapsed for
  735.    this phase was about six months (August to January).  The work
  736.    time:
  737.  
  738.  
  739.     Dave Lo   Two person-months.
  740.  
  741.     Bob Green Half person-month.
  742.  
  743.     David GreerThree person-months.
  744.  
  745.  
  746.                       Phase Three:  Rebuild Qedit
  747.  
  748.  
  749.    By this point, things were looking pretty good.  We had a number
  750.    of useful MPE routines written, a lot of the Robelle library was
  751.    running on HP-UX, and we had one module (Qhelp) that did file I/O
  752.    using an interface layer.  It was now time for the big show:
  753.    porting the Qedit source code to HP-UX.  This was a much bigger
  754.    project than what we had completed so far, since Qedit itself
  755.    consists of about 75,000 lines of code.
  756.  
  757.  
  758.    The First Attempt
  759.  
  760.    We started by compiling all of Qedit's source modules using
  761.    SPLash! and copying the resulting object-code to HP-UX.  Our
  762.    first attempt to link Qedit using the ld command had many errors
  763.    about missing procedures (e.g., all of the MPE file system
  764.    routines).  You can run an HP-UX program with missing externals,
  765.    but the program aborts if any missing routine is called.  To work
  766.    around this problem, we wrote one source module that had all of
  767.    the MPE routines that we had not rewritten for HP-UX.  Each dummy
  768.    routine returned a failure status.  A portion of this file looked
  769.    like this:
  770.  
  771.         integer procedure fopen;
  772.         begin
  773.  
  774.            fopen := 0;
  775.  
  776.            hpsetccode(ccl);
  777.  
  778.         end'proc;   <<fopen>>
  779.  
  780.         procedure flock      ;begin hpsetccode(ccl); end'proc;
  781.         procedure fpoint     ;begin hpsetccode(ccl); end'proc;
  782.         procedure fread      ;begin hpsetccode(ccl); end'proc;
  783.         procedure freaddir   ;begin hpsetccode(ccl); end'proc;
  784.         procedure freadlabel ;begin hpsetccode(ccl); end'proc;
  785.  
  786.  
  787.    Redo Module
  788.  
  789.    Qedit supports the Do, Redo, and Listredo commands.  After our
  790.    first attempt to link Qedit on HP-UX, we realized that we needed
  791.    the redo module to work.  The redo module also requires a "new"
  792.    file (these are files that on MPE you cannot see with Listf or
  793.    Listftemp).  HP-UX does not have new or temporary files, but
  794.    there is a solution.  For the invisible scratch files needed by a
  795.    program, you use the following algorithm on HP-UX:
  796.  
  797.        get a temporary filename (use tmpnam or tempnam)
  798.        open the temporary filename
  799.        unlink the filename from the file system
  800.  
  801.    If your program stops for any reason, the scratch file will
  802.    disappear and the space the file occupied will be returned to the
  803.    HP-UX free space list.
  804.  
  805.    With the redo module working, we were now able to link our first
  806.    version of Qedit/UX.  However, this version couldn't do much.  It
  807.    accepted commands, but most failed immediately.  For example, the
  808.    command:
  809.  
  810.         /open file
  811.  
  812.    would fail because the open command was still calling fopen.
  813.    Therefore, the next step was to completely reengineer Qedit so
  814.    that no direct calls were made to MPE routines.  Like Qhelp, we
  815.    began to reengineer Qedit to call an interface layer.
  816.  
  817.  
  818.    Implementing the Qedit Interface Layer
  819.  
  820.    Bob and I took about one month to completely reengineer Qedit so
  821.    that it called an interface layer for all operating system
  822.    services.  Bob changed Qedit and wrote the MPE version of the
  823.    interface.  I wrote the equivalent interface for HP-UX in C.  A
  824.    lot of our time involved Bob asking me if it was possible to do
  825.    certain things in HP-UX (e.g., how to obtain exclusive access to
  826.    an opened file in HP-UX).  By now, I had ported enough source
  827.    code to have a pretty good idea of what was possible and what was
  828.    not.  Writing the interface layer was not our only problem.
  829.    There were many other parts of Qedit that had to be changed.
  830.  
  831.  
  832.    Upshifting Filenames
  833.  
  834.    Inside Qedit, filenames were always upshifted, often in several
  835.    places.  On MPE this didn't matter, since filenames are not
  836.    case-sensitive.  On HP-UX, this was now important since filenames
  837.    are case-sensitive.
  838.  
  839.    Bob had to go through Qedit to find every single location where
  840.    filenames were upshifted and remove the upshifting code.  We also
  841.    had to cope with a different filename syntax (e.g., ../init.c is
  842.    a valid HP-UX filename).
  843.  
  844.    While we made these changes for HP-UX, we are now taking
  845.    advantage of these same changes for POSIX on MPE.  In MPE/iX 5.0,
  846.    POSIX filenames have the same syntax as on HP-UX (they are
  847.    mixed-case and can contain directory names).  So our efforts have
  848.    paid off twice.
  849.  
  850.  
  851.    The 32-Bit Alignment Problem
  852.  
  853.    The HP-UX C compiler prefers to have 32-bit variables aligned on
  854.    32-bit boundaries.  In SPL and SPLash!, it is common to have
  855.    32-bit variables aligned on 16-bit boundaries.  The interface
  856.    layer for Qedit was much more complicated than any of the other
  857.    interfaces that we had written.  Because the interface was more
  858.    sophisticated, large data structures had to be passed between
  859.    SPLash! and C routines.  We had to carefully implement these
  860.    structures so that all 32-bit variables were aligned on 32-bit
  861.    boundaries.  We also had to insure that these structures
  862.    themselves started on a 32-bit boundary.
  863.  
  864.    You can force SPLash! to allocate arrays on 32-bit boundaries by
  865.    making the arrays virtual.  This often has unexpected
  866.    side-effects (e.g., you cannot pass a virtual integer array to an
  867.    option splash procedure that is only expecting an integer array).
  868.    In Qedit, we ended up doing the following.  We would allocate one
  869.    more word of storage than was necessary and then would have code
  870.    that looked like this:
  871.  
  872.         if @ext'record mod 2 <> 0 then
  873.            @ext'record := @ext'record(1); ! assumes integer array
  874.  
  875.    This code fragment adjusts the start of the ext'record structure
  876.    if it does not start on a 32-bit boundary.  We also had to be
  877.    very careful of 32-bit variables that were passed by reference
  878.    (these are often status parameters).   It was often very
  879.    difficult to detect a 32-bit alignment problem:  due to the
  880.    nature of SPL and SPLash!, the problems can come and go.
  881.  
  882.  
  883.    The End-Of-File Problem
  884.  
  885.    Many parts of Qedit need to know how many records are in a file.
  886.    For example, to print the line numbers for a command like:
  887.  
  888.         /list somefile last-10/
  889.  
  890.    requires that Qedit know how many records are in somefile.  MPE
  891.    remembers how many records are in a file while HP-UX does not.
  892.  
  893.    Bob realized that rewriting Qedit so that it did not need to know
  894.    how many records were in a file would take longer than everything
  895.    we had done so far.  This meant that in the HP-UX interface layer
  896.    we have to read a file from beginning to end in order to count
  897.    the number of lines in it.  We do this every time that we open an
  898.    external file in Qedit/UX.  It's not very efficient, but it was
  899.    the only way to provide this information to Qedit.
  900.  
  901.  
  902.    Implementing Full-Screen
  903.  
  904.    By this point we had many of Qedit's line-mode commands working
  905.    on HP-UX.  The big question left was what to do about Qedit's
  906.    full-screen mode.  On MPE, Qedit uses block-mode to implement
  907.    full-screen.  On HP-UX, we didn't know what we were going to do
  908.    about full-screen.
  909.  
  910.    One Friday night after a long day, my two children came into my
  911.    office (at my home).  They wanted to play the computer game "The
  912.    Playroom".  I soon had one child on each knee (they were 4 and 2
  913.    at the time), happily playing on my computer.  I was surrounded
  914.    by the HP-UX reference manuals, which I had been using all day.
  915.    As my children were playing, I started flipping through one of
  916.    the manuals.  I wasn't really concentrating, but suddenly I
  917.    noticed an entry for blmode.  The opening description read:
  918.  
  919.       "This terminal library interface allows support of block
  920.       mode transfers with HP terminals."
  921.  
  922.    By accident, I had found a set of routines that implemented
  923.    block-mode.  Bob liked the HP-UX block-mode interface enough that
  924.    he reengineered the Qedit block-mode interface on MPE to look
  925.    like the one on HP-UX.  In a few days time, we had full-screen
  926.    working on HP-UX.
  927.  
  928.  
  929.    Phase Three Summary
  930.  
  931.    Qedit was now running on HP-UX.  The process we used helped
  932.    ensure that future Qedit enhancements would appear in both
  933.    versions, since only one set of source code is used for the MPE
  934.    and HP-UX versions of Qedit.  Most of Qedit no longer knew which
  935.    platform it was running on.  The time that elapsed for this phase
  936.    was about three months (February to April).  The work time:
  937.  
  938.  
  939.     Dave Lo   One person-month.
  940.  
  941.     Bob Green Two person-months.
  942.  
  943.     David GreerTwo person-months.
  944.  
  945.  
  946.                     Phase Four:  Polishing Qedit/UX
  947.  
  948.  
  949.    With the basic research complete, we now had to polish Qedit/UX
  950.    to turn it into a product.  Up to this point I had to write all
  951.    of the C code on HP-UX using the vi editor.   I was certainly
  952.    pleased when we had a working version of Qedit/UX that I could
  953.    start using.  I wasn't sorry to see the end of vi.
  954.  
  955.  
  956.    Porting the Test Suite
  957.  
  958.    For years, we have developed test suites for all of our products.
  959.    The Qedit test suite has a few hundred tests organized into
  960.    sixty-three batch jobs.  We knew that in order for Qedit/UX to be
  961.    reliable, we would have to have a good portion of our test suite
  962.    working on HP-UX.
  963.  
  964.    There was no automated way to convert our tests from MPE to
  965.    HP-UX.  We had to go through each test manually and convert MPE
  966.    commands to their equivalent HP-UX commands.  We also had to
  967.    implement several of our test tools on HP-UX (e.g., the program
  968.    that compares two Qedit files one line at a time looking for
  969.    differences).
  970.  
  971.  
  972.    Temporary Files
  973.  
  974.    On MPE, Qedit uses temporary files for a scratch file and for
  975.    "hold" files.  The hold filename on MPE was chosen so that you
  976.    could use the name in commands.  For example,
  977.  
  978.          /open file1
  979.          /hold 15/20            {save lines 15/20 in file "hold"}
  980.          /open file2
  981.          /add  75=hold          {add lines from the "hold" file}
  982.  
  983.    Initial versions of Qedit/UX created files in the current
  984.    directory called QEDITSCR, HOLD, and HOLD0 (note the upper case
  985.    filenames).  The Add command in the previous example would not
  986.    work, since there was no file called "hold":  it was "HOLD".
  987.  
  988.    We modified Qedit/UX to create the qeditscr, hold, and hold0
  989.    files in /usr/tmp.  HP-UX system managers expect temporary files
  990.    to be created in the /usr/tmp directory (our nightly backup
  991.    script removes all files from /usr/tmp more than twenty days
  992.    old).  We also had to modify Qedit/UX so that when it held lines
  993.    or when you wanted to look at a file called "hold", it
  994.    substituted the temporary filename.  For example,
  995.  
  996.          /open file1
  997.          /hold 15/20            {save lines in "qholdBAAa23359"}
  998.          /open file2
  999.          /add  75=hold          {add lines from "qholdBAAa23359"}
  1000.  
  1001.    On HP-UX there really are no temporary files.  HP-UX programs
  1002.    just create permanent files in a directory considered to be
  1003.    temporary.  The different-looking filename is a result of the
  1004.    HP-UX routine tempnam which creates a file with a unique name in
  1005.    /usr/tmp.
  1006.  
  1007.  
  1008.    More HP-UX Features
  1009.  
  1010.    Qedit/UX was modified to execute shell commands (a shell is like
  1011.    the MPE/iX CI.PUB.SYS program).  One of the most common HP-UX
  1012.    commands is ls (like the MPE Listf command).  This conflicted
  1013.    with the Qedit command LSort.  In Qedit/UX, we made ls mean list
  1014.    files and LSO mean sort lines (although the LSOrt command is not
  1015.    yet implemented).
  1016.  
  1017.    HP-UX users can have different shells.  We changed Qedit/UX so
  1018.    that when it executes shell commands it does so with the user's
  1019.    preferred login shell.
  1020.  
  1021.    We could not obtain command line arguments in our SPLash!
  1022.    programs.  Fortunately, Stan Sieler worked on the problem and
  1023.    modified SPLash! to make the argument count and a pointer to the
  1024.    argument list available to SPLash! programs.  HP-UX programs
  1025.    expect options to be specified by a leading dash.  We changed
  1026.    Qedit/UX to accept command line arguments such as this:
  1027.  
  1028.         qedit -s -cvi file1
  1029.  
  1030.    This example asks Qedit/UX to edit a single file (-s), go
  1031.    directly into visual-mode (-cvi), and to edit file1.  This also
  1032.    made it possible to set the HP-UX EDITOR variable, so that any
  1033.    HP-UX program that invoked an editor would invoke Qedit/UX on
  1034.    behalf of the user.
  1035.  
  1036.  
  1037.    Tab Characters
  1038.  
  1039.    One problem that we have not solved adequately is how to handle
  1040.    tab characters.  In MPE, tab characters are used as a short-hand
  1041.    way of moving the cursor across the screen.  The tab character is
  1042.    always translated into spaces and never stored in files.  On
  1043.    HP-UX, the tab character is also used to move across the screen,
  1044.    but it is also used as data.  Some programs (e.g., make and
  1045.    sendmail) require that certain lines have tab characters.
  1046.  
  1047.    In Qedit/UX, we automatically expand tabs to spaces when we text
  1048.    a file.  This is not what HP-UX users expect, especially if you
  1049.    are editing a Makefile or the sendmail configuration file
  1050.    (important data gets removed by Qedit/UX).  Qedit/UX has a
  1051.    feature to prevent tabs from turning into spaces, but it is not
  1052.    the default.  If you leave tabs as data and go into full-screen,
  1053.    you will lose the tab characters that were in the lines shown on
  1054.    the screen.
  1055.  
  1056.    There are various technical problems that make it difficult for
  1057.    Qedit to treat tabs as data.  How to handle tab characters is
  1058.    similar to our number-of-records problem in the file system
  1059.    interface.  It's a fundamental assumption that is different on
  1060.    HP-UX from MPE.  We continue to work on ideas in Qedit/UX to
  1061.    solve this problem.
  1062.  
  1063.  
  1064.    Releasing a Product
  1065.  
  1066.    Besides all of the technical and programming problems, there were
  1067.    many other issues to deal with.  We had to create a whole new set
  1068.    of software to make tapes.  I spent two full weeks rewriting the
  1069.    Qedit documentation so that we could have both a Qedit/UX user
  1070.    manual and on-line help.  There were data sheets to write,
  1071.    advertising, training (every technical person at Robelle has
  1072.    taken the week-long HP-UX introductory course), and pre-release
  1073.    customers to work with.  It was all worth it when we first
  1074.    demonstrated Qedit/UX at the San Francisco Interex User Group
  1075.    Meeting.  We had many excited customers and just a week later we
  1076.    started shipping Qedit/UX.
  1077.  
  1078.  
  1079.    Phase Four Summary
  1080.  
  1081.    Our final phase took a working R&D program and turned it into a
  1082.    new product.  Many changes were made to integrate Qedit/UX into
  1083.    HP-UX.  The supporting documentation and technical support were
  1084.    created to provide a high quality product for our customers.  The
  1085.    time that elapsed for this phase was about five months (May to
  1086.    September).  The work time:
  1087.  
  1088.  
  1089.     Dave Lo   Two person-months.
  1090.  
  1091.     Bob Green Two person-months.
  1092.  
  1093.     David GreerTwo person-months.
  1094.  
  1095.  
  1096.                         The Future of Qedit/UX
  1097.  
  1098.  
  1099.    We have proven that the initial concept of cross-platform
  1100.    development using SPLash! was feasible.  The object-code format
  1101.    on MPE/iX and HP-UX are the same.  It is possible to compile
  1102.    SPLash! code on MPE, copy it to HP-UX, and then link and run the
  1103.    resulting program on HP-UX.  In total, we ported over 100,000
  1104.    lines of code.  We could never have rewritten Qedit in the same
  1105.    amount of time.
  1106.  
  1107.  
  1108.    Full-Screen
  1109.  
  1110.    Our use of the blmode routines enabled us to get full-screen mode
  1111.    up and running quickly.  Now that Qedit/UX has been released for
  1112.    several months, it is clear that even on HP-UX many users have
  1113.    decided to use vt terminals or vt terminal emulators.  Because
  1114.    full-screen uses HP block-mode, it requires an HP terminal and
  1115.    will not work with vt terminals.  One major research goal for
  1116.    1994 is to reengineer full-screen to use a terminal-independent
  1117.    method of communicating with the user.
  1118.  
  1119.  
  1120.    Shell Commands
  1121.  
  1122.    On MPE, users are used to living inside Qedit all day.  You
  1123.    cannot do this in Qedit/UX, because many common shell features
  1124.    are missing (e.g., setting environment variables).  Some of these
  1125.    are due to limitations of UNIX, but we expect to implement many
  1126.    more shell features in Qedit/UX.  It took us more than ten years
  1127.    to fully integrate MPE command features into Qedit/MPE, so it
  1128.    isn't a big surprise that it will take us a year or two to add
  1129.    all the necessary shell features to Qedit/UX.
  1130.  
  1131.  
  1132.    MPE Flavor
  1133.  
  1134.    Qedit was originally written for MPE.  There are many features of
  1135.    Qedit/UX that retain an MPE flavor.  If we are to expand the
  1136.    potential market of Qedit to users who have never seen MPE, we
  1137.    will have to remove most of this MPE feel and introduce more of
  1138.    an HP-UX feel.  This is a challenge, since we still want Qedit/UX
  1139.    to look familiar to former Qedit/MPE users.
  1140.  
  1141.  
  1142.    The End
  1143.  
  1144.    Qedit/UX has been both a technical and a marketing success.  We
  1145.    now have one set of source code that can be used to generate two
  1146.    different products:  Qedit/MPE and Qedit/UX.  If you have a lot
  1147.    of SPL/SPLash! code, perhaps our solution will work for you as
  1148.    well.
  1149.