N ASA / TM- 1998-208466

Designing for Change:

Minimizing the Impact of Changing

Requirements in the Later Stages of a

Spaceflight Software Project

B. Danette Allen

Langley Research Center, Hampton, Virginia

National Aeronautics and

Space Administration

Langley Research Center

Hampton, Virginia 23681-2199

October 1998

https://ntrs.nasa.gov/search.jsp?R=19990013874 2018-05-11T17:25:11+00:00Z
Available from the following:

NASA Center for AeroSpace Information (CASI)

7121 Standard Drive

Hanover, MD 21076-1320

(301) 621-0390

N_.tional Technical Information Service (NTIS)

52 _5 Port Royal Road

SFringfield, VA 22161-2171

(7_)3) 487-4650
Designing for Change:

Minimizing the Impact of Changing Requirements in

the Later Stages of a Spaceflight Software Project

B. Danette Allen

NASA Langley Research Center

M/S 488

Hampton, VA 23681-0001

b.d. allen@larc.nasa, gov

Abstract

In the traditional "waterfall" model of the software project life cycle, the Requirements

Phase ends and flows into the Design Phase, which ends and flows into the Development

Phase. Unfortunately, the process rarely, if ever, works so smoothly in practice. Instead,

software developers often receive new requirements, or modifications to the original

requirements, well after the earlier project phases have been completed. In particular,

projects with shorter than ideal schedules are highly susceptible to frequent requirements

changes, as the software requirements analysis phase is often forced to begin before the

overall system requirements and top-level design are complete. This results in later

modifications to the software requirements, even though the software design and

development phases may be complete. Requirements changes received in the later stages

of a software project inevitably lead to modification of existing developed software.

Presented here is a series of software design techniques that can greatly reduce the

impact of last-minute requirements changes. These techniques were successfully used to

add built-inflexibility to two complex software systems in which the requirements were

expected to (and did) change frequently. These large, real-time systems were developed at

NASA Langley Research Center (LaRC) to test and control the Lidar In-Space Technology

Experiment (LITE) instrument which flew aboard the space shuttle Discovery as the

primary payload on the STS-64 mission. Although developed in the Ada programming

language, most of these methods are language-independent and can easily be modified to

be used in any high-level language.
Acronym List

AT

CAP

CDR

CFG

DOD

GSE

IC

I&T

JSC

KSC

LaRC

Lidar

LITE

MSFC

NASCOM

OOD

PIC

PGSC

POCC

SFMDM

SRS

STS

IBM PC AT

Command Acceptance Pattern

Critical Design Review

Command File Generator

Department of Defense

Ground Support Equipment

Instrument Controller

Integration and Test

Johnson Space Center

Kennedy Space Center

Langley Research Center

Light Detection and Ranging

Lidar In-space Technolc, gy Experiment

Marshall Space Flight Center

NASA Communications

Object Oriented Design

Payload Interface Converter

Payload General Support Computer

Payload Operations Control Computer

Smart Flexible Multiple _er DeMultiplexer

System Requirements Specification

Space Transportation System
1. Introduction

The Lidar In-space Technology Experiment (LITE) is a three-wavelength backscatter lidar

developed by NASA Langley Research Center (LaRC) that flew on the space shuttle

Discovery in September 1994 as primary payload on the STS-64 mission. Lidar (Light

Detection ad Ranging) is a remote sensing technique that can be used to study clouds ad

aerosols in the atmosphere by sending out short pulses of laserlight and detecting the

portion scattered back to the instrument. The goals of the LITE mission were to validate

key lidar technologies for spaceborne applications, to explore the applications of space

lidar, and to gain operational experience which will benefit the development of future

systems on free-flying satellite platforms. The 40 Gbytes of science data collected

provide the first highly detailed global view of the vertical structure of clouds and aerosols

from the Earth's surface through the middle stratosphere. LITE also provided the In'st

demonstration of space lidar for study of the Earth's atmosphere and resulted in the

collection of 53 hours of data, equivalent to 35 orbits of the Earth. This is the first data set

that provides the highly detailed vertical structure of clouds and aerosols on a global scale.

The success of the mission demonstrates the maturity of lidar technology and the potential

for long-term orbital lidars on free-flying platforms. The LITE mission is detailed further

in [1].

Two sets of real-time Ground Support Equipment (GSE) software were required for the

development, integration, test and flight of the LITE payload. Integration and test

required a real-time platform that simulated absent shuttle interfaces, displayed

engineering and science data and provided a means for commanding the instrument.

Mission software was required for use in the Payload Operations Control Computer

(POCC) facility for commanding and data display during the flight. The software team

was assembled with 18 months to develop and deliver the test GSE and, following a

successful test at Kennedy Space Center (KSC), 12 months to develop and deliver mission

critical ground software to Johnson Space Center (JSC) for integration into the POCC.

The test GSE was developed in parallel with the instrument and was required to simulate

yet-to-be-defined interfaces. The mission software would follow-on from the test

software but would require major changes to accommodate new interfaces onboard the

shuttle and at JSC. Both systems were developed on an accelerated schedule by small

teams of three to five people. We knew we had to design for change. In order to design

for change, we needed to predict what could change and when. This required that we

understand why software requirements changes occur. Five change agents were

identified: immature system requirements, documentation, detail comprehension, shifting

user requirements and external influences. As immature external requirements were

defined and new ones added, our design needed to minimize impact on the existing

system. The decision was made to counter risk by driving the uncertainty into the data, as

opposed to the code, through the use of external files.

The following sections will describe techniques used on these systems to build in

flexibility in order to minimize the impact of late requirements changes on the software

systems. A history of the LITE payload is provided for context. The disconnect between

academic life cycle models and their application in our working environment is presented
alongwith our chosen data-driven approach. Finally, the philosophies and techniques that

were successfully used in designing for change are di,cussed in detail.

2. LITE History

During the 10-day mission, commanding of the LITE instrument was accomplished

primarily from Mission Control at JSC in Houston. All commands are received by the onboard Instrument Controller (IC), which parses the commands and relays them to the Aft

Optics or Boresight Assembly subsystems, if required. The IC executes instrument level

commands. The LITE instrument command set is very versatile, including over 200

commands to control every facet of the instrument operation. The LITE Command File

Generator (CFG) operated without error for the entire mission duration.

The CFG is a relatively large (over 30,000 Ada statements), PC-based real-time platform

from which all commands were issued to the LITE instrument during its 10-day mission.

It was developed specifically for LITE and allowed for commanding the IC directly or via

the Payload General Support Computer (PGSC) in the shuttle flight deck. The CFG

requirements [2] are summarized in Table 1.

Requirement Center Reference

Display relevant Payload Data Interleaver (PDI) and LaRC

LITE data JSC

Retrieve instrument data from Lantastics network LaRC

Conform to NASA Communication (NASCOM) JSC [3]

uplink format

Conform to Smart Flexible Multiplexer Demuitiplexer MSFC [5]

command format

Conform to LITE IC command format LaRC [4]

Conform to PGSC command format MSFC [5]

Interface directly to Payload Interface Converter (PIC)

for uplink commands

JSC [31

Receive Command Acceptance Pattern (CAP) from JSC [3]

PIC

Table 1: CFG Requirements

As shown in Table 1, requirements from numerous Nt_SA centers and, therefore,

numerous documents, had to be understood and merged in order to generate the CFG

requirements and platform. Figure 1 shows the CFG c ata path.
........................................ _S_h_uttje_ ___

CFG PIC

Figure 1: LITE CFG Data Path

Before any resources could be put towards the design, development and delivery of a

mission commanding platform, test GSE was needed for integration and test of LITE at

LaRC and KSC. Software was brought in late in the LITE project lifecycle. Any and all

problems that had been hand-waved off with "we'll take care of that in software" had to

be addressed. The IC was the heart of the LITE instrument and had no formal

requirements. The LITE instrument needed to be fully integrated and tested in 18 months.

Test GSE development would have to be in parallel with the design of the IC software and

integration of the instrument.

The Pallet Simulator (Figure 2) is a large (over 60,000 Ada statements), real-time,

distributed system consisting of three platforms: Master AT, Display AT, and Quicklook

AT. The Master AT interfaced directly with the LITE instrument via in-house GSE. It

simulated a shuttle interface, the Smart Flexible Multiplexer Demultiplexer (SFMDM) [5],

through which all commands and engineering data were transferred. For test purposes, it

also provided the instrument interface for science data, again though in-house GSE.

Because this platform simulated a shuttle interface, the real-time requirements of the

system were its first priority and could not be compromised. These requirements were

successfully married with the storage of science and engineering data along with the

transfer of data to the appropriate platform, either the Quicklook AT or the Display AT.

These two platforms were receive-only except for communication health checks with the

Master AT and, therefore, did not interface directly with the instrument. For this reason,

discussion of the Pallet simulator will be limited to the Master AT software only.

The design and development of the Master AT (IBM PC AT) software coincided with the

design, integration and test of the LITE instrument. Therefore, requirements changes were

inevitable. The team was forced to devise an approach that would allow for built-in

system flexibility. Because the instrument was still at the subsystem level, the IC was still
at theconceptualstage.Instrumentcommandinganddatahandlingwereundefined.We

neededautonomybutdid nothaveanoperationsscenario.Little thoughthadbeengiven

to exactlyhow theseitemswouldbeaccomplished.WhatwouldaLITE commandlook

like? Whatwasthedownlink dataformat? Wehadthechallengeof developinga test

systemfor aninstrumentthatwas,from asoftwareperspective,undefined.Theflight

software and GSE software would be defined, designed, developed and tested in parallel

alongside the instrument itself.

Data

__, _ Cornrnand_

I .............................................

I

!

I

I

Figure 2: Master AT Architecture

The software team was faced with a challenge. The CFG would follow-on from the

Master AT. The Master AT had to be delivered coincdent with the semi-specified LITE

instrument and the unspecified LITE IC. Figure 3 illu ;trates the major milestones in the

LITE project timeline. Each box marks the beginning of the specified task but is not

intended to communicate task duration. Of particular interest, the final System

Requirement Specification (SRS) was not available until the Master AT software was

delivered and the CFG software was in development.

6
1989 1990 1991 1992 1993 1994 1995

Hardware CDR

LITE Milestones

SRS draft first I SRS draft final

LITEI&T ] KSC delivery [

LITE

Performance

Checkout

LaRC SIMS [

JSC testing

Mission

IC Milestones

I start C software

Software Review

IC I&T

Initial

software

delivery

Pallet Simulator Milestones

Master AT [ [ Final software software start delivery

Software review

CFG Milestones

CFG software

start Partial delivery CFG

Final CFG

delivery

Figure 3: LITE Project Major Milestones

We needed to design and code to minimize system impacts when changes occurred. We

also needed to design with reuse in mind knowing that the CFG would leverage off the

Master AT development. The traditional waterfall model where all activity of a certain

type occurs during a phase of the same name and in which phases do not overlap [6], was

simply not an appropriate model. The spiral model requires several revolutions requiring

time and experience, neither of which we had in abundance. We needed an approach

suitable for the accelerated schedule under which we were to develop mission-critical

GSE. Prototyping seemed the best choice but was not entirely appropriate given our short

schedule and real time requirements. We combined the appropriate philosophies from

several models in creating a data-driven approach that was workable within our short

development schedule. We also needed to design for change. The area most susceptible

to change was the data so we countered risk by using a data-driven design that generated

code to accommodate changes in external text files. Presented here are the design and

coding techniques used in the development of these complex platforms.
3. The Unstable Process of Software De,_ign and Development

Change is a very natural and intrinsic aspect of the software development process. For

example, change occurs [7]:

• during software requirements analysis phase, when the software requirements

specification is agreed to by all parties and is baselined.

• during software development and test, when the software design, or the code,

or the test plans are completed.

• during software maintenance, when requirements have changed or matured,

and

• during software maintenance or later enhancement, when a problem is detected

in the software requirements or system that forces modifications to the design

or the code or the test plan.

Knowing that software will change is not enough. In order to design for change, one must

understand why software will change.

3.1 Immature System Requirements

The trend to implement in software functions traditionally accomplished by hardware

devices has led to increased size and complexity of software subsystems [ 18].

Historically, software has been a very small part of the total project cost and was managed

as such. Older paradigms provide little or no guidance for managing software projects [8].

As a result, the need for software often goes unrecognized at the beginning stages of a

project. Even once the need for software is recognized, the resources required are often

underestimated, especially in the early requirements specifications and design phases. The

software team regularly plays catch-up to the more mature project. However, this

maturity is often limited to the subsystem level and does not apply to the system as a

whole. The software team serves double duty as both software developers and system

engineers [8]. In order to develop software requirements, system questions must be asked

and answered. Often, these questions are fu'st asked ir the software requirements

specification effort. These questions cannot always be answered immediately and, if the

software team waits until the system is fully defined (all the questions are answered),

schedules would never be met. As the system evolves, system requirements will change

imposing new requirements on the software. However, even with a relatively stable

system, the unstable process remains.

3.2 Documentation

Documentation alone is a weak communication medium [9]. CFG gathered and merged

requirements from three NASA centers and four systeras. Conflict among requirements is

not uncommon in large systems [9] and the CFG was ro exception. All PGSC commands

are routed through the SFMDM. However, [5] stated that all SFMDM commands were to

be 32 words in length while all PGSC commands were to be 30 words in length. This

ambiguity was not uncovered until End-to-End test at JSC, very late in the project time

8
line. If more verbal communication had been possible earlier, this problem could have

been caught while we were still developing at LaRC. The documentation could have been

clarified and the problem solved much faster.

3.3 Detail Comprehension

It is impossible to see every requirement at first glance. Many of the details become

known as we progress through the implementation [10]. Often one does not know the

questions that need to be asked until faced with an implementation question. Even if we

knew every requirement, experience shows that people are unable to fully comprehend the

plethora of details that must be taken into account in order to design and build a correct

system [10]. For this reason, as the picture of what is required of the software system

becomes clearer, changes will occur.

3.4 User Requirements

In many cases, those who commission the building of a software system cannot specify

exactly what they want nor are they able to communicate everything they know up front.

There is a cultural gap between the developer and the customer [11]. The developer has

the skills necessary to meet the customer requirements but does not have a complete

understanding of the application while the customer has a complete view of the

application but cannot know the capabilities of the software. This is often the case with

mission GSE. The user specifies that a system is needed for commanding or to display

science data. Often, little thought has been given to exactly what the user wants to see and

how the user will interact with the system. Scientists and engineers are busy at the

subsystem level while the software developers are working at the system level. Software

prototyping has been proposed as a solution to this problem and the generation of a

strawman concept is useful in minimizing the impact of changing user interface

requirements. However, we found that there is a limit to how far ahead a system can be

prototyped. No amount of prototyping can predict the wants and wishes of the users once

the system is integrated, new system hot spots have been discovered and the community of

users changes.

3.5 External Influences

Because software is intangible, it is constantly subject to pressures for change [12]. This

can be due to "creeping elegance", an altered interface, "planned" flexibility, or the need

to f'LXa system problem. In any case, no traces are cut, no connectors demated, and,

usually, flight configuration is not broken when a software change is made. Software can

be viewed as infinitely malleable and an inexpensive fix since it can be changed "more

easily" than hardware. To some degree, this is true, especially in the later phases of the

project life cycle. When external interfaces change, the software is often expected to

change in order to accommodate the new requirements. When a new capability of deemed

necessary, software is often expected to provide this functionality.
4. Software Development Approaches

Three widely accepted approaches to software development are the waterfall life cycle

model, the spiral life cycle model and prototyping. While we recognized the merit of

these schemes, careful examination proved that no single one of them would meet our

needs given the immature system requirements and the accelerated project schedule. We

selected the most fitting aspects from these well-documented models to create an approach

that suited our development environment.

4.1 Waterfall

The waterfall model consists of five basic stages (requirements analysis and definition,

system and software design, implementation and unit testing, system testing, operations

and maintenance) and assumes that one stage ends before the next stage begins [13]. In

the typical flight software development environment, strict adherence to waterfall

development methodologies is impossible [ 14]. The uncertainties of high-level

requirements definition and significant hardware and spacecraft interface design changes

well into the software development cycle would prevent ever evolving out of the software

requirements phase. This was the case during the development of the Pallet Simulator

Master AT. If we had waited until all requirements were firm before moving on to the

design phase, we would have had nothing but requirements to show on the designated

delivery date.

4.2 Spiral

The spiral model [15] is a risk-driven approach that emphasizes prototyping and

incremental and iterative deliveries and allows a more realistic approach to requirements

satisfaction than the traditional waterfall models [ 16]. Each iteration around the spiral

passes through four phases (Planning, Risk Analysis, Engineering, Customer Evaluation)

as progressively more complete versions of the software are built. It attempts to combine

the best elements of the waterfall model and prototyping while recognizing and providing

a mechanism for risk analysis. In that, the spiral model demands considerable risk

assessment expertise and we simply did not have the ti me or the expertise to fully

implement the spiral model development approach.

4.3 Prototyping

Software prototyping enables the developer to create a model of the software that must be

built. It is especially helpful in the requirements specification phase [11]. Because we

had a set of general objectives for the GSE software btt little detailed information about

input, processing, and output requirements, prototypin_; seemed the best modeling choice,

especially for gaining insight into the user interface. Eowever, we did not have the time

to implement a pure prototyping life cycle. We could _lot afford to throw away precious

development time along with the models themselves. However, prototyping would enable

us to create a model of the software that, at a minimurr, would simulate the user-machine

interface. This "strawman" approach worked well. It .tefined what the user interface

10
should look like and we were able to extract other system requirements. In GSE, very

little processing is performed that is not displayed in one form or another. Prototyping led

to a top-down function design process that meshed well with the real-time context. The

first "quick design" prototype was a throw-away. After a look and feel was agreed upon,

we moved to a data driven approach.

4.4 Data Driven Approach

Many real-time system developers feel that present-day software engineering methods are

insufficient to meet the needs of real-time programming [ 17]. Data flow-oriented

techniques are generally seen as the best fit method for real-time system design.

Functional decomposition makes it easy to cope with some peculiar aspects of real-time

systems such as concurrency and timing requirements [18]. For non-embedded

applications like the CFG, prototyping is helpful in designing the user interface from

which requirements inevitably fall out. We found this to be true in the Pallet Simulator

development but wanted a more modular design for the CFG. Due in part to the language

selection (Ada), the design of the Master AT was inherently modular enough to allow for

reuse of packages whose functionality would be required later (i.e. LITE command block

construction) but we knew we could improve on that with the CFG. In general, functional

oriented methods are stronger in the early stages of software design in going from

requirements to top-level design elements. We carried over this philosophy to the CFG

but used an Object Oriented Design (OOD) approach at the package level. Our high-level

requirements were functional in nature and mapping the CFG requirements back to the

mission requirements was simple. We defined objects to represent the interfaces and data

definitions that required further clarification. This enabled us to isolate the code that we

knew would change, as requirements were refined and system changes impacted current

requirements. This helped in driving the changes into the data but was not sufficient. We

did not want to perform a system rebuild every time a data definition changed. External

data files could be used to provide dynamic data definition. The following narrates the

design decisions and techniques used to minimize risk by pushing the system uncertainty

into the data.

5. Design Techniques

The selected language for flight and ground software development was Ada. Ada

facilitated the use of a number of design techniques such as information hiding, data

abstraction and modularity. These techniques were successfully employed in the

generation of several reusable packages for menuing, operating system isolation and data

display.

5.1 Ada Language Choice

Ada was developed in the early 1980's as the mandated language of the Department of

Defense (DOD) and as a potential solution to the rising cost of software development.

NASA LaRC had not mandated the use of Ada in its flight projects but the organization

responsible for the LITE software was in the process of establishing a center-wide

11
standard for software. The software engineer on LITE selected Ada as the language best

suited for real-time system development at LaRC for both embedded and non-embedded

environments. Ada was not specifically manufactured to support object oriented design.

Nevertheless, some of its features like data and processing abstraction, generic types,

packages (that support information hiding), are particularly useful in implementing object

oriented design. The "package" is an important Ada concept. Inherent in the use of the

Ada package is a certain degree of modularity. Even though OOD was not used in the

development of the Master AT, all of the functions also needed by the CFG system could

be ported directly over with only a few modifications. Ada was especially useful in the

design phase of the CFG. The design was a team effo_ with individual responsibilities

assigned to each member. During the design, specifications for all packages were created

and compiled. These specifications imported other specifications so we were able to

group blocks and subsystems before any processing code was created. Package bodies

were created with procedure and function stubs. The coding phase simply filled in these

functions and procedures one by one. Integration and test was simplified in that we

already had a system in place. We needed only to verify functional correctness. Ada

promotes software engineering better than any other modern language [19]. The package

concept, strong typing and Ada compiler helped us enforce our software interfaces and

imposed a modular design on both systems. Adherence to the Ada philosophy inherent in

the language provided modularization, abstract data types and hierarchical structuring

[121.

5.2 Modularity

Modularity has a direct positive impact on maintainability [18]. To this end, the design of

the CFG system was modular in nature. At the top level, functional decomposition

separated logical modules. Within each functional module, objects were separated though

the use of packages using an OOD approach. A high-level architectural block diagram

can be found in Figure 4. Due to immature requirements during the initial design phase,

we often did not know the exact definition of that data that was to be passed from module

to module. We knew the size of the data but the format was yet to be determined. To

work around this problem, we were forced to override one of the features of Ada, strong

typing. To simplify parameter passing to and from procedures, all parameters were passed

as arrays of unsigned bytes. Unchecked Conversion allowed for the integration of many

different data types used within individual packages. When the data definitions were

defined, the existing procedures and functions were overloaded to handle both the

primitive data (unsigned byte) and the strongly typed data type.

12
I CFG Commanding ]

SFMDM

NASCOM I

Figure 4: Partial CFG Architecture

5.3 Abstraction and Information Hiding

Information hiding focuses on what to hide; abstraction focuses on what to reveal. The

principle of information hiding is that each module (or package) hides a design decision

and implementation. If the design decision changes later, then no calling code should

need to change. It is the other side of the coin from data abstraction [20]. Abstract data

types should make it possible to change the data representation of objects while

guaranteeing that all visible operations on the objects have the same properties. Procedural

abstraction can be used to obtain much of the effect of abstract data types. A data

structure can be defined and a set of procedures can be written to manipulate that data

[21]. In Ada, data abstraction is often accomplished through the use of generic packages.

In the CFG development, abstraction was achieved through procedures for ease of testing.

Generic packages presented difficulties in the test and debug phase of software

development. The inline debuggers could not see inside an Ada generic. Further, in Ada

83, generics were highly inefficient in memory usage and reclamation at execution time.

The Menu Package (Appendix 1) is one example of data abstraction and information

hiding used in the software. It provides a text-based menuing facility that was developed

for the user interfaces on both the Master AT and CFG platforms. Neither system had

graphics displays requirements. Therefore, text-based menuing and data display was

chosen for speed and executable size advantages. With the Menu Package, vertical menus

were defined, displayed and read via the limited private type Menu_Type and the

13
procedures and functions provided for operations on a menu object. Menus are defined by

procedure De fineMenu using upper left and lower right coordinates, color scheme,

title, and border style. The parameters are read from an input t'de specified by the calling

routine. This is an excellent example of information hiding. The programmer creates a

text file that contains all the information required to define a menu and declares an object

of type Menu_Type with no need to know exactly what this type looks like. Procedures

and functions are provided for access information about the menu.

Get_Menu_Coordinates, Ge t_Menu_Col or_S cheme,

Get_MenuBorderStyle and Get_Menu_Tit le are examples ofthe procedural

data abstraction used in providing operations on the Menu_Type. Read_Menu returns

the sequence number of the selected item in the menu specified. Other operations are

Append_I t em, Ins ert_I: era, and De 1 e t e I tem that allow menu modification

during program execution.

While the Menu Package was created specifically for menuing, we also used it during the

prototyping phase of development. Menu parameters can be defined such that no

highlighted selection bar is present and dummy data can quickly and easily be placed on

the screen with calls to DefineMenu and DisplayMenu. Data can then be moved

around on the screen and colors changed with a simple modification to the input text files

with no required recompilation, bind or link. This is discussed in more depth in Section

5.7.

5.4 Filename Manager Package

The Filename Manager Package allowed greater flexibility in naming external files such

as data files, initialization files, and menu definition flies. It allowed the code to use

identifier strings, called "tags", to select files, instead of being limited to the file naming

restrictions imposed by the host operating system. In addition, it also prevented literal fide

names from being "hard-wired" into the code. This allowed us to change file names, or

use a substitute fde with a different name in a test, without having to modify or re-compile

the code. It also provided operating system independeace.

An input file is created that contains a list of data pairings, the actual file name and its

associated file tag. A pairing in an input file appears as

[CFG_Command_Log fi i e ]

[C :\CFG\LOG\COMMAND. LO(J]

where the file tag CFG_Command_Logf i i e is mapred to the actual file

COMMAND. LOG in directory C : \CFG\LOG\.

The actual file names are assigned when the fde is reac in at list initialization. This allows

complete code isolation from the operating system. It dso allows for easy testing of new

data files. The filename input file can be modified to associate a different file name with

an existing file tag and the new file name will be used. No modifications are required to

an existing working file so nothing is lost in testing the new data definition.

The following functions are available operations on the private type

14
F i i ename_Li s t_Type that is a record that contains the filename list and the length of

the list. Private type Fi l e_Node Type defnes the list contents as a record that holds

the file tag, the actual filename to which the tag maps and a pointer to the next list

element. The private type declarations are listed below. Filename Manager Package, in

its entirety, can be found in Appendix 2.

TYPE Filename_List_Type IS

RECORD

Length : NATURAL: : 0;

Node_List : File_Node_Access_Type;

END RECORD;

TYPE

TYPE

TYPE

File_Node_Type;

File_Node_Access_Type IS ACCESS File_Node_Type;

FileNode_Type IS

RECORD

File_Tag : Variable_String Package.VString;

Filename : Variable_String_Package.VString;

Next : File_Node_Access_Type;

END RECORD;

The overloaded function Get_Fi lename searches the specifed list for the file tag or tag

position passed to it and returns the actual file name associated with that tag. A mapping

is created with procedure Ge ner a t e_F i 1 emame_L i s t that requires a filename list and

an actual flename, From_Fi l e, which can be passed in as a result of the function

Get_Fi lename. File tags can be retrieved with function Get_Fi le_Tag based on a

file name or position and specified list. Careful file management allows the position

returned to be used in combination with the Menu Package choice in ReadMenu.

Pairings can be removed from the set by either file name or file tag with procedures

De i et e_F i i e_Name and De i et e_F i I e_Tag, respectively. Pairings can be inserted

via procedures Append_To_F i i ename_L i s t or

Insert_Into Filename List. Procedure Insert Into Filename_List

inserts the new pairing in sorted order, assuming a sorted list, by either file name or file

tag as specified in the parameter Insert. Sorted mappings are achieved through

procedure Sort_F i 1 e name_L i s t which sorts by either file tag or filename. Procedure

Save Fi lename Li st allows the user to save the current contents of a flename list to

an external file so that runtime changes to a list are not lost. If S ave_F i 1 ename Li s t

is not called at shutdown, the original file from which the list was created will remain

intact.

5.5 External Initialization Files

A big challenge for the Master AT development was lack of command and data definition.

The data size had been determined, as had the maximum command size. However, little

consideration had been given to the command and data format. Additionally, the LITE

subsystems were not yet completed, further complicating command definition. Even once

the basic command format was defined, the command codes themselves were still

changing. Each LITE serial command had a unique associated 8-bit identifier when

15
coupledwith the2-bit commandsubsystemdestinatioa.Threeinitializationfileswere

created- onefor eachsubsystemdestination.At runtime,thesefileswerereadin andthe

commanddatabasewasinitializedfrom thesefiles. A_thesubsystemcommandcodes

weredefined,weneededonly to edittheexternaltext files in orderto accommodatethe

systemchanges.

5. 6. Constants Package

Figure 5 illustrates the evolution of the Constants Package concept used in both the Master

AT and CFG systems. The following sections explain the refinement of this package that

can be found in its entirety in Appendix 3.

5.6.1. Specification only. While developing the Pallet Simulator and CFG software, the

team noticed that many constants and objects were needed in several packages resulting in

multiple declarations. For example,

Byte_size : constant integer :: 8;

appeared in almost every package body developed. If a requirements change effected any

of these variables, the domino effect would have been significant. Our solution was the

Constants Package that was used in both systems. A package Specification was created to

isolate shared data definitions. Theoretically, this makes maintenance easier in that a

change in one place will trickle down through the entire software system. However, there

was one major drawback. While changes were isolated, a complete system rebuild was

required whenever a change to the constants package was made. Many packages WlTHed

in the constants specification and had to be recompiled whenever the constants package

specification was recompiled.

5.6.2. Specification and Body (Package) with function calls. In order to avoid a

recompile of the entire system when a data definition changed, the existing constants

package Specification was modified. Each object in the Specification was redefined as a

function whose name was identical to the existing object name. No code modifications of

existing software were required since the object to fun.ztion translation was transparent to

the calling code. The data values were defined as con., tant declarations in the package

body. If a data definition changed, all that was required was a constants package body

recompile which did not necessitate any further recornpiles. All that was required was a

new BIND and, as with the constants specification concept, the changes trickled down

though the software. This was an improvement over the original specification only

package but still did not isolate the risk to the data exclusively.

5.6.3. Package with initialization files. In order to eliminate recompiles entirely, the

constants package body was further refined. At runtirre, an initialization file was read in.

All constant declarations were changed to object decla'ations. The objects declared were

defined at runtime with the contents of the initializatio,a file. With this modification, data

definition changes could be affected with no compilati)n, no bind and no link of the

system. The code was data independent and, as much _s possible, data definition changes

16
wereisolatedto simpleASCII textfiles.

5.6.4. Package with initialization files and filename manager package. The final

modification to the Constants Package was for OS isolation. The filename manager

package was used in opening, reading and closing the initialization file. While this change

did not increase data isolation, it was in keeping with the OS-independent design

approach.

I

I

I

I I Spec Body

Filename

Manager

Figure 5 : Evolution of Constants Package

5.7. Relative Positioning

Relative referencing combines the data abstraction and information hiding

illustrated by the Menu Package with the data-driven design approach of

initialization files. The prototyping efforts accomplished with the Menu Package

were so successful that we wanted to incorporate this idea into the delivered

product. With the prototype, dummy data was used for display purposes. Static

displays were sufficient for conveying the look and feel of the user interface. We

needed a way to handle periodic, dynamic data for the working systems in both the

test and mission environments and accomplished this through relative positioning

of data. Menu files were used to define the placement, size and color of a data

block. For example, a window to display command tracking is illustrated in Figure

6.

17
Commandssentfrom CFG:

Commandsrejectedby MCC:

SFMDM Inputcommandcounter:

SFMDM Commandrejectcount:

Invalid Uplink Commands:

Figure 6: Command Count Data Window

This window can be created with a text file that contains the information in Figure 7.

[] -- Menu Title

[0] -- initial value of Current_Item

[2] -- Upper Left Row

[2] -- Upper Left Column

[8] -- Lower Right Row

[30 -- Lower Right Column

[Blue_Background -- Background Color

[Yellow Foreground] -- Foreground Color

[Yellow Foreground] -- Title Color

[Light_Cyan Foreground] -- Border Color

[Bright_White_Foreground]-- Highlight Color

[Single] -- Border Type

[0]

[Commands sent from CFG:]

[0]

[Commands rejected by MCC:]

[0]

[SFMDM Input Command Counter:]

[0]

[SFMDM Command Reject Count:]

[0]

[Invalid Uplink Commands:]

Figure 7: Command Count Window File

Defining and displaying the data blocks was simple. We needed a way to update the data

that was equally as simple and flexible. Relative positioning was the solution to this. The

Command Count Window was defined as a menu:

18
Command_Count_Window : Menu_Package.Menu_Type;

Objects were declared to hold the row and column positions of the window.

Command_Count_Window_TopRow,

Command_Count_Window_Bottom_Row : Screen_Package.Row_Type;

Command_Count_Window_Left_Column,

Command_Count_Window_Right_Column:Screen_Package.Column_Type;

At start-up, the menu is defined using the Filename Manager Package to avoid the use of

OS-specific file names and reduce recompilations.

Menu_Package. Define_Menu

(The_Menu :> Command_CountWindow,

Item_List => Command_Count_Window_List,

Filename =>

CFG_Filename_Package.Get_CFG_Filename

(CFG_List => CFG_Filename_Package.MENU,

File_Tag => Command_Count_Window_File_Tag));

The menus coordinates are assigned after the external file is read in and the coordinates are

defined.

Menu_Package.Get_Menu_Coordinates

(Command_CountWindow,

Command_Count_Window_Top_Row,

Command_Count_Window_Left_Column,

Command_Count_Window_Bottom_Row,

Command_Count_Window_Right_Column);

At this point, the cursor positioning for data updates is entirely relatively to the coordinates

read in from the external menu file.

ScreenPackage. Position_Cursor

(Row :> Command_Count_Window_Top Row + i,

Column => Command_Count_Window_Right_Column - 5);

Changes to the menu file will be reflected in all data updates and data placement can be

easily altered without any system changes.

6. Conclusions

LITE flew as the primary payload on STS-64 in September of 1994. It is the fh'st lidar

system to be operated in space and the first to use lasers in space for study of the Earth's

atmospheric environment. It provided the most accurate measure of cloud top heights to

date and provided data on the depth and structure of cirrus and other thin clouds. The

success of LITE has provided new information on the distribution and characteristics of

clouds to increase our understanding of their role in the global climate system. The LITE

instrument CDR was held in April of 1989. A software team was formed in late 1990 to

19
develop systems to support integration and test, and mission. These real time systems

were developed under a tight schedule and, despite the late start, with immature system

requirements. Steps had to be taken to incorporate flexibility into the support software.

We had no choice but to design for change.

One of the clearest lessons in this discussion about "design for change" is that one must

anticipate changes before one begins the design [22]. System architecture changes in the

later stages of a software project are dangerous, costly, and common. In order to avoid

system architecture changes, the areas of the software most likely to change must be

identified and consideration given to why they will change. This process illuminates how

requirements will change and methods for accommodating these changes can be designed

into the deliverable. Life cycle modeling attempts to capture this process but required

unavailable resources such as personnel and time. The software team developed a data

driven approach to development that incorporated aspects of several models. In both

software systems developed for LITE, data was the most likely target for change.

Information hiding, low intermodule coupling achieved through modular design and

object-oriented development were key in limiting the impact of requirements changes.

Additionally, we attempted to build in modifiability by pushing the elements we knew

would change out of the code into external files and designing for dynamic data

definitions.

Acknowledgments

The author gratefully acknowledges fellow CFG and Master AT software development

team members Kerry M. Gough and Mark A. Parks. The author is also grateful to

Michael L. Nelson whose careful reviews of this paper have improved its clarity and

readability.

20
References

[ 1] David M. Winker, Richard H. Couch, and M. Patrick McCormick, "An Overview of

LITE: NASA's Lidar In-space Technology Experiment", IEEE Proceedings, Vol. 84, No.

2, February1996, pp. 164-180.

[2] B. Danette Allen, Kerry M. Gough, Mark A. Parks, "Mission Operations Command

File Generator Software Requirements Specification for Lidar In-Space Technology

Experiment (LITE)", Version 2.0, NASA LaRC Document No. LITE-04-8-01-01, May 5,

1995.

[3] "POCC Capabilities Document", NSTS-21063-POC-CAP, Rev. A, PCN-1, October

1991.

[4] "LITE Instrument Controller Software Requirements Specification", D-IC-SRS, April

1993.

[5] "LITE-1 DDCS/SFMDM Software Requirements Specification", SLMDH-0183,

McDonnell Douglas Space Systems Company, Huntsville, February 1993.

[6] Marvin V. Zelkowitz, "Resource Utilization During Software Development" NASA

Contractor Report, NASA-CR- 191609, 1988.

[7] Edward H. Bersoff and Alan M. Davis, "Impacts of Life Cycle Models on Software",

Communications of the ACM, Vol. 34, No. 8, August 1991, pp. 104- 117.

[8] Findings of the Software Process Improvement Initiative, NASA Langley Research

Center, October 12, 1997. Available:

<http://fmad-www.larc.nasa.gov/mdob/users/jctown/SPII/FindingsBfrg_4.html>

[9] Bill Curtis, Herb Krasner, and Neil Iscoe, "A Field Study of the Software Design

Process for Large Systems", Communications of the ACM, Vol. 31, No. 11, November

1988.

[10] David Lorge Parnas and Paul C. Clements, "A Rational Design Process and How to

Fake It", IEEE Transactions on Software Engineering, Vol. SE-12, No. 2, February 1986,

pp. 251 - 257.

[ 11] John McDermid, Software Engineer's Reference Book, Butterworth-Heinemann Ltd.,

1991. p. 40/3.

[12] Fred P. Brooks, "No Silver Bullet: Essence and Accidents of Software Engineering",

Computer, Vol. 20 No. 4, 1987, pp. 10 - 20.

21
[13] W. W. Royce,"ManagingtheDevelopmentof LargeSoftwareSystems:conceptsand

techniques",Proceedings oflEEE WESTCON, 1970, pp. 1 -9.

[14] Anne B. Elson, "Hardware Impacts to Software Development Strategies -The

History of the Mars Observer Payload Data Subsystem Embedded Real-time Software",

Proceedings of the AIAA Computers in Aerospace VII Conference, AIAA Paper 89-3078,

October 1989.

[15] B. Boehm, "A Spiral Model for Software Development and Enhancement",

Computer, Vol. 21, No. 5, May 1988, pp. 61 - 72.

[16] Herbert P. Woodward, "Developing Better Software: A Five Year History of

Software Engineering Advancement", NASA Goddard Space Flight Center Proceedings of

the Sixteenth Annual Software Engineering Workshop, December 1991, pp. 283 - 301.

[17] D. Harel, H. Lachover, A. Naamad, A. Pnueli, M. Politi, R. Sherman, and A. ShtulTrauring, "STATEMATE: A Working Environment for the Development of Complex

Reactive Systems ", Proceedings of the Tenth International Conference on Software

Engineering, April 1988, pp. 396- 406.

[18] P. Occelli, "Object versus Functional Oriented Design", AGARD, Aerospace

Software Engineering for Advanced Systems, May 1993.

[19] Herbert P. Woodward, "Developing Better Software: A Five Year History of

Software Engineering Advancement ", Proceedings of the Sixteenth Annual Software

Engineering Workshop, SEL-91-006, NASA Goddard Space Flight Center Software

Engineering Laboratory, December 1991, pp. 283 -301.

[20] David Alex Lamb, Software Engineering: Planning for Change, Prentice Hall, 1988,

p. 48.

[21] Theodore A. Linden, "The Use of Abstract Data Types to Simplify Program

Modifications", Contribution of the National Bureau of Standards, 1984.

[22] David L. Parnas, "Designing Software for Ease of Extension and Contraction",

Proceedings of the 3rd International Conference on S,_ftware Engineering, May 10-12,

1978, pp. 264 - 277.

22
Appendix 1: Menu Package

................................................................................

-- File Name: MENU.ADS

-- Organization: NASA - Langley Research Center (LaRC)

-- Project: LIDAR In-Space Technology Experiment (LITE)

................................................................................

-- Name/Number:

-- Menu Package (package spec)

-- Abstract:

This package provides provides a basic menuing facility. Vertical

menus can be defined, displayed,

This package relies on the device driver ANSI.SYS.

Acronyms/Abbreviations:

Dependencies:

Dynamic_StringPackage

List_Package

Keyboard_Package

Screen_Package

Global Objects:

NONE

Exceptions:

NONE

Machine/Compiler Dependencies:

NONE

with Variable_StringPackage;

with ListPackage;

with Keyboard_Package;

with Screen_Package;

package Menu_Package is

Subtype VString is Variable_String_Package.VString;

type Menu_ItemType is

record

Item_VString : VString;

Hot_Key_Position : Natural range 0

end record;

.. i00 : 0;

Procedure Dispose_VString (Menu_Item : in out Menu_Item_Type);

package Menu_List_Package is new List_Package (Item_Type => Menu_Item_Type,

Dispose => Dispose_VString);

..................................................................................

type Border_Type is (Single,Double,Double_Vertical_Border,Double Horizontal Border);

type Color_SchemeType is

record

Background_Color : Screen_Package.Background_Color_Type;

Foreground_Color : Screen_Package.Foreground_Color_Type;

23
TitleColor

Border_Color

Highlight_Color

end record;

: Screen_Package.Foreground_Color_Type;

: Screen_Package.Foreg_ound_Co!or_Type;

: Screen_Package. Foreground_Color_Type;

type Clear Screen Type is (No_Clear Screen, Clear_Screen);

Default Color Scheme : constant Color_Scheme_Fype :=(Screen_Package.Blue Background,

Screen_Package.White_Foreground,

Screen_Package.Yellow Foreground,

Screen_Package.White_Foreground,

Screen Package. Red_Foreground);

Default_Menu Upper_Left_Row : constant Screen_Package. Row_Type :- i0;

Default_Menu_Upper_Left_Column : constant Screen Package.Column_Type := i0;

Default_Menu Lower_Right_Row : constant Sc=een_Package.Row_Type := 20;

Default_Menu_Lower_Right_Column : constant Scceen_Package.Column_Type := 20;

type MenuType is limited private;

-- This procedure will draw a rectangular b)rder as specified by

-- by the diagonal coordinates below. The oorder is drawn in the

-- current foreground color. This procedure requires that the

-- video system support the extended charac:er set of the IBM PC.

-- The title will be displayed in the foreground and background

-- colors as specified when the procedure "Set_Title_Colors" is called.

procedure Draw_Border (Upper_Left_Row : l:_ Screen Package.Row Type :=

Default_Menu_Upper_Left_Row;

Upper_Left_Column : in Screen_Package.Column_Type :=

Default_Menu_Upper_Left_Column;

Lower_Right_Row : in Screen_Package.Row_Type :-

D,_fault_Menu_LowerRight_Row;

Lower_Right_Column : in Screen_Package.Column_Type :=

D,_fault_Menu_Lower_Right_Column;

Color_Scheme : i_I Color_Scheme_Type :

D4_fault_Color_Scheme;

Title : l_l String := "',;

Border_Style : i:_ Border_Type := Single;

Clear_Mode : ill Clear_Screen_Type :=

Nc,_Clear_Screen);

-- Define a Menu ...........................................................

procedure DefineMenu (TheMenu

Item_List

Current_Item

UpperLeftRow

-- This procedure defines a menu containing a list of items with the given

-- upper left & lower right coordinates, color scheme, title, border style.

-- If the Current Item field is left to its default, you cannot execute a

-- Read_Menu command without raising a constraint error!

: in out Menu_Type;

: ii. Menu_List_Package. List_Type;

: i_ Natural := 0;

: il Screen_Package.Row_Type :=

DEfault_Menu_Upper_Left_Row;

Upper_Left_Column : i: Screen_Package.Column_Type :=

Default_Menu_Upper_Left_Column;

Lower_Right_Row : il Screen_Package.Row_Type :=

D(fault_Menu_Lower_Right_Row;

Lower_Right_Column : il Screen_Package.Column_Type :=

D(fault_Menu_Lower_Right Column;

Color_Scheme : in Co]or_Scheme_Type := Default Color_Scheme;

Title : in St_ing := "";

24
Border_Style : in Border_Type :: Single);

-- Define a Menu ...........................................................

-- This procedure defines a menu containing a list of items with the given

-- upper left & lower right coordinates, color scheme, title, border style.

-- The parameters are read from the file specified by the user.

procedure Define Menu (The_Menu : in out Menu Type;

Item_List : in out Menu_List_Package. List Type;

Filename : in String);

-- Change specific attributes of an existing menu ..........................

-- reposition where the menu is on the screen

procedure Set_Menu_Coordinates (The_Menu : in out Menu Type;

Upper_Left_Row : in Screen_Package.Row Type;

Upper_Left_Column : in Screen_Package.Column_Type;

Lower_Right Row : in Screen Package.Row_Type;

Lower_Right_Column: in Screen_Package.Column_Type);

-- changes the list of items which are available for The Menu

procedure Set Menu_Item_List (The_Menu : in out Menu_Type;

Item_List : in Menu_List_Package. List Type);

procedure Set_Color_Scheme_Type (The_Menu : in out Menu Type;

Color Scheme : in Color_Scheme_Type);

procedure Set Menu_Title (The_Menu : in out Menu Type;

Title : in String);

procedure Set_Menu_Border Style (The_Menu : in out Menu Type;

Border Style : in Border_Type);

procedure Set_Current_Item (The_Menu : in out Menu_Type;

New Item : in Natural := 0) ;

-- Define a Color Scheme ...................................................

function Define_Color_Scheme(Background_Color:in Screen_Package.Background_Color_Type;

Foreground_Color:in Screen_Package. Foreground_Color_Type;

Title_Color :in Screen_Package. Foreground_Color_Type;

Border_Color :in Screen Package.Foreground_Color_Type;

Highlight_Color :in Screen_Package.Foreground_Color_Type)

return Color_Scheme_Type;

-- Request specific info about a menu ......................................

procedure Get_Menu_Coordinates (The Menu : in Menu_Type;

Upper_Left Row : out Screen Package.Row_Type;

Upper_Left_Column : out Screen_Package.Column_Type;

Lower_Right_Row : out Screen_Package.Row_Type;

Lower_Right Column : out Screen Package.Column_Type);

Function Get Menu_Color Scheme (The_Menu : in Menu Type) return Color_Scheme_Type;

Function Get_Menu_Border_Style (The_Menu : in Menu_Type) return Border_Type;

Function Get_Menu_Title (The Menu : in Menu_Type) return VString;

25
-- Initialize and append Items to an Item List .............................

procedure Initialize_Item List (Item_List : in out Menu List Package. List Type);

procedure Append_Item (The Item : in String;

With_Hot Key_Position : in Natural := 0;

To_List : in out Menu_List_Package.List Type);

procedure insert Item( The_Item : in String;

With_Hot Key_Position : in Natural :- 0;

At Position : in out Natural;

In List : in out Menu_List_Package.List Type);

procedure Delete_Item( At Position : in out Natural;

From List : in out Menu List_Package. List Type);

-- returns the number of items associated with the specified menu

function Number Of Items( In_Menu : in Menu_Type) return Natural;

-- Display Menu ............................................................

procedure Display Menu (The_Menu : in Menu_Type);

-- Hide Menu ...............................................................

procedure Hide_Menu (The_Menu : in Menu_Type;

Fill Color : in Screen Package.Background_Color Type);

-- Read Menu ...............................................................

procedure Read_Menu (The_Menu : in out Menu_Type;

The_Choice : out Naturall;

-- Read Menu ...............................................................

-- This version of Read_Menu adds two important funtions: one, it allows the

-- use of a predefined array of special keys as additional exits from the

-- menu, and two, it allows the user to define a special case for the use

-- of the escape key.

procedure Read_Menu (The_Menu : in )ut Menu Type;

Legal_Special_Keys : in {eyboard_Package. Special_Keys Array_Type;

Special_Key_Hit : out Boolean;

EnteredSpecial_Key: out Keyboard_Package. Special_Keys_Type;

Escape_Key Hit : out Boolean;

The Choice : out Natural);

-- Undefine Menu ...........................................................

procedure Undefine_Menu (The Menu : in out Me:lu Type);

-- Undefine Menu ...........................................................

-- Remove menu definition from memory ...................................

-- This version allows user to also clear :he menu_list contained in the

-- user's application code with deallocati,)n of VStrings.

procedure Undefine_Menu (The Menu : in out Me:lu_Type;

The_List : in out Me_lu_List_Package. List_Type);

26
private

type Menu_Structure is

record

Title

Item_List

ItemList_Length

Current_Item

HighlightBar

First_Window_Item

Last_Window_Item

Upper Left_Row

Upper_Left_Column

• VString;

: Menu_List_Package. List_Type;

: Natural := 0;

: Natural := 0;

: Natural := 0;

: Natural := 0;

: Natural :- 0;

: Screen_Package. Row_Type := Default_Menu_Upper_Left_Row;

: Screen_Package. Column Type :=

Default_Menu_Upper_Left_Column;

Lower_RightRow : Screen_Package. Row_Type :- Default_MenuLower_Right_Row;

Lower_Right Column : Screen Package.Column_Type ::

Default_Menu_Lower_Right_Column;

Color_Scheme • Color_Scheme_Type := Default_Color_Scheme;

Border Style : Border Type := Single;

end record;

type Menu_Type is access Menu_Structure;

end Menu_Package;

27
-- File Name: MENU.ADB

-- Organization: NASA - Langley Research Center (LaRC)

-- Project: LIDAR In-Space Technology E_periment (LITE)

................................................................................

-- Name/Number:

-- Menu_Package (package body)

-- Abstract:

-- This package provides provides a basic memuing facility. Vertical

-- menus can be defined, displayed, read, and removed from memory.

-- Acronyms/Abbreviations:

-- Dependencies:

-- DOS

-- GetToken

-- Text_IO

-- Keyboard Package

-- Screen_Package

-- Unsigned

-- Unchecked_Conversion ! !! not required !! !

-- Global Objects:

-- NONE

-- Exceptions:

-- NONE

-- Machine/Compiler Dependencies:

-- NONE

with Get_Token;

with Text_IO;

with Keyboard_Package;

wfth Screen_Package;

with Unsigned;

with UncheckedConversion;

with Unchecked_Deallocation;

package body Menu_Package is

-- Functions for explicit type conversions.

function To Character is new Unchecked Conver_ion (Source -> Unsigned. Byte,

Target => Character);

function Convert Special_Key To Char is new Uhchecked_Conversion

(Source => Keyboard_P_ckage.Special_Keys Type,

Target => Character).

-- for undefining menus

procedure Dispose Of Menu is new Unchecked De_llocation( Menu Structure, Menu Type) ;

Single_Upper Left Corner : constant Characte] := To Character( 218);

Single_Upper_Right_Corner : constant Characte] := To_Character( 191);

Single Lower Left Corner : constant Characte] := To Character( 192);

Single Lower Right Corner : constant Characte_ := To Character( 217);

28
Single_Vertical : constant Character := To_Character( 179);

Single_Horizontal : constant Character := To Character( 196);

Double_Upper_Left_Corner : constant Character :- To Character( 201);

Double_Upper_Right_Corner : constant Character := To_Character( 187);

Double_Lower_Left Corner : constant Character := To_Character( 200);

Double_Lower Right_Corner : constant Character := To_Character( 188);

Double Vertical_Upper Left Corner : constant Character := To Character( 214);

Double_Vertical Upper_Right_Corner : constant Character := To Character( 183);

Double_Vertical_Lower_Left_Corner : constant Character := To_Character( 211);

Double_Vertical_Lower_Right Corner : constant Character : To_Character( 189);

Double_Horizontal_Upper_Left_Corner : constant Character := To Character( 213);

Double Horizontal Upper Right Corner : constant Character := To Character( 184);

Double_Horizontal_Lower_Left_Corner : constant Character := To Character( 212);

Double_Horizontal Lower_Right_Corner : constant Character := To_Character( 190);

Double_Vertical : constant Character := To_Character( 186);

Double_Horizontal : constant Character := To_Character( 205);

Highlight_Row_Cursor Position : Screen_Package. Row_Type;

Highlight_Column Cursor_Position : Screen Package.Column Type;

-- Arithmetic/Logical function renamings for Row_Types and Column Types defined in

-- Screen_Package.

function "+" (Rowl, Row2 : in Screen Package. Row_Type) return Screen_Package.Row_Type

renames Screen_Package."+";

function .... (Rowl, Row2 : in Screen_Package. Row Type) return Screen_Package.Row Type

renames Screen_Package.' ....;

function ">=" (Rowl, Row2 : in Screen_Package.Row_Type) return Boolean renames

Screen_Package.">=";

function "+" (Columnl,Column2:in Screen_Package. Column_Type) return

Screen Package. Column_Type renames Screen_Package."+";

function ..... (Columnl, Column2 : in Screen Package.Column_Type) return

Screen_Package.Column_Type renames Screen_Package.' ....;

function ">=" (Coiumnl, Column2 : in Screen Package.Column Type) return Boolean renames

Screen_Package.">=";

function "/" (Columnl, Column2 : in Screen Package.Column_Type) return

Screen_Package.Column_Type renames Screen Package."/";

Procedure Dispose VString (Menu_Item : in out Menu_Item_Type) IS

Begin

Variable_String Package. Destroy(Menu_Item. Item_VString);

end Dispose_Vstring;

29
function MIN (Numl, Num2

begin

if Numl <: Num2 then

return Numl;

else

return Num2;

end if;

: in Natural) return Natural is

end MIN;

function MAX (Numl, N_m2 : in Natural)

begin

if Numl > Num2 then

return Numl;

else

return Num2;

end if;

return Natural is

end MAX;

function Menu_Window_Length (The Menu : in Menu Type) return Natural is

begin

if The_Menu.Upper_Left_Row >- The_Menu. Lower_Right_Row then

return 0;

else

return Natural (The_Menu. Lower_Right_Row - The_Menu.Upper_Left_Row - I);

end if;

end Menu_Window_Length;

function Menu_Window_Width (The_Menu : in Menu_Type) return Natural is

begin

if The_Menu. Upper_Left_Column >= The Menu.],ower_Right_Column then

return 0;

else

return Natural (The_Menu. Lower_Right_Column - The_Menu.Upper_Left_Column - i);

end if;

end Menu_Window_Width;

procedure Internal_Draw Border (Upper_Left_Ro_' : in Screen Package. Row Type

Default_Menu_Upper_Left_Row;

Upper Left Column : il Screen Package.Column Type :=

Default_Menu_Upper_Left_Column;

Lower_Right Row : ir Screen Package.Row_Type :=

D(fault_Menu_Lower_Right_Row;

3O
Lower_Right_Column : in Screen Package.Column_Type :

Default_Menu_Lower_Right_Column;

Color_Scheme • in Color Scheme Type :

Default_Color Scheme;

Title • in String :- "";

Border Style • in Border Type := Single;

Clear_Mode : in Clear Screen Type :=

No_Clear_Screen) is

Blank_Line : constant String( Positive (Upper_Left_Column + I) .. Positive

(Lower_Right Column - i)) := (others => ' ');

Horiz or Vert Bar : Character; -- jnr, 9/13/91

Top_Row : Screen_Package.Row_Type;

Bottom_Row : Screen_Package.Row_Type;

Left_Column : Screen_Package.Column_Type;

Right_Column : Screen_Package.Column_Type;

Available_Positions : Screen_Package.Column Type;

Start_Offset : Screen_Package.Column_Type;

Saved_Foreground_Color : Screen_Package. Foreground_Color_Type;

Saved_BackgroundColor : Screen_Package. Background_Color_Type;

begin -- Internal_Draw_Border

-- Save the cursor position and colors so that they may be restored later.

Screen_Package. Save Cursor_Position;

Saved_Foreground_Color := Screen_Package. Present_Foreground_Color;

Saved_Background_Color := Screen_Package. Present_Background_Color;

-- Set the border color.

Screen_Package. Set Foreground_Color (Color_Scheme. Border_Color);

Screen_Package. Set Background_Color (Color_Scheme. Background_Color);

-- Position the cursor to the upper left corner and draw the

-- appropriate upper left corner symbol.

Screen_Package. Position_Cursor (Upper_Left_Row, Upper_Left_Column) ;

-- set horizontal bar character

case Border_Style is

when Single >

Screen_Package. Put (Single_Upper_Left_Corner);

Horiz or Vert_Bar :- Single_Horizontal;

when Double >

Screen_Package. Put (Double_Upper_Left_Corner);

Horiz or Vert_Bar := Double Horizontal;

when Double_Vertical_Border ->

Screen_Package. Put (Double_Vertical_Upper_Left_Corner);

Horiz or Vert_Bar := Single_Horizontal;

when Double_Horizontal Border =>

Screen_Package.Put (Double_Horizontal_UpperLeftCorner);

Horiz or Vert_Bar := Double_Horizontal;

end case;

-- Print the horizontal symbols for the top part of the border.

Left_Column := Upper_Left_Column + i;

Right_Column := Lower_Right_Column - i;

for Horizontal_Bar in Left_Column .. Right Column loop

Screen Package. Put (Horiz or Vert_Bar);

end loop;

-- Draw the appropriate upper right corner symbol.

31
case Border Style is

when Single =>

Screen_Package. Put (Single Upper Richt_Corner);

when Double =>

Screen Package. Put (Double Upper Richt_Corner);

when Double Vertical Border =>

Screen_Package.Put (Double Vertical_Upper_Right Corner);

when Double_Horizontal_Border =>

ScreenPackage. Put (DoubleHorizontalUpper_RightCorner

end case;

-- If the user requests a title for this border, then determine how to

-- center the title in the border. If the title is longer than than the

-- border, then the title will be truncated. If the user allows the default

-- null ....as the title, then no title will be printed.

if Title'Length > 0 then

-- Set up the title foreground color.

Screen Package. Set_Foreground Color (Color_Scheme. Title Color);

Available Positions := Lower Right Column - Upper Left_Column - i;

if Available_Positions >= Screen_Package. Column_Type(Title'Length) then

Start_Offset := (Available Positions - Screen_Package. Column Type

(Title'Length)) / 2 _ i;

Screen_Package. Position_Cursor

(Upper_Left_Row, Upper_Left Column+Start_Offset);

Screen_Package.Put( Title);

else

Screen_Package.Position_Cursor (Uppec Left Row, Upper_Left_Column + i);

Screen Package.Put( Title( 1 .. Natucal (Available Positions)));

end if;

end if;

-- Restore the border foreground color.

Screen Package. Set_Foreground_Color (Color Scheme. Border_Color);

-- Position the cursor to the lower left side of the menu so that the

-- lower left corner symbol may be print _d.

Screen_Package. Position_Cursor (Lower_Righ: Row, Upper Left Column);

case Border Style is

when Single =>

Screen Package. Put (Single Lower Lefn_Corner);

when Double =>

Screen_Package. Put (Double_Lower Lefu Corner);

when Double_Vertical_Border =>

Screen Package. Put (Double Vertical [,ower Left_Corner);

when Double Horizontal_Border =>

Screen_Package. Put (Double_HorizontaiLower_LeftCorner);

end case;

-- Print the horizontal symbols for the ]_ottom part of the border.

for Horizontal_Bar in Left_Column .. Right Column loop

Screen_Package. Put Horiz or Vert Bar);

end loop;

-- Print the lower rlght corner symbol f(r the menu.

-- set vertical bar character

case Border_Style is

when Single =>

Screen_Package. Put (Single Lower Right Corner);

Horiz or Vert_Bar :- Single Vertical;

32
when Double >

Screen_Package. Put (Double_Lower_Right_Corner);

Horiz or Vert_Bar := Double Vertical;

when Double Vertical_Border =>

ScreenPackage. Put (DoubleVertical_LowerRight_Corner);

Horiz or Vert_Bar := Double_Vertical;

when Double_Horizontal_Border ->

Screen_Package.Put (Double Horizontal Lower_Right_Corner);

Horiz or Vert_Bar :- Single Vertical;

end case;

-- Print both the left and right vertical sides of the menu bar.

Top_Row := Upper Left_Row + i;

Bottom_Row : Lower_Right_Row - !;

for Vertical_Bar in Top_Row .. Bottom_Row loop

Screen_Package. Position Cursor (Vertical Bar, Upper_Left_Column);

Screen_Package. Put (Horiz or Vert_Bar);

if Clear_Mode = Clear Screen then

Screen_Package. Put( Blank_Line);

end if;

Screen_Package. Position Cursor (Vertical_Bar, Lower_Right_Column);

Screen_Package. Put (Horiz or Vert_Bar);

end loop ;

-- Restore the saved cursor position.

Screen_Package.Restore_Cursor_Position;

-- Restore the original foreground and background colors.

Screen_Package.Set_Foreground_Color (Saved_Foreground Color);

Screen Package.Set Background_Color (Saved Background_Color) ;

end Internal_Draw_Border;

procedure Draw_Border (Upper Left_Row : in Screen_Package.Row_Type :=

Default_Menu_Upper_Left_Row;

Upper_Left_Column : in Screen_Package.Column_Type :=

Default_Menu_Upper_Left_Column;

Lower_Right_Row : in Screen_Package.Row Type :=

Default_Menu_Lower_Right_Row;

Lower Right_Column : in Screen_Package.Column_Type :=

Default_Menu_Lower_Right_Column;

Color Scheme : in Color_Scheme_Type:= Default_Color Scheme;

Title : in String :.... ;

Border_Style : in Border Type := Single;

Clear_Mode : in Clear Screen_Type := No Clear Screen) is

begin -- Draw_Border

-- Save the cursor position and colors so that they may be restored later.

ScreenPackage.Get_Screen;

Internal_Draw_Border (Upper_Left_Row, Upper_Left_Column, Lower_Right_Row,

Lower_Right_Column,

Color_Scheme, Title, Border_Style,Clear_Mode);

Screen_Package.Release_Screen;

33
end Draw_Border;

-- The following adjusts the value of The _tenu. Current Item if it is

-- too large, and also assigns values to t_e following fields in The_Menu:

-- First Window_Item

-- Last Window_Item

procedure Determine_Items In Window (The Menu : in out Menu Type) is

Temp_Window Length : Natural :- 0;

begin

-- make sure Current_Item is not beyond the end of the list

if The_Menu. Current_Item > The_Menu. Item_List_Length then

The Menu. Current_Item :- The_Menu. Item_List_Length;

end if;

Temp_WindowLength : Menu_Window_Length (The_Menu);

-- if there are items and space to display them all, then do so.

if The Menu. Item List Length in 1 .. Temp_Window_Length - 1 then

The_Menu. First_Window_Item := i;

TheMenu. Last_Window_Item := The_Menu.ltem_List_Length;

-- there are items but only space to display some of them.

elsif (The_Menu. Item_List_Length > 0) and (Temp Window Length > 0) then

-- Make the Current_Item the top item in the window. If Current Item : 0

-- the top item will be item #i.

The_Menu. First_Window_Item :: MAX (i, The_Menu. Current_Item);

-- Determine last item that will fit in the window, but don't go

-- beyond the end of the Item_List.

The_Menu. Last_Window_Item := MIN (The Menu. Item_List_Length,

The_Menu. First_Window_Item+Temp_Window_Length-l);

-- If we are at the bottom of the list and the window is not full,

-- move top of window above the Current_Item.

The_Menu. First_Window_Item : The_Menu._ast_Window_Item+l-Temp_Window_Length;

else -- no items or no space.

The Menu. First_Window Item := 0;

The Menu. Last_Window_Item :- 0;

end if;

end Determine_Items In Window;

procedure Define_Menu (The_Menu

Item_List

Current_Item

Upper_Left_Row

Upper Left_Column

Lower_RightRow

: i_ out Menu Type;

: i_l Menu_List_Package. List_Type;

: i_i Natural := 0;

: i_ Screen_Package. Row Type :=

D+_fault_Menu_Upper Left Row;

: i:L Screen Package.Column Type :=

D_fault Menu_Upper Left_Column;

: iI_ Screen_Package.Row Type :-

Dc_fault_Menu_Lower_RightRow;

Lower_Right_Column : ii Screen_Package. Column_Type :-

D(_fault_Menu Lower Right_Column;

34
Color_Scheme

Title

Border Style

: in Color Scheme Type

DefaultColorScheme;

: in String

: in Border Type

: = ,, ,,;

: Single) is

VTitle : VString;

begin

-- Allocate storage for the new menu, if required

Undefine_Menu (The Menu);

The_Menu := new Menu_StrucZure;

-- Convert title to a "Variable String"

Variable_String_Package. Make_VString (The_String => Title, New_VString => VTitle);

-- Define the various fields in the menu

The_Menu. Current_Item := Current_Item;

The Menu.Upper_Left Row :- Upper_Left_Row;

The_Menu.Upper Left_Column : Upper_Left_Column;

The_Menu. Lower_Right_Row : Lower_Right_Row;

The_Menu. Lower_Right Column :- Lower Right_Column;

The_Menu. Color_Scheme :- Color Scheme;

The_Menu. Title := VTitie;

The Menu. Border Style :- Border_Style;

Set Menu_Item_List (The_Menu > The_Menu, Item_List -> Item_List);

-- Determine which items to display, based on Current_Item.

Determine_Items In Window (The_Menu => The_Menu);

end Define_Menu;

procedure Define_Menu (The Menu : in out Menu_Type;

Item_List : in out Menu_List Package.List Type;

Filename : in String) is

Length • Natural;

Hot_Key_Position : Natural;

Token : String (i .. 80);

Menu File : Text_Io. File_Type;

VTitle : VString;

begin -- Define_Menu

Text_Io. Open (File => Menu_File, Mode -> Text_Io. In File, Name => Filename);

-- Allocate storage for the new menu, if needed

Undefine Menu (The_Menu);

The_Menu := new Menu_Structure;

Get_Token (Menu_File, Token, Length);

-- Convert title to a "Dynamic String"

Variable String Package.Make_VString(The_String->Token(l..Length),New_VString >VTitle);

The_Menu.Title := VTitle;

-- Define the various fields in the menu

Get_Token (Menu_File, Token, Length);

The_Menu.Current Item :- Natural'VALUE (Token (i .. Length));

Get_Token (MenuFile, Token, Length);

The_Menu.Upper_Left Row :- Screen Package. Row_Type'VALUE (Token (I .. Length));

Get_Token (Menu_File, Token, Length);

35
The_Menu.Upper_Left_Column :: Screen_Packaze.Column_Type'VALUE (Token (l..Length));

GetToken (MenuFile, Token, Length);

The Menu. Lower_Right_Row := Screen Package.Row Type'VALUE (Token (i .. Length));

GetToken (Menu_File, Token, Length);

The_Menu. Lower Right_Column := Screen Pack_ge. Column_Type'VALUE(Token (l..Length));

-- Set the color scheme

Get_Token (Menu_File, Token, Length);

The_Menu.Color Scheme. Background Color :=Screen Package. Background_Color_Type'VALUE

(Token (i .. Length));

Get_Token (Menu_File, Token, Length);

The_Menu.Color_Scheme. Foreground_Color:= Szreen_Package. Foreground Color_Type'VALUE

(Token (i .. Length));

Get_Token (Menu_File, Token, Length);

The Menu. Color_Scheme. Title_Color:= Screen_Package.Foreground_Color_Type'VALUE

(Token (i .. Length));

Get_Token (Menu_File, Token, Length);

The_Menu.Color_Scheme. Border Color := Screen_Package. Foreground_Color_Type'VALUE

(Token (I .. Length));

Get_Token (Menu_File, Token, Length);

The_Menu.Color_Scheme. Highlight_Color := Screen_Package. Foreground Color Type'VALUE

(Token (I .. Length));

GetToken (MenuFile, Token, Length);

The_Menu.Border_Style :- Border Type'VALUE (Token (i .. Length));

Initialize_Item_List( Item_List);

-- read the items into list

while not Text_IO.End of File (Menu File) loop

Get_Token (MenuFile, Token, Length);

Hot_Key_Position := Natural'VALUE (Token (i .. Length));

GetToken (Menu_File, Token, Length);

Append_Item (Token (i .. Length), Hot Key_Position, Item_List);

end loop;

Set_Menu_Item_List (The_Menu, ItemList);

-- Determine which items to display, bas,_d on Current_Item.

Determine_Items In Window (The_Menu => The Menu);

Text_IO.Close (Menu File);

exception

when Text_Io.Name_Error =>

Screen_Package. Put ("Menu file => " & F: lename & " not found");

raise;

when Constraint_Error =>

Text_IO.Close (Menu_File);

Screen_Package. Put ("Invalid field valu{_ in Menu Initialization File");

raise;

when others :>

Text IO.Close (Menu File) ;

Screen_Package. Put ("Unanticipated erro] in subprogram Define Menu");

raise;

end Define_Menu;

procedure Set_Menu_Coordinates (The_Menu

Upper_Left_RoY

Upper_Left Column

Lower_Right_R(w

: in out Menu Type;

: in Screen Package. Row_Type;

: in Screen Package. Column Type;

: in Screen_Package. Row_Type;

36
Lower_Right_Column : in Screen_Package. Column_Type) is

begin

The_Menu.Upper_Left_Row := Upper_Left_Row;

The_Menu.Upper_Left_Column := Upper Left_Column;

The_Menu. Lower_Right_Row := Lower_Right_Row;

The Menu. Lower_Right_Column := Lower Right_Column;

-- Changing coordinates may change window size

Determine Items In Window (The_Menu => The_Menu);

end Set_MenuCoordinates;

procedure Set_Menu Item List (The_Menu : in out Menu_Type;

Item_List : in Menu_List_Package. List_Type) is

begin

The_Menu.ltem_List :- Item_List;

The_Menu.item_List_Length :

Menu_List_Package. Length_Of(The_List >The_Menu. Item_List);

-- Changing Item List may affect number of items available for display

Determine_Items In Window (The_Menu => The Menu);

end Set_Menu Item_List;

procedure Set_Color_Scheme Type (The_Menu : in out Menu Type;

Color_Scheme : in Color Scheme_Type) is

begin

The Menu.Color Scheme := Color_Scheme;

end Set_Color_Scheme_Type;

procedure Set_Menu Title (The Menu : in out Menu_Type;

Title : in String) is

VTitle : VString;

begin

-- Convert title to a "Variable String"

Variable String_Package. Make_VString (The String => Title, New_VString => VTitle);

The Menu.Title := VTitle;

end Set_Menu_Title;

procedure Set_Menu_Border_Style (The_Menu - in out Menu_Type;

Border_Style : in Border Type) is

begin

The_Menu. Border_Style := Border_Style;

end Set_Menu_Border_Style;

37
procedure Set_Current_Item (The_Menu : in out Menu Type;

New Item : in Natural := 0) is

begin

The_Menu. Current_Item : New_Item;

end Set_Current Item;

function Define_Co!or Scheme(Background Color:in Screen_Package.Background_Color Type;

Foreground Color:in Screen Package.Foreground_Color_Type;

Title Color :in Screen_Package.Foreground Color_Type;

Border_Color :in Screen Package. Foreground_Color Type;

Highlight_Color :in Screen_Package. Foreground Color Type)

return Color_SchemeType is

begin

return (Background_Color,Foreground_Color,Title Color,

Border Color,Highlight_Color);

end Define_Color Scheme;

procedure Get Menu_Coordinates(The_Menu : in Menu_Type;

Upper_Left_Row : out Screen Package. Row_Type;

Upper_Left_Column : out Screen Package. Column Type;

Lower_Right Row : out Screen_Package. Row_Type:

Lower_Right_Column : out Screen Package. Column_Type) is

begin

Upper_Left_Row := The_Menu.Upper_Left_Row;

Upper_Left Column := The Menu.Upper Left Column;

Lower Right Row := The_Menu.Lower_Right Row;

Lower_Right_Column := The_Menu.Lower_Right_Column;

end GetMenuCoordinates;

function Get_Menu_Color Scheme (The_Menu : in Menu_Type) return Color_Scheme_Type is

begin

return TheMenu. Color_Scheme;

end Get_Menu_Color_Scheme;

function Get_Menu_Border_Style (The_Menu : in Menu Type) return Border_Type is

begin

return The_Menu. Border Style;

end Get_Menu_Border Style;

function Get_Menu_Title (The Menu : in Menu T['pe) return VString is

begin

38
return TheMenu. Title;

end Get_MenuTitle;

procedure Initialize Item_List (Item_List : in out Menu List Package. List Type) is

begin

Menu_List_Package. Clear (The_List > Item_List);

end Initialize_Item_List;

procedure Append_Item (The_Item • in String;

with_Hot_Key_Position : in Natural := 0;

To_List • in out Menu_List Package.List_Type) is

List_Position : Natural := Menu_List_Package.Length Of( The_List => To List

Temp_VString : VString;

Temp_Item : Menu_Item_Type;

+ i;

begin

-- Convert the Standard. String The Item to a variable string prior to asslgnment

Variable_String Package.Make_Vstring

(The String=>The_Item,New_VString=>Temp_VString);

Temp_Item. Item VString :- Temp_VString;

-- Make sure position of hot key is valid.

if With Hot_Key Position>Variable_String_Package.Length_Of(Temp_Item. Item_VString)

then

Temp_Item. Hot_Key_Position := 0;

else

Temp_Item. Hot_Key_Position : With_Hot_Key_Position;

end if;

Menu_List_Package. Insert_Item (The_Item => Temp_Item, In List => To_List,

At Position => List Position);

end Append_Item;

-- Return the item following the Current_Item from the menu Item List.

-- Wrap around to the first if Current_Item is at the end of the list.

function Next Item (Of Menu : in Menu_Type) return Natural is

begin

if Of_Menu. Current_Item = 0 then

return 0;

elsif Of_Menu. Current_Item < Of_Menu. Item_List_Length then

return Of_Menu. Current_Item + i;

else

return i;

end if;

end Next_Item;

39
procedure Insert Item( The_Item : in String;

With_Hot Key_Position : in Natural := 0;

At_Position : in out Natural;

In List : in out Menu_List Package.List Type) is

Temp_VString : VString;

Temp_Item : Menu item_Type;

begin

-- Convert the Standard. String The_Item to a variable string prior to assignment

Variable String Package. Make VString(

The_String->The_Item,New_VString=>Temp_VString);

Temp Item. Item_VString := Temp_VString;

-- Make sure position of hot key is valid.

if With_Hot_Key_Position>Variable_String P_ckage. Length_Of(Temp_Item. Item_VString)

then

Temp_Item. Hot_Key_Position := 0;

else

Temp_item. Hot_Key_Position := With Hot_Key_Position;

end if;

Menu_List_Package. Insert_Item( The_Item >Temp Item, In_List=>In_List, At_Position

=> At_Position);

end Insert_Item;

---- ::= --:::_ ================================================= :::_ _:::-

procedure Delete_Item( At Position : in out Natural;

From_List : in out Menu List Package. List Type) is

begin

Menu_List_Package. Delete_Item( From_List =2 From_List, At_Position -> At_Position);

end Delete_Item;

function Number Of Items( In_Menu : in Menu_TT/pe ) return Natural is

begin

return In_Menu. Item_List_Length;

end Number Of Items;

-- Return the item preceding the Current_It,_m from the menu Item_List.

-- Wrap around to the last if Current_Item :.s the first item in the list.

function Prev_Item (Of Menu : in Menu Type) r_turn Natural is

begin

if Of_Menu. Current_Item _ 0 then

return 0;

elsif Of Menu. Current_Item = 1 then

return Of_Menu. Item_List_Length;

else

return Of_Menu. Current_Item - i;

end if;

4O
end Prey_Item;

-- Returns true if The Item_Number is within the menu's display window bounds

function Is In Window (The_Item Number : in Natural;

Of_Menu • in Menu_Type) return boolean is

begin

if The Item_Number = 0 then

return false;

--elsif The_Item_Number >- Of_Menu.First Window item and The_Item_Number <=

--Of_Menu. Last_Window_Item then

elsif The_Item Number in Of_Menu. First_Window_Item .. Of_Menu. Last_Window_Item then

return true;

else

return false;

end if;

end Is In Window;

-- Displays a menu item in the given colors bounded by the given maximum width.

-- Display occurs at the current screen cursor position.

procedure Display_Item (The_Item : in Menu_Item_Type;

Background_Color : in Screen_Package. Background_Color_Type;

Foreground_Color : in Screen_Package. Foreground_Color_Type;

Highlight_Color : in Screen_Package. Foreground_Color_Type;

Width : in Natural) is

Temp Length: Natural :=

MIN(Width,Variable_String Package.Length_Of(The item. Item_VString));

Temp_Text : constant String := Variable_String_Package.Text_Of

(The Item. Item VString) (i .. Temp Length);

begin

Screen_Package. Save_Cursor_Position;

-- Set foreground and background colors for text

ScreenPackage. SetBackground_Color (Background_Color);

Screen_Package. Set Foreground_Color (Foreground_Color);

-- print entire string

Screen_Package. Put (Temp_Text);

-- if there is a hot key position, overprint that character in the

-- highlight color

if (The Item. Hot_Key_Position > 0) and (Screen Package.Foreground_Color_Type'POS

(Foreground_Color)/=Screen_Package. Foreground_Color Type'POS (Highlight Color))

then

Screen Package. Set_Foreground Color (Highlight Color);

Screen_Package. Restore_Cursor_Position;

if (The_Item. Hot_Key Position > i) then

Screen_Package.Move_Cursor Forward (Screen Package.Column_Type

(The Item. Hot Key_Position - !));

end if;

Screen Package. Put (Temp Text (The_Item. Hot_Key Position));

end if;

41
Screen_Package.Restore_Cursor_Position;

end Display Item;

-- Quickly moves highlight bar to another position in current display window.

-- NOTE: Assumes the old highlighted position and the new highlighted Current_Item

-- are within the current display window, and does not perform any checking.

procedure Fast Bar_Move (The_Menu : in out Menu Type) is

Temp_Window_Width : Natural := Menu_Window_Width (The_Menu);

Temp Item : Menu_Item_Type;

Temp_List_Index : Natural;

begin

-- Erase old highlight bar, if one exists

if The Menu. Highlight Bar > 0 then

Screen Package. Position_Cursor (The_Menu. Upper_Left Row +

Screen_Package. RowType

(The Meru. Highlight_Bar -

The_Menu. First_Window Item + i),

The_Menu. Upper_Left_Column + i};

Temp_List Index := The Menu.Highlight_Par;

Menu List_Package.Get Item (The_Item -> Temp_Item, From_List >

The_Menu. Item List,

At_Position => Temp_List Index);

Display_Item (The_Item => Temp Item,

Background_Color => The_Menu. Color_Scheme.Background_Color,

Foreground_Color _> The Menu. Color Scheme. Foreground_Color,

Highlight Color => The_Menu. Color Scheme. Highlight_Color,

Width => Temp_Nindow_Width);

end if;

-- Write Current_Item in "reversed colors"

Highlight_Row_Cursor_Position := The_Menu. Upper_Left_Row +

Screen_Package. Row_Type (The_Menu.Current Item -

The_Menu. First Window Item + !);

Highlight_Column_Cursor Position := The_Me%u.Upper_Left_Column + i;

Screen Package. Position Cursor (Highlight {ow Cursor Position,

Highlight Zolumn Cursor_Position);

Temp_List Index := The_Menu. Current_Item;

Menu_List_Package. Get_Item (The_Item :> Tenp_Item, From_List => The_Menu. Item_List,

At_Position => Temp List_Index);

Display_Item (The_Item -> Temp Iten,

Background Color => Screen P{ckage.White Background,

Foreground Color => Screen_P_ckage. Black Foreground,

Highlight_Color => Screen_P_ckage.Black Foreground,

Width => Temp_Win_ow_Width);

The Menu.Highlight_Bar := The Menu.Current Item;

end Fast_Bar_Move;

...............................................................................

...............................................................................

-- Displays the menu items in the "current lisplay window", i.e. those items

-- in the item list postions First Window I :em..Last_Window_item.

42
-- The Current_Item, if any, is displayed with the highlight bar on it.

procedure Display Menu Items (Of_Menu : in Menu Type) is

Temp Window_Width: Natural := Menu_Window_Width (Of Menu);

Temp Blank String: constant String (I .. Temp_Window_Width) := (others -> ' ');

TempRow : Screen_Package. Row_Type :=Of_Menu. Upper_Left_Row+l;

Temp_Col :constant Screen Package. Column_Type:=Of_Menu.Upper_Left_Column+l;

Temp_Item : Menu_Item_Type;

Temp_List_Index : Natural;

begin

.... Blank" the window part of the menu

Screen_Package. Set_Foreground Color (Of Menu.Color Scheme. Foreground_Color);

Screen Package. Set Background_Color (Of_Menu.Coior_Scheme. Background Color);

for I in Of_Menu.Upper_Left_Row + 1 .. Of_Menu.Lower_Right Row - 1 loop

Screen_Package. Position_Cursor (I, Temp_Col);

Screen Package. Put (Temp_Blank_String);

end loop;

if Of_Menu. Item_List_Length : 0 then

Highlight_Row_Cursor Position := Temp_Row;

Highlight Column Cursor_Position : Temp Col;

else

-- Display just the items currently in the window

for I in Of_Menu. First_Window_Item .. Of_Menu. Last_Window_Item loop

Temp_List_Index : I;

Screen_Package. Position_Cursor (Temp Row, Temp Col);

Menu_List_Package.Get_Item (The_Item -> Temp Item, From_List =>

Of Menu.ltem_List, At_Position =>

Temp_List_Index);

-- Reverse video "BAR" will be positioned on "Current_Item"

if I = Of_Menu.Current_Item then

-- Save the highlighted row,column position for Read_Menu when it is called.

Highlight Row_Cursor_Position := Temp Row;

Highlight_Column_Cursor_Position := Temp_Col;

Display_Item (The_Item => Temp_Item,

Background Color => Screen_Package.White Background,

Foreground_Color => Screen_Package. Black Foreground,

Highlight_Color => Screen_Package. Black_Foreground,

Width => Temp_Window_Width);

Of_Menu. Highlight_Bar := Of_Menu. Current_Item;

else

Display Item (The_Item -> Temp Item,

Background Color => Of Menu. Color_Scheme. Background Color,

Foreground_Color => Of_Menu.Color_Scheme. Foreground_Color,

Highlight_Color -> Of_Menu.Color_Scheme. Highlight_Color,

Width -> Temp Window_Width);

end if;

Temp_Row := Temp_Row + i;

end loop;

end if;

T

end Display_Menu ,tems;

43
-- Updates the display by moving the highlight bar with "Fast Bar_Move" if the

-- old and new bar positions are already on the screen. Redefines and displays

-- the whole display window if some previously undisplayed items must be displayed.

procedure Update Menu Items (The Menu : in out Menu_Type) is

begin

-- Current item is in window already

if Is In Window (The_Item_Number => The_Menu.Current_Item, Of Menu > The Menu)

then

Fast Bar Move (The Menu => The_Menu] ;

else -- Current item not in the window

Determine Items In Window (The Menu => The Menu);

Display_Menu_Items (Of Menu => The_Menu);

end if;

end Update_Menu_Items;

procedure Display Menu (The Menu : in Menu_Type) is

SavedForeground_Color : Screen_Package.Foreground_Color_Type;

Saved_Background_Color : Screen_Package.Background_Color_Type;

begin

Screen_Package.GetScreen;

Saved_Foreground_Color := Screen_Package. P_:esent_Foreground_Color;

Saved_Background_Color := Screen_Package. Present_Background Color;

Internal Draw Border (The Menu.Upper_Left_Row, The_Menu. Upper_Left_Column,

The Menu. Lower_Right_Row, The_Menu. Lower_Right_Column,

The Menu. Color_Scheme, Variable String Package.Text O:

(The_Menu.Title), The Menu. Border_Style ;

Display Menu Items (Of_Menu => The Menu) ;

-- Restore the original foreground and b,_ckground colors.

Screen Package. Set_Foreground_Color (Saved Foreground_Color)

Screen_Package. Set Background_Color (Saved Background_Color)

Screen_Package. Release_Screen;

end DisplayMenu;

-- Hides the menu by overwriting it with bl_nks. Uses either the

-- fill color passed in from the calling rol tine or the current

-- background color.

procedure Hide_Menu (The_Menu : in Menu Typ(_;

Fill_Color : in Screen_P_ckage.Background_Color_Type) is

Temp_Background_Color : Screen_Package. Background_Color_Type;

Temp_String : constant String (integer (Th(_Menu.Upper Left_Column) .. integer

(The_Menu.Lo_er_Right_Column)) :=

(others :> ' ');

begin

Screen_Package.Get_Screen;

44
Temp_Background_Color :: Screen_Package. Present_Background_Color;

Screen_Package.Set_Background_Color (FillColor);

for I in The_Menu. Upper Left_Row .. The_Menu. Lower Right_Row loop

Screen_Package. Position_Cursor (I, The_Menu.Upper_Left_Column);

Screen_Package. Put (Temp_String) ;

end loop;

Screen_Package. Set Background_Color (Temp_Background_Color);

ScreenPackage.Release_Screen;

end HideMenu;

procedure Menu Page Down (The Menu : in out Menu Type) is

Temp Window_Length : Natural := Menu_Window_Length (The_Menu);

begin

-- Move Current_Item down one page, or to bottom of list, whichever comes first.

if (The_Menu. Current_Item + Temp_Window_length) >- The_Menu. Item_List Length then

The_Menu. Current_Item := The_Menu. Item_List_Length;

else

The_Menu. Current_Item :- The_Menu. Current_Item + Temp_Window_Length;

end if;

-- Adjust the display window to include the new current item.

Update Menu_Items (The_Menu => The_Menu);

end Menu_Page_Down;

procedure Menu_Page_Up (The_Menu : in out Menu_Type) is

Temp_Window_Length : Natural := Menu_Window_Length (The_Menu);

begin

-- Move Current_Item up one page, or to top of list, whichever comes first.

if The_Menu. Current_Item > Temp_Window_length then

The_Menu. Current_Item :: The_Menu. Current item - Temp Window_Length;

elsif The_Menu.Current_Item > 0 then

The_Menu. Current_Item := i;

end if;

-- Adjust the display window to include the new current item.

Update_Menu Items (The Menu => The_Menu);

end Menu_PageUp;

__ :::::_: ----:::::::::: .... =::::::::::::::::_ ::::::::::__ :::::::::m_-:----:

procedure Menu First_Page (The_Menu : in out Menu Type) is

begin

-- Move Current_Item to top of list.

The_Menu.Current_Item := i;

-- Adjust the display window to include the new current item.

Update_Menu_Items (The_Menu => The_Menu);

end Menu_First_Page;

45
procedure Menu Last_Page (The Menu : in out Menu Type) is

begin

-- Move Current_Item to bottom of list.

The Menu.Current_Item : The_Menu. Item_List_Length;

-- Adjust the display window to include the new current item.

Update Menu Items (The_Menu => The_Menu);

end Menu_Last_Page;

procedure Menu_Bar Down_One Line (The Menu : in out Menu_Type) is

Temp_Window_Length : Natural := Menu_Window_Length (The_Menu);

Temp_Item_List Length : Natural := Menu_List_Package. Length Of

(The_Menu. Item_List);

begin

-- There are items, window space to display items, and there is a menu bar.

if (Temp Window_Length > 0) and (The Menu. Current_Item > 0) and

(Temp_Item_List_Length > 0) then

-- Move Current_Item "cyclically" to next item of list.

The Menu. Current Item := Next_Item (Of_Menu => The_Menu);

-- Adjust the display window to inclu:]e the new current item.

Update_Menu_Items (The_Menu => The_Menul;

end if;

end Menu_Bar_Down_One_Line;

................... =============================================== :::_

procedure Menu Bar_Up One_Line (The_Menu : in out Menu_Type) is

Temp_Item_List_Length : Natural : Menu_Li_t_Package.Length_Of

(The_Men1.Item_List);

Temp Window_Length : Natural := Menu_Wiildow Length (The_Menu);

begin

-- There are items, window space to disp!ay items, and there is a menu bar.

if (Temp_Window_Length > 0) and (The_Menu.,]urrent Item > 0) and

(Temp_Item_List_Length > 0) then

-- Move Current_Item "cyclically" to ])revious item of list.

The_Menu. Current Item := Prev_Item (Of_]lenu => The_Menu);

-- Adjust the display window to inclu,{e the new current item.

Update_Menu_Items (The Menu => The_Menu ;

end if;

end Menu_Bar_Up_OneLine;

-- Returns the index of the next location o: The_Char in In String, starting

46
-- from Starting_Pos. Returns 0 if The_Char does not occur in the string

-- or if the only occurance of The_Char is at the current position.

function Find Char_Index In String (The_Char : in Character;

In_String : in String;

Starting_Pos : in Natural) return Natural is

begin

for String_Index in Starting_Pos + ! .. in_Siring'LAST loop

if (The_Char = In_String (String_Index)) then

return Natural (String Index);

end if;

end loop;

for String Index in In_String'FIRST .. Starting_Pos - 1 loop

if (The Char - In String (String Index)) then

return Natural (String_Index);

end if;

end loop;

return 0;

end Find_Char_Index In String;

__ ====-----=-- -- _========= :====::---- _===== .... =======: --_=======- _==

-- Check to see if a special key is in the array of special keys

function Check_Special Keys (Legal Special_Keys : in

Keyboard_Package.Special_KeysArray_Type;

SpecialKey

Keyboard_Package. Special_KeysType)

return Boolean is

begin -- Check Value

: in

for Key in Legal_Special_Keys'RANGE loop

if Convert_Special Key To Char (Special Key) = Convert_Special Key To_Char

(Legal_Special_Keys (Key)) then

return True;

end if;

end loop;

return False;

end Check_Special_Keys;

procedure Undefine Menu (The Menu : in out Menu_Type) Is

begin

if The_Menu /= null then

Variable String_Package. Destroy (The_Menu.Title);

Dispose Of Menu( TheMenu);

end if;

end Undefine Menu;

procedure Undefine_Menu (The_Menu : in out Menu Type;

The_List : in out Menu_List_Package. List_Type) is

begin

Menu List_Package. Clear( The_List);

47
Undefine_Menu (The_Menu);

end Undefine_Menu;

procedure Read_Menu (The_Menu : in out Menu Type;

The Choice : out Natural) is

Special_Key List : constant Keyboard Package. Special_Keys Array Type :=

(Keyboard_Paceage Home_Key,

Keyboard_Paceage Up_Arrow_Key,

Keyboard_Paceage Pg_Up_Key,

Keyboard_Paceage Left_Arrow_Key,

Keyboard_Paceage Right_Arrow_Key,

Keyboard Package End_Key,

Keyboard_Package. Down_Arrow_Key,

Keyboard_Package. Down_Arrow_Key,

Keyboard_Pac<age. Pg Dn Key);

Kbd_Char : Character := ASCII.nul;

Special_Key : Keyboard_Package.Speci_l_Keys_Type;

Is_Special Key : Boolean := false;

Temp Window Width : constant Natural := Me]u_Window_Width (The_Menu);

Item_List_Length : constant Natural := Menu List_Package. Length_Of

(TheMenu. ItemList);

Temp List Index : Natural;

Hot_Key String : String (i .. Item_List_Length) := (others => ' ');

Temp_Item : Menu_Item_Type;

Hot_Key_Item : Natural := 0;

Saved_Foreground_Color : Screen_Package. Foreground_Color_Type;

Saved_Background_Color : Screen Package. Background_Color_Type;

begin

if The Menu. Current_Item 0 then

The_Menu. Current_Item : l;

end if;

-- Construct the "Hot-Key String" of cha_acters that will cause cursor

-- movement to specific items.

for I in 1 .. Item_List_Length loop

Temp List_Index := I;

Menu_List_Package.Get_Item (The_Item => Temp_Item, From_List =>

The_Menu. It_m List,

At Position => Temp_List_Index);

-- If item has a Hot_Key and it shows up in the window, then store it

-- in the appropriate position in Hot Key String.

if Natural( Temp_item. Hot_Key Position) in 1 .. Temp Window Width then

Hot_Key String (I) : Variable_Strinc_Package. Text Of

(Temp Item. Iter_VString)

(Positive (Temp_Item. Hot Key_Positiol ));

end if;

end loop;

loop

-- Valid inputs are:

48
SPECIAL KEYS: Menu => (Home_Key,Up_Arrow_Key,Pg_Up_Key,Left_Arrow_Key,

Right_Arrow_Key,End Key,Down_Arrow_Key,Pg Dn_Key)

HOT KEYS: Menu item characters denoted by user for fast cursor

movement.

ENTER KEY: Key that causes a selection to be made.

Keyboard Package.Get_One Valid Char (Legal Values =>

Hot_Key String&ASCII.CR,

Legal_Special_Keys => Special Key_List,

Special_Key_Hit -> Is_Special_Key,

Entered_Special_Key => Special_Key,

Entered_Value _> Kbd Char);

if The_Menu. Item_List_Length = 0 then

exit when Kbd_Char = ascii.cr;

eisif Is_Special_Key then

-- Actions to take for the special keys.

Screen_Package.Get_Screen;

Saved_Foreground_Color :- Screen_Package. Present_Foreground_Color;

Saved Background_Color :- Screen_Package. Present Background_Color;

Screen Package. Position_Cursor (Highlight_Row_Cursor_Position,

Highlight_Column_Cursor_Position);

case SpecialKey is

when Keyboard_Package.Up_Arrow Key I Keyboard_Package.Left_Arrow_Key =>

Menu_Bar Up_One_Line (The Menu -> The Menu);

when Keyboard_Package.Down_Arrow_Key I Keyboard_Package.Right_Arrow_Key ->

Menu Bar_Down_One_Line (The_Menu => The_Menu);

when Keyboard_Package.Home Key =>

Menu First Page (The_Menu => The Menu);

when Keyboard_Package. End_Key =>

Menu_Last Page (The_Menu => The Menu);

when Keyboard_Package. Pg_Up_Key ->

Menu Page_Up (The_Menu => The_Menu);

when Keyboard_Package. Pg_Dn Key =>

Menu Page_Down (The_Menu => The_Menu);

when others ->

null;

end case;

-- Restore the original foreground and background colors.

Screen_Package. Set_Foreground_Color (Saved_Foreground_Color);

Screen_Package. Set Background_Color (Saved Background Color);

Screen_Package.Release_Screen;

else

-- a carriage return has been entered

-- The highlighted Current Item has been selected.

exit when Kbd_Char = ascii.cr;

-- Hot_Key was pressed. Move highlight bar to the corresponding item.

-- Key pressed is a character, is it a Hot_Key or a carriage return?

Hot_Key_Item := Find_Char_Index In String( The Char => Kbd_Char,

In_String => Hot_Key_String,

Starting_Pos=>

The_Menu.Current item);

if Hot_Key Item > 0 then

-- Actions to take for the special keys.

Screen_Package.Get_Screen;

49
Saved_Foreground_Color :: ScreenPackage. Present_Foreground_Color;

Saved_Background_Color := Screen Package. Present Background_Color;

The Menu. Current_Item :: Hot_Key Item;

Update Menu Items (The Menu :> The_Menu);

-- Restore the original foreground and background colors.

Screen_Package. Set_Foreground_Color (Saved_Foreground_Color);

Screen Package. Set_Background Color (Saved_Background_Color);

Screen_Package. ReleaseScreen;

end if;

end if;

end loop;

The Choice : The_Menu. Current_Item;

end Read_Menu;

-- Allows the user to make a selection from the menu.

procedure Read_Menu (The Menu : in out Menu Type;

Legal Special Keys : in

Keyboard_Package.Special_Keys_Array_Type;

Special_Key_Hit : ou: Boolean;

Entered_Special_Key : ou_ Keyboard_Package. Special_Keys_Type;

Escape_Key Hit : ou_ Boolean;

The Choice : ou_ Natural) is

use Keyboard_Package;

Menu_Keys

Special_Key_List

Menu_Key_List

Kbd_Char

Special_Key

IsSpecialKey

Temp_Window_Width

ItemList_Length

Temp_List_Index

Hot_Key_String

Temp_Item

Hot_Key_Item

: constant Keyboard_Package. Special Keys_Index_Type :: 9;

: Keyboard Package. Special_Keys_Array_Type

(Keyboard Package. Sp,_cial_Keys_Index_Type'first ..

Menu_Keys . Keybo,_rd_Package. Special_Keys Index_Type'pos (

Legal_Special_Key::'last));

: Keyboard Package.Sp,_cial_Keys_Array_Type

(Keyboard_Package. S],ecial_Keys_Index_Type'first ..

Menu_Keys) :=

(Keyboard_Package. H(,me_Key, KeyboardPackage.Up_Arrow_Key,

Keyboard_Package. P_T_Up_Key,Keyboard_Package. Left_Arrow_Key,

Keyboard_Package. R:ght_Arrow_Key, Keyboard_Package. End Key,

Keyboard_Package. D(,wn_Arrow_Key,

Keyboard_Package.Dc,wn_ArrowKey,

Keyboard_Package. P_ Dn Key);

: Character;

: Keyboard_Package. SI.ecial_Keys_Type;

: Boolean :: false;

: constant Natural := Menu_Window_Width (The Menu) ;

: constant Natural := Menu_List_Package. Length_of

(TheMenu. ItemList);

: Natural;

: String (i .. Item_list_Length) := (others => ' );

: Menu_Item_Type;

: Natural := 0;

Saved_Foreground_Color : Screen_Package. Fozeground_Color_Type;

Saved_Background_Color : Screen Package.Background_Color_Type;

5O
begin

Special_Key Hit := FALSE;

Escape_Key_Hit := FALSE;

if The Menu. Current_Item = 0 then

The_Menu. Current_Item : i;

end if;

-- Construct the "Hot-Key String" of characters that will cause cursor

-- movement to specific items.

for I in 1 .. Item List_Length loop

Temp_List_Index := I;

Menu_List Package.Get_Item (The_Item => Temp_Item,

From List => The_Menu. Item_List,

At_Position => Temp_List_Index);

-- If item has a Hot_Key and it shows up in the window, then store it

-- in the appropriate position in Hot Key_String.

if Natural( Temp_Item. Hot Key Position) in 1 .. Temp_Window Width then

Hot_Key String (I) := Variable_String_Package. Text_Of

(Temp Item. Item_VString)

(Positive (Temp Item. Hot_Key_Position));

end if;

end loop;

-- Construct the special key list.

Special Key List (Keyboard_Package.Special_Keys Index Type'first .. Menu Keys) :-

Menu_Key_List;

Special_Key List (Menu_Keys + i .. Menu_Keys +

Keyboard Package. Special_Keys_Index_Type'pos

(Legal Special Keys'last)) :=

Legal_Special_Keys;

loop

-- Valid inputs are:

-- SPECIAL KEYS: Menu => (Home_Key,Up_Arrow_Key,Pg_Up_Key,Left_Arrow Key,

-- Right_Arrow Key,End_Key,Down_Arrow_Key,Pg Dn_Key)

-- Also, any special keys specified in the Legal_Special_Keys -

-- array

-- by the user (if the predefined ones appear in this array, it

-- will be ignored).

-- HOT KEYS: Menu item characters denoted by user for fast cursor

-- movement.

-- ENTER KEY: Key that causes a selection to be made.

-- ESCAPE KEY: Often used as a special-purpose key during user input (sets

-- Escape_Key_Hit flag parameter).

Keyboard_Package. Get One_Valid_Char

(Legal_Values=>Hot_Key_String&ascii.CR&ASCII.ESC,

Legal_Special_Keys => Special_Key_List,

Special_Key Hit => Is_Special_Key,

Entered_Special_Key => Special_Key,

Entered_Value => Kbd_Char);

if The_Menu. Item_List_Length 0 then

Escape_Key Hit := Kbd Char = ASCII.Esc; -- user pressed the escape key

exit when Kbd_Char Ascii.CR or Kbd_Char - ASCII.Esc;

elsif Is Special_Key then

-- Actions to take for the special keys.

51
Screen_Package.Get_Screen;

Saved_Foreground_Color :: Screen_Package. Present_Foreground_Color;

Saved Background Color := Screen_Package. Present_Background_Color;

Screen_Package. Position_Cursor (Highlight_Row_Cursor_Position,

Highlight_Column_Cursor_Position);

case SpecialKey is

when Keyboard_Package.Up_Arrow_Ke.f i Keyboard Package. Left Arrow Key >

Menu_Bar_Up_One Line (The Menu => The_Menu);

when Keyboard_Package.Down_Arrow_Key i Keyboard Package.Right Arrow Key =>

Menu_Bar_Down_One_Line (The_Menu => The_Menu);

when Keyboard Package.Home Key =>

Menu_First Page (The_Menu => Tile_Menu);

when Keyboard Package.End_Key =>

Menu Last_Page (The_Menu => The_Menu);

when Keyboard_Package. Pg_Up_Key =>

Menu_Page_Up (The_Menu => The_Menu);

when Keyboard_Package. Pg_Dn_Key =>

Menu_Page Down (The_Menu => The_Menu);

when others =>

if Check_Special Keys (Legal_S_]ecial_Keys, Special_Key) then

Special_Key_Hit := TR]E;

Entered Special Key := Special_Key;

Screen_Package. Release_Screen;

exit;

end if;

end case;

-- Restore the original foreground and background colors.

Screen_Package. Set_Foreground_Color (Saved_Foreground_Color);

Screen_Package. Set_Background_Color (Saved_Background_Color);

Screen_Package. Release_Screen;

else

if Kbd_Char = ASCII.CR then

exit; -- The highlighted Cur::ent_Item has been selected.

elsif Kbd_Char = ASCII.ESC then

Escape_Key_Hit := True;

exit;

-- The user pressed the escape key

else -- Key pressed is a character, is it a Hot_Key?

Hot_Key_Item := Find_Char_Index Ill String (The_Char => Kbd_Char,

In_String=> Hot_Key_String,

Starting_Pos =>

The_Menu. Current_Item);

if (Hot Key_Item > 0) then

-- Hot Key was pressed. Move h:!ghlight bar to the corresponding item.

-- Actions to take for the spe('ial keys.

Screen_Package.Get_Screen;

Saved_Foreground_Color := Scre(n_Package. Present_Foreground_Color;

Saved_Background_Color := Scre(n_Package.Present_Background_Color;

Screen Package.Position_Cursor (Highlight_Row_Cursor_Position,

Highlight_Column_Cursor_Position);

The_Menu. Current_Item := Hot_K(y_Item;

Update_Menu_Items (The_Menu => The_Menu);

-- Restore the original foregr(und and background colors.

52
Screen_Package. Set_Foreground_Color (Saved_Foreground_Color);

ScreenPackage. SetBackground_Color (SavedBackgroundColor);

Screen_Package.Release_Screen;

end if;

end if;

end if,

end loop;

The_Choice := The_Menu.Current_Item;

end Read_Menu;

end Menu_Package;

53
-- File Name: DOL_CMDS.MNU

-- Organization: NASA - Langley Research Center (LaRC)

-- Project: LIDAR In-Space Technology E_periment (LITE)

...............................................................................

--*****************************************************************************

-- Name/Number:

-- DOL_CMDS.YLNU (Master AT Menu File)

-- Abstract:

-- This is the menu of all legal DOL commands that can be sent over DOLs

-- 7-12. Note that the entries in this menu **MUST** be in the same order

-- as the entries in the data file DOL_CMDS.EAT for the DOL interface to

-- work properly. The strings themselves don't have to match, or even be

-- close, but each DOL command name in the data file should be in tha

-- corresponding location with the identifier for it in this menu. See

-- comments at the top of the data file for more info.

-- Called By:

-- DOL_CMDS.ADB

---*****************************************************************************

[]

[i]

[15]

[2]

[35]

[25]

[Blue_Background]

[Bright white_Foreground]

[Yellow_Foreground]

[Yellow_Foreground]

[Light_RedForeground]

[Single]

-- Menu Title

-- initial value of Current Item

-- Upper Left Row

-- Upper Left Column

-- Lower Right Row

-- Lower Right Column

-- Background Color

-- Foreground Color

-- Title Color

-- Border Color

-- Highlight (Hot Key) Color

-- Border Type

************************** Menu Items ****************************

[7]

[Turn "Q" Switch On ]

[7]

[Turn "Q" Switch Off ]

[i]

[Flashlamps On ]

[1]

[Flashlamps Off ]

[8]

[Select Laser A ]

[8]

[Select Laser B ]

[i]

[Initialize Encoders ]

[6]

[Stow Prism ]

54
[i]

[Search ]

Ill

[Align ]

[l]

[Last Aligned Position ]

Ill

[Camera On ]

Ill

[Camera Off ]

[7]

[Go To Day Data Take ]

[7]

[Go To Night Data Take ]

[7]

[Go To Standby ]

[71

[Go To BITS ]

[i]

[Ignore SDIO Commands ]

[z]

[Accept SDIO Commands

5S
Appendix 2: Filename Manager Package

...............................................................................

-- File Name: FNAMEMGR.ADS

-- Organization: NASA - Langley Research Center (LaRC)

-- Project: LIDAR In-Space Technology E>periment (LITE)

...............................................................................

--*****************************************************************************

- Name/Number:

-- Fiiename_Manager Package (package spec)

-- Abstract:

-- This package is used to allow greater flexibility in naming external

-- files such as data files, initialization files, menu definition files,

-- and so on. It allows the code to use idertifier strings, called "tags",

-- to select files, instead of being limited to the file naming restrictions

-- imposed by the host operating system. In addition, it also prevents

-- literal file names from being "hard-wired" into the code. This allows

-- the programmer to change file names, or use a substitute file with a

-- different name in a test, without having to modify or re-compile his

-- code.

-- Acronyms/Abbreviations:

-- None

-- Dependencies:

-- None

-- Global Objects:

-- None

-- Exceptions:

-- Duplicate_Filename

-- Duplicate_Tag

-- Invalid File

-- Invalid_Filename

-- Invalid_File Contents

-- Invalid_Position

-- Invalid_Tag

Machine/Compiler Dependencies:

None

WITH Variable_StringPackage;

PACKAGE Filename Manager_Package IS

-- VISIBLE TYPES

-- file name/tag list type

TYPE Filename List_Type IS PRIVATE;

-- When writing a filename list to an externa_ file, this enumerated type

-- allows a calling routine to have control o,'er the desired type of

-- file I/O action. When generating a filenai1e list from an external file

-- it allows the calling routine have control over the type of action

-- taken on the input list.

TYPE List_Action_Type IS (Overwrite,

Append);

56
-- This enumerated type is used in the procedure that Sorts a list.

-- It allows the calling routine the choice of reordering the

-- list either by tag or name.

TYPE List_Sort_Type IS (By_FileTag,

By_Filename);

-- VISIBLE EXCEPTIONS

............................................................................

-- When searching a list for a file tag, this exception is raised if the

-- file tag is not found

Invalid_Tag : EXCEPTION;

-- When searching a list for a filename, this exception is raised if the

-- filename is not found

invalid_Filename : EXCEPTION;

-- This exception is raised when a new file tag to be added to a

-- filename list already exists in that list.

Duplicate_Tag : EXCEPTION;

-- This exception is raised when a new filename to be added to a

-- filename list already exists in that list.

Duplicate Filename : EXCEPTION;

-- This exception is raised when a list position passed to a function does

-- not exist.

Invalid_Position : EXCEPTION;

-- This exception is raised when a problem is encountered with opening

-- or creating an external file

Invalid_File : EXCEPTION;

-- This exception is raised when a problem is encounte red while getting

-- token pairs from an external file. The problem may be a token that

-- is too long ( > 80 chars) or a token may be missing

Invalid_File_Contents : EXCEPTION;

-- VISIBLE FUNCTIONS

............................................................................

............................................................................

-- This function returns the number of nodes in a filename list.

-- Inputs:

-- Filename List : input list whose number of nodes (tag/filename pairs)

-- is to be returned

-- Outputs:

-- Exceptions:

............................................................................

FUNCTION Length_Of

$7
(Filename_List : IN Filename List Type) RETURN NATURAL;

-- This procedure clears (deallocates) the ingut list

-- Inputs:

-- Filename List : input list to be cleare_

-- Outputs:

-- Fiiename_List : cleared null list to re:urn

-- Exceptions:

............................................................................

PROCEDURE Ciear_Filename_List (Filename_List : IN OUT Filename_List_Type) ;

-- This procedure allows the user to save the current contents of a

-- filename list to an external file. If theiAction is "Append",

-- then the tag/filename pairs in the list are appended to the end of the

-- To_File, empty or not. In this case, if tlhe input list happens to

-- be null, the file will remain unchanged, rf the Action is "Overwrite"

-- and the file is not empty, then the tag/fi ename pairs will overwrite

-- the contents of the file. In this case, i: the input list happens

-- to be null, the file will be empty afterwoTds.

-- Inputs:

-- Filename List - tag/filename list to be written from

-- To_File - external output file for which to write the

tag/filename pairs

- action to take on file, either append or overwrite -- Action

-- Outputs:

-- Exceptions:

-- Invalid_File raised when there is a problem with the external

file open or creation

............................................................................

PROCEDURE Save Filename List (Filename_List : IN Filename_List _"_ype;

To File : IN STRING;

Action : IN List_Action_Type);

-- This procedure is used to create a new list of filenames and tags.

-- It reads the filenames and the tags

-- from an external file. If the Action is

-- "Overwrite", the list will be overwritten _'ith the new entries found in

-- the From_File. If the Action is Append, tle tag/filename pairs found

-- in the given From File will be appended to the list. The From File

-- is checked for duplicate file tags and fil(names and exceptions raised

-- when necessary.

58
-- Inputs:

-- Filename_List - tag/filename list to be manipulated

-- From_File - external file from which to read the tag/filename

-- pairs and put int the Filename_List

-- Action - action to take on list, either append or overwrite

-- Outputs:

-- Filename_List - zag/fiiename list to be manipulated

-- Exceptions:

-- Invalid File_Contents - raised when an expected token can not

-- be found in the external file or

-- if a token is too long ( > Max_Token Length)

-- Invalid File - raised when there is a problem with the

-- external file open or creation

............................................................................

PROCEDURE Generate_Fi!ename_List

(Filename_List : IN OUT Filename_List Type;

From_File : IN STRING;

Action : IN List Action_Type);

-- This procedure allows the user to add a new file tag/filename pair to

-- the end of the filename list. Duplicate tags and filenames are not

-- allowed and raise the Duplicate_Tag or Duplicate_Filename exceptions.

-- Inputs:

-- Filename List - tag/filename list to be add to

-- File Tag file tag to be added to list end

-- Filename filename to be added to list end

-- Outputs:

-- Filename List - tag/filename list after addition of new pair

-- Exceptions:

-- Duplicate Filename - raised when the input filename is found to

-- already exist in the list

-- Duplicate_File_Tag - raised when the input file tag is found to

-- already exist in the list

............................................................................

PROCEDURE Append To Filename_List

(Filename_List : IN OUT Filename_List_Type;

File_Tag : IN STRING;

Filename : IN STRING);

-- This procedure allows the user to do a "sorted" insert of a new

-- file tag/filename pair into the filename list. The pair will be

-- alphanumerically inserted either by file tag or by filename. The

-- routine assumes that the list is already properly sorted for the

-- desired insert. Results will be unpredictable if either the list

-- is not already sorted or if the pair is inserted by the wrong

-- token (tag or name). Duplicate tags and fi!enames are not

-- allowed and raise the Duplicate_Tag or Duplicate Filename exceptions.

59
-- Inputs:

-- Filename List - tag/filename list to be add to

-- File_Tag - file tag to be added tc list end

-- Filename - filename to be added tc list end

-- Insert - insert type (by file tag or filename)

-- Outputs:

-- Filename_List - tag/filename list after addition of new pair

-- Exceptions:

-- Duplicate_Filename - raised when the input filename is found to

-- already exist in the list

-- Duplicate File_Tag - raised when the in3ut file tag is found to

-- already exist in tze list

............................................................................

PROCEDURE Insert Into Filename_List

(Filename List : IN OUT Filename_List_Type;

File_Tag : IN STRING;

Filename : IN STRING;

Insert : IN List_Sor_=_Type);

-- This procedure allows the user to delete a file tag/fiiename pair

-- from a filename list. The list is searched for the given file tag and

-- when found, the tag/filename pair are deleted. The Invalid_Tag

-- exception will be raised if the file tag is not found.

-- Inputs:

-- Fiiename_List - tag/filename list to be deleted from

-- File Tag - file tag to delete (filename deleted also)

-- Outputs:

-- Filename_List - tag/filename list after addition of new pair

-- Exceptions:

-- Invalid Tag - raised when the input file tag is not found in the list

............................................................................

PROCEDURE DeleteFile_Tag

(Filename_List : IN OUT Filename List_Type;

File_Tag : IN STRING);

-- This procedure allows the user to delete a file tag/filename pair

-- from a filename list. The list is searche_{ for the given filename and

-- when found, the tag/filename pair are de!e_ ed. The Invalid_Filename

-- exception will be raised if the filename i:: not found.

-- Inputs:

-- Filename_List - tag/filename list to be deleted from

-- Filename filename to delete (fil_ tag deleted also)

-- Outputs:

-- Filename List - tag/filename list after addition of new pair

-- Exceptions:

-- Invalid Filename - raised when the input filename is not found

60
-- in the list

............................................................................

PROCEDURE Delete_Filename

(Filename List : IN OUT Filename List Type;

Filename : IN STRING);

-- This function searches a filename list for a filename and returns

-- a boolean telling whether or not it was found.

-- Inputs:

-- Filename List - tag/filename list to be searched

-- Filename filename to search for in list

-- Outputs:

-- Exceptions:

............................................................................

FUNCTION Filename_Exists

(Filename_List : IN Eilename_List Type;

Filename : IN STRING) RETURN BOOLEAN;

-- This function searches a filename list for a file tag and returns

-- a boolean telling whether or not it was found.

-- Inputs:

-- Filename_List - tag/filename list to be searched

-- File Tag - tag to search for in list

-- Outputs:

-- Exceptions:

............................................................................

FUNCTION File_Tag_Exists

(Filename_List : IN Filename_List_Type;

File_Tag • IN STRING) RETURN BOOLEAN;

-- This function searches the specified list for the file tag passed

-- to it and returns the file name associated with that tag. The

-- tag comparisons are NOT case sensitive.

-- Inputs:

-- Filename List - tag/filename list to be searched

-- File Tag tag to search for in list

-- Outputs:

-- Exceptions:

Invalid Tag - raised when the input file tag is not found

61
-- in the list

............................................................................

FUNCTION Get_Filename

(Filename_List : IN Filename_List Type;

File Tag • IN STRING) RETURN STRING;

-- This function searches the specified list for the filename passed

-- to it and returns the file tag associated with that filename. The

-- filename comparisons are NOT case sensitive.

-- Inputs:

-- Filename_List - tag/filename list to be searched

-- Filename - filename to search for in list

-- Outputs:

-- Exceptions:

-- Invaiid Filename - raised when the input filename is not found

-- in the list

............................................................................

FUNCTION Get File_Tag

(Filename_List : IN Filename_List_Type;

Filename : IN STRING) RETURN STRING;

-- This function finds the node specified by :he position passed

-- in and returns the filename at that positign.

-- Inputs:

-- Filen_me_List - tag/filename list to be searched

-- Position - position in list to return filename from

-- Outputs:

-- Exceptions:

-- Invalid_Position - position does not ex_st for input list

............................................................................

FUNCTION Get_Filename

(Filename_List : IN Filename__ist Type;

Position : IN Natural) RETURN STRING;

-- This function finds the node specified by :he position passed

-- in and returns the file tag at that positi,}n.

-- Inputs:

-- Filename_List - tag/fiiename list to be searched

-- Position position in list to ret_rn file tag from

-- Outputs:

-- Exceptions:

-- Invalid_Position - position does not ex:st for input list

62
FUNCTION Get_File_Tag

(Filename_List : IN Filename_List_Type;

Position : IN Natural) RETURN STRING;

-- This function searches for the specified filename in the list, and

-- returns the position in the list of the node which contains it.

-- Inputs:

-- Filename List - tag/filename list to be searched

-- Filename filename to search for in list

-- Outputs:

-- Exceptions:

-- Invalid_Filename - raised when the input fiiename is not in the

-- input list

............................................................................

FUNCTION Get_Filename_Position

(Filename_List : IN Filename_List_Type;

Filename : IN STRING) RETURN NATURAL;

-- This function searches for the specified file tag in the list, and

-- returns the position in the list of the node which contains it.

-- Inputs:

-- Filename_List - tag/filename list to be searched

-- File_Tag - file tag to search for in list

-- Outputs:

-- Exceptions:

-- Invalid_File_Tag - raised when the input file tag is not in the

-- input list

............................................................................

FUNCTION Get_File_Tag_Position

(Filename List : IN Filename List_Type;

File Tag : IN STRING) RETURN NATURAL;

-- This procedure sorts a list. The user has the option to do the

-- reorder by file tag or filename. The procedure uses a bubble sort

-- swapping pointers when necessary instead of exchanging file tags and

-- filenames.

-- Inputs:

-- Filename_List - tag/filename list to be sorted

-- Sort sort type (by file tag or filename)

-- Outputs:

-- Filename_List - tag/filename list to be sorted

63
-- Exceptions:

............................................................................

PROCEDURE Sort Filename_List

(Filename_List : IN OUT Filenam__List_Type;

Sort : IN List_Solt_Type);

PRIVATE

TYPE File_NodeType;

TYPE File_NodeAccess_Type IS ACCESS File_Node_Type;

TYPE File_NodeType IS

RECORD

File_Tag : Variable_String_Package.VString;

Fiiename : Variable_String Package. VString;

Next : File_Node Access_Type;

END RECORD;

TYPE Filename List_Type IS

RECORD

Length : NATURAL :- 0;

Node List : File Node Access Type;

END RECORD;

END Filename Manager Package;

64
-- File Name: FNAMEMGR.ADB

-- Organization: NASA - Langley Research Center (LaRC)

-- Project: LIDAR In-Space Technology Experiment (LITE)

...............................................................................

Name/Number:

FilenameManager_Package (package body)

Abstract:

This package is used to allow greater flexibility in naming external

files such as data files, initialization files, menu definition files,

and so on. It allows the code to use identifier strings, called "tags",

to select files, instead of being limited to the file naming restrictions

imposed by the host operating system. In addition, it also prevents

literal file names from being "hard-wired" into the code. This allows

the programmer to change file names, or use a substitute file with a

different name in a test, without having to modify or re-compile his

code.

Acronyms/Abbreviations:

None

-- Dependencies:

-- Global Objects:

-- None

-- Exceptions:

-- Duplicate_Filename

-- Duplicate_Tag

-- Invalid_File

-- Inva!id_Filename

-- Invalid_File_Contents

-- Invalid_Position

-- Invalid_Tag

-- Machine/Compiler Dependencies:

-- None

__*****************************************************************************

WITH Unchecked_Deallocation;

WITH File_Utilities_Package;

PACKAGE BODY Filename Manager_Package IS

Max Token_Length : CONSTANT : 80;

-- Unchecked deailocation procedure

............................................................................

PROCEDURE Dispose IS NEW Unchecked_Deallocation

(FileNodeType, File_NodeAccess_Type);

65
-- This internal function takes an input string, converts it to all

-- upper case, and then returns the new string.

-- Inputs:

-- Input_String - string to convert to upper case

-- Outputs:

-- Exceptions:

............................................................................

FUNCTION Convert_To_Upper(Input_String : IN STRING) RETURN STRING IS

Temp String : STRING(I..Max Token_Length) := OTHERS => ' ');

Lower_To_Upper_ASCII_Offset : CONSTANT

: CHARACTER'POS(a') - CHARACTER'POS('A');

BEGIN

Temp String(Input_String'RANGE) := Input S:ring;

-- examine every character in the string

FOR I IN input String'RANGE LOOP

-- if lower case,

IF Temp String(I)

Temp_String(I)

END IF;

END LOOP;

convert it to upper case

IN 'a'..'z' THEN

:= CHARACTER'VAL((CHARACTER'POS(Temp_String(I)

Lower_To_Upper_ASCIi_Offset));

RETURN Temp_String(Input String'RANGE) ;

-- allow calling routine to handle the exceptions

EXCEPTION

WHEN OTHERS :>

RAISE;

END Convert_To_Upper;

This function returns the number of nodes .n a filename list.

Inputs:

Filename List input list whose number of nodes (tag/filename pairs)

is to be returned

-- Outputs:

-- Exceptions:

............................................................................

FUNCTION Length_Of

(Filename_List : IN Filename _ist_Type) RETURN NATURAL IS

BEGIN

RETURN Filename_List.Length;

-- allow calling routine to handle the except ons

EXCEPTION

WHEN OTHERS =>

66
RAISE;

END Length_Of;

-- This procedure clears (dealiocates) the input list

-- Inputs:

-- Filename List : input list to be cleared

-- Outputs:

-- Filename List : cleared null list to return

-- Exceptions:

............................................................................

PROCEDURE Clear_Filename List(Filename_List : IN OUT Filename_List Type) IS

-- temporary pointer used to manipulate tag/filename list

Temp_Ptr : File Node_Access_Type := Fiiename_List.Node List;

BEGIN

-- delete every node

WHILE Filename_List.Node_List /= NULL LOOP

-- dispose of the tag and filename

Variable_String Package.

Destroy (The String -> Temp_Ptr. File Tag);

Variable_String Package.

Destroy (The String => Temp Ptr. Filename);

-- set the temp pointer to the next node

Temp_Ptr := Temp_Ptr.Next;

-- dispose of the current node

Dispose (Filename List.Node_List);

-- make list point to next node

Eilename_List.Node_List := Temp_Ptr;

END LOOP;

-- reset the list length

Filename_List. Length := 0;

-- allow calling routine to handle the exceptions

EXCEPTION

WHEN OTHERS =>

RAISE;

END Clear_Filename_List;

-- This procedure allows the user to save the current contents of a

-- filename list to an external file. If the Action is "Append",

-- then the tag/filename pairs in the list are appended to the end of the

-- To_File, empty or not. In this case, if the input list happens to

67
-- be null, the file will remain unchanged. If the Action is "Overwrite"

-- and the file is not empty, then the tag/filename pairs will overwrite

-- the contents of the file. In this case, if the input list happens

-- to be null, the file will be empty afterwcrds.

-- Inputs:

-- Filename_List - tag/filename list to be written from

-- To File - external output file for which to write the

tag/filename pairs

- action to take on file, either append or overwrite -- Action

-- Outputs:

-- Exceptions:

-- Invalid_File - raised when there is a Qroblem with the external

-- file open or creation

............................................................................

PROCEDURE Save Filename_List (Filename_List : IN Filename List Type;

To_File : IN STRING;

Action : IN List_Action_Type) IS

-- for opening file

Aborted : BOOLEAN := FALSE;

-- file utilities package file identifier

File_ID : File_Utilities_Package. File_Identifier_Type;

-- temporary pointer used to manipulate tag/filename list

Temp Ptr : File Node_Access Type :- Filename_List.Node List;

BEGIN

-- open the file according to the desired action

IF Action = Append THEN

File Utilities_Package.

OpenOutputFile

(Filename => To File,

File_Mode => File_Utilities_Package.Append,

File ID => Fi!e_ID,

Aborted > Aborted);

ELSE

File_Utilities Package.

Open Output_File

(Filename => To File,

File Mode -> File Utilities_Package.Overwrite,

File_ID -> File_ID,

Aborted => Aborted);

END IF;

IF NOT Aborted THEN -- file open/creation ok

-- put all tag/filename pairs to output file

FOR I in l..Filename_List.Length LOOP

File_UtilitiesPackage.

Put_Token

(Token File => File ID,

Item => Variable_String_ Package.

Text Of(Temp_ Ptr.File Tag));

File_Utilities_Package.

Put_Token

(Token File => File ID,

Item > Variable String_.Package.

Text Of(Temp_ Ptr. Filename));

68
-- blank line

File_Utilities_Package.

Put_Line(File_ID :> File_ID, Item > "") ;

-- go to next pair

Temp_Ptr :- Temp_Ptr.Next;

END LOOP;

-- all done getting token pairs, close the file

File_Utilities_Package.Close_Input_File(File ID);

ELSE

RAISE Invalid_File; -- problem w/ file open or creation

END IF;

-- allow calling routine to handle the exceptions

EXCEPTION

WHEN OTHERS =>

RAISE;

END Save_Filename_List;

This procedure is used to create a new list of filenames and tags.

"Generate Filename_List", reads the filenames and the tags associated

with them from a file to build a filename list. If the Action is

"Overwrite", the list will be overwritten with the new entries found in

the From_File. If the Action is Append, the tag/filename pairs found

in the given From_File will be appended to the list. The From_File

is checked for duplicate file tags and filenames and exceptions raised

when necessary.

Inputs:

FilenameList - tag/filename list to be manipulated

From File - external file from which to read the tag/filename

pairs and put into the Filename_List

-- Action - action to take on list, either append or overwrite

-- Outputs:

-- Filename List - tag/filename list to be manipulated

-- Exceptions:

-- Invalid File Contents - raised when an expected token can not

-- be found in the external file or

-- if a token is too long ( > Max_Token_Length)

-- Invalid_File raised when there is a problem with the

-- external file open or creation

............................................................................

PROCEDURE Generate_Filename_List

(Filename_List : IN OUT Filename List_Type;

From_File : IN STRING;

Action • IN List_Action Type) IS

-- for opening file

Successful : BOOLEAN := FALSE;

-- file utilities package file identifier

69
File_ID : File_Utilities_Package. File_]dentifier_Type;

-- get token length variables

FN Length : NATURAL := 0;

FT Length : NATURAL := 0;

-- get token tokens

File_Tag : STRING(l..Max_Token_Length) := (OTHERS => ' ');

Filename : STRING(l..Max_Token_Length) := (OTHERS => ' ');

-- token strings are converted and stored in the list as vstrings

VFile_Tag : Variable_String_Package.VSTRING;

VFilename : Variable_String_Package.VSTRING;

-- for counting the number of nodes in the list

Node_Counter : NATURAL :: i;

-- temporary pointer used to manipulate tag/filename list

Temp_Ptr : File_Node_Access_Type := Filename List.Node_List;

BEGIN

-- open the input file

File_Utilities Package.Open_Input_File

(Filename > From_File,

Fi!e ID => File ID,

Successful -> S:ccessfu!);

IF Successful THEN -- file opened ok

-- clear list if Action is Overwrite

IF Action : Overwrite THEN

-- if current list not null, deallocate it

IF Fiiename_List.Length > 0 THEN

Clear Filename_List(Filename List);

END IF;

END IF;

-- get all tag/filename pairs in input file

WHILE NOT File_Utilities Package. EOF(Fiie ID) LOOP

-- get the file tag from the input file

File utilities_Package.Get_Token

(Token_Fil _ => File ID,

Token => File Tag,

Length -> FT_Length);

-- check to see that a token exists; if one doesn't, get out of

-- the loop

IF FT_Length = 0 THEN

IF File_Utilities Package.EOF(File ID) THEN

EXIT;

ELSE

RAISE Invalid_File_Contents;

END IF;

END IF;

-- get the filename from the input f le

File_Utilities_Package.Get_Token

(Token_Fil,! => File ID,

7O
Token => Filename,

Length => FN_Length) ;

-- check to see that the corresponding fiiename token exists in

-- the file; if one doesn't, raise the Invalid File Contents

-- exception

IF FN_Length = 0 THEN

RAISE Invalid_File_Contents;

ELSE

Append To Eilename List

(Filename List -> Eilename_List,

File Tag -> File Tag(I..FT Length),

Filename => Filename(l..FN Length));

END LOOP;

-- all done getting token pairs, close the file

File Utilities_Package. Close_Input_File(File_ID);

ELSE

RAISE Invalid_File; -- problem w/ open

END IF;

-- allow calling routine to handle the exceptions

EXCEPTION

-- token too long

WHEN Constraint_Error ->

RAISE InvalidFileContents;

WHEN OTHERS =>

RAISE;

END Generate_Filename_List;

This procedure allows the user to add a new file tag/filename pair to

the end of the filename list. Duplicate tags and filenames are not

allowed and raise the Duplicate_Tag or Duplicate Filename exceptions.

Inputs:

Eilename_List - tag/filename list to be add to

FileTag file tag to be added to list end

Fiiename filename to be added to list end

Outputs:

Filename_List - tag/filename list after addition of new pair

Exceptions:

Duplicate_Eilename - raised when the input filename is found to

already exist in the list

Duplicate_File Tag - raised when the input file tag is found to

-- already exist in the list

............................................................................

PROCEDURE Append To Filename_List

(Filename List : IN OUT Filename List_Type;

File_Tag • IN STRING;

Filename • IN STRING) IS

71
-- token strings are converted and stored in the list as vstrings

VFile_Tag : Variable_String_Package.VS_RING;

VFi!ename : Variable_String_Package.VS_RING;

-- for counting the number of nodes in the list

Node Counter : NATURAL :- i;

-- temporary pointer used to manipulate tag/filename list

Temp Ptr : File_Node_Access_Type := Filename List.Node_List;

BEGIN

Node Counter := I; -- initially

-- first search list for duplicate tag & filenames

IF Filename_List.Length > 0 THEN

-- examine all nodes

WHILE Node Counter <= Filename_List.Length LOOP

-- compare tags

IF Convert To_Upper(Variable String_Package.

Text_Of(Temp Ptr. File_Tag)) :

Convert_ToUpper(FileTag) THEN

RAISE Duplicate_Tag;

-- compare filenames

ELSIF Convert_To Upper(Variable_Strilg_Package.

Text Of(Temp_Ptr.Filename)) -

Convert To Upper(Filename) ?HEN

RAISE Duplicate_Filename;

-- bump to next node

ELSE

Temp_Ptr :- Temp_Ptr.Next;

Node Counter := Node_Counter + i;

END IF;

END LOOP;

END IF;

-- convert the strings to vstrings

Variable String_Package.Make Vstring (The_String :> File_Tag,

New_Vstring :> VFile Tag);

Variable String_Package. Make_Vstring (The_String :> Filename,

New__rstring => VFilename);

-- append a node to the list

IF Filename List.Length = 0 THEN

-- for the first node, the temporary pointer should point

-- to the new node and the filename list's node list should

-- point to the first node

Temp_Ptr := NEW File Node Type' (VFile T_g, VFilename, NULL);

Filename_List.Node List := Temp_Ptr;

ELSE

-- reset the pointer to the front of the list

Temp_Ptr := Filename_List.Node_List;

-- find the end of the list if it is not empty and add new

-- tag/filename pair there

WHILE Temp Ptr. Next /- NULL LOOP

Temp_Ptr : Temp_Ptr.Next;

72
END LOOP;

-- append new node

Temp Ptr.Next := NEW File Node Type' (VFile Tag, VFilename, NULL);

END IF;

-- increment the list length

Filename_List.Length := Filename_List. Length+ i;

-- allow calling routine to handle the exceptions

EXCEPTION

WHEN OTHERS =>

RAISE;

END Append To Filename List;

-- This procedure allows the user to do a "sorted" insert of a new

-- file tag/filename pair into the filename list. The pair will be

-- alphanumerically inserted either by file tag or by filename. The

-- routine assumes that the list is already properly sorted for the

-- desired insert. Results will be unpredictable if either the list

-- is not already sorted or if the pair is inserted by the wrong

-- token (tag or name). Duplicate tags and filenames are not

-- allowed and raise the Duplicate Tag or Duplicate Filename exceptions.

-- Inputs:

-- Filename List - tag/filename list to be add to

-- File Tag file tag to be added to list end

-- Filename fi!ename to be added to list end

-- Insert insert type (by file tag or filename)

-- Outputs:

-- Filename List - tag/filename list after addition of new pair

-- Exceptions:

-- Duplicate_Filename - raised when the input filename is found to

-- already exist in the list

-- Duplicate File_Tag - raised when the input file tag is found to

-- already exist in the list

............................................................................

PROCEDURE Insert_Into_Filename_List

(Filename List : IN OUT Filename_List Type;

File_Tag : IN STRING;

Filename : IN STRING;

Insert : IN List_Sort_Type) IS

-- token strings are converted and stored in the list as vstrings

VFile Tag : Variable_String_Package.VSTRING;

VFilename : Variable String_Package.VSTRING;

-- for counting the number of nodes in the list

Node_Counter : NATURAL := i;

-- temporary pointers used to manipulate tag/filename list

Temp Ptr : File_Node Access_Type := Filename_List.Node_List;

-- local boolean

73
Insert_Made : BOOLEAN : = FALSE;

BEGIN

Node Counter : i; -- initially

-- first search list for duplicate tag & _ilenames

IF Filename_List.Length > 0 THEN

-- examine all nodes

WHILE Node Counter <: Filename_List. Lergth LOOP

-- compare tags

IF Convert To_Upper(Variable_String_Package.

Text_Of(Temp Ptr. File_Tag)) =

Convert_To Upper(File_Tag) THEN

RAISE Duplicate_Tag;

-- compare filenames

ELSIF Convert To_Upper(Variable_String_Package.

Text_Of(Temp_Ptr.Filename)) =

Convert To Upper(Filename) THEN

RAISE Duplicate_Filename;

-- bump to next node

ELSE

Temp_Ptr := Temp_Ptr. Next;

Node_Counter :- Node_Counter + i;

END IF;

END LOOP;

._ND IF;

-- reset the pointers to the front of the list

Temp Ptr : Filename List.Node_List;

-- convert the strings to vstrings

Variable_String Package. Make Vstring (The__tring => File_Tag,

New 7string => VFile Tag);

Variable String_Package.Make_Vstring (The _tring => Filename,

New_fstring => VFilename);

-- insert a node into the list

IF Filename List.Length - 0 THEN

-- for the first node, the temporary po_nter should point

-- to the new node and the filename lis :'s node list should

-- point to the first node

Temp_Ptr := NEW File Node Type' (VFi!e T,_g, VFilename, NULL);

Filename_List.Node_List := Temp_Ptr;

ELSE

-- prepend new node

IF (Insert - By_File Tag AND

Convert To Upper(File Tag) <

Convert To_Upper(Variable_String_Package.

Text Of(Temp. Ptr.File Tag))) OR

(Insert = By_Filename AND

Convert To Upper(Filename) <

74
Convert_To_Upper (Variable String_Package.

Text_Of(Temp_Ptr.Filename))) THEN

Temp_Ptr :- NEW File_Node_Type'

(VFile Tag, VFilename, Filename_List.Node List);

Filename_List.Node_List :- Temp_Ptr;

ELSE

Insert_Made :- FALSE;

-- find the node to insert at if the list is not empty and add new

-- tag/filename pair there

WHILE Temp_Ptr.Next /= NULL LOOP

IF (Insert = By_File Tag AND

Convert To Upper(File Tag) <

Convert To_Upper(Variable_String_Package.

Text_Of(Temp Ptr.Next. File Tag))) OR

(Insert = By_Filename AND

Convert To_Upper(Filename) <

Convert_To_Upper(Variable String_Package.

Text_Of(Temp_Ptr.Next. Fi!ename))) THEN

Temp_Ptr. Next : NEW File_Node Type'

(VFile_Tag, VFilename, Temp Ptr. Next);

Insert_Made :- TRUE;

EXIT;

ELSE

Temp_Ptr := Temp_Ptr.Next;

END IF;

END LOOP;

IF NOT Insert_Made THEN

-- append new node

Temp_Ptr.Next :- NEW File Node_Type'

(Wile Tag, VFilename, NULL);

END IF;

END IF;

END IF;

-- increment the list length

Filename List.Length :- Filename_List.Length + i;

-- allow calling routine to handle the exceptions

EXCEPTION

WHEN OTHERS =>

RAISE;

END Insert Into_Filename List;

-- This procedure allows the user to delete a file tag/filename pair

-- from a filename list. The list is searched for the given file tag and

-- when found, the tag/fiiename pair are deleted. The Invalid_Tag

-- exception will be raised if the file tag is not found.

75
-- Inputs:

-- Filename_List - tag/filename list to be deleted from

-- File Tag - file tag to delete (filename deleted also)

-- Outputs:

-- Filename_List - tag/filename list after addition of new pair

-- Exceptions:

-- Invalid_Tag - raised when the input file tag is not found in the list

............................................................................

PROCEDURE Delete_File_Tag

(Filename_List : IN OUT Filename_List_Type;

File_Tag : IN STRING) ZS

-- for counting the number of nodes in the list

Node_Counter : NATURAL :: i;

-- temporary pointers used to manipulate t_g/filename list

Temp_Ptr : File_Node_Access_Type := Fi[ename List.Node_List;

Prev_Ptr : File_Node_Access_Type := Fi[ename_List.Node_List;

-- boolean used to control search

Found : BOOLEAN :: FALSE;

BEGIN

-- initialize

Found := FALSE;

Node_Counter :: i;

-- examine every node until found or end o£ list is reached

WHILE Node_Counter <= Filename_List. Length AND NOT Found LOOP

-- comparisons are not case sensitive; convert both to upper case

-- and then compare them

IF Convert_To_Upper

(Variable_StringPackage.

Text_Of(Temp_Ptr. File_Tag)) : Convert_To_Upper(File_Tag) THEN

Found :: TRUE;

-- first node

IF Node Counter : ! THEN

Filename_List.Node_List :: Temp_P<r.Next; -- move to next node

-- last node

ELSIF Node_Counter : Filename_List.L,_ngth THEN

-- bump to next to last node

FOR I IN l..Fi!ename List.Length 2 LOOP

Prev_Ptr :- Prev_Ptr.Next;

END LOOP;

Prev_Ptr.Next :: NULL; -- set new last node to null

-- all others

ELSE

-- bump to next to node just befo_e the one to be deleted

FOR I IN l..Node_Counter - 2 LOOP

Prev_Ptr := Prev_Ptr.Next;

END LOOP;

Prev_Ptr. Next : Temp_Ptr.Next; -- circumvent deleted node

76
END IF;

Dispose (Temp_Ptr) ; -- dispose of deleted node

Filename_List. Length := Filename_List.Length - i;

-- bump to next node; increment node counter

ELSE

Temp_Ptr := Temp_Ptr.Next;

Node_Counter := Node_Counter + i;

END IF;

END LOOP;

-- done searching list; if the file tag was not found raise the

-- Invalid_Tag exception

IF NOT Found THEN

RAISE Invalid_Tag;

END IF;

-- allow calling routine to handle the exceptions

EXCEPTION

WHEN OTHERS >

RAISE;

END Delete_File_Tag;

-- This procedure allows the user to delete a file tag/filename pair

-- from a filename list. The list is searched for the given filename and

-- when found, the tag/filename pair are deleted. The Invalid_Filename

-- exception will be raised if the filename is not found.

-- Inputs:

-- Fi!ename List - tag/filename list to be deleted from

-- Filename filename to delete (file tag deleted also)

-- Outputs:

-- Filename_List - tag/filename list after addition of new pair

-- Exceptions:

-- Invalid_Filename - raised when the input filename is not found

-- in the list

............................................................................

PROCEDURE Delete_Filename

(Filename_List : IN OUT Filename List_Type;

Filename : IN STRING) IS

-- for counting the number of nodes in the list

Node_Counter : NATURAL := i;

-- temporary pointers used to manipulate tag/filename list

Temp_Ptr • File Node_Access_Type := Filename_List.Node List;

Prev_Ptr • File Node_Access_Type := Fiiename_List.Node_List;

-- boolean used to control search

Found • BOOLEAN := FALSE;

BEGIN

-- initialize

Found := FALSE;

Node_Counter := i;

77
-- examine every node until found or end cf list is reached

WHILE Node_Counter <: Filename_List. Length AND NOT Found LOOP

-- comparisons are not case sensitive; convert both to upper case

-- and then compare them

IF Convert_To_Upper

(Variable_String_Package.

Text_Of(Temp Ptr. Filename)) = Convert_To Upper(Filename) THEN

Found :: TRUE;

-- first node

IF Node_Counter - 1 THEN

Filename_List.Node List :: Temp_P=r.Next; -- move to next node

-- last node

ELSIF Node_Counter _ Filename List.Length THEN

-- bump to next to last node

FOR I IN l..Filename_List.Length - 2 LOOP

Prev_Ptr : Prev_Ptr.Next;

END LOOP;

Prev Ptr. Next :: NULL; -- set new last node to null

-- all others

ELSE

-- bump to next to node just before the one to be deleted

FOR I IN l..Node Counter - 2 LOOP

Prev_Ptr :: Prev_Ptr.Next;

END LOOP;

Prev Ptr. Next :- Temp_Ptr.Next; -- circumvent deleted node

END IF;

Dispose (Temp_Ptr); -- dispose of de_eted node

Filename_List.Length :: Filename_Lis:.Length - i;

-- bump to next node; increment node counter

ELSE

Temp_Ptr := Temp_Ptr.Next;

Node_Counter := Node Counter + i;

END IF;

END LOOP;

-- done searching list; if the filename wa:_ not found raise the

-- Invalid_Filename exception

IF NOT Found THEN

RAISE Invalid_Filename;

END IF;

-- allow calling routine to handle the exceptions

EXCEPTION

WHEN OTHERS =>

RAISE;

END Delete_Filename;

-- This function searches a filename list for a filename and returns

78
-- a boolean telling whether or not it was found.

-- Inputs:

-- Filename_List - tag/filename list to be searched

-- Filename filename to search for in list

-- Outputs:

-- Exceptions:

............................................................................

FUNCTION Filename_Exists

(Filename_List : IN Filename List Type;

Filename : IN STRING) RETURN BOOLEAN IS

-- for counting the number of nodes in the list

Node Counter : NATURAL : i;

-- temporary pointer used to manipulate tag/filename list

Temp_Ptr : File_Node Access_Type := Filename_List.Node_List;

-- boolean used to control search

Found • BOOLEAN : FALSE;

BEGIN

-- initialize

Found :- FALSE;

Node_Counter := i;

-- examine every node until found or end of list is reached

WHILE Node_Counter <= Filename_List. Length AND NOT Found LOOP

-- comparisons are not case sensitive; convert both to upper case

-- and then compare them

IF Convert_To_Upper

(VariableStringPackage.

Text Of(Temp Ptr. Filename)) - Convert_To_Upper(Filename) THEN

Found := TRUE; -- search is done, exit loop

-- bump to next node; increment node counter

ELSE

Temp_Ptr : Temp_Ptr.Next;

Node_Counter := Node_Counter + i;

END IF;

END LOOP;

RETURN Found;

-- allow calling routine to handle the exceptions

EXCEPTION

_£EN OTHERS =>

RAISE;

END Filename_Exists;

-- This function searches a filename list for a file tag and returns

79
-- a boolean telling whether or not it was f<und.

-- Inputs:

-- Filename_List - tag/filename list to bc searched

-- File Tag tag to search for in list

-- Outputs:

-- Exceptions:

............................................................................

FUNCTION FileTag_Exists

(Filename_List : IN Filename_List Type;

File_Tag : IN STRING) RETURN BOOLEAN IS

-- for counting the number of nodes in the list

Node_Counter : NATURAL := i;

-- temporary pointer used to manipulate taz/filename list

Temp_Ptr : File_Node_Access_Type := Filename List.Node_List;

-- boolean used to control search

Found : BOOLEAN : FALSE;

BEGIN

-- initialize

Found := FALSE;

Node_Counter := i;

-- examine every node until found or end of list is reached

WHILE Node_Counter <= Filename_List. Length AND NOT Found LOOP

-- comparisons are not case sensitive; convert both to upper case

-- and then compare them

IF Convert_To_Upper

(Variable String_Package.

Text Of(Temp_Ptr. File Tag)) = Convert To Upper(File Tag) THEN

Found := TRUE; -- search is done, e:_it loop

-- bump to next node; increment node coaster

ELSE

Temp_Ptr : Temp_Ptr.Next;

Node_Counter := Node_Counter + i;

END IF;

END LOOP;

RETURN Found;

-- allow calling routine to handle the exceptions

EXCEPTION

WHEN OTHERS :>

RAISE;

END File_Tag_Exists;

-- This function searches the specified list _or the file tag passed

8O
-- to it and returns the file name associated with that tag. The

-- tag comparisons are NOT case sensitive.

-- Inputs:

-- Fiiename_List - tag/fi!ename list to be searched

-- File_Tag tag to search for in list

-- Outputs:

-- Exceptions:

-- Invalid_Tag raised when the input file tag is not found

-- in the list

............................................................................

FUNCTION Get_Filename

(Filename List : IN Filename List_Type;

File Tag : IN STRING) RETURN STRING IS

-- for counting the number of nodes in the list

Node_Counter : NATURAL := i;

-- temporary pointer used to manipulate tag/filename list

Temp_Ptr : File_Node Access_Type := Filename_List.Node_List;

-- boolean used to control search

Found • BOOLEAN := FALSE;

BEGIN

-- initialize

Found :: FALSE;

Node_Counter :- i;

-- examine every node until found or end of list is reached

WHILE Node_Counter <= Filename_List. Length AND NOT Found LOOP

-- comparisons are not case sensitive; convert both to upper case

-- and then compare them

IF Convert_To_Upper

(Variable_String Package.

Text Of(Temp_Ptr. File_Tag)) Convert_To_Upper(File Tag) THEN

Found := TRUE; -- search is done, exit loop

-- bump to next node; increment node counter

ELSE

Temp_Ptr := Temp_Ptr.Next;

Node_Counter := Node_Counter + i;

END IF;

END LOOP;

-- done searching list; if the tag was found return the filename;

-- otherwise, raise the Invalid_Tag exception

IF Found THEN

RETURN Variable_String Package. Text_Of(Temp_Ptr. Filename) ;

ELSE

RAISE Invalid_Tag;

END IF;

-- allow calling routine to handle the exceptions

EXCEPTION

WHEN OTHERS =>

RAISE;

81
END Get Filename;

-- This function searches the specified list for the filename passed

-- to it and returns the file tag associated with that filename. The

-- filename comparisons are NOT case sensitive.

-- Inputs:

-- Filename List - tag/filename list to bc searched

-- Filename filename to search for in list

-- Outputs:

-- Exceptions:

-- Invalid Filename - raised when the input filename is not found

-- in the list

............................................................................

FUNCTION Get_File_Tag

(Fi!ename List : IN Filename_List Type;

Filename : IN STRING) RETURN STRING IS

-- for counting the number of nodes in the list

Node_Counter : NATURAL := i;

-- temporary pointer used to manipulate tag/filename list

Temp Ptr : File_Node_Access Type := Filename_List.Node List;

-- boolean used to control search

Found : BOOLEAN :: FALSE;

BEGIN

-- initialize

Found := FALSE;

Node_Counter := l;

-- examine every node until found or end of list is reached

WHILE Node Counter < Filename_List. Lengnh AND NOT Found LOOP

-- comparisons are not case sensitive; _onvert both to upper case

-- and then compare them

IF Convert_ToUpper

(VariableStringPackage.

Text_Of(Temp Ptr. Filename)) = Convert_To Upper(Filename) THEN

Found := TRUE; -- search is done, e:<it loop

-- bump to next node; increment node coInter

ELSE

Temp_Ptr := Temp_Ptr.Next;

Node_Counter := Node_Counter + i;

END IF;

END LOOP;

-- done searching list; if the filename wa:_ found return the file tag;

-- otherwise, raise the Invalid Filename e::ception

IF Found THEN

RETURN Variable String Package. Text Of(['emp Ptr. File Tag);

82
ELSE

RAISE Invalid_Filename;

END IF;

-- allow calling routine to handle the exceptions

EXCEPTION

WHEN OTHERS =>

RAISE;

END GetFile_Tag;

-- This function finds the node specified by the position passed

-- in and returns the filename at that position.

-- Inputs:

-- Filename List - tag/filename list to be searched

-- Position position in list to return filename from

-- Outputs:

-- Exceptions:

-- Invalid Position - position does not exist for input list

............................................................................

FUNCTION Get_Filename

(Filename List : IN Filename List_Type;

Position : IN Natural) RETURN STRING IS

-- temporary pointer used to manipulate tag/filename list

Temp_Ptr : File_Node_Access_Type : Filename_List.Node_List;

BEGIN

-- make sure that the postion is valid; if not, raise exception

IF Position = 0 OR Position > Fiiename_List.Length THEN

RAISE InvalidPosition;

ELSE

-- traverse list to desired position

FOR I IN l..Position - 1 LOOP

Temp_Ptr := Temp_Ptr.Next;

END LOOP;

-- return the filename at the desired position

RETURN Variable_String_Package. Text Of(Temp_Ptr.Filename) ;

END IF;

-- allow calling routine to handle the exceptions

EXCEPTION

WHEN OTHERS =>

RAISE;

END Get Filename;

83
-- This function finds the node specified by the position passed

-- in and returns the file tag at that position.

-- Inputs:

-- Filename List - tag/filename list to be searched

-- Position - position in list to return file tag from

-- Outputs:

-- Exceptions:

-- Invalid Position - position does not exist for input list

............................................................................

FUNCTION GetFile_Tag

(Filename_List : IN Filename List_Type;

Position : IN Natural) RETURN STRING IS

-- temporary pointer used to manipulate tag/filename list

Temp_Ptr : File_Node_Access_Type := Filename_List.Node List;

BEGIN

-- make sure _hat the postion is valid; if not, raise exception

IF Position = 0 OR Position > Filename_Lis:.Length THEN

RAISE InvalidPosition;

ELSE

-- traverse list to desired position

FOR I IN l..Position - 1 LOOP

Temp_Ptr := Temp_Ptr.Next;

END LOOP;

-- return the file tag at the desired p)sition

RETURN Variable_String_Package. Text_Of( ?emp_Ptr.File_Tag);

END IF;

-- allow calling routine to handle the exceptions

EXCEPTION

WHEN OTHERS >

RAISE;

END GetFile_Tag;

-- This function searches for the specified f: lename in the list, and

-- returns the position in the list of the no{[e which contains it.

-- Inputs:

- Filename List - tag/filename list to be searched

-- Filename filename to search for n list

-- Outputs:

-- Exceptions:

-- Invalid Filename - raised when the input filename is not in the

-- input list

............................................................................

FL_CTION Get_Filename_Position

(Filename List : IN Filename list Type;

Filename : IN STRING) rETURN NATURAL IS

84
-- for counting the number of nodes in the list and returning

-- the position at which the input fi!ename is found

Position : NATURAL := i;

-- temporary pointer used to manipulate tag/filename list

Temp Ptr : File Node_Access_Type := Filename List.Node_List;

-- boolean used to control search

Found : BOOLEAN := FALSE;

BEGIN

-- initialize

Found :: FALSE;

Position := i;

-- examine every node until found or end of list is reached

WHILE Position <= Filename_List. Length AND NOT Found LOOP

-- comparisons are not case sensitive; convert both to upper case

-- and then compare them

IF Convert_ToUpper

(Variable String_Package.

Text_Of(Temp Ptr. Filename)) = Convert_To Upper(Fiiename) THEN

Found := TRUE; -- search is done, exit loop

-- bump to next node; increment node counter

ELSE

Temp_Ptr := Temp_Ptr.Next;

Position := Position + i;

END IF;

END LOOP;

-- done searching list; if the filename was found return the position;

-- otherwise, raise the Invalid_Filename exception

IF Found THEN

RETURN Position;

ELSE

RAISE Invalid_Filename;

END IF;

-- allow calling routine to handle the exceptions

EXCEPTION

WHEN OTHERS =>

RAISE;

END Get Filename Position;

-- This function searches for the specified file tag in the list, and

-- returns the position in the list of the node which contains it.

-- Inputs:

-- Filename List - tag/filename list to be searched

-- File Tag - file tag to search for in list

-- Outputs:

85
-- Exceptions:

-- Invalid_File_Tag - raised when the input file tag is not in the

-- input list

............................................................................

FUNCTION Get_File_Tag_Position

(Filename List : IN Filename_List_Type;

File_Tag : IN STRING) RETURN NATURAL IS

-- for counting the number of nodes in th_ list and returning

-- the position at which the input file <ag is found

Position : NATURAL := i;

-- temporary pointer used to manipulate tag/fi!ename list

Temp Ptr : File_Node_Access_Type := Filename List.Node_List;

-- boolean used to control search

Found : BOOLEAN : : F_LSE;

BEGIN

-- initialize

Found := FALSE;

Position : i;

-- examine every node until found or end of list is reached

WHILE Position < Filename_List. Length ANE NOT Found LOOP

-- comparisons are not case sensitive; convert both to upper case

-- and then compare them

IF Convert_To_Upper

(VariableStringPackage.

Text_Of(Temp Ptr. File_Tag)) = Convert_To Upper(File Tag) THEN

Found := TRUE; -- search is done, exit loop

-- bump to next node; increment node counter

ELSE

Temp_Ptr := Temp_Ptr.Next;

Position := Position + i;

END IF;

END LOOP;

-- done searching list; if the file tag was found return the position;

-- otherwise, raise the Invalid_File_Tag exception

IF Found THEN

RETURN Position;

ELSE

RAISE Invalid_Tag;

END IF;

-- allow calling routine to handle the except_ons

EXCEPTION

WHEN OTHERS =>

RAISE;

END Get_File_Tag_Position;

86
-- This procedure sorts a list. The user has the option to do the

-- reorder by file tag or filename. The procedure uses a bubble sort

-- swapping pointers when necessary instead of exchanging file tags and

-- filenames.

-- Inputs:

-- Filename List - tag/fiiename list to be sorted

-- Sort sort type (by file tag or filename

-- Outputs:

-- Filename_List - tag/filename list to be sorted

-- Exceptions:

............................................................................

PROCEDURE Sort_Fi!ename List

(Filename List : IN OUT Filename_List Type;

Sort : IN List Sort_Type) IS

-- temporary pointers used to manipulate tag/filename list

Temp_Ptr : File Node_Access_Type :- Filename_List.Node_List;

Prev_Ptr : File Node_Access_Type : NULL;

-- local booleans

No_Exchange : BOOLEAN := TRUE;

Swap • BOOLEAN := FALSE;

BEGIN

LOOP

-- initially point to front of list on each pass of this outer loop

Temp Ptr :_ Filename List.Node_List;

Prev_Ptr := NULL;

-- initially

No_Exchange := TRUE;

WHILE Temp_Ptr.Next /= NULL LOOP

-- check sort type and compare tag or filename at current node

-- and next node. Swap if necessary.

Swap := FALSE;

IF Sort - By_File_Tag THEN

IF Convert_To_Upper

(VariableString_Package

.Text Of(Temp_Ptr. File Tag)) >

Convert_ToUpper

(Variable_String Package.

Text Of(Temp_Ptr.Next.File Tag)) THEN

Swap :- TRUE;

END IF;

ELSE

IF Convert_To_Upper

(VariableStringPackage.

Text_Of(Temp Ptr.Filename)) >

87
Convert_To_Upper

(Variable String_Package.

Text_Of(Temp Ptr.Next.Filename)) THEN

Swap :: TRUE;

END IF;

END IF;

-- if swap is necessary, just swap _ointers

IF Swap THEN

-- node to swap is first node

IF Temp_Ptr : Filename_List.Node List THEN

Filename_List.Node_List := Temp_Ptr.Next;

Prev_Ptr := Filename_List.Node_List;

Temp_Ptr.Next :: Temp_Ptr.Next.Next;

Prev_Ptr.Next : Temp_Ptr;

-- all other nodes

ELSE

Prev_Ptr.Next :- Temp Ptr. Next;

Temp_Ptr.Next := Temp_Ptr.Next.Next;

Prev_Ptr.Next.Next :- Temp_Ptr;

Prev_Ptr := Prev_Ptr.Next;

END IF;

-- made a swap

No Exchange := FALSE;

ELSE

-- no swap made; go to next node

Prev_Ptr := Temp_Ptr;

Temp_Ptr := Temp_Ptr.Next;

END IF ;

END LOOP ;

-- list is sorted

EXIT WHEN No_Exchange;

END LOOP;

-- allow calling routine to handle the exceptions

EXCEPTION

WHEN OTHERS >

RAISE;

END Sort_Filename_List;

END Filename_Manager_Package;

88
Appendix 3: Constants Package

-- File Name: CFGCONST.ADS (spec only version)

-- Organization: NASA - Langley Research Center (LaRC)

-- Project: LIDAR In-Space Technology Experiment (LITE)

...............................................................................

__*****************************************************************************

-- Name/Number:

System_Constants (package spec)

Abstract:

This package spec contains several constants which are used in the

CFG User Interface software to define color schemes, file name

extensions and directories, Screen mode constants, and others. It

has no body.

Acronyms/Abbreviations:

None

Dependencies:

Menu_Package

Screen_Package

KeyboardPackage

Global Objects:

All

-- Exceptions:

-- None

-- Machine/Compiler Dependencies:

with Unsigned;

with Menu_Package;

with Screen_Package;

with KeyboardPackage;

Package SystemConstants Is

-- This is the main color scheme used in the menus and windows of the

-- user interface on the Master AT.

Normal_Color_Scheme : constant Menu_Package.Color_Scheme Type :-

(Screen_Package. Blue Background, -- Background_Color

Screen Package. Bright_White Foreground, -- Foreround_Color

Screen Package. Yellow Foreground, -- Title Color

Screen_Package. Yellow Foreground, -- Border_Color

Screen Package. Light Red_Foreground); -- Highlight_Color

-- This color scheme is used on the Master AT when a menu or window is

.... grayed out" after the user has made a selection.

Inactive Color_Scheme : constant Menu_Package.Color_Scheme_Type :-

(Screen Package.Blue_Background, -- Background_Color

Screen_Package.White_Foreground, -- Foreround_Color

Screen_Package.Yellow Foreground, -- Title Color

89
Screen_Package. White_Foreground,

Screen_Package. Black_Foreground);

-- Border Color

-- Highlight_Color

Warning_CScheme : CONSTANT Menu_Package.Color_Scheme Type :

(ScreenPackage. Red_Background, -- Background_Color

Screen Package. Bright_White_Foreground, -- Foreround_Color

Screen Package. Yellow_Foreground, -- Title Color

Screen Package. Yellow Foreground, -- Border_Color

Screen Package. Yellow Foreground); -- Highlight_Color

Standby_Warning CScheme : CONSTANT Menu_Package.Color_Scheme_Type :_

(Screen Package. Magenta Backgroundn -- Background Color

Screen_Package. Light_Green_Foreground, -- Foreround_Color

Screen_Package. Bright_White Foreground, -- Title Color

Screen Package. Yellow Foreground, -- Border_Color

Screen Package. Yellow_Foreground); -- Highlight_Color

-- These constants define the size of the screen for anybody that needs

-- to know these things

Screen_Mode : CONSTANT Screen_Package. Text_Mode_Type :- Screen_Package. Color_80x50;

Number of Columns : CONSTANT Screen_Package. Column_Type :- 80;

Number Of Rows : CONSTANT Screen_Package. Row_Type := 50;

File_Name_Length : CONSTANT := 8;

Full_File_Name Length : CONSTANT := 12; -- this includes the file extension

-- 600 bytes in NASCOM block --

NASCOM_Block_Length : CONSTANT in_eger := 600;

Bit_Size

NibbleSize

Word_Size

: CONSTANT := i;

: CONSTANT := 4;

: CONSTANT := 16;

Lookup_Table 1 Minimum_Pressure : CONSTANT FLOAT := 15.0;

Lookup_Table 1 Maximum_Pressure : CONSTANT FL]AT := 65.0;

Lookup_Table 2 Minimum Pressure : CONSTANT FL]AT := 5.0;

Lookup_Table 2 Maximum Pressure : CONSTANT FL)AT := 65.0;

-- maximum number of command words a command :]lock can contain

Max_Command_Words : CONSTANT := 28;

-- maximum number of command words in a command block transferred to

-- the IC via the PGSC

Max_Via_PGSC_Command_Words : CONSTANT : 22;

-- maximum number of words in a single comman_ block, including header

-- information words

Max_Block Size : CONSTANT := 30;

S_Key_Array : CONSTANT Keyboard Package. Special_Keys Array_Type (1..3) :=

(Keyboard Package. Fl_Key, K_board_Package. F2 Key,

Keyboard Package. Fl0_Key);

IC S Key_Array : CONSTANT Keyboard_Package. S[)ecial Keys_Array_Type (1..4) :=

(Keyboard_Package.Fl_Key, K,_yboard_Package. F2_Key,

Keyboard Package.F3_Keyn K,_yboard_Package. Fl0_Key) ;

No F! Key_Array : CONSTANT Keyboard_Package. S]_ecial_Keys Array Type (i..2) :-

(Keyboard_Package.F2_Key, K,_yboard_Package. Fl0 Key) ;

Fl0_Key_Array : CONSTANT Keyboard_Package. S])ecial_Keys_Array_Type (I..i) :

(OTHERS > Keyboard Package Fl0_Key);

Extra_Chars

Blanks

: CONSTANT STRING : " .,<>?/\,;: []{}-_=+J'_!@#S%^&,(),,;

: CONSTANT STRING (i .. 80) : (]THERS => ' ');

9O
-- This is the maximum number of Time Specific Commands that could be in

-- a single L!TE command block (if all commands were non-parametric,

-- time-specific commands, they would be 3 words each, and so at most 9 of

-- them could fit in a 28-word LITE command block).

Max TS Cmds_Per_Block : CONSTANT : 9;

Max TS Commands : CONSTANT := 32;

Command_MenuWidth : CONST_MT : 24;

-- this offset is added to the hot key position read in from the data file, so that

-- all mnemonics in the menu are a few spaces over from the left edge of the menu

Menu_Offset : CONSTANT := 3;

Menu_Offset String : CONSTANT STRING (1..3) := (OTHERS -> ' ');

Max_MnemonicLength

Descriptor Length

Units_String_Max

: CONSTANT := 15;

: CONSTANT := 40;

• CONSTANT := 5;

-- Command Code constants for uplink code mode commands

Byte IO Write_Command Code : CONSTANT := 16#50#;

Word IO Write_Command_Code : CONSTANT := 16#51#;

Memory_Write_Command_Code : CONSTANT :- 16#54#;

Memory_Fill Command_Code : CONSTANT :- 16#56#;

-- LITE IC null commands

LITE IC Null_Cmd_Fill_Pattern_High_Byte : CONSTANT := 16#04#;

LITE IC Null Cmd_Fiil_Pattern_Low_Byte : CONSTANT := 16#FF#;

Reserved : CONSTANT Unsigned. Byte :- 0;

-- row offset for next menu after drawing an inactive box around the

-- previous menu selection

Show_Menu_Choice_Offset : CONSTANT :- 5;

-- there are 28 Memory read strings that can be displayed at one time; this

-- area of the display is broken down into 28 rows of 45 character strings

Max_Memory Reads : CONSTANT POSITIVE : 28; -- up to 28 mem read displayable

Memory_String_Length : CONSTANT := 45; -- string length

-- there are 45 IO read strings that can be displayed at one time; this area

-- of the display is broken down into 9 rows and 5 columns of 9 character

-- strings

Max IO Rows : CONSTANT POSITIVE : 9; -- max IO read rows

Max IO Cols : CONSTANT POSITIVE := 5; -- max IO read co!s

IO String_Length : CONSTANT POSITIVE := 9; -- individual read string length

Max IO Reads : CONSTANT POSITIVE := Max IO Rows * Max IO Cols; -- max mem reads

ICCommand_Frame

IC_Memory_Frame

IC_Uplink Byte

: CONSTANT :- 8;

: CONSTANT := I0;

: CONSTANT := 53;

Byte IO Read_Command_Code : CONSTANT : 16#52#;

Word IO Read_Command_Code : CONSTANT := 16#53#;

Memory_Read_Command_Code : CONSTANT := 16#55#;

PDI_Sync_Pattern : CONSTANT Unsigned.Word := 16#BEEF#;

-- min and max screen rows

Max_Top_Row : CONSTANT Screen_Package. Row_Type := i;

91
Max_Bottom_Row : CONSTANT Screen_Package. Row_Type :: 49 ;

Max_Column : CONSTANT := 79;

-- number of rows in the general error windo%

Rows In Error_Window : CONSTANT := 5;

-- user input and title row offsets from top of many prompt windows

Input_Offset Row : CONSTANT Screen Package. Row_Type := 2;

Title_Offset_Row : CONSTANT Screen Package. Row_Type := 2;

-- bottom row offset from top for many prompt windows

Bottom_Row Offset : CONSTANT Screen Package. Row_Type := 4;

-- # of rows in a yes/no box

Yes No Box_Rows : CONSTANT Screen Package. Row_Type : 6;

SecondsPerDay

Seconds_Per_Hour

: CONSTANT Integer := 86500;

: CONSTANT Integer :: 3690;

-- These constants define the "boiler plate" fields for the NASCOM shell. They are as

-- correct as we can make them right now. We have had difficulty verifying the proper

-- current values for many of these fields, and a few are still set to zero because

-- we have not yet been able to find ANY value for them from JSC. They will need to

-- be updated later.

NASCOM_HeaderSync_Byte_l

NASCOM_Header_Sync_Byte_2

NASCOM_Header_Sync Byte 3

SourceCode

Destination_Code

Block_SequenceCounter

Format_ID

User_Header_Source Circuit ID

: CONSTANT := 98; -- 62h

: CONSTANT :- 118; -- 76h

: CONSTANT :- 39; -- 27h

• CONSTANT := 173;

: CONST_ := 56; -- 38h

: CONSTANT := 7;

: CONSTANT := 9;

• CONSTANT := 0;

-- ADh

User_Header_Source Circuit_Sequence_Number : CONSTANT := 15;

User_Header Spare Bit : CONSTANT := I;

User_Header_Block_Sequence_Number : CONSTANT := 7;

User_Header_Message_Type : CONSTANT := 143; -- 8Fh

User_Header Destination Code • CONST_ := 112; -- 70h

User_Header_Spare_Bit_l

User_Header_Spare_Bit_2

UserHeader_FullBlockFlag

User_Header_DataLength

NASCOM Trailer_Fl

NASCOM_Trailer_F2

Command_DataPOCC_Command_Message_Number

Command_DataPayload_Vehicle_ID

Command_DataCommandType

Command Data Orbiter Uplink_Mode

TestCommandCommand_Type

: CONSTANT := l;

: CONSTANT := i;

: CONSTANT := 0;

: CONSTANT := 512;

: CONSTANT :- i;

: CONSTANT := 0;

: CONSTANT := 999;

: CONSTANT : 0;

: CONSTANT := i;

: CONSTANT := 0;

: CONSTANT := 0;

-- 01h

LITE_CommandHeader_SFMDM_Source_ID

LITE_Command_Header_SFMDM_Sync

LITE_CommandHeader_SFMDM_IOMType

: CONSTANT := 13;

: CONSTANT : 5;

: CONSTANT :- 14;

LITE_Command_Header_SFMDM_Command_ID

LITE_Command_Header_SFMDM_IOM

LITE_Command_Header_SFMDM Channel_Number

LITE_Command_Header_Fil!

LITE_Command_Word_Count

LITE_Command Footer Filler

: CONSTANT :- 3;

: SONSTANT := 0;

: _ONSTANT : 0;

: SONSTANT := 0;

: :ONSTANT := 30;

: :ONSTANT := 0;

DOL Command_Header SFMDM_Source_ID

DOLCommand_Header_SFMDH_Sync

DOLCommand_Header_SFMDM_IOM_Type

: _ONSTANT := 13;

: :ONST_NT := 5;

: :ONSTANT := 13;

92
DOL_Command_Heade r_SFMDM_Command_ i D

DOL_Command_Heade r_SFMDM_I OM

DOL Command Hea de r_SFMDM_Channe 1Number

DOL Command Word_Count

DOL_Command Footer Checksum

DDCS_Command_Header_SFMDM_Source_ID

DDCS_Command_Header_SFMDM_Sync

DDCS_Command_HeaderSFMDM_IOMType

DDCS_Command_Header_DDCS_Command_ID

DDCS_Command_WordCount

DDCS_Command_Footer_Filler

: CONSTANT : 8;

: CONSTANT : 0;

: CONSTANT :- 0;

: CONSTANT := 3;

: CONSTANT : 244;

: CONSTANT := 13;

: CONSTANT := 5;

: CONSTANT := 0;

: CONSTANT := i0;

: CONSTANT := 8;

: CONSTANT := 0;

-- Ai_

End System_Constants;

93
°.. ................ _ ....... o ............... o ................................. •...................................................

-- File Name: CFGCONST.ADS (Function vers:_on)

-- Organization: NASA - Langley Research Center (LaRC)

-- Project: LIDAR In-Space Technology E}periment (LITE)

...............................................................................

__*****************************************************************************

Name/Number:

System_Constants (package sL_ec)

Abstract:

This package spec contains several constarts which are used in the

CFG User Interface software to define colcr schemes, file name

extensions and directories, Screen mode constants, and others.

Acronyms/Abbreviations:

None

Dependencies:

Unsigned

MenuPackage

ScreenPackage

Keyboard_Package

Global Objects:

All

Exceptions:

None

with Unsigned;

with Menu_Package;

with ScreenPackage;

with KeyboardPackage;

Package System_ConstantsPackage Is

-- This is the main color scheme used in the nenus and windows of the

-- user interface on the Master AT.

Function Normal_Color_Scheme RETURN Menu_Pack_ge.Color_Scheme_Type;

-- This color scheme is used on the Master AT when a menu or window is

.... grayed out" after the user has made a selection.

Function inactive_Color_Scheme RETURN Menu_Pazkage. Color_Scheme_Type;

-- This color scheme is used for all CFG warn.ng message and error

-- message windows

Function Warning_CScheme RETURN Menu_Package.,_olor_Scheme_Type;

-- This color scheme is used for the "Emergen:y Go To Standby" Command Window

Function Standby_Warning_CScheme RETURN Menu_ )ackage. Color_SchemeType;

-- These constants define the size of the scr,_en for anybody that needs

-- to know these things

Function Screen Mode RETURN Screen_Package.Te::t_Mode Type;

Function Number of Columns RETURN Screen_Pack,_ge. Column_Type;

Function Number Of Rows RETURN Screen_Package Row_Type;

94
Function File_NameLength RETURN Natural;

Function Full_FileName_Length RETURN Natural;

-- 600 bytes in NASCOM block --

Function NASCOM_Block_Length RETURN Integer;

Function

Function

Function

BitSize RETURN Positive;

Nibble_Size RETURN Positive;

Word_Size RETURN Positive;

Function

Function

Function

Function

Lookup_Table 1 Minimum_Pressure RETURN FLOAT;

Lookup Table 1 Maximum_Pressure RETURN FLOAT;

Lookup Table 2 Minimum_Pressure RETURN FLOAT;

Lookup_Table 2 Maximum_Pressure RETURN FLOAT;

-- maximum number of command words a command block can contain

Function Max_Command Words RETURN Positive;

-- maximum number of command words in a command block transferred to

-- the IC via the PGSC

Function Max_Via_PGSC_Command_Words RETURN Positive;

-- maximum number of words in a single command block,

-- information words

Function Max_Block_Size RETURN Positive;

including header

Function S_KeyArray RETURN Keyboard_Package. Special Keys_Array_Type;

Function IC S Key_Array RETURN Keyboard Package. Special_Keys_Array_Type;

Function No F1 Key_Array RETURN Keyboard Package. Special_Keys Array_Type;

Function Fl0_Key_Array RETURN Keyboard Package. Special_Keys_ArrayType;

Function ExtraChars

Function Blanks

RETURN STRING;

RETURN STRING;

-- This is the maximum number of Time Specific Commands that could be in

-- a single LITE command block (if all commands were non-parametric,

-- time-specific commands, they would be 3 words each, and so at most 9 of

-- them could fit in a 28-word LITE command block).

Function Max TS Cmds_Per_Block RETURN Positive;

Function Max TS Commands RETURN Positive;

Function Command_Menu_Width RETURN Positive;

-- this offset is added to the hot key position read in from the data file, so that

-- all mnemonics in the menu are a few spaces over from the left edge of the menu

Function Menu_Offset RETURN Natural;

Function Menu Offset_String RETURN STRING;

Function Max_MnemonicLength

Function Descriptor Length

Function UnitsString_Max

RETURN Positive;

RETURN Positive;

RETURN Positive;

-- Command Code constants for uplink code mode commands

Function Byte IO Write_Command_Code RETURN Natural;

Function Word IO Write Command_Code RETURN Natural;

Function Memory_Write_Command_Code RETURN Natural;

Function Memory_Fill_Command_Code RETURN Natural;

95
-- LITE IC null commands

Function LITE IC Null_Cmd_Fill_Pattern_High__yte RETURN Natural;

Function LITE IC Null_Cmd_Fill_Pattern_Low_B}te RETURN Natural;

Function Reserved RETURN Unsigned. Byte;

-- row offset for next menu after drawing an inactive box around the

-- previous menu selection

Function Show Menu Choice_Offset RETURN Natural;

-- there are 28 Memory read strings that can be displayed at one time; this

-- area of the display is broken down into 28 rows of 45 character strings

Function Max_Memory_Reads RETURN Positive; -- up to 28 mem read displayable

Function Memory_String_Length RETURN Positive; -- string length

-- there are 45 IO read strings that can be displayed at one time; this area

-- of the display is broken down into 9 rows and 5 columns of 9 character

-- strings

Function Max IO Rows RETURN Positive; -- max IO read rows

Function Max IO Cols RETURN Positive; -- max IO read cols

Function IO_String_Length RETURN Positive; -- individual read string length

Function Max IO Reads RETURN Positive; -- max mem reads

Function

Function

Function

Function

Function

Function

IC_Contmand_Frame RETURN Nat]ral;

IC_Memory_Frame RETURN Natural;

IC_Uplink_Byte RETURN Natural;

Byte IO Read_Command_Code RETURN Natural;

Word IO Read_Command_Code RETURN Natural;

Memory_Read_Command_Code RETURN Natural;

Function PDI_Sync_Pattern RETURN Unsigned. Word;

-- min and max screen rows

Function Max_Top_Row

Function Max_Bottom_Row

Function Max_Column

RETURN Screen_Package.Row_Type;

RETURN Screen_P_ckage. Row_Type;

RETURN Screen_P_ckage.Column_Type;

-- number of rows in the general error window

Function Rows In Error_Window RETURN Screen_Package.Row_Type;

-- user input and title row offsets from top of many prompt windows

Function Input_OffsetRow RETURN Screen_Package.Row_Type;

Function Title_Offset_Row RETURN Screen Package. Row_Type;

-- bottom row offset from top for many prompt windows

Function Bottom_Row_Offset RETURN Screen_P, tckage.Row_Type;

-- # of rows in a yes/no box

Function Yes No Box_Rows RETURN Screen_P_ckage.Row_Type;

Function Seconds_Per_Day RETURN Integer;

Function Seconds_Per_Hour RETURN Integer;

Function NASCOM_Header_Sync_! RETURN

Function NASCOM_Header_Sync_2 RETURN

Function NASCOM_Header_Sync_3 RETURN

Function Source_Code RETURN

Function Destination_Code RETURN

Function Block_Sequence_Counter RETURN

Function Format_ID RETURN

Function User_Header_Source_Circuit_ID RETURN

Function User_Header_Source_Circuit_Sequence__umber RETURN

Integer;

Integer;

Integer;

Integer;

Integer;

Integer;

Integer;

Integer;

Integer;

96
Function

Function

Function

Function

Function

Function

Function

Function

Function

Function

Function

Function

Function

Function

Function

User Header_Spare_Bit

UserHeader_BlockSequence_Number

UserHeader_MessageType

User Header_Destination_Code

User_Header_Spare_Bit_l

User_Header_Spare_Bit_2

User_HeaderFullBlock_Flag

User_Header_Data_Length

NASCOM_Trailer F1

NASCOM_Trailer_F2

Command Data_POCC_Command_Message Number

Command Data_Payload_Vehicle_ID

CommandDataCommand_Type

Command Data Orbiter_Uplink_Mode

Test_Command_Command_Type

Function

Function

Function

Function

Function

Function

Function

Function

Function

LITE_Command_HeaderSFMDM_Source_ID

LITECommand_Header_SFMDM_Sync

LITE_Command_HeaderSFMDM_IOMType

LITE_CommandHeader_SFMDM_CommandID

LITE_Command_Header_SFMDMIOM

LITE_Command_Header_SFMDM_Channel_Number

LITE_Command_Header_Fill

LITE_Command_WordCount

LITE_Command_Footer Filler

Function

Function

Function

Function

Function

Function

Function

Function

Function

Function

Function

Function

Function

Function

DOLCommand_Header_SFMDM_Source_ID

DOL_Command_Header_SFMDM_Sync

DOLCommand_Header_SFMDMIOM_Type

DOL_Command_Header_SFMDM_Command_ID

DOL_Command_HeaderSFMDM_IOM

DOL_CommandHeader_SFMDMChannel_Number

DOLCommand_Word_Count

DOL_Command_Footer_Checksum

DDCS_CommandHeader_SFMDMSource_ID

DDCS_Command_Header_SFMDM_Sync

DDCSCommand_Header_SFMDM_IOM_Type

DDCS_Com_and_Header_DDCS_Command_ID

DDCS_Command_WordCount

DDCS_Command_Footer_Filler

End System_Constants_Package;

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

RETURN

integer;

Integer;

Integer;

Integer;

Integer;

Integer;

Integer;

Integer

Integer

Integer

Integer

Integer

Integer

Integer

Integer

Integer;

Integer;

Integer;

Integer;

Integer;

Integer;

Integer;

Integer;

Integer;

integer;

Integer;

Integer;

Integer;

Integer;

Integer;

Integer;

integer;

Integer;

Integer;

Integer;

Integer;

Integer;

Integer;

97
-- File Name: CFGCONST.ADB

-- Organization: NASA - Langley Research Center (LaRC)

-- Project: LIDAR In-Space Technology E}periment (LITE)

...............................................................................

__*****************************************************************************

-- Name/Number:

-- System Constants Package (peckage body)

-- Abstract:

This package spec contains several constants which are used in the

CFG User Interface software to define color schemes, file name

extensions and directories, Screen mode ccnstants, and others, it

has no body.

-T

Acronyms/Abbreviations:

None

Dependencies:

Unsigned

Menu_Package

ScreenPackage

Keyboard_Package

Global Objects:

All

Exceptions:

None

Machine/Compiler Dependencies:

with Unsigned;

with MenuPackage;

with Screen_Package;

with KeyboardPackage;

Package Body SystemConstants_Package Is

-- This is the main color scheme used in the menus and windows of the

-- user interface on the Master AT.

Normal Color_Scheme Val : CONSTANT Menu_Packa,[e.Color Scheme_Type :-

(Screen Package. Blue Background, - Background Color

Screen Package.Bright White_Foreground, - Foreround_Color

Screen_Package. Yellow Foreground, -Title_Color

Screen Package. Yellow_Foreground, - Border Color

Screen_Package. Light Red_Foreground); - Highlight Color

-- This color scheme is used on the Master AT when a menu or window is

-- "grayed out" after the user has made a sel_ction.

Inactive_Coior_Scheme_Val : CONSTANT Menu Pac]:age.Color Scheme_Type ::

(Screen Package. Blue_Background, - Background Color

Screen Package. White Foreground, - Foreround_Color

Screen_Package. Yellow_Foreground, -- Title Color

Screen Package.White Foreground, -- Border_Color

Screen Package. Black_Foreground); -- Highlight Color

-- This color scheme is used for all CFG warning message and error

-- message windows

98
Warning_CScheme_Val : CONSTANT Menu_Package. Color_Scheme_Type ::

(Screen_Package. Red_Background, -- Background_Color

Screen_Package. Bright_White Foreground, -- Foreround_Coior

Screen Package. Yellow Foreground, -- Title Color

Screen_Package. Yellow_Foreground, -- Border_Color

Screen Package. Yellow_Foreground); -- Highlight_Color

-- This color scheme is used for the "Emergency Go To Standby" Command Window

Standby Warning CScheme_Val : CONSTANT Menu Package.Color_Scheme Type :=

(Screen Package. Magenta Background, -- Background_Color

Screen_Package.Light_Green Foreground, -- Foreround_Color

Screen Package. Bright_White Foreground, -- Title_Color

Screen_Package.Yellow Foreground, -- Border Color

Screen Package. Yellow Foreground); -- Highlight_Color

-- These constants define the size of the screen for anybody that needs

-- to know these things

Screen_Mode_Val : CONSTANT Screen Package.Text_Mode Type :

Screen_Package.Color_80x50;

Number of Columns_Val : CONSTANT Screen_Package.Column Type : 80;

Number Of Rows_Val : CONSTANT Screen_Package.Row_Type := 50;

File_Name_Length_Val : CONSTANT Natural := 8;

Full_Fiie Name_Length_Val : CONSTANT Natural := 12; --this includes the file extension

-- 600 bytes in NASCOM block --

NASCOM_Block_Length_Val • CONSTANT Integer := 600;

Bit_Size Val

Nibble Size_Val

Word_Size Val

: CONSTANT Positive := i;

: CONSTANT Positive := 4;

: CONSTANT Positive := 16;

Lookup_Table ! Minimum_Pressure Val : CONSTANT FLOAT := 15.0;

Lookup_Table 1 Maximum_Pressure_Val : CONSTANT FLOAT := 65.0;

Lookup_Table 2 Minimum_Pressure_Val : CONSTANT FLOAT := 5.0;

Lookup_Table 2 Maximum_Pressure_Val : CONSTANT FLOAT := 65.0;

-- maximum number of command words a command block can contain

Max Command_Words_Val : CONSTANT Positive := 28;

-- maximum number of command words in a command block transferred to

-- the IC via the PGSC

Max_Via_PGSC Command_Words_Val : CONSTANT Positive : 22;

-- maximum number of words in a single command block, including header

-- information words

Max_Block Size_Val : CONSTANT Positive := 30;

S Key_Array_Val

(Keyboard_Package. Fl_Key, Keyboard_Package. F2_Key,

Keyboard_Package. Fl0 Key);

IC_S_Key Array_Val : CONSTANT Keyboard Package.Special_Keys Array Type (i..4

(Keyboard_Package. Fl_Key, Keyboard_Package. F2_Key,

Keyboard_Package. F3 Key, Keyboard_Package. Fl0_Key);

No F1 Key_Array_Val : CONSTANT Keyboard_Package. Special_Keys_Array_Type (1..2

(Keyboard_Package. F2_Key, Keyboard_Package. Fl0 Key);

Fl0_Key_Array_Val : CONSTANT Keyboard_Package. Special_Keys Array Type (i..i

(OTHERS -> Keyboard_Package. Fl0_Key);

: CONSTANT Keyboard Package. Special Keys_Array Type (1..3) :=

Extra Chars_Val

Blanks_Val

: CONSTANT STRING := " .,<>?/\';: [] {}-_=+l'-[@#$%^&*()";

: CONSTANT STRING (i .. 80) := (OTHERS => ' ');

99
-- This is the maximum number of Time Specifiz Commands that could be in

-- a single LITE command block (if all commands were non-parametric,

-- time-specific commands, they would be 3 words each, and so at most 9 of

-- them could fit in a 28-word LITE command block).

Max TS Cmds Per Block Val : CONSTANT Positive := 9;

Max TS Commands Val : CONSTANT Positive := 32;

Command_Menu Width Val : CONSTANT Positive := 24;

-- this offset is added to the hot key position read in from the data file, so that

-- all mnemonics in the menu are a few spaces over from the left edge of the menu

Menu_Offset_Val : CONSTANT Natural := 3;

Menu_Offset_String_Val : CONSTANT STRING ([..3) := (OTHERS => ' ');

Max_MnemonicLength_Val

Descriptor_Length Val

Units String Max_Va!

: CONSTANT Positive :: 15;

: CONSTANT Positive :: 40;

: CONSTANT Positive := 5;

-- Command Code constants for uplink code mode commands

Byte IO Write Command_Code VAL : CONSTANT Natural := 16#50#;

Word IO Write_Command Code_Val : CONSTANT Natural := 16#51#;

Memory_Write_Command Code_Val : CONSTANT Natural := 16#54#;

Memory_Fill_Command_Code_Val : CONSTANT Natiral :: 16#56#;

-- LITE IC null commands

LITE IC Null Cmd Fill Pattern High Byte_Val : CONSTANT Natural := 16#04#;

LITE IC Null_Cmd_Fill_Pattern Low_Byte_Val : CONSTANT Natural := 16#FF#;

Reserved_Val : CONSTANT Unsigned. Byte := 0;

-- row offset for next menu after drawing an inactive box around the

-- previous menu selection

Show_Menu_Choice Offset_Val : CONSTANT NatiLral := 5;

-- there are 28 Memory read strings that can be displayed at one time; this

-- area of the display is broken down into 28 rows of 45 character strings

Max_Memory Reads Val : CONSTANT Positive ;= 28; -- up to 28 mem read displayable

Memory_String Length_Val : CONSTANT Positive :- 45; -- string length

-- there are 45 IO read strings that can be displayed at one time; this area

-- of the display is broken down into 9 rows _nd 5 columns of 9 character

-- strings

Max IO Rows_Val : CONSTANT POSITIVE := 9; -- max IO read rows

Max IO Cois Vai : CONSTANT POSITIVE := 5; -- max IO read cols

IO_String_Length_Val: CONSTANT POSITIVE := 9; -- individual read string length

Max IO Reads Val : CONSTANT POSITIVE := Ma} IO Rows * Max IO Cols; -- max mem reads

IC_Command_Frame_Val

IC_MemoryFrame_Val

IC_UplinkByte_Val

Byte IO Read_Command_Code_Val

Word IO Read_Command_Code Val

Memory_Read_Command_Code_Val

: CONSTANT Nat<ral := 8;

: CONSTANT Nat<ral :: i0;

: CONSTANT Nat<ral :: 53;

: CONSTANT Natural : 16#52#;

: CONSTANT Natural := 16#53#;

: CONSTANT Natural := 16#55#;

PDI_Sync_Pattern_Val : CONSTANT Unsigned. Word :: 16#BEEF#;

-- min and max screen rows

Max Top_Row_Val : CONSTANT Screen_Package. Row_Type :: i;

Max_Bottom_Row_Val : CONSTANT Screen_Package. Row Type :- 49;

Max_Column Val : CONSTANT Screen Package. Column Type := 79;

-- number of rows in the general error window

Rows In Error_Window_Val : CONSTANT Screen_Package. Row_Type :: 5;

100
-- user input and title row offsets from top of many prompt windows

Input_Offset_Row_Val : CONSTANT Screen_Package. Row_Type :- 2;

Title_Offset Row Val : CONSTANT Screen_Package. Row_Type : 2;

-- bottom row offset from top for many prompt windows

Bottom Row_Offset_Val : CONSTANT Screen Package. Row_Type :: 4;

-- # of rows in a yes/no box

Yes No Box_Rows Val : CONSTANT Screen_Package. Row_Type := 6;

Seconds_Per_Day_Val

Seconds_Per Hour_Val

: CONSTANT Integer : 86400;

: CONSTANT Integer : 3600;

NASCOM_Header Sync_Byte 1 Val

NASCOM_Header Sync_Byte 2 Val

NASCOM_Header Sync_Byte 3 Val

Source_Code Val

Destination Code_Val

Block_Sequence_Counter_Val

Format ID Val

User Header_Source Circuit ID Val

: CONSTANT Integer :: 98; -- 62h

: CONSTANT Integer := 118; -- 76h

: CONSTANT Integer := 39; -- 27h

: CONSTANT Integer := 173; -- ADh

: CONSTANT Integer := 56; -- 38h

: CONSTANT Integer := 7;

: CONSTANT Integer := 9;

: CONSTANT Integer := 255;

User_Header_Source Circuit_Sequence_Number_Val : CONSTANT Integer := 15;

User_Header_Spare Bit_Val

User_Header_Block_SequenceNumber_Val

User_Header Message_Type_Val

User_Header Destination Code Va!

User_Header Spare_Bit 1 Val

User_Header_Spare_Bit 2 Val

User_Header_Full_Block_Flag_Val

User_Header_Data_Length_Val

NASCOM Trailer F1 Val

NASCOM_Trailer F2 Va!

Command_Data_POCCCommand_Message_Number_Val

Command_Data Payload_Vehicle ID Val

Command_DataCommand_TypeVal

Command_DataOrbiter_Uplink_Mode_Val

Test_Command_Command_Type_Val

: CONSTANT Integer :- I;

: CONSTANT Integer : 7;

: CONSTANT Integer :- 143; -- 8Fh

: CONSTANT Integer : !12; -- 70h

: CONSTANT Integer : i;

: CONSTANT Integer := i;

: CONSTANT Integer := 0;

: CONSTANT Integer := 512;

: CONSTANT Integer := I;

: CONSTANT Integer := 0;

: CONSTANT Integer := 999;

: CONSTANT Integer : 55; -- 37h

: CONSTANT Integer := i; -- 01h

: CONSTANT Integer := 4; -- 04h

• CONSTANT Integer :- 0; -- Oh

LITE_Command_Header_SFMDM_Source ID Val

LITE_Command_Header_SFMDM_SyncVal

LITE_Command_Header_SFMDM_IOMType_Val

LITE_Command_Header_SFMDM_Command ID Val

LITE_Command_Header_SFMDM_IOM_Val

LiTE_Command_Header_SFMDM_Channel_Number_Val

LITECommand_Header_Fill_Val

LITE_Command Word_Count_Val

LITE_Command_Footer_FillerVal

: CONSTANT Integer := 13;

: CONSTANT Integer := 5;

: CONSTANT Integer := 14;

: CONSTANT Integer :- 3;

: CONSTANT Integer := 0;

: CONSTANT Integer : 0;

: CONSTANT Integer := 0;

: CONSTANT Integer := 30;

: CONSTANT Integer := 0;

DOL_Command_Header_SFMDM_Source ID Val

DOL_Command_Header_SFMDM_SyncVal

DOL_CommandHeader_SFMDM_IOMType_Val

DOL_CommandHeader_SFMDMCommand ID Val

DOL_Command_Header_SFMDM_IOM_Val

DOLCommand_HeaderSFMDM_Channel_Number_Val

DOL_Command_Word_Count_Val

DOLCommand_Footer_Checksum_Va!

: CONSTANT Integer :: 13;

: CONSTANT Integer := 5;

: CONSTANT Integer := 13;

: CONSTANT Integer := 8;

• CONSTANT Integer : 0;

: CONSTANT Integer := 0;

: CONSTANT Integer := 3;

• CONSTANT Integer : 244; -- F4h

DDCS_Command_Header_SFMDM_Source ID Val

DDCS_CommandHeader_SFMDMSync_Val

DDCS_Command_Header_SFMDM_IOM_Type_Val

DDCS_Command_Header_DDCS_Command ID Val

DDCSCommand_Word_Count_Val

DDCS_Command_Footer_Filler_Val

: CONSTANT Integer := 13; -- Dh

: CONSTANT Integer := 5;

: CONSTANT Integer := 0;

• CONSTANT Integer := i0; -- Ah

: CONSTANT Integer := 8;

• CONSTANT Integer := 0;

101
-- This is the main color scheme used in the menus and windows of the

-- user interface on the Master AT.

Function Normal_Color Scheme RETURN Menu_Package.Color_Scheme_Type IS

BEGIN

RETURN Normal_Color_Scheme_Val;

END Normal_Color_Scheme;

-- This color scheme is used on the Master AT when a menu or window is

.... grayed out" after the user has made a selection.

Function Inactive_Color_Scheme RETURN Menu_Package. Color_SchemeType IS

BEGIN

RETURN Inactive_Color_Scheme_Val;

END Inactive_Color_Scheme;

-- This color scheme is used for all CFG warning message and error

-- message windows

Function Warning_CScheme RETURN Menu_Package. Color_Scheme_Type IS

BEGIN

RETURN Warning_CSchemeVal;

END Warning_CScheme;

-- This color scheme is used for the "Emergency Go To Standby" Command Window

Function Standby_Warning_CScheme RETURN Menu Package.Color Scheme_Type IS

BEGIN

RETURN Standby Warning CScheme Val;

END Standby Warning_CScheme;

-- ... next, some screen locations and important columns and rows:

-- These constants define the size of the scr(en for anybody that needs

-- to know these things

Function Screen_Mode RETURN Screen_Package.Text_Mode_Type IS

BEGIN

RETURN Screen_ModeVal;

END Screen_Mode;

Function Number of Columns RETURN Screen Package. Column_Type IS

BEGIN

RETURN Number of Columns_Val;

END Number of Columns;

Function Number Of Rows RETURN Screen_Package.Row_Type IS

BEGIN

102
RETURN Number Of Rows_Val;

END Number Of Rows;

-- min and max screen rows

Function Max_Top_Row RETURN Screen_Package.Row_Type IS

BEGIN

RETURN Max_TopRow_Val;

END Max_Top_Row;

Function Max Bottom_Row RETURN Screen_Package.Row_Type IS

BEGIN

RETURN Max_Bottom_RowVal;

END Max_Botnom_Row;

Function Max Column RETURN Screen Package. Column_Type IS

BEGIN

RETURN Max Column_Val;

EN_ Max_Column;

-- number of rows in the general error window

Function Rows In Error_Window RETURN Screen_Package.Row Type IS

BEGIN

RETURN Rows In Error_Window Val;

END Rows in Error_Window;

-- user input and title row offsets from top of many prompt windows

Function Input Offset_Row RETURN Screen_Package.Row Type IS

BEGIN

RETURN Input_Offset_Row_Val;

END Input Offset_Row;

Function Title Offset_Row RETURN ScreenPackage.Row_Type IS

BEGIN

RETURN Title_Offset_Row Val;

END Title_OffsetRow;

-- bottom row offset from top for many prompt windows

Function Bottom_Row_Offset RETURN Screen_Package. Row_Type IS

BEGIN

RETURN Bottom_Row_Offset_Val;

END Bottom_Row_Offset;

-- # of rows in a yes/no box

Function Yes No Box_Rows RETURN Screen_Package. RowType IS

BEGIN

RETURN Yes No Box_Rows_Val;

END Yes No Box_Rows;

-- row offset for next menu after drawing an inactive box around the

-- previous menu selection

Function ShowMenu_ChoiceOffset RETURN Natural IS

BEGIN

RETURN Show_Menu_ChoiceOffset_Val;

END Show_Menu_Choice Offset;

Function Command_Menu_Width RETURN Positive IS

BEGIN

RETURN Command_Menu_Width_Val;

END Command_Menu_Width;

103
Function S_KeyArray RETURN Keyboard_Package. Special_Keys_Array_Type IS

BEGIN

RETURN S_Key_Array_Val;

END S_Key_Array;

Function IC S Key_Array RETURN Keyboard_Package. Special_Keys_Array_Type IS

BEGIN

RETURN IC S Key_Array Val;

END IC S Key_Array;

Function No F1 Key_Array RETURN Keyboard_Pack_ge. Special_Keys_Array_Type IS

BEGIN

RETURN No F1Key_Array_Val;

END No F! Key_Array;

Function FI0 Key_Array RETURN Keyboard_Package. Special_Keys Array_Type IS

BEGIN

RETURN Fl0_Key_Array_Vai;

End Fl0_Key_Array;

-- ... and these are some general-purpose constants used in the user interface:

...............................................................................

Function Extra_Chars RETURN STRING IS

BEGIN

RETURN Extra_Chars_Val;

END Extra_Chars;

Function Blanks RETURN STRING IS

BEGIN

RETURN Blanks_Val;

END Blanks;

-- this offset is added to the hot key positL)n read in from the data file, so that

-- all mnemonics in the menu are a few spaces over from the left edge of the menu

Function Menu_Offset RETURN Natural IS

BEGIN

RETURN Menu_Offset_Val;

END Menu_Offset;

Function Menu_Offset_String RETURN STRING IS

BEGIN

RETURN Menu_Offset_String_Val;

END Menu Offset_String;

Function Max_Mnemonic_Length RETURN Positive [IS

BEGIN

RETURN Max_Mnemonic_Length_Val;

END Max_Mnemonic_Length;

Function Descriptor Length RETURN Positive IS

BEGIN

RETURN Descriptor_Length_Va!;

END Descriptor_Length;

Function Units_String_Max RETURN Positive IS

BEGIN

RETURN Units_String_Max_Val;

104
END Units_String_Max;

-- maximum number of command words a command block can contain

Function Max_Command Words RETURN Positive IS

BEGIN

RETURN Max_Command Words_Val;

END Max_Command_Words;

-- maximum number of command words in a command block transferred to

-- the IC via the PGSC

Function Max_Via_PGSC_Command Words RETURN Positive IS

BEGIN

RETURN Max Via_PGSC_Command_Words_Val ;

END Max_Via_PGSC_Command_Words ;

-- maximum number of words in a single command block, including header

-- information words

Function Max_Block_Size RETURN Positive IS

BEGIN

RETURN Max_Block_Size_Val;

END Max_Block_Size;

-- This is the maximum number of Time Specific Commands that could be in

-- a single LITE command block (if all commands were non-parametric,

-- time-specific commands, they would be 3 words each, and so at most 9 of

-- them could fit in a 28-word LITE command block).

Function Max TS Cmds Per_Block RETURN Positive IS

BEGIN

RETURN Max TS Cmds_Per_B!ock_Val;

END Max TS Cmds_Per_Block;

Function Max TS Commands RETURN Positive IS

BEGIN

RETURN Max TS Commands_Val;

END Max TS Commands;

-- Command Code constants for uplink code mode commands

Function Byte IO Write_Command_Code RETURN Natural IS

BEGIN

RETURN Byte IO Write_Command Code_Val;

END Byte IO Write_Command_Code;

Function Word IO Write_Command_Code RETURN Natural IS

BEGIN

RETURN Word IO Write_Command Code_Val;

END Word IO Write_Command_Code;

Function Byte IO Read_Command_Code RETURN Natural IS

BEGIN

RETURN Byte IO Read Command_Code_Val;

END Byte IO Read_Command_Code;

Function Word IO Read_Command_Code RETURN Natural IS

BEGIN

RETURN Word IO Read_Command_Code_Val;

END Word IO Read_Command_Code;

Function Memory_Write_Command_Code RETURN Natural IS

105
BEGIN

RETURN Memory_Write_Command_Code_Va!;

END Memory_WriteCommand_Code;

Function Memory_Read_Command_Code RETURN Natural IS

BEGIN

RETURN Memory_Read_Command_CodeVal;

END Memory_Read_Command_Code;

Function Memory_Fill_CommandCode RETURN Natural IS

BEGIN

RETURN Memory_Fill_CommandCode_Val;

END Memory_FillCommand_Code;

-- there are 28 Memory read strings that can be displayed at one time; this

-- area of the display is broken down into 28 rows of 45 character strings

Function MaxMemory_Reads RETURN Positive IS

BEGIN

RETURN Max_Memory_Reads_Val;

END Max_Memory_Reads;

Function Memory_String_Length RETURN Positive IS

BEGIN

RETURN Memory String_Length_Val;

END Memory_String_Length;

-- there are 45 IO read strings that can be displayed at one time; this area

-- of the display is broken down into 9 rows _nd 5 columns of 9 character

-- strings

Function Max IO Rows RETURN Positive IS

BEGIN

RETURN Max IO Rows Val;

END Max IO Rows;

Function Max IO Cols RETURN Positive IS

BEGIN

RETURN Max IO Cois_Val;

END Max IO Cols;

Function IO_String_Length RETURN Positive IS

BEGIN

RETURN IO String_Length_Val;

END IO_String_Length;

Function Max IO Reads RETURN Positive IS

BEGIN

RETURN Max IO Reads_Val;

END Max IO Reads;

Function IC_Command_Frame RETURN Natural IS

BEGIN

RETURN ICCommand_Frame_Val;

END IC_Command_Frame;

Function IC_Memory_Frame RETURN Natural IS

BEGIN

RETURN ICMemory_Frame_Val;

END IC_Memory_Frame;

Function iC_Uplink_Byte RETURN Natural IS

BEGIN

RETURN IC Uplink_Byte_Val;

106
END IC_Uplink_Byte;

-- these are used to compute the parameter for lookup table commands

...............................................................................

Function Lookup Table 1 Minimum_Pressure RETURN FLOAT IS

BEGIN

RETURN Lookup Table 1 Minimum_Pressure_Val;

END Lookup_Table 1 Minimum_Pressure;

Function Lookup_Table 1 Maximum Pressure RETURN FLOAT IS

BEGIN

RETURN Lookup_Table ! Maximum_Pressure_Val;

END Lookup_Table 1 Maximum_Pressure;

Function Lookup_Table 2 Minimum_Pressure RETURN FLOAT IS

BEGIN

RETURN Lookup_Table 2 Minimum Pressure_Val;

END Lookup_Table 2 Minimum_Pressure;

Function Lookup_Table 2 Maximum Pressure RETURN FLOAT IS

BEGIN

RETURN Lookup Table 2 Maximum_Pressure_Val;

END Lookup_Table 2 Maximum_Pressure;

Function Bit_Size RETURN Positive IS

BEGIN

RETURN Bit_Size_Val;

END Bit_Size;

Function NibbleSize RETURN Positive IS

BEGIN

RETURN Nibble_Size_Val;

END Nibble Size;

Function Word_Size RETURN Positive IS

BEGIN

RETURN Word_Size_Val;

END WordSize;

Function File_Name_Length RETURN Natural IS

BEGIN

RETURN File_Name_Length_Val;

END File_NameLength;

Function Full_File_Name_Length RETURN Natural IS

BEGIN

RETURN Full_File_Name_Length_Val;

END Full_FileName_Length;

Function Seconds_Per Day RETURN Integer IS

BEGIN

RETURN Seconds Per_Day_Val;

END SecondsPer_Day;

Function Seconds_Per Hour RETURN Integer IS

BEGIN

107
RETURN Seconds_Per_Hour_Val;

END Seconds_Per_Hour;

Function PDI_Sync_Pattern RETURN Unsigned. Word IS

BEGIN

RETURN PDI_Sync_Pattern_Val;

END PDI_Sync_Pattern;

-- 600 bytes in NASCOM block --

Function NASCOM_Block_Length RETURN Integer IS

BEGIN

RETURN NASCOM_Block_LengthVal;

END NASCOM Block Length;

Function NASCOM_Header_Sync_l RETURN Integer IS

BEGIN

RETURN NASCOM_Header_Sync_Byte 1 Val;

END NASCOM_Header_Sync_l;

Function NASCOM Header Sync_2 RETURN Integer

BEGIN

RETURN NASCOM_Header_Sync_Byte 2 Val;

END NASCOM_Header Sync 2;

IS

Function NASCOM_Header_Sync_3 RETURN Integer IS

BEGIN

RETURN NASCOM_Header_Sync_Byte 3 Val;

END NASCOM_Header_Sync_3;

Function Source_Code RETURN Integer IS

BEGIN

RETURN Source_Code_Val;

END SourceCode;

Function Destination_Code RETURN Integer IS

BEGIN

RETURN Destination_Code_Val;

E_ Destination_Code;

Function Block_Sequence_Counter RETURN Intege: IS

BEGIN

RETURN Block_Sequence_CounterVal;

END BlockSequence_Counter;

Function Format_ID RETURN Integer IS

BEGIN

RETURN Format ID Val;

END Format_ID;

Function User_Header_Source_Circuit_ID RETURN Integer IS

BEGIN

RETURN User_Header_Source_Circuit ID Val;

END User Header Source_Circuit ID;

Function User Header_Source_Circuit_Sequence }Umber RETURN Integer IS

BEGIN

RETURN User Header Source Circuit_Sequence Number Val;

END User_Header_Source_Circuit_SequenceNumbel;

108
Function User_Header_Spare_Bit RETURN Integer IS

BEGIN

RETURN User Header_Spare Bit_Val;

END User_Header_Spare_Bit;

Function User_Header_Block_Sequence_Number RETURN Integer IS

BEGIN

RETURN User_Header_Block Sequence Number_Va!;

END User_Header_Block_Sequence_Number;

Function User_Header Message_Type RETURN Integer IS

BEGIN

RETURN User_Header_Message_Type_Val;

END User_Header_Message_Type;

Function User_Header_Destination_Code RETURN Integer IS

BEGIN

RETURN User_Header Destination_Code_Val;

END User_Header_Destination_Code;

Function User Header_Spare_Bit_l RETURN Integer IS

BEGIN

RETURN User Header_Spare Bit 1 Val;

END User_Header_Spare_Bit l;

Function User_Header Spare_Bit_2 RETURN Integer IS

BEGIN

RETURN User_Header Spare_Bit 2 Val;

END User_Header_Spare Bit_2;

Function User_Header_Full_BlockFlag RETURN Integer IS

BEGIN

RETURN User Header_Full_Block_Flag_Val;

END User_Header_Full_BlockFlag;

Function User_Header_Data_Length RETURN Integer IS

BEGIN

RETURN User_Header_Data_Length_Val;

END User_Header_Data_Length;

Function NASCOM_Trailer_FI RETURN Integer IS

BEGIN

RETURN NASCOM_Trailer F1 Val;

END NASCOM_Trailer_FI;

Function NASCOM_Trailer F2 RETURN Integer IS

BEGIN

RETURN NASCOM Trailer F2 Val;

END NASCOM_Trailer_F2;

Function Command_Data POCC_Command_Message_Number RETURN Integer IS

BEGIN

RETURN Command_Data_POCC Command_Message_Number_Val ;

END Command Da t a_POCC_C ommand_Me s sage_Number ;

Function Command_Data_Payload_Vehicle_ID RETURN Integer IS

BEGIN

RETURN Command_Data Payload_Vehicle ID Val;

END Command_Data_Payload Vehicle ID;

Function Command_Data_Command_Type RETURN Integer IS

BEGIN

RETURN Command Data_Command_TypeVal;

109
END Command_Data_Command_Type;

Function Command_Data_Orbiter_Uplink_Mode REqURN Integer IS

BEGIN

RETURN Command_Data_Orbiter_Uplink_Mode_V61;

END Command_Data_Orbiter_Uplink_Mode;

Function Test_Command_Command_Type RETURN Integer IS

BEGIN

RETURN Test Command_CommandType_Val;

END Test_Command_CommandType;

-- constants required to fill the LITE commadn klock header and footer:

...............................................................................

Function LITE_Command_Header_SFMDM_Source_ID RETURN Integer IS

BEGIN

RETURN LiTE_Command_Header_SFMDM_Source IE Val;

END LiTE_Command_Header_SFMDM_SourceID;

Function LITE_Command_Header_SFMI)M_Sync RETURN Integer IS

BEGIN

RETURN LITE_Command_HeaderSFMDM_Sync_Val;

END LITE_Command_Header_SFMDM_Sync;

Function LITE_Command_Header_SFMDM_IOM_Type RETURN Integer IS

BEGIN

RETURN LITE_Command_Header_SFMDMIOM_Type_Jal;

END LITE_CommandHeader_SFMDM_IOM_Type;

Function LITE_Command_Header_SFMDM_CommandID RETURN Integer IS

BEGIN

RETURN LITECommand_Header_SFMDM_Command ID Val;

END LITE Command_Header SFMDM Command ID;

Function LITE_Co_mand Header_SFMI]M_IOM RETURN Integer IS

BEGIN

RETURN LITECommand_Header_SFMDM_IOM_Val;

END LITE_Command_Header_SFMDM_IOM;

Function LITE_Command_Header_SFMDM_ChannelNui_er RETURN Integer IS

BEGIN

RETURN LITE_Command_Header_SFMDM_Channel_Nunber_Val;

END LITE_Command_Header_SFMDM_Channel_Number;

Function LITE_Com_and_Header_Fill RETURN Inte,_er IS

BEGIN

RETURN LITECommand_Header_Fill_Val;

END LITE_Command_Header_Fill;

Function LITE_Command_Word_Count RETURN Integ,_r IS

BEGIN

RETURN LITE_Command_Word_Count_Val;

END LITE_Command Word_Count;

Function LITE_Command_Footer Filler RETURN Inl eger IS

BEGIN

RETURN LITE_Command_Footer_Filler_Val;

END LITE_Command_Footer_Filler;

Function Reserved RETURN Unsigned. Byte IS

BEGIN

110
RETURN Reserved_Val;

END Reserved;

-- LITE IC null commands

Function LITE IC Null_Cmd Fill_Pattern High_Byte RETURN Natural IS

BEGIN

RETURN LITE IC Null_Cmd Fill_Pattern_High_Byte_Val;

END LITE IC Null_Cmd_Fill_Pattern High_Byte;

Function LITE IC Null_Cmd Fill_Pattern_Low_Byte RETURN Natural IS

BEGIN

RETURN LITE IC Null_Cmd_Fil!_Pattern_Low Byte_Val;

END LITE IC Nu!l_Cmd Fill_Pattern Low_Byte;

-- constants used to configure and send DOL commands in a NASCOM block

...............................................................................

Function DOL Command_Header_SFMDM Source_ID RETURN Integer IS

BEGIN

RETURN DOL_Command_Header_SFMDM_Source ID Val;

END DOL_Command Header_SFMDM Source_ID;

Function DOL_Command_Header_SFMDM_Sync RETURN Integer IS

BEGIN

RETURN DOL_CommandHeader_SFMDM_Sync_Val;

END DOL_Command_Header_SFMOM_Sync;

Function DOL_Command_HeaderSFMDM_IOM_Type RETURN Integer IS

BEGIN

RETURN DOLCommand_Header_SFMDM_IOM_Type_Val;

END DOL_Command_Header_SFMDM_IOM_Type;

Function DOL_Command_HeaderSFMDM_Command_ID RETURN Integer IS

BEGIN

RETURN DOLCommand_Header_SFMDM_Command ID Val;

END DOL_Command_HeaderSFMDM_CommandID;

Function DOL_Command Header_SFMDM_IOM RETURN Integer IS

BEGIN

RETURN DOL_CommandHeader_SFMDMIOM_Val;

END DOLCommand_Header_SFMDM_IOM;

Function DOL_CommandHeader_SFMDM_Channel_Nu-mber RETURN Integer IS

BEGIN

RETURN DOL_Command_Header_SFMDM_Channel_Number_Vai;

END DOL_Command_Header_SFMDM_Channel_Number;

Function DOL_Command Word_Count RETURN Integer IS

BEGIN

RETURN DOLCommand Word_Count_Val;

END DOL_Command_WordCount;

Function DOL_Command_Footer_Checksum RETURN Integer IS

BEGIN

RETURN DOL_Command_Footer_Checksum_Val;

END DOLCommand_Footer_Checksum;

-- constants used to configure and send DDCS commands in a NASCOM block

...............................................................................

111
Function DDCS_Command_Header_SFMI)M_Source ID RETURN Integer IS

BEGIN

RETURN DDCS_Command_Header SFMDM_Source I[ Val;

END DDCS_Command_Header_SFMDM Source_ID ;

Function DDCS_Command_Header_SFMDM_Sync RETURN Integer IS

BEGIN

RETURN DDCS_Command_HeaderSFMDMSync_Val;

END DDCS_Command_Header_SFMDMSync;

Function DDCS_Command_Header SFMDM_IOM_Type RETURN Integer IS

BEGIN

RETURN DDCS_Command_HeaderSFMDM_IOM_Type_Val;

END DDCS_Command_Header_SFMDMIOM_Type;

Function DDCSCommand_Header_DDCS_Command_ID RETURN Integer IS

BEGIN

RETURN DDCS Command_Header DDCS_Command ID Val;

END DDCS_Command_Header_DDCS_Command_ID;

Function DDCS_Com_and_Word_Count RETURN Integer IS

BEGIN

RETURN DDCS_Command_Word_Count_Val;

END DDCSCommand Word_Count;

Function DDCS_Command_Footer Filler RETURN Integer IS

BEGIN

RETURN DDCS_Command_FooterFiller_Val;

END DDCS_Command_Footer_Filler;

End System_ConstantsPackage;

112
-- File Name: CFGCONST.INI

-- Organization: NASA - Langley Research Center (LaRC)

-- Project: LIDAR In-Space Technology Experiment (LITE)

...............................................................................

Name/Number:

CFG System Constants

-- Acronyms/Abbreviations:

-- None

-- Dependencies:

-- None

-- Global Objects:

-- None

-- Exceptions:

-- None

(initialization file)

Abstract:

This file contains the values of all of the constants which are accessed

through the System_Constants_Package. They are read in at startup by the

Initialize_System_Constants procedure.

-- Normal Color Scheme

[BlueBackground]

[Bright_White_Foreground]

[Yellow_Foreground]

[YellowForeground]

[Light_Red_Foreground]

-- Background_Color

-- Foreround_Color

-- Title_Color

-- Border_Color

-- Highlight_Color

-- Inactive_Color_Scheme

[Blue_Background]

[White_Foreground]

[Yellow_Foreground]

[White_Foreground]

[Black_Foreground]

-- Background_Color

-- Foreround_Color

-- Title_Color

-- Border_Color

-- Highlight_Color

-- Warning Color Scheme

[Red_Background]

[BrightWhite_Foreground]

[YellowForeground]

[Yellow_Foreground]

[Yellow_Foreground]

-- Background_Color

-- Foreround_Color

-- Title_Color

-- Border_Color

-- Highlight_Color

-- Standby Warning Color Scheme

[Magenta_Background] -- Background_Color

[Light_Green Foreground] -- Foreround Color

[Bright White Foreground] -- Title_Color

[Yellow_Foreground] -- Border_Color

[Yellow_Foreground] -- Highlight_Color

[Color_80x50]

[8O]

[50]

If]

-- Screen Mode

-- Number of Columns

-- Number of Rows

-- Max Top_Row

113
[49]

[79]

[8]

[12]

[600]

Ill

[4]

[16]

[15.0]

[65.0]

[5.0]

[65.0]

[28]

[22]

[30]

[3]

[F !_Key ]

[F 2_Key ]

IF10 Key]

[43

[Fl_Key]

[F2_Key]

[F3_Key]

[Fl0_Key]

-- Max_Bottom_Row

-- Max_Column

-- File Name Length (no extension)

-- File Name Length (WITH extensiol (and 'dot'))

-- NASCOM Block Length

-- Bit Size

-- Nibble Size

-- Word Size

-- Lookup_Table 1 Minimum Pressure

-- Lookup Table 1 Maximum Pressure

-- Lookup Table 2 Minimum_Pressure

-- Lookup_Table 2 Maximum_Pressure

-- Max # of command words in a LITZ command block

-- Max # command words in a LITE command block sent via the PGSC

-- Total size of LITE command block, including headers

-- S Key Array size

-- IC S Key_Array size

[2]

[F2_Key]

[Fl0Key]

size of No F1 Key_Array

[i] -- Fl0_Key Array size

[Fl0_Key]

[ .,<>?/\';:[]{}-_:+l'-!@#$%^&*()]

[80]

-- Extra_Chars string for (File ID input)

-- Length of Blanks string

[9] -- Max number of Time Specific Commands ira LITE command block

[32] -- Max number of commands, period, in a LIfE command block (all Immed, 0 parms)

[24] -- Command Menu width (for ALL CFG commacLn_ menus)

[3]

[ ]

-- Menu Offset

-- Menu Offset_String

[15]

[40]

[5]

-- Max Mnemonic_Length

-- Descriptor Length

-- Units String_Max

[16#50#]

[16#51#]

[16#52#]

[16#53#]

[16#54#]

[16#55#]

-- Byte IO Write_Command_Code

-- Word IO Write_Command Code

-- Byte IO Read_Command_Code

-- Word IO Read Command_Code

-- Memory Write Command_Code

-- Memory Read_Co_mandCode

114
[16#56#] -- Memory Fill_Command_Code

[16#04#]

[16#FF#]

-- LITE IC Null Cmd_Fill_Pattern_High_Byte

-- LITE IC Nuli_Cmd_Fill_Pattern_Low_Byte

[0] -- Reserved

[5] -- Show Menu_Choice Offset

[28]

[4S]

[9]

[5]

[9]

-- Max Memory_Reads

-- Memory String Length

-- Max IO Rows

-- Max IO Cois

-- IO_String Length

[8] -- IC_Command_Frame

[i0] -- iC_Memory_Frame

[53] -- IC_Uplink_Byte

[i6#BEEF#] -- PDI_Sync_Pattern

[5]

[2]

[2]

[4]

[6]

-- Rows In Error_Window

-- Input_Offset_Row

-- Title Offset Row

-- Bottom Row_Offset

-- Yes No Box_Rows

[86400]

[3600]

-- Seconds_Per Day

-- Seconds_Per_Hour

[98]

[118]

[39]

[173]

[56]

[7]

[9]

[255]

[15]

[1]

[7]

[143]

[112]

[1]

[1]

[0]

[512]

[i]

[0]

[999]

[55]

[1]

[4]

[0]

-- NASCOM_Header_Sync_Byte_!

-- NASCOM_Header_Sync_Byte_2

-- NASCOM_Header_Sync_Byte_3

-- Source_Code

-- Destination_Code

-- Block_Sequence_Counter

-- Format_ID

-- User_Header_Source_Circuit_ID

-- User_Header_Source_CircuitSequence_Number

-- User_Header_Spare_Bit

-- User Header_Block_Sequence_Number

-- User_Header_Message Type

-- User_Header_Destination Code

-- User Header_Spare_Bit_l

-- User Header_Spare_Bit 2

-- User_Header_Full_Block_Flag

-- User_Header_Data Length

-- NASCOM_Trailer F1

-- NASCOM_Trailer_F2

-- Command_Data_POCCCommand_Message_Number

-- Command_Data_Payload_Vehicle_ID

-- CommandData_Command_Type

-- Command_Dat a_Orbi t er Up i ink_Mode

-- Te s t_Command_Command_Type

[13] -- LITE_Command_Header_SFMDM_Source_ID

[5] -- LITE_Command_Header_SFMDM_Sync

[14] -- LITE_Command Header_SFMDM IOM_Type

[3] -- LITE_Command_Header_SFMDM_Command_ID

[0] -- LITECommand_Header_SFMDM_IOM

[0] -- LITECommand_Header_SFMDM_Channel_Number

[0] -- LITE Command_Header_Fill

[30] -- LITE Command Word_Count

[0] -- LITE_Command_Footer_Filler

115
[13]

[5]

[13]

[8]

[0]

[0]

[3]

[244]

[13]

[5]

[0]

[10]

[81

[0]

-- DOL_Command_HeaderSFMDM_Source_ID

-- DOLCommand_HeaderSFMDM_Sync

-- DOL_Command_HeaderSFMDM_IOM_Type

-- DOL_Command_He ade r S FMDM_C ommand_I D

-- DOL_Command_Heade r S FMDM_I OM

-- DOL_Command_Header S FMDM_Cha_ne l_Numbe _:

-- DOL Command_Word_Count

-- DOL_Command_FooterChecksum

-- DDCSCommand_Header_SFMDM_Source_ID

-- DDCS_Command_Header_SFMDMSync

-- DDCS Command Header SFMDM IOM_Type

-- DDCS Command Header DDCS Command_ID

-- DDCS_Co_mand_Word_Count

-- DDCS Command_Footer_Filler

116
117
REPORTDOCUMENTATIONPAGE Fo_ _p_ove_

OMB No. 0704-0188

Pubic reporting burden for this collection of information is estimated to average 1 hour per raspor_se, including the time for reviewing instructions, seamhing existing data

soumes, gathenng and maintaining the date needed, and completing and reviewing the collec_on of infon'nation. Send comments regarding this burden estimate or any other

aspect of this collection of information, including suggestions for reducing this burden, to Washin{ ton Headquarters Senhces, Directorate for Information Operations and

Reports, 1215 Jefferson Davis Highway, Suite 1204, Arlington, VA 22202-4302, and to the Offic _of Management and Budget, Paperwork Reduction Project (0704-0188),

Washington, De 20503.

1. AGENCY USE ONLY (Leave blank) 2. REPORT DATE 3. REPORT TYPE AND DATES COVERED

October 1998 Technical Memorandum

4. TITLE AND SUI_¥tVLE 5. FUNDING NUMBERS

Designing for Change: Minimizing the Impact of Changing Requirements in

the Later Stages of a Spaceflight Software Project WU 258-70-21-10

6.AUTHOR(S)

B. Danette Allen

7.PERFORMINGORGANIZATIONAME(S)ANDADDRESS(ES)

NASA Langley Research Center

Hampton, VA 23681-2199

9.SPONSORING/MONITORINGAENCYNAME(S)ANDADDRESSEES)

National Aeronautics and Space Administration

Washington, DC 20546-0001

8. PERFORMING ORGANIZATION

REPORT NUMBER

L-17762

IO. SPONSORING/MONITORING

AGENCY REPORT NUMBER

NASA/TM-1998-208466

11. SUPPLEMENTARY NOTES

12a.DISTRIBUTION/AVAILABILITY STATEMENT

Unclassified-Unlimited

Subject Category 61 Distribution: Nonstandard

Availability: NASA CASI (301) 621-0390

12b. DISTRIBUTION CODE

13. ABe; HACT (Maximum 200 words)

In the traditional "waterfall" model of the software project life cycle, the Requirements Phase ends and flows

into the Design Phase, which ends and flows into the Development Phase. Unfortunately, the process rarely, if

ever, works so smoothly in practice. Instead, software developers often receive new requirements, or

modifications to the original requirements, well after the earlier project phases have been completed. In

particular, projects with shorter than ideal schedules are highly susceptible to frequent requirements changes, as

the software requirements analysis phase is often forced to begin before the overall system requirements and toplevel design are complete. This results in later modifications :o the software requirements, even though the

software design and development phases may be complete, l_equirements changes received in the later stages of

a software project inevitably lead to modification of existing developed software. Presented here is a series of

software design techniques that can greatly reduce the impact of last-minute requirements changes. These

techniques were successfully used to add built-in flexibility to two complex software systems in which the

requirements were expected to (and did) change frequently. These large, real-time systems were developed at

NASA Langley Research Center (LaRC) to test and control tie Lidar In-Space Technology Experiment (LITE)

instrument which flew aboard the space shuttle Discovery as The primary payload on the STS-64 mission.

14.SUBJECTTERMS

software design, change

17. SECURITY CLASSIFICATION

OF REPORT

Unclassified

NSN 7540-01-280-5500

18, SECURITY CLASSIFICATION

OF THIS PAGE

Unclassified

118

19. SEI:URITY CLASSIFICATION

OF ABSTRACT

U lclassified

15. NUMBER OF PAGES

121

16. PRICE CODE

A06

20. LIMITATION

OF ABSTRACT

Standard Form 298 (Rev. 2-8g

Prescribed by ANSI Std. Z-39-18

298-102