Manuale per la programmazione Tivoli Service Desk 6.0 Developer's Toolkit Script
Developer's Toolkit consente di raggruppare le istruzioni nelle routine e di impacchettarle in file .kb o moduli riutilizzabili. Questa caratteristica del modulo facilita la conservazione di grandi quantità di codice di risorsa.
Questo capitolo contiene le informazioni di base necessarie per comprendere e creare applicazioni a più file .kb.
La parola chiave ROUTINES viene utilizzata per introdurre ogni sezione di un file .kb che contiene sottoroutine e procedure.
Nella sezione pubblica tra l'intestazione KNOWLEDGEBASE e la parola chiave PRIVATE, la sezione delle routine contiene dichiarazioni delle procedure e delle funzioni implementate nella sezione privata.
Nella sezione privata, la parola chiave ROUTINES è seguita dalle
implementazioni della procedura completa e della funzione.
Un esempio viene riportato di seguito:
KNOWLEDGEBASE Print; TYPES EmployeeRecord IS RECORD first_name, last_name: String; employee_ID: String; hireDate: Date; salary: Real; END; ROUTINES PrintEmployee(REF e: EmployeeRecord); PRIVATE ROUTINES PROCEDURE PrintString(VAL s: String) IS ACTIONS ... END; PROCEDURE PrintEmployee(REF e: EmployeeRecord) IS ACTIONS PrintString(e.first_name); PrintString(e.last_name); ... END;
Ogni file .kb Developer's Toolkit è costituito da due sezioni principali.
L'esempio seguente presenta un file .kb denominato Statistics (contenuto nel file statisti.kb) utilizzato da un altro file .kb denominato Application (nel file applicat.kb):
KNOWLEDGEBASE Statistics; ROUTINES PROCEDURE Regression; PROCEDURE TimeSeries; PROCEDURE ChiSquare; ... KNOWLEDGEBASE Application; ... PRIVATE USES Statistics; ...
Dichiarando Statistics nella relativa sezione Uses, le routine in Application possono chiamare le tre procedure definite da Statistics.
La sezione degli utilizzi viene introdotta dalla parola chiave USES e deve trovarsi in una di queste posizioni (o entrambe):
Un file .kb può utilizzare un qualsiasi numero di altri file .kb. Ogni file .kb deve essere elencato nella sezione uses e deve essere seguito da un punto e virgola:
KNOWLEDGEBASE User; ... PRIVATE USES Used1; Used2; ... Used99;
Un file .kb viene utilizzato privatamente quando è contenuto nell'istruzione USES nella sezione privata di un file .kb.
Quando un file .kb viene utilizzato privatamente, le variabili e le procedure pubbliche a esso relative sono disponibili in tutta la sezione privata per implementare le routine dichiarate nella sezione pubblica. In altre parole, l'implementazione privata del file .kb può essere composta dalle routine pubbliche di un altro file .kb.
Due file .kb possono utilizzarsi reciprocamente e privatamente senza limitazioni, finché essi si denominano reciprocamente nella sezione privata. Cioè, un file .kb A può utilizzare un file .kb B e viceversa.
Un file .kb viene utilizzato pubblicamente quando è contenuto nell'istruzione USES nella sezione pubblica di un file .kb.
Quando un file .kb viene utilizzato pubblicamente, i simboli del file .kb utilizzato sono disponibili in tutti i file .kb.
E' possibile utilizzare un file .kb pubblicamente
quando i simboli a esso relativi sono necessari per alcune
dichiarazioni pubbliche nel file .kb utilizzato.
Un esempio di ciò viene fornito quando un tipo di record definito in
un file .kb viene utilizzato in una dichiarazione del tipo di record
di un altro file .kb.
L'utilizzo ciclico si verifica quando un file .kb A utilizza un file .kb B e viceversa. I file .kb non possono utilizzarsi reciprocamente e ciclicamente nella sezione PUBLIC.
Un modo per evitare questa limitazione è quello di spostare le dichiarazioni comuni necessarie per entrambi i file .kb in un file .kb separato che non utilizza nulla in modo pubblico. Ciò non è sempre fattibile perché potrebbe non avere senso combinare dichiarazioni per funzioni molto diverse in un file .kb. Talvolta, tuttavia, questa soluzione risulta adeguata.
Ad esempio, supporre di creare un programma che traccia informazioni relative a impiegati e al reparto in cui lavorano. Si desidera concentrare tutte le informazioni sugli impiegati in un file .kb denominato "Employee" e le informazioni sui reparti in un file .kb denominato "Department."
Tuttavia, le routine pubbliche che gestiscono i record employee richiedono talvolta i record department come parametri e viceversa. Quindi, è necessario che i file .kb si utilizzino reciprocamente e pubblicamente. Se ciò non funziona, i file .kb devono essere organizzati come mostrato nell'esempio seguente:
KNOWLEDGEBASE EmplType; TYPES Employee IS RECORD ... END; ... END; KNOWLEDGEBASE DeptType; TYPES Department IS RECORD ... END; ... END; KNOWLEDGEBASE Employee; USES EmplType; DeptType; ROUTINES PROCEDURE AddEmployee (VAL lst: LIST OF Employee, REF dept: Department); ... PRIVATE ... END; KNOWLEDGEBASE Department; USES EmplType; DeptType; ROUTINES PROCEDURE AssignOffice (REF dept: Department, REF empl: Employee); ... PRIVATE END;
Una procedura è una raccolta di istruzioni Developer's Toolkit a cui è possibile fare riferimento tramite un nome che non restituisce un valore a colui che ha effettuato la chiamata.
Una procedura è un blocco nidificato all'interno del file .kb. Come lo stesso file .kb, una procedura può disporre di sezioni per costanti, tipi, variabili e routine. Gli identificativi in queste sezioni sono locali per la procedura e non sono visibili all'esterno di essa.
Ogni procedura dispone di una sezione di azioni che indica la posizione per le istruzioni eseguibili Developer's Toolkit che stabiliscono ciò che fa la procedura.
La forma generale di una procedura è mostrata di seguito:
PROCEDURE <procedure-name>(<formal-parameter-list>) IS CONSTANTS <constant-declarations> TYPES <type-declarations> VARIABLES <variable-declarations> ROUTINES <subroutine-implementations> ACTIONS <KML statement-list> END;
Quella di seguito riportata è una procedura semplice con una sezione di azioni che contiene due istruzioni Developer's Toolkit. Quando questa procedura viene chiamata, le due istruzioni nella sezione delle azioni vengono eseguite:
PROCEDURE CopyrightMessage; ACTIONS WinWriteLN($DeskTop,'Copyright 1996 by'); WinWriteLN($DeskTop,'Software Artistry, Inc.'); END;
Spesso è utile che una procedura contenga variabili locali in una sezione di variabili nidificate. Le variabili locali sono variabili di programma il cui ambito è limitato a un blocco di codice specifico. Di regola, le variabili locali sono confinate a una sottoroutine.
L'esempio seguente crea una procedura definita WriteTenLines. La procedura utilizza una variabile locale denominata i; questa variabile deve essere ripetuta per tutto il loop FOR e per scrivere 10 stringhe su una finestra:
PROCEDURE WriteTenLines; VARIABLES i: Integer; ACTIONS FOR i:=1 TO 10 DO WinWriteLn(myWindow,''); END; END;
Questo esempio viene migliorato ulteriormente per includere una costante locale:
PROCEDURE WriteTenLines; CONSTANTS MAX_LINES IS 10; VARIABLES i: Integer; ACTIONS FOR i:=1 TO MAX_LINES DO WinWriteLn(myWindow,''); END; END;
Spesso risulta utile creare delle routine locali, in particolare se la variabile che si desidera utilizzare si presenta solo in una parte di un programma. Le routine locali sono procedure o funzioni dichiarate all'interno di un'altra funzione o procedura. Una routine locale può essere richiamata solo dalla procedura o dalla funzione che la contiene o da altre routine locali contenute in essa. Consultare l'esempio:
PROCEDURE PrintEmployeeInfo(REF e: EmployeeRecord) IS ROUTINES PROCEDURE PrintDemographics IS ACTIONS PrintString(e.first_name); PrintString(e.last_name); PrintString(e.ssn); END; PROCEDURE PrintManages IS ACTIONS FOR e.manages DO PrintString(e.manages[$Current]); END; END; ACTIONS PrintDemographics; PrintManages; END;
Uno dei problemi concettuali più importanti nelle lingue strutturate in blocchi è l'ambito. All'interno di ogni blocco dato, esistono solo determinati identificativi oppure sono nell'ambito. In generale, i blocchi nidificati sono in grado di "visualizzare" gli identificativi dichiarati in un ambito limitato. Un oggetto o identificativo è in un ambito limitato è locale solo per quel blocco.
Considerare il seguente esempio:
KNOWLEDGEBASE Scope; CONSTANTS MAX_EMPLOYEES IS 500; TYPES EmployeeRecord IS RECORD first_name, last_name: String; END; VARIABLES employeeList: List of EmployeeRecord; PRIVATE CONSTANTS ARRAY_SIZE IS 1000; VARIABLES employeeArray[ARRAY_SIZE]: ARRAY OF EmployeeRecord; ROUTINES PROCEDURE ProcTwo IS VARIABLES i: Integer; ACTIONS ... END;
PROCEDURE ProcOne IS VARIABLES i: String; j: Integer; ACTIONS ... END;
MAX_EMPLOYEES, EmployeeRecord e employeeList sono visibili in tutto il file .kb poiché sono dichiarati nel blocco più esterno. Questi elementi appaiono nella sezione pubblica del file .kb, in modo da poter essere visibili anche dagli altri file .kb che utilizzano questo file .kb.
In modo analogo, poiché ARRAY_SIZE e employeeArray sono dichiarati nella sezione privata del blocco più esterno, sono visibili nell'intera sezione privata. Sia ProcTwo che ProcOne possono riferirsi a questi identificativi, ma poiché si trovano nella sezione privata, nessun altro file .kb può accedere a essi.
La variabile i in ProcTwo è visibile solo in ProcTwo. Le variabili i e j in ProcOne sono visibili solo in ProcOne. La variabile i in ProcOne non è correlata alla variabile i in ProcTwo.
I valori della variabile esistono solo quando è in esecuzione il blocco in cui esse sono contenute. Ad esempio, le variabili i e j dispongono di valori solo durante l'esecuzione di ProcOne.
Quando si chiamano delle procedure, spesso è necessario
inoltrare a esse delle informazioni.
Per inoltrare delle informazioni seguire questi passi:
PROCEDURE ComputePercent (VAL Dividend : INTERGER, VAL Divisor : INTEGER, REF Quotient : INTEGER) IS (*parameter to PROCEDURE ComputePercent*)
ACTIONS Quotient := Dividend/Divisor*100; END;
Quando si richiama la procedura, il numero di espressioni passate eguaglia il numero di parametri dichiarati per la procedura. Le espressioni passate devono avere lo stesso tipo di parametro e lo stesso tipo di dati dei parametri specificati.
VARIABLES (*Compute the percentage of cars of differing colors in a garage*) NumBrownCars : INTEGER; NumBlackCars : INTEGER; NumMixedCars : INTEGER; TotalCars : INTEGER; PercentBrownCars : INTEGER; PercentBlackCars : INTEGER; PercentMixedCars : INTEGER; ACTIONS (*Expressions passed to compute the percentage of cars of differing colors in a garage*) ComputePercent (NumBrownCars, TotalCars, PercentBrownCars); ComputePercent (NumBlackCars, TotalCars, PercentBlackCars); ComputePercent (NumMixedCars, TotalCars, PercentMixedCars); End;
Nell'esempio successivo, alcuni parametri vengono inoltrati per valore (VAL) altri per riferimento (REF).
In un parametro VAL, un valore viene copiato dal chiamante sulla routine richiamata e nulla di quanto la routine chiamata esegue influenza il valore ancora in possesso del chiamante.
Un parametro REF indirizza la stessa memoria posseduta dal richiedente. Perciò, le modifiche al valore del parametro che si apportano nel corso della routine richiamata diventano effettive immediatamente sul valore del richiedente.
Considerare il seguente esempio:
ROUTINES PROCEDURE DistanceFormula(VAL x1, y1, x2, y2: Integer, REF distance: REAL) IS ACTIONS distance:=Sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)); END;
PROCEDURE ComputeDistances IS VARIABLES distance: Real; ACTIONS DistanceFormula(1,1,9,9,distance); WinWriteLN(myWindow,'The distance is ' & distance); DistanceFormula(9,9,15,87,distance); WinWriteLN(myWindow,'The distance is ' & distance); END;
Nell'esempio precedente, è stata dichiarata una procedura denominata DistanceFormula.
La procedura comprende cinque argomenti formali:
Quando viene chiamata una procedura, vengono inviate a essa le copie dei primi quattro valori interi passati. Tuttavia, nel caso del quinto parametro, la variabile attuale inviata dal richiedente viene passata alla procedura.
Se una procedura prevede che un parametro sia passato per valore, il richiedente può inviare una:
Tuttavia, se una procedura prevede di passare un parametro per riferimento, il chiamante può inviare solo una variabile.
Una procedura può trattare come variabili tutti i parametri che le vengono passati. Essa può:
Le modifiche apportate ai parametri passati per valore non sono restituite al chiamante.
Nell'esempio precedente, ComputeDistances invia valori literal per i quattro argomenti interi a DistanceFormula, perché i parametri corrispondenti sono stati dichiarati con la parola chiave VAL. Tuttavia, ComputeDistances inoltra solo una variabile per il quinto argomento poiché il quinto parametro è stato dichiarato con la parola chiave REF.
Nota: Non esiste un tipo di parametro di default. In una dichiarazione di procedura è necessario specificare il valore VAL o il valore REF per ogni parametro.
Le funzioni sono identiche alle procedure, ma restituiscono un valore al chiamante. Per questo motivo, le funzioni possono essere utilizzate solo in assegnazioni o in espressioni. Non possono essere utilizzate come istruzioni.
Le funzioni possono restituire tipi semplici (come stringhe, numeri interi, numeri reali, valori booleani, data e ora), tipi strutturati e definiti dall'utente.
E' possibile, inoltre, scrivere una funzione che restituisce un elenco di record.
Le funzioni hanno il seguente formato generale:
FUNCTION <function-name>(<formal-parameter-list>): <Type> IS CONSTANTS <constant-declarations> TYPES <type-declarations> VARIABLES <variable-declarations> ROUTINES <subroutine-implementations> ACTIONS <KML statement-list> END;
L'esempio seguente modifica DistanceFormula in modo che essa sia una funzione e non una procedura:
ROUTINES FUNCTION DistanceFormula(VAL x1, y1, x2, y2: Integer): REAL IS ACTIONS Exit Sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)); END;
PROCEDURE ComputeDistances IS VARIABLES distance: Real; ACTIONS distance:=DistanceFormula(1,1,9,9); WinWriteLN(myWindow,'The distance is ' & distance); distance:=DistanceFormula(9,9,15,87); WinWriteLN(myWindow,'The distance is ' & distance); END;
Nota: Ogni funzione deve disporre di un tipo di restituzione esplicito che segue l'elenco dei parametri ed è separato da esso da un segno d'interpunzione due punti (:).
$Result può essere utilizzato nel corpo di una funzione per accedere al valore di restituzione corrente per quella funzione. E' possibile impostarlo o testarlo nel corpo della funzione.
Prendere in considerazione la seguente modifica per DistanceFormula:
FUNCTION DistanceFormula(VAL x1, y1, x2, y2: Integer): REAL IS ACTIONS $Result := Sqrt((x2-x1)*(x2-x1) + (y2-y1)* (y2-y1)); END;
In questo esempio, il valore di restituzione della funzione è impostato con $Result.
$Result può essere assegnato più volte nel corpo di una funzione. $Result dispone automaticamente del tipo di dati dichiarato per il valore di restituzione della funzione.
Exit, se utilizzato con una funzione, causa:
Quando si utilizza un'istruzione Exit in una funzione, è possibile assegnare a essa un parametro che indica il valore che si desidera restituire.
Exit (42);
è lo stesso di:
$Result := 42; Exit;
Se un'istruzione termina senza utilizzare un'istruzione Exit, viene restituito un valore $Unknown.
Exit combina le attività che:
L'accesso alle routine scritte in C o C++ da un programma scritto in Developer's Toolkit è fornito dal meccanismo di routine esterno del Developer's Toolkit.
Una routine esterna è composta da due parti:
A partire da Developer's Toolkit 4.2, la sintassi dichiarativa del Developer's Toolkit supporta la maggior parte dei requisiti d'interfaccia senza una conoscenza approfondita delle strutture di dati sottostanti di Developer's Toolkit.
Per chiamare una routine esterna, Developer's Toolkit Interpreter deve disporre di una dichiarazione della routine che indica:
La sintassi di una dichiarazione di routine esterna viene mostrata nell'esempio seguente. Come ogni implementazione di routine Developer's Toolkit, queste dichiarazioni possono apparire solo nella sezione privata di un file .kb Developer's Toolkit.
FUNCTION name [(VAL|REF parameter : type [, ...])] : type IS EXTERNAL dll_name [, entry_point][, linkage]; PROCEDURE name [(VAL|REF parameter : type [, ... ])] IS EXTERNAL dll_name [, entry_point][, linkage];
Il nome DLL è un'espressione costante di stringa costante che identifica la libreria in cui è ubicata la routine esterna. L'estensione .dll è solitamente diversa su una base per piattaforma e viene generalmente omessa dal nome dato.
I punti d'immissione sono dei punti all'interno di un programma o di una routine in cui può cominciare l'esecuzione. Generalmente, una routine ha un solo punto d'immissione. Il punto d'immissione può essere:
Una stringa rappresenta il nome di un punto d'immissione e un numero intero rappresenta il relativo numero ordinale nella libreria.
I compilatori C++ utilizzano, generalmente, una tecnica nota come
estensione del nome che assicura il corretto collegamento tra i
moduli degli oggetti compilati separati.
Le funzioni esterne scritte in C++ possono essere dichiarate come
esterne "C" nel codice di risorsa C++ oppure possono essere
caricate in base al numero ordinale a esse relativo.
La specifica di collegamento in una dichiarazione di routine esterna deve essere uno dei simboli seguenti:
Nota: La funzione callout DLL di Developer's Toolkit riporta esito negativo per gli argomenti "passati per riferimento" se la DLL non è richiamata con Microsoft Visual C++.
Per IBM C++ su OS/2, il protocollo è _Optlink._
Per OS/2, il protocollo è _System.
Se la specifica di collegamento viene omessa completamente da una dichiarazione di routine esterna, il collegamento è impostato per default su $STANDARD.
Per tutti i sistemi operativi UNIX, la convenzione è di compilazione specifica. Se la libreria è stata scritta in C o C++, utilizzare $C. Altrimenti, utilizzare $System.
Per facilitare l'utilizzo di librerie di terza parte, TSD Script fornisce una serie di nomi del tipo predefinito che definiscono direttamente i tipi C/C++.
TYPES SHORT IS INTEGER: INT(2) DEFAULT($ERROR); USHORT IS INTEGER: UINT(2) DEFAULT($ERROR); LONG IS INTEGER: INT(4) DEFAULT($ERROR); ULONG IS INTEGER: UINT(4) DEFAULT($ERROR); PSZ IS STRING : POINTER DEFAULT(0); FLOAT IS REAL : FLOAT(4) DEFAULT($ERROR); DOUBLE IS REAL : FLOAT(8) DEFAULT($ERROR);
I tipi SHORT, USHORT, LONG, ULONG, PSZ, FLOAT e DOUBLE vengono forniti nel file .kb del sistema trovato nel file TSD Script.KB.
I tipi di DLL esterni vengono definiti da TSD Script per i tipi di dati di bassa qualità più comuni utilizzati in C e C++. La sintassi extra dichiarativa indica a TSD Script Interpreter come definire i dati.
Ad esempio, la dichiarazione per SHORT dice che il valore deve essere compresso in un numero intero a due byte. La dichiarazione Default indica che $Unknown provoca un errore nel tempo di esecuzione se si tenta di passare a una routine esterna tramite un parametro SHORT.
La dichiarazione per PSZ dice che il valore deve essere compresso come un puntatore e che $Unknown deve essere passato come un puntatore zero (NULL).
Segue un esempio di come dichiarare la funzione ExitWindows fornita da Microsoft Windows:
FUNCTION ExitWindows (VAL reserved: INTEGER, VAL returnCode: INTEGER ): BOOLEAN IS EXTERNAL `USER.EXE', `ExitWindows', $SYSTEM;
Nota: Un "numero intero" è un valore a 32 bit e "int" non sempre opera in C.
Come i parametri per le routine TSD Script, i parametri per le routine esterne vengono specificati in base al modo in cui vengono passati:
Il parametri VAL per le routine esterne si comportano in modo molto simile ai parametri VAL per le routine non esterne.
Il valore viene copiato dal chiamante sulla routine chiamata e nulla di quanto la routine chiamata esegue influenza il valore ancora in possesso del chiamante.
Una stringa passata per VAL viene ricevuta anche dalla routine esterna come un puntatore che indirizza una ubicazione di memoria temporanea in cui è stata copiata la stringa TSD Script.
I parametri REF differiscono leggermente dai parametri VAL per le routine esterne.
Quando una routine non esterna riceve un parametro REF, essa indirizza la stessa memoria posseduta dal chiamante. Ogni modifica apportata al valore del parametro durante il richiamo della routine diventa effettiva immediatamente sul valore del chiamante.
Il passaggio per riferimento a una routine esterna è implementato realmente come copy-in/copy-out. La differenza è sottile, ma in alcune circostanze, è possibile distinguerne la funzionalità. La distribuzione di un messaggio da una routine esterna costituisce un esempio di tale funzionalità.
La STRINGA tipo di dati (e gli alias come PSZ) rappresenta un'eccezione e viene passata tramite un puntatore al valore di stringa TSD Script reale, se inoltrata per REF.
Tutti i parametri REF vengono passati a routine esterne C o C++ come puntatori. TSD Script non tenta di supportare la nozione C++ dei riferimenti. Se è necessario chiamare una routine C++ contenente parametri di riferimento, è possibile scrivere una funzione wrapper piccola. Il wrapper prende un puntatore da TSD Script, lo priva dei riferimenti e lo passa alla funzione C++ richiesta.
Poiché TSD Script non supporta direttamente le nozioni C e C++ di const, generalmente i programmatori TSD Script dichiarano un parametro REF se la funzione C/C++ comprende un argomento del puntatore const.
Spesso, il passaggio di dati tra TSD Script e una routine esterna richiede la conversione dei dati in un formato alternativo. Prima di chiamare una routine esterna, il valore del chiamante è:
Se il parametro è REF, dopo la restituzione del chiamante, l'area temporanea è impacchettata nuovamente nella memoria del chiamante.
Nonostante sia possibile costruire interfacce piuttosto elaborate
utilizzando tipi semplici, potrebbe comunque essere necessario
passare strutture di dati aggregate a una routine esterna.
Developer's Toolkit 4.2 aggiunge una nuova sintassi a TSD Script che
consente la specifica esplicita che spiega nei dettagli come vengono
definiti i dati TSD Script su strutture di dati C o C++.
A questa definizione si farà riferimento con un pacchetto binario.
Le informazioni di pacchetto binario vengono fornite come un'annotazione alla specifica del tipo in una dichiarazione di tipo denominata o in una specifica del campo, in una dichiarazione di record. La sintassi generica per entrambi è riportata di seguito:
TYPES type_name IS type : annotation ... ; type_name IS RECORD [ field_name : type ] [ : annotation ... ] ; ... END;
Le seguenti annotazioni specificano il formato in cui vengono impacchettati i dati del TSD Script. Esse si escludono reciprocamente.
Annotazione | Descrizione |
INT(width) | L'annotazione INT specifica che il campo viene impacchettato nel formato intero di origine con la larghezza specificata. I valori consentiti per la larghezza sono 1, 2 e 4. Ogni tipo di dati TSD Script che può essere convertito esplicitamente in INTEGER può essere impacchettato come INT. |
UINT(width) | L'annotazione UINT specifica che il campo viene compresso nel formato intero di origine come un valore non definito nella larghezza specificata. Quando un valore viene passato da TSD Script a una routine esterna, non esiste una differenza significativa tra INT e UINT, perché , in entrambi i casi, viene passato lo stesso modello bit. Comunque, quando un valore a 1 o 2 byte viene restituito a TSD Script dalla routine esterna, la distinzione tra INT e UINT stabilisce qual è il valore con segno. Ancora, i valori legal per la larghezza sono 1, 2 e 4. |
NUMERIC(width) | I campi con l'annotazione NUMERIC vengono compressi come una sequenza di caratteri vuoti con la larghezza data. I numeri interi e i numeri reali e qualsiasi tipo di dati TSD Script che possono essere convertiti in Numeri interi possono essere anche compressi come un campo NUMERIC. |
FLOAT(width) | I campi con l'annotazione FLOAT vengono compressi come un numero a virgola mobile IEEE con la larghezza specificata. Le larghezze valide sono 4 e 8. Ogni tipo di TSD Script che può essere esplicitamente convertito in REAL può essere compresso come FLOAT. |
BCD(width) | I campi con l'annotazione BCD vengono compressi come BCD (Binary Coded Decimal). Ogni tipo di dati TSD Script che può essere convertito esplicitamente in REAL può essere compresso come BCD. |
CHAR(width) | I campi con l'annotazione CHAR vengono compressi come una schiera di caratteri semplici con la larghezza data. Ogni tipo di dati TSD Script che possono essere convertiti in STRING possono essere compressi come CHAR. |
ZSTRING(width) | I campi con l'annotazione ZSTRING vengono compressi come una stringa a terminazione null (stile C) con la larghezza data. Ogni tipo di dati TSD Script che può essere convertito in STRING può essere compresso come ZSTRING. |
LSTRING(width) | I campi con l'annotazione LSTRING vengono compressi come una stringa stile Pascal, con un byte iniziale contenente la lunghezza della stringa. Ogni tipo TSD Script che può essere convertito in STRING può essere compresso come LSTRING. |
ASE_DATE | I campi con l'annotazione ASE_DATE vengono compressi come una struttura DATEREC. Ogni tipo di dati che può essere convertito esplicitamente in DATE può essere compresso come un ASE_DATE. |
BTRV_DATE | I campi con l'annotazione BTRV_DATE vengono compressi come una data in stile Btrieve. Ogni tipo di dati che può essere convertito esplicitamente in DATE può essere compresso come un BTRV_DATE. |
CCYYMMDD | I campi con l'annotazione CCYYMMDD vengono compressi come una stringa di carattere contenente il secolo, l'anno, il mese e il giorno, ognuno compresso in due byte. Ogni tipo che può essere esplicitamente convertito in DATE può essere compresso come un CCYYMMDD. |
ASE_TIME | I campi con l'annotazione ASE_TIME vengono compressi come un TIMEREC. Ogni tipo di dati che può essere esplicitamente convertito in TIME può essere compresso come un ASE_TIME. |
BTRV_TIME | I campi con l'annotazione BTRV_TIME vengono compressi come un'ora stile Btrieve. Ogni tipo di dati che può essere esplicitamente convertito in TIME può essere compresso come BTRV_TIME. |
HHMMSS | I campi con l'annotazione HHMMSS vengono compressi come una stringa di caratteri contenente l'ora, i minuti e i secondi, ognuno compresso in due byte. Ogni tipo di dati che può essere esplicitamente convertito in TIME può essere compresso come HHMMSS. |
POINTER | I campi con l'annotazione POINTER vengono compressi come un puntatore a 32 bit nei dati reali TSD Script a essi relativi. Ognuno dei dati non aggregati in TSD Script può essere compresso come POINTER. |
NOEXPORT | L'annotazione NOEXPORT contrassegna un campo non incluso nella rappresentazione binaria esterna. Tutti i tipi di campo possono essere contrassegnati con NOEXPORT |
In aggiunta a un'annotazione del formato, può essere specificata un'annotazione di valore di default. L'annotazione del valore di default indica al TSD Script interpreter come riempire un campo nella struttura binaria quando il valore TSD Script è sconosciuto. La sintassi per l'annotazione del valore di default è:
DEFAULT( $ERROR|expression )
Quando viene specificato $ERROR, la compressione di un valore sconosciuto provoca la visualizzazione di un messaggio di errore e l'interruzione della routine esterna da parte del TSD Script Interpreter.
Questo è il valore di default quando non viene specificata nessuna annotazione di valore.
Se viene specificata un'espressione, essa viene valutata e i valori a essa relativi vengono compressi secondo l'annotazione del formato, quando il valore TSD Script non è sconosciuto. Questa caratteristica viene utilizzata per definire stringhe sconosciute per NULL.
In una sequenza di specifiche di campo, è possibile fornire annotazioni di pacchetto senza un nome campo o un tipo di dati corrispondente. Queste annotazioni specificano i campi nella struttura binaria che non appaiono nel record TSD Script. Ciò si verifica perché gli stessi campi non appaiono nel record TSD Script. E' necessario fornire un'annotazione ulteriore con il valore per quel campo.
La sintassi per questa annotazione speciale è
VALUE(espressione)
Ogni volta che viene compresso un campo, l'espressione fornita viene valutata e compressa secondo l'annotazione del formato corrispondente.
Infine, per l'allineamento del campo, l'annotazione FILL può essere utilizzata per ubicare un numero arbitrario di byte di riempimento tra i campi nella struttura binaria.
La sintassi dell'annotazione FILL è
FILL( width [ , value ] )
Il numero di byte specificato per larghezza e quello dei dati contenente il valore fornito viene compresso nella struttura binaria. Sebbene un qualsiasi valore intero di costante possa essere specificato per l'annotazione FILL, i byte realmente compressi contengono solo gli ultimi 8 bit, così da -128 a 255 rappresenta un intervallo utile di valori. Il valore di default è zero.
I tipi e i campi denominati senza annotazioni di pacchetto
specifiche vengono compressi per default per i tipi sottostanti.
La tabella seguente indica i valori di default per i tipi di dati TSD
Script non aggregati intrinseci.
Tipo | Informazioni sul pacchetto di default | Risultato di default |
Booleano | INT(1) | DEFAULT($ERROR) |
Numero intero | INT(4) | DEFAULT($ERROR) |
Numero reale | FLOAT(8) | DEFAULT($ERROR) |
Stringa | POINTER | DEFAULT(0) |
Ora | ASE_TIME | DEFAULT($ERROR) |
Data | ASE_DATE | DEFAULT($ERROR) |
Finestra, File (Tipi handle) | UINT(4) | DEFAULT($ERROR) |
Manuale per la programmazione Tivoli Service Desk 6.0 Developer's Toolkit Script