927 lines
24 KiB
Plaintext
927 lines
24 KiB
Plaintext
|
|
# Originally this was a backup of text input clicketitoggled into ArgoUML
|
|
# Meanwhile it becomes an intermediate storage for attributes and
|
|
# class interconnections in the notation of my C stub generator CgeN
|
|
# (see also end of this text)
|
|
|
|
|
|
Model=libdax
|
|
|
|
ClassDiagram=Overview
|
|
|
|
Class=API
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=11.03.2007
|
|
Documentation=\
|
|
The API is the only layer visible to the applications. It exposes MMC concepts
|
|
which it reflects and augments by its own architectural concepts.
|
|
Subordinates=EQUIP,JOB,AUX
|
|
Cgen=\
|
|
cevapi
|
|
-r -m struct CevapeqP *equip
|
|
-r -m struct CevapjoB *job
|
|
-r -m struct CevapauX *aux
|
|
-r -m struct CevapgestureS *gestures
|
|
@
|
|
=end Class
|
|
|
|
Class=EQUIP
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=11.03.2007
|
|
Documentation=\
|
|
EQUIP represents the physical and logical equipment in reach of libdax.
|
|
This includes the system, drives, media, and their current states.
|
|
PeerToPeer=GESTURES
|
|
Boss=API
|
|
Cgen=\
|
|
cevapeqp
|
|
-r -v struct CevapI *boss
|
|
-r -m struct CevapsysteM *sys
|
|
@
|
|
=end Class
|
|
|
|
Class=JOB
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=11.03.2007
|
|
Documentation=\
|
|
JOB models the tasks to be performed via libdax.
|
|
This includes disc, session, track, source, fifo, dewav, burn options.
|
|
PeerToPeer=GESTURES
|
|
Boss=API
|
|
Cgen=\
|
|
cevapjob
|
|
-r -v struct CevapI *boss
|
|
-r -m struct CevaptodO *todo
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=AUX
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=11.03.2007
|
|
Documentation=\
|
|
AUX bundles any models which are neither EQUIP nor JOB.
|
|
This includes abort handler and message system.
|
|
PeerToPeer=GESTURES
|
|
Boss=API
|
|
Cgen=\
|
|
cevapaux
|
|
-r -v struct CevapI *boss
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=GESTURES
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=11.03.2007
|
|
Documentation=\
|
|
GESTURES ist the procedural repertoire which interconnects EQUIP, JOB, and AUX
|
|
and also provides to them the services from the SCSI oriented layers.
|
|
PeerToPeer=EQUIP,JOB,AUX
|
|
Subordinates=SCSI_CMD
|
|
Cgen=\
|
|
cevapgestures
|
|
-r -v struct CevapI *boss
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=SCSI_CMD
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=11.03.2007
|
|
Documentation=\
|
|
SCSI_CMD represents the semantic part of SCSI (i.e. mainly MMC) specs.
|
|
This layer models each SCSI command that is used by libdax. It knows about
|
|
its parameters and constraints with particular equipment and jobs.
|
|
Boss=GESTURES
|
|
Subordinates=Classes with SCSI_EXEC Interface
|
|
=end Class
|
|
|
|
Interface=SCSI_EXEC
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=16.03.2007
|
|
Documentation=\
|
|
SCSI_EXEC hides the difference between the implementation principle of
|
|
SCSI format+transport and the principle of SCSI service.
|
|
Boss=SCSI_CMD
|
|
Implementations=SCSI_FORMAT,SCSI_SERVICE
|
|
Cgen=\
|
|
cevapsexec
|
|
-p -v struct CevapsforM *scsi_format
|
|
-p -v struct CevapsservicE *scsi_service
|
|
-v int silent_on_scsi_error
|
|
# >>>
|
|
@
|
|
=end Interface
|
|
|
|
Class=SCSI_FORMAT
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=11.03.2007
|
|
Documentation=\
|
|
SCSI_FORMAT translates parameters of SCSI commands into CDBs, takes care for
|
|
transport and decodes the reply into parameters.
|
|
Boss=SCSI_CMD via SCSI_EXEC
|
|
Subordinates=SCSI_TRANSPORT
|
|
Cgen=\
|
|
cevapsform
|
|
-r -v struct CevapsexeC *boss
|
|
-p -v struct CevapstransP *scsi_transport
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=SCSI_TRANSPORT
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=11.03.2007
|
|
Documentation=\
|
|
SCSI_TRANSPORT takes a formatted CDB from SCSI_FORMAT and makes the operating
|
|
system perform a SCSI transaction. It then returns the reply data in raw form.
|
|
Boss=SCSI_FORMAT
|
|
Os_specific=yes
|
|
Cgen=\
|
|
cevapstransp
|
|
-r -v struct CevapsforM *boss
|
|
|
|
# >>> needs thorough rethought
|
|
-p -v struct Burn_os_transport_drive_elementS *system_dep_drive_info
|
|
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=SCSI_SERVICE
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=11.03.2007
|
|
Documentation=\
|
|
SCSI_SERVICE provides the combined services of SCSI_FORMAT and SCSI_TRANSPORT
|
|
via a set of parametrized functions which abstract SCSI command transactions.
|
|
Boss=SCSI_CMD via SCSI_EXEC
|
|
Os_specific=yes
|
|
Cgen=\
|
|
cevapsservice
|
|
-r -v struct CevapsexeC *boss
|
|
|
|
# >>> needs thorough rethought
|
|
-p -v struct Burn_os_transport_drive_elementS *system_dep_drive_info
|
|
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
=end ClassDiagram=Overview
|
|
|
|
|
|
|
|
ClassDiagram=Equip_overview
|
|
|
|
Class=EquipSystem
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=16.03.2007
|
|
Documentation=\
|
|
EquipSystem is the inner root class of EQUIP. It describes the system on
|
|
which libdax is working. This includes the operating system, the system
|
|
adapter classes, the drives.
|
|
Boss=EQUIP
|
|
Subordinates=EquipDrive*N
|
|
Cgen=\
|
|
cevapsystem
|
|
-r -v struct CevapeqP *boss
|
|
-r -m char *infotext
|
|
-r -l struct CevapdrivE *drive
|
|
-p -v struct CevapdrivE *eol_drive
|
|
|
|
# >>> be boss of SCSI_CMD ?
|
|
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
|
|
Class=EquipDrive
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=16.03.2007
|
|
Documentation=\
|
|
EquipDrive represents a drive, including its capabilities, its processing
|
|
status, the media loaded.
|
|
Subordinates=EquipMedia
|
|
Boss=EquipSystem
|
|
Cgen=\
|
|
-l cevapdrive
|
|
-r -v struct CevapsysteM *boss
|
|
-r -v int global_index
|
|
-r -m char *devname
|
|
-r -v int bus_no
|
|
-r -v int host
|
|
-r -v int id
|
|
-r -v int channel
|
|
-r -v int lun
|
|
# (ex struct burn_scsi_inquiry_data)
|
|
-r -v char idata_vendor[9]
|
|
-r -v char idata_product[17]
|
|
-r -v char idata_evision[5]
|
|
-r -v int idata_valid
|
|
-r -v int phys_if_std
|
|
-r -m char *phys_if_name
|
|
-p -v struct CevapsexeC *BURN_OS_TRANSPORT_DRIVE_ELEMENTS
|
|
-r -v int block_types[4]
|
|
# (ex struct scsi_mode_data)
|
|
-p -v int mdata_buffer_size
|
|
-p -v int mdata_dvdram_read
|
|
-p -v int mdata_dvdram_write
|
|
-p -v int mdata_dvdr_read
|
|
-p -v int mdata_dvdr_write
|
|
-p -v int mdata_dvdrom_read
|
|
-p -v int mdata_cdrw_read
|
|
-p -v int mdata_cdrw_write
|
|
-p -v int mdata_cdr_read
|
|
-p -v int mdata_cdr_write
|
|
-p -v int mdata_simulate
|
|
-p -v int mdata_max_read_speed
|
|
-p -v int mdata_max_write_speed
|
|
-p -v int madata_min_write_speed
|
|
-p -v int mdata_cur_read_speed
|
|
-p -v int mdata_cur_write_speed
|
|
-p -v int mdata_retry_page_length
|
|
-p -v int mdata_retry_page_valid
|
|
-p -v int mdata_write_page_length
|
|
-p -v int mdata_write_page_valid
|
|
-p -v int mdata_c2_pointers
|
|
-r -v int mdata_underrun_proof
|
|
-p -v int mdata_valid
|
|
# >>> How to handle this by cgen ? : -v pthread_mutex_t access_lock
|
|
-r -v int current_feat2fh_byte4
|
|
-v volatile int released
|
|
-v struct CevapbuffeR *buffer
|
|
|
|
# >>> next to process: transport.h : struct burn_toc_entry *toc_entry;
|
|
|
|
# >>> transport.h : toc_temp (what is this ? It belongs to BURN_WRITE_RAW)
|
|
# >>>
|
|
|
|
-r -m struct CevapmediA *media
|
|
@
|
|
=end Class
|
|
|
|
|
|
Class=EquipMedia
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=16.03.2007
|
|
Documentation=\
|
|
EquipMedia represents an optical disc, including its type, its writeability,
|
|
its formatting, its available formats and performances.
|
|
Subordinates=\
|
|
EquipProfile*N,EquipFormat*N,EquipPerformance*N,EquipStatus,EquipMulticaps
|
|
Boss=EquipDrive
|
|
Cgen=\
|
|
cevapmedia
|
|
-r -v struct CevapdrivE *boss
|
|
-r -m struct CevapstatuS *status
|
|
-r -l struct CevapprofilE *profile
|
|
-p -v struct CevapprofilE *eol_profile
|
|
-r -v int current_has_feat21h
|
|
-r -v int current_feat21h_link_size
|
|
-v int needs_close_session
|
|
-r -v int bg_format_status
|
|
-r -v int format_descr_type
|
|
-r -v off_t format_curr_max_size
|
|
-r -v unsigned int format_curr_blsas
|
|
-r -v int best_format_type
|
|
-r -v off_t best_format_size
|
|
-r -l struct CevapformaT *format_descriptor
|
|
-p -v struct CevapformaT *eol_format_descriptor
|
|
-r -v int nwa
|
|
-r -v int start_lba
|
|
-r -v int end_lba
|
|
-r -m struct CevapmcapS *multicaps
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
|
|
Class=EquipProfile
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=16.03.2007
|
|
Documentation=\
|
|
EquipProfile maps a MMC profile into libdax (See mmc5r03c.pdf chapter 5).
|
|
A profile describes a set of features and may be either current, possible,
|
|
disabled, or unavailable.
|
|
Subordinates=EquipFeature*N
|
|
Boss=EquipMedia
|
|
Cgen=\
|
|
-l cevapprofile
|
|
-r -v struct CevapmediA *boss
|
|
-r -v int profile_code
|
|
-r -v char *profile_text
|
|
-r -v int is_cd_profile
|
|
-r -v int is_supported_profile
|
|
-r -l struct CevapfeaturE *feature
|
|
-p -v struct CevapfeaturE *eol_feature
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=EquipFeature
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=16.03.2007
|
|
Documentation=\
|
|
EquipFeature maps a MMC feature into libdax (See mmc5r03c.pdf chapter 5).
|
|
A feature describes a set of SCSI commands and (implicitely) of use cases.
|
|
Boss=EquipProfile
|
|
Cgen=\
|
|
-l cevapfeature
|
|
-r -v struct CevapprofilE *boss
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=EquipFormat
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=
|
|
Documentation=\
|
|
>>> EquipFormat
|
|
Boss=EquipMedia
|
|
Cgen=\
|
|
-l cevapformat
|
|
-r -v struct CevapmediA *boss
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=EquipPerformance
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=
|
|
Documentation=\
|
|
>>> EquipPerformance
|
|
Boss=EquipMedia
|
|
Cgen=\
|
|
-l cevapperf
|
|
-r -v struct CevapmediA *boss
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=EquipStatus
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=17.3.2007
|
|
Documentation=\
|
|
EquipStatus represents the status of media and drive. This includes
|
|
blank/appendable/closed, progress indicator.
|
|
Boss=EquipMedia
|
|
Cgen=\
|
|
cevapstatus
|
|
-r -v struct CevapmediA *boss
|
|
-v int status
|
|
-m char *status_text
|
|
-v volatile int busy
|
|
-v struct CevapprofilE *current_profile
|
|
-v int complete_sessions
|
|
-v int last_track_no
|
|
-v off_t media_capacity_remaining
|
|
-v int media_lba_limit
|
|
-v struct CevapprogresS *progress
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=EquipMulticaps
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=14.8.2007
|
|
Documentation=\
|
|
EquipMulticaps represents media dependent properties and media states. This
|
|
includes eventually existing sessions, closure status, profile dependent
|
|
capabilities.
|
|
Boss=EquipMedia
|
|
Cgen=\
|
|
cevapmcaps
|
|
-r -m struct CevapdisC *disc
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=EquipTocItem
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=14.8.2007
|
|
Boss=
|
|
Cgen=\
|
|
-l cevaptocitem
|
|
-r -v struct CevapdisC *boss
|
|
-v int session
|
|
-v int valid
|
|
-v int control
|
|
|
|
# obscure info from CD TOC : possibly length of track
|
|
-v unsigned char point
|
|
-v unsigned char min
|
|
-v unsigned char sec
|
|
-v unsigned char frame
|
|
#
|
|
-v int pmin
|
|
-v int psec
|
|
-v int pframe
|
|
#
|
|
-v int start_lba
|
|
-v int track_blocks
|
|
@
|
|
=end Class
|
|
|
|
|
|
|
|
=end ClassDiagram=Equip_overview
|
|
|
|
|
|
ClassDiagram=Job_overview
|
|
|
|
Class=JobTodo
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=18.3.2007
|
|
Documentation=\
|
|
JobTodo records what is to be done during a job. This includes peripheral
|
|
actions like tray load/eject and central actions like blank, format, burn.
|
|
Subordinates=JobDisc,JobOptions
|
|
Cgen=\
|
|
cevaptodo
|
|
-v volatile int cancel
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=JobDisc
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=18.3.2007
|
|
Documentation=\
|
|
JobDisc models a disc structure. Either one which already exists or
|
|
one which is to be created in a job run.
|
|
Subordinates=JobSession*N
|
|
Boss=JobTodo
|
|
Cgen=\
|
|
cevapdisc
|
|
-l struct CevapsessioN *session
|
|
-r -v struct CevapsessioN *eol_session
|
|
-l struct CevaptociteM *toc_entry
|
|
-r -v struct CevaptociteM *eol_toc_entry
|
|
# >>> take over services of struct burn_disc
|
|
@
|
|
=end Class
|
|
|
|
Class=JobSession
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=18.3.2007
|
|
Documentation=\
|
|
JobSession represents a recording session. A session usually bundles
|
|
several tracks. Traditionally the last session of a disc is recognized
|
|
by operating systems as the thing to be mounted.
|
|
Subordinates=JobTrack*N,JobFifo
|
|
Boss=JobDisc
|
|
Cgen=\
|
|
-l cevapsession
|
|
-r -v struct CevapdisC *boss
|
|
|
|
# >>>
|
|
|
|
-l struct CevaptracK *track
|
|
-r -v struct CevaptracK *eol_track
|
|
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=JobTrack
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=18.3.2007
|
|
Documentation=\
|
|
JobTrack represents a track to be recorded. A track mainly is associated with
|
|
a data source but in many cases it also becomes a recognizable entity on the
|
|
target media.
|
|
Subordinates=JobBlock*N,JobTrackFilter,JobSource
|
|
Boss=JobSession
|
|
Cgen=\
|
|
-l cevaptrack
|
|
-r -v struct CevapsessioN *boss
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=JobBlock
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=18.3.2007
|
|
Documentation=\
|
|
JobBlock represents a single output data transaction unit. On CD this is
|
|
the same as an addressable media block resp. sector. On DVD this might be
|
|
an addressable block od 2k or a packet of e.g. 32k.
|
|
Boss=JobTrack
|
|
Cgen=\
|
|
cevapblock
|
|
-v int alba
|
|
-v int rlba
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=JobSource
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=8.4.2007
|
|
Documentation=\
|
|
JobSource represents a data source for a track. Typically this is a disk
|
|
file or a stream file descriptor like stdin.
|
|
Subordinates=JobSourceBlock*N
|
|
Boss=JobTrack
|
|
=end Class
|
|
|
|
Class=JobSourceBlock
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=8.4.2007
|
|
Documentation=\
|
|
JobSourceBlock represents a single input data transaction unit.
|
|
Boss=JobSource
|
|
=end Class
|
|
|
|
Class=JobFifo
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=8.4.2007
|
|
Documentation=\
|
|
JobFifo reads data via JobTrackFilter and buffers them until JobBlock can
|
|
accept them.
|
|
Boss=JobSession
|
|
=end Class
|
|
|
|
Class=JobTrackFilter
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=8.4.2007
|
|
Documentation=\
|
|
JobTrackFilter reads data from JobSourceBlock, processes them and presents
|
|
them to JobFifo or JobBlock. This includes stripping of .wav headers.
|
|
Boss=JobTrack
|
|
=end Class
|
|
|
|
Class=JobOptions
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=18.3.2007
|
|
Documentation=\
|
|
JobOptions bundles the adjustable parameters of a job. This includes dummy
|
|
mode, speed, appendability, blank mode, format selection, write mode,
|
|
underrun protection, random access addressing.
|
|
Boss=JobTodo
|
|
Cgen=\
|
|
cevapjobopts
|
|
# >>>
|
|
-v int wait_for_buffer_free
|
|
-v unsigned int wfb_min_usec
|
|
-v unsigned int wfb_max_usec
|
|
-v unsigned int wfb_timeout_sec
|
|
-v unsigned int wfb_min_percent
|
|
-v unsigned int wfb_max_percent
|
|
# >>> -m struct params params (used by disabled read cd funtionality)
|
|
@
|
|
=end Class
|
|
|
|
Class=JobBuffer
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=13.8.2007
|
|
Documentation=\
|
|
JobBuffer is an intermediate storage for the content of several JobBlock
|
|
or JobSourceBlock.
|
|
Cgen=\
|
|
cevapbuffer
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=JobProgress
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=13.8.2007
|
|
Documentation=\
|
|
JobProgress reflects the state and parts of the history of a job
|
|
Cgen=\
|
|
cevapprogress
|
|
-v int nominal_write_speed
|
|
-v off_t pessimistic_buffer_free
|
|
-v int pbf_altered
|
|
-v unsigned int pessimistic_writes
|
|
-v unsigned int waited_writes
|
|
-v unsigned int waited_tries
|
|
-v unsigned int waited_usec
|
|
|
|
# >>> the info provided by struct burn_progress
|
|
|
|
# >>>
|
|
@
|
|
=end Class
|
|
|
|
Class=
|
|
Author=Thomas Schmitt <scdbackup@gmx.net>
|
|
Version=1.0
|
|
Since=
|
|
Documentation=\
|
|
=end Class
|
|
|
|
=end ClassDiagram=Equip_overview
|
|
|
|
# >>> a dummy to be integrated into the model
|
|
Cgen=\
|
|
burn_os_transport_drive_elements
|
|
# >>>
|
|
@
|
|
|
|
|
|
=end Model=libdax
|
|
|
|
----------------------------------------------------------------------------
|
|
Notes:
|
|
----------------------------------------------------------------------------
|
|
|
|
Generate C stubs:
|
|
test_dir=...where_to_generate_the_stub...
|
|
model_dir=...where_to_find_the_model_file_libdax_model.txt...
|
|
xtr_dir=...where_to_find_the_extractor_script_extract_cgen_input.sh...
|
|
cgen_dir=...where_to_find_the_cgen_binary...
|
|
|
|
/bin/rm "$test_dir"/cevap*.[cho] \
|
|
"$test_dir"/burn_os_transport_drive_elements*.[cho] \
|
|
"$test_dir"/a.out
|
|
cd "$test_dir"/
|
|
cat "$model_dir"/libdax_model.txt | \
|
|
"$xtr_dir"/extract_cgen_input.sh | \
|
|
"$cgen_dir"/cgen -smem_local -ansi -global_include cevap_global.h
|
|
|
|
Compile:
|
|
( cd "$test_dir" ; cc -g -c *.c 2>&1 | less )
|
|
|
|
----------------------------------------------------------------------------
|
|
"$xtr_dir"/extract_cgen_input.sh :
|
|
|
|
#!/bin/sh
|
|
|
|
copy_mode=0
|
|
|
|
while true
|
|
do
|
|
read line
|
|
if test "$copy_mode" = "0"
|
|
then
|
|
if echo " $line" | grep '^ Cgen=' >/dev/null 2>&1
|
|
then
|
|
copy_mode=1
|
|
if echo " $line" | grep '^ Cgen=..' >/dev/null 2>&1
|
|
then
|
|
echo " $line" | sed -e 's/^ Cgen=//'
|
|
fi
|
|
elif echo " $line" | grep '^ =end Model=' >/dev/null 2>&1
|
|
then
|
|
break
|
|
fi
|
|
else
|
|
if test " $line" = " @"
|
|
then
|
|
copy_mode=0
|
|
echo "@"
|
|
else
|
|
echo " $line" | sed -e 's/^ //'
|
|
fi
|
|
fi
|
|
done
|
|
|
|
----------------------------------------------------------------------------
|
|
|
|
|
|
Description of CgeN
|
|
|
|
cgen produces a class stub in C programming language. The data structure of
|
|
the class is described by some lines which get read from stdin. The stub will
|
|
consist of two files <classname>.h and <classname>.c which emerge in the
|
|
current working directory.
|
|
It will define a struct <ClassnamE> for representing the class data aspects,
|
|
construtor <Classname>_new(), destructor <Classname>_destroy(),
|
|
getter <Classname>_<element>_get() for each structure element.
|
|
Some more functions get added for particular class and element roles.
|
|
|
|
After first generation, there is no further support by cgen. It simply refuses
|
|
to overwrite existing files because it supposes that those contain code added
|
|
by the human programmer.
|
|
Those programmer enhancements are supposed to include explanatory comments,
|
|
class specific methods, initial element values and other special precautions
|
|
within the generated functions.
|
|
|
|
|
|
Command line options
|
|
|
|
-no_stic prevents usage of stic_dir/s_tools/*.[ch]
|
|
|
|
-ansi generates ANSI C function heads and makes file <classname>.h hold
|
|
only public definitions: an opaque declaration of the class struct
|
|
and a list of function prototypes. The definiton of the class
|
|
struct is then in <classname>_private.h .
|
|
-global_include filename
|
|
sets the name of a file which will contain globally necessary
|
|
declarations. Currently it lists the existence of all class
|
|
structs.
|
|
|
|
A class can have one of two roles:
|
|
|
|
- Standalone class.
|
|
Input example:
|
|
my_class
|
|
|
|
- Listable class, which has pointers to peer instances: .prev and .next
|
|
Such classes get a list destructor <Classname>_destroy_all() which destroys
|
|
all members of a list (which is given by any of the list members).
|
|
Such a class should have a pointer *boss as first element in which case
|
|
the constructor will look like
|
|
<Classname>_new(struct <ClassnamE> **o,struct <Some_clasS> *boss,int flag);
|
|
There is a function <Classname>_link() which inserts an instance into a list
|
|
and a function <Classname>_count() which tells the number of list members.
|
|
Input example:
|
|
-l my_class
|
|
|
|
A modifier is defined for listable classes:
|
|
|
|
- Bossless listable. cgen will not warn if the first element is not
|
|
struct <Some_clasS> *boss
|
|
and will not include a parameter *boss into the constructor. I.e. it will
|
|
look like the constructor of non-listable classes:
|
|
<Classname>_new(struct <ClassnamE> **o, int flag);
|
|
|
|
|
|
Elements have one of the following roles:
|
|
|
|
- Value. It provides only storage for a C data type (which may be a C pointer
|
|
despite the role name "value"), a getter method <Classname>_<element>_get(),
|
|
and a setter method <Classname>_<element>_set().
|
|
Input examples:
|
|
-v int i
|
|
-v int a[100]
|
|
-v char *cpt
|
|
-v struct xyz x
|
|
-v struct xyz *xpt
|
|
|
|
- Managed. This has to be a pointer to a struct <XyZ> or to char. It will not
|
|
get attached to an object by the stub's code but its destructor
|
|
<Xyz>_destroy() will be called by <Classname>_destruct(). In case of (char *)
|
|
it is supposed that a non-NULL value has been allocated by malloc().
|
|
Managed (char *) types get a setter function <Classname>_<element>_set()
|
|
which allocates memory and copies the textstring from its parameter.
|
|
Input examples:
|
|
-m struct XyZ *xyzpt
|
|
-m char *textstring
|
|
|
|
- Chainlink. A pair of prev-next-style pointers to the own class struct.
|
|
Function <Classname>_destruct() will unlink the affected instance and
|
|
put together its link partners.
|
|
Input example (there must always be two consequtive -c lines):
|
|
-c struct My_clasS *up
|
|
-c struct My_clasS *down
|
|
|
|
- List. A pair of pointers to the struct <XyZ> of a listable class. The first
|
|
one <ls> holds the start of the list, the second one <eol> holds the end.
|
|
For insertion of list items there is provided method <Classname>_new_<ls>().
|
|
The inserted item is then content of the <eol> pointer.
|
|
<Classname>_destroy() instance calls <Xyz>_destroy_all(). There is a method
|
|
<Classname>_set_<eol>() which should be used with caution, if ever.
|
|
Input example (there must always be a -l and a -v line):
|
|
-l struct XyZ *list_start
|
|
-v struct XyZ *list_end
|
|
|
|
The availability of getter method <Classname>_get_<element>(), and setter
|
|
method <Classname>_set_<element>_set() can be controled by two modifiers:
|
|
|
|
- Readonly. Only a getter method.
|
|
Input example
|
|
-r -v int broadcasted_status
|
|
|
|
- Private. Neither getter nor setter method.
|
|
Input example
|
|
-p -v int private_value
|
|
|
|
- Bossless listable. This marks elements which are listable objects but do not
|
|
expect a boss pointer in their constructor. See above: Listable class and
|
|
the bossless listable modifier for classes.
|
|
Input example
|
|
-b -l struct XyZ *list
|
|
-v struct XyZ *last_in_list
|
|
|
|
|
|
Example run:
|
|
|
|
rm class_x.c class_x.h class_y.c class_y.h
|
|
bin/cgen <<+
|
|
-l class_x
|
|
-r -v struct Boss_clasS *boss
|
|
-v int x
|
|
-r -v struct stat stbuf
|
|
-m struct Class_Y *y
|
|
-m char *text
|
|
-c struct Class_X *master
|
|
-c struct Class_X *slave
|
|
-b -l struct Class_X *provider
|
|
-r -v struct Class_X *last_provider
|
|
@
|
|
-b -l class_y
|
|
-r -v char providername[80]
|
|
@
|
|
+
|
|
|
|
|
|
------------------------------------------------------------------------
|
|
|
|
The generated code uses smem.[ch] out of one of my BSD licensed projects.
|
|
Out of smem.h :
|
|
|
|
|
|
smem
|
|
|
|
Functions to replace malloc() and free() in order to get more control
|
|
over memory leaks or spurious errors caused by faulty usage of malloc()
|
|
and free().
|
|
|
|
|
|
Sourcecode provisions:
|
|
|
|
Use only the following macros for memory management:
|
|
TSOB_FELD(type,count) creates an array of items of given type
|
|
Smem_malloC() analogue of malloc()
|
|
Smem_freE() analogue of free()
|
|
One may #define malloc Smem_malloC resp. #define free Smem_freE
|
|
but better would be to review (and often to streamline) the sourcecode
|
|
in respect to those two functions.
|
|
|
|
|
|
Speed versus control:
|
|
|
|
In production versions, where maximum speed is required, one may undefine
|
|
the macro Smem_own_functionS in smem.h .
|
|
This causes the above macros to directly invoke malloc() and free() without
|
|
any speed reduction (and without any additional use).
|
|
Undefinitio can be done globaly by modifying smem.h or locally by defining
|
|
Smem_no_own_functionS before including smem.h .
|
|
|
|
If Smem_own_functionS remains defined, then the functions
|
|
Smem_malloc()
|
|
Smem_free()
|
|
are used rather than malloc() and free().
|
|
They count the number of calls to maintain a rough overview of memory usage.
|
|
Smem_malloc() additionally checks for 0 size and Smem_free() checks for
|
|
NULL pointers, which they both report to stderr. Eventually one should set
|
|
a breakpoint in function Smem_protest() to learn about the origin of such
|
|
messages.
|
|
A status line may be obtained by Smem_report() or printed by Smem_stderr().
|
|
|
|
As long as the variable Smem_record_itemS is set to 0, there is not very much
|
|
overhead compared with malloc() and free().
|
|
If the variable is set to 1 by Smem_set_record_items() then all malloc()
|
|
results are kept in a list where they will be deleted by their corresponding
|
|
Smem_free() calls. If a pointer is to be freed, which is not recorded in the
|
|
list then an error message will be printed to stderr. The memory will not
|
|
be freed !
|
|
This mode not only may be very slow, it also consumes at least 16 byte per
|
|
piece of data which was obtained by malloc as long as it has not been freed.
|
|
Due to the current nature of the list, large numbers of memory items are freed
|
|
much faster in the reverse order of their creation. If there is a list of
|
|
100000 strings to delete, it is very rewarding to free the youngest ones first.
|
|
A shortcut via hashing is available but consumes 24 bytes rather than 16.
|
|
(see above Smem_with_hasH )
|
|
|
|
The function Smem_is_recorded() can be used to check wether a pointer is
|
|
valid according to the list. It returns :
|
|
0 = is not in list , 1 = is in list , 2 = recording is off
|
|
|
|
If one decides to start recording malloc() results in the midst of a program
|
|
run, one has to be aware of false protests of Smem_free() if a memory piece
|
|
has been allocated before recording started. This will also cause those pieces
|
|
to be memory leaks because Smem_free() refuses to delete them. (Freeing memory
|
|
that was not obtained by malloc or was already freed previously can result in
|
|
deferred SIGSEGV or similar trouble, depending on OS and library.)
|
|
Also in that case one should stop recording before ending the program, to
|
|
avoid a lot of false complaints about longliving memory objects.
|
|
|