17.11.2012 Views

lCondition2 - Index of

lCondition2 - Index of

lCondition2 - Index of

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Parte lxxii<br />

Dos<br />

358 Dos: introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86<br />

358.1 Avvio del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86<br />

358.2 Dispositivi secondo il Dos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87<br />

358.3 Directory, file ed eseguibili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87<br />

358.4 Comandi e ambiente di avvio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .89<br />

358.5 Caratteri jolly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90<br />

358.6 Invito dell’interprete dei comandi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91<br />

358.7 Comandi interni principali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92<br />

358.8 Flussi standard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .97<br />

358.9 Accesso diretto ai dispositivi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99<br />

358.10 Riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99<br />

359 Dos: dischi, file system, directory e file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100<br />

359.1 Suddivisione in partizioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100<br />

359.2 Inizializzazione di un’unità di memorizzazione . . . . . . . . . . . . . . . . . . . . . . . . . . . 100<br />

359.3 Etichetta di un’unità di memorizzazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101<br />

359.4 Analisi e correzione del file system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101<br />

359.5 Copia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102<br />

359.6 Trasferimento del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103<br />

359.7 Modifica delle unità . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103<br />

359.8 Altre particolarità . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105<br />

360 Dos: configurazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108<br />

360.1 CONFIG.SYS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108<br />

360.2 AUTOEXEC.BAT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112<br />

360.3 Comandi ridondanti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112<br />

360.4 Localizzazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113<br />

360.5 Orologio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114<br />

361 Dos: script dell’interprete dei comandi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115<br />

361.1 Parametri, variabili ed espansione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115<br />

361.2 Chiamate di altri script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115<br />

361.3 Strutture di controllo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115<br />

361.4 Comandi utili negli script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118<br />

362 Dos: gestione della memoria centrale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .121<br />

83


362.1 Gestione particolare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121<br />

362.2 Comandi appositi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121<br />

362.3 Verifica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121<br />

363 FreeDOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123<br />

363.1 Installazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .123<br />

363.2 Impostazione e configurazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124<br />

363.3 RxDOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125<br />

363.4 Riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125<br />

364 Progetto GNUish . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .126<br />

364.1 Programmi di servizio vari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126<br />

364.2 Gnuplot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126<br />

364.3 Spreadsheet Calculator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127<br />

364.4 Ispell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127<br />

364.5 Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .127<br />

364.6 Riferimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127<br />

365 The valuable DOS Freeware page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128<br />

365.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128<br />

365.2 OS and GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129<br />

365.3 Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129<br />

365.4 Network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130<br />

365.5 Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132<br />

365.6 Typesetting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132<br />

365.7 More Dos s<strong>of</strong>tware sources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133<br />

365.8 Search engines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133<br />

366 Clean the Clipper 5.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134<br />

366.1 Step 1: try to compile with the /P parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135<br />

366.2 Step 2: understand well the use <strong>of</strong> code blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136<br />

366.3 Step 3: understand the object programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137<br />

366.4 Step 4: understand the get object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138<br />

366.5 Step 5: trying to stop using commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140<br />

366.6 Step 6: free yourself from STD.CH - /U . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153<br />

366.7 Step 7: take control over all include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153<br />

367 nanoBase 1997 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160<br />

367.1 What is it . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160<br />

367.2 The dot command line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160<br />

367.3 The menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161<br />

367.4 The macro recording, compiling and execution . . . . . . . . . . . . . . . . . . . . . . . . . . . .161<br />

84


367.5 The report system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162<br />

367.6 The integrated text editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163<br />

367.7 The internal documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164<br />

367.8 Download it . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164<br />

367.9 Bugs and known problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165<br />

368 nanoBase 1997 user manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166<br />

368.1 Dos xBase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166<br />

368.2 Composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171<br />

368.3 How to use nB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173<br />

368.4 Status line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174<br />

368.5 The dot line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175<br />

368.6 The menu system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175<br />

368.7 The text editor DOC() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187<br />

368.8 The help text file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187<br />

368.9 Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188<br />

368.10 Data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192<br />

368.11 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200<br />

368.12 Delimiters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201<br />

368.13 Code blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202<br />

368.14 Standard functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202<br />

368.15 nB functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261<br />

368.16 Normal command substitution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299<br />

368.17 nB command substitution functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305<br />

368.18 RPT: the nB print function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310<br />

368.19 How can I... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313<br />

368.20 The source files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314<br />

85


Dos: introduzione<br />

Capitolo 358<br />

DOS è acronimo di Disk Operating System e sta a indicare il nome di un sistema operativo per<br />

micro elaboratori basati su microprocessori i86, successore del vecchio CP/M. Probabilmente,<br />

data la sua estrema limitatezza, è un po’ azzardato voler parlare di «sistema operativo», tanto che<br />

qualcuno lo appella: «gestore di interruzioni» (interrupt).<br />

Questo sistema operativo nasce come s<strong>of</strong>tware proprietario; tuttavia, attualmente il progetto più<br />

attivo attorno a questo tipo di sistema è FreeDOS, il cui scopo è quello di realizzarne un’edizione<br />

libera e completa.<br />

358.1 Avvio del sistema<br />

Un sistema Dos è composto essenzialmente da un kernel, un interprete dei comandi e da una<br />

serie di programmi di servizio. Questo concetto è analogo ai sistemi Unix, con la differenza che<br />

il kernel <strong>of</strong>fre funzionalità molto scarse e solo per mezzo di interruzioni s<strong>of</strong>tware (IRQ).<br />

Nelle versioni proprietarie del Dos, il kernel era suddiviso in due file, che raccoglievano funzionalità<br />

distinte in base all’importanza relativa. I nomi usati sono stati differenti e nel caso di<br />

FreeDOS il kernel è contenuto tutto in un solo file (tabella 358.1).<br />

Tabella 358.1. Comparazione tra i nomi dei file che compongono il kernel di un<br />

sistema Dos.<br />

Micros<strong>of</strong>t IBM Novell, Caldera RxDOS FreeDOS<br />

IO.SYS<br />

MSDOS.SYS<br />

IBMBIO.COM<br />

IBMDOS.COM<br />

IBMBIO.COM<br />

IBMDOS.COM<br />

RXDO-<br />

SBIO.SYS<br />

RXDOS.SYS<br />

KERNEL.SYS<br />

--<br />

I file del kernel devono trovarsi nella directory radice della partizione o del dischetto per poter<br />

essere avviati. Per la precisione, l’avvio del kernel viene gestito direttamente dal codice inserito<br />

nel settore di avvio della partizione o del dischetto (512 Kibyte), che a sua volta viene avviato<br />

dal firmware (il BIOS, secondo la terminologia specifica dell’architettura i86 e successiva).<br />

Il kernel, dopo essere stato avviato, non attiva una procedura di avvio, ma si limita a interpretare<br />

uno script speciale, ‘CONFIG.SYS’, e subito dopo avvia l’interprete dei comandi, ovvero<br />

la shell. Tradizionalmente, il programma in questione è ‘COMMAND.COM’. Secondo la tradizione,<br />

l’interprete dei comandi che viene avviato dal kernel si occupa subito di eseguire lo script<br />

‘AUTOEXEC.BAT’. Gli script ‘CONFIG.SYS’ e ‘AUTOEXEC.BAT’ devono trovarsi nella directory<br />

radice del disco o della partizione da cui si avvia il sistema, ovvero quella in cui si trova già il<br />

kernel che viene avviato.<br />

L’interprete dei comandi, ‘COMMAND.COM’, è in grado di eseguire direttamente alcune funzionalità,<br />

attraverso comandi interni che non si traducono in programmi di servizio veri e propri.<br />

Tradizionalmente ‘COMMAND.COM’ si colloca nella directory radice del disco o della partizione<br />

in cui si trova il kernel stesso. Ciò non è propriamente indispensabile, ma conviene attenersi a<br />

questa linea per evitare fastidi inutili.<br />

86


Dos: introduzione 87<br />

358.2 Dispositivi secondo il Dos<br />

I dispositivi secondo il Dos hanno un nome, composto da lettere e cifre numeriche, terminato da<br />

due punti opzionali:<br />

nome_dispositivo[:]<br />

Il nome in questione può essere indicato utilizzando lettere maiuscole o minuscole, senza che la<br />

cosa faccia differenza. I nomi più comuni sono elencati nella tabella 358.2. È il caso di osservare<br />

che i due punti che concludono il nome, vanno usati necessariamente quando questo viene<br />

abbinato ad altre informazioni da cui non potrebbe essere distinto (per esempio un percorso).<br />

Tabella 358.2. Nomi dei dispositivi più comuni in Dos.<br />

Dispositivo Descrizione<br />

‘A:’ Disco nella prima unità a dischetti.<br />

‘B:’ Disco nella seconda unità a dischetti.<br />

‘C:’ Prima partizione Dos nel primo disco fisso.<br />

‘D:’, ‘E:’,... ‘Z:’ Partizione Dos o altro tipo di disco.<br />

‘CON:’ Console: tastiera e schermo.<br />

‘PRN:’ Porta stampante principale.<br />

‘LPT1:’, ‘LPT2:’,... Porte parallele.<br />

‘COM1:’, ‘COM2:’,... Porte seriali.<br />

Il Dos mantiene distinti i dischi e le partizioni, nel senso che questi non devono creare una<br />

struttura unica come avviene nei sistemi Unix. Pertanto, quando si fa riferimento a un percorso<br />

di un file o di una directory, si deve tenere in considerazione anche il disco o la partizione in cui<br />

si trova.<br />

Il modo utilizzato dal Dos per identificare i dischi e le partizioni, di fatto impedisce di accedere a<br />

questi dispositivi in modo indipendente dal file system sottostante. Per intenderci, l’«unità» ‘X:’<br />

può essere una partizione Dos di un disco non meglio identificato; mentre non esiste un modo<br />

univoco per poter raggiungere il dispositivo fisico in cui si trova questo disco.<br />

358.3 Directory, file ed eseguibili<br />

Il Dos è nato dopo Unix e da questo sistema ha ereditato alcuni concetti elementari (forse troppo<br />

pochi). I percorsi di file e directory si separano con una barra obliqua, che però è inversa rispetto<br />

allo Unix. Anche con il Dos c’è una directory radice; tuttavia si aggiunge l’indicazione dell’unità<br />

di memorizzazione (il disco o la partizione). Si può osservare a questo proposito la figura 358.1.<br />

Figura 358.1. Struttura di un percorso in un file system Dos.<br />

C:\PRIMO\SECONDO\TERZO\QUARTO<br />

^ ^ ^ ^ ^<br />

| | | | |<br />

| | | | file o directory finale<br />

| | | |<br />

| | | directory<br />

| | |<br />

| | separazione tra una directory e la successiva<br />

| |<br />

| directory radice<br />

|<br />

unità di memorizzazione


88 volume VIII Argomenti avanzati e accessori<br />

I nomi di file e directory possono essere indicati utilizzando lettere maiuscole o minuscole, senza<br />

che la cosa possa fare differenza. Questi nomi possono essere composti utilizzando anche cifre<br />

numeriche e altri simboli (che comunque è bene usare con parsimonia).<br />

Per la precisione, sono esclusi i simboli: ‘/’, ‘\’, ‘[’, ‘]’, ‘’, ‘+’, ‘=’, ‘;’, ‘:’, ‘,’, ‘?’, ‘*’,<br />

‘{’, ‘}’ e il punto che va usato esattamente come descritto nel seguito.<br />

Tradizionalmente, il Dos utilizza un tipo di file system elementare, denominato FAT (Dos-FAT),<br />

in cui i nomi dei file e delle directory possono essere composti utilizzando al massimo 11 caratteri,<br />

di cui otto compongono un prefisso e tre un suffisso. Il prefisso e il suffisso di questi nomi<br />

appaiono uniti attraverso un punto. Per esempio: ‘CIAO.COM’, ‘LETTERA.TXT’, ‘PIPPO.NB’,...<br />

Questa conformazione dei nomi è una caratteristica fondamentale del Dos, da cui derivano una<br />

serie di consuetudini e di limitazioni molto importanti.<br />

È importante osservare che non è opportuno che i nomi dei file coincidano con quelli dei dispositivi<br />

(senza i due punti finali). In pratica, non conviene creare file del tipo ‘CON:’, ‘PRN:’,<br />

ecc. Tutto dipende dal contesto, ma in generale è bene fare attenzione a questo particolare.<br />

Come nei sistemi Unix il Dos annovera il concetto di directory corrente, a cui si aggiunge il<br />

concetto di unità di memorizzazione corrente. Infatti, la directory va collocata in un disco o<br />

in una partizione. In base a questo principio, si possono indicare dei percorsi relativi, che fanno<br />

riferimento alla posizione corrente (nell’unità di memorizzazione corrente). Tuttavia, in più,<br />

ogni unità di memorizzazione ha una sua directory corrente. Per esempio, fare riferimento a un<br />

file in una certa unità di memorizzazione ‘x:’, senza specificare il percorso, significa indicare<br />

implicitamente la directory corrente di quella unità.<br />

Per esempio, supponendo che la directory corrente dell’unità ‘X:’ sia ‘X:\PRIMO\SECONDO\’,<br />

facendo riferimento al file ‘X:CIAO’, si intende indicare implicitamente il file ‘X:\PRIMO\<br />

SECONDO\CIAO’.<br />

In un percorso si possono usare anche i simboli ‘.’ e ‘..’, con lo stesso significato che hanno in<br />

un sistema Unix: la directory stessa e la directory genitrice.<br />

Il file system tradizionale del Dos consente di annotare solo poche informazioni per i file e le<br />

directory: la data di modifica e quattro indicatori booleani, rappresentati da altrettante lettere:<br />

• H file o directory nascosti;<br />

• S file o directory di sistema;<br />

• R file o directory in sola lettura e non cancellabile;<br />

• A file o directory da archiviare (i dati sono stati modificati).<br />

Si tratta di attributi completamente differenti da quelli di Unix. Si può osservare in particolare la<br />

mancanza di un attributo che specifichi la possibilità di eseguire un programma o di attraversare<br />

una directory. Secondo la tradizione Dos, gli attributi vanno considerati nel modo seguente:<br />

• A viene attivato ogni volta che il file viene scritto o modificato e serve per automatizzare<br />

i sistemi di copia periodica;<br />

• R se attivo, il Dos non consente la scrittura o la rimozione;


Dos: introduzione 89<br />

• S se attivo si tratta di un file di «sistema», ma in pratica si comporta come l’attributo H;<br />

• H se attivo si tratta di un file «nascosto», che così non dovrebbe apparire nelle liste di file<br />

e directory.<br />

In generale, file e directory nascosti o di sistema non dovrebbero essere spostati fisicamente,<br />

nemmeno nell’ambito della stessa unità di memorizzazione. Questa esigenza nasce in particolare<br />

per i file del kernel, che non possono essere spostati se si vuole poter riavviare il sistema<br />

operativo.<br />

Dal momento che il file system non permette di determinare se un file è un eseguibile, l’unico<br />

modo per permettere al sistema di conoscere questa caratteristica sta nell’uso di suffissi convenzionali<br />

nei nomi: i file che terminano con l’estensione ‘.COM’ e ‘.EXE’ sono programmi binari<br />

(la differenza tra i due tipi di estensione riguarda il formato del binario); quelli che terminano per<br />

‘.BAT’ sono script dell’interprete dei comandi (‘COMMAND.COM’).<br />

La prima stranezza che deriva da questa caratteristica del Dos sta nel fatto che per avviare un<br />

eseguibile di questi, è sufficiente indicare il nome del file senza l’estensione, che diventa così<br />

un componente opzionale agli occhi dell’utilizzatore.<br />

358.4 Comandi e ambiente di avvio<br />

L’interprete dei comandi tradizionale dei sistemi Dos è il programma ‘COMMAND.COM’, che viene<br />

avviato direttamente dal kernel. ‘COMMAND.COM’ può essere avviato più volte successive, anche<br />

se di solito ciò è di scarsa utilità, dal momento che il Dos non è un sistema operativo in multiprogrammazione.<br />

In ogni caso, quando viene avviato dal kernel, si occupa di interpretare ed eseguire<br />

lo script ‘AUTOEXEC.BAT’ che si trova nella directory radice dell’unità di avvio.<br />

‘COMMAND.COM’ mostra un invito simile idealmente a quello delle shell Unix, dopo il quale possono<br />

essere inseriti i comandi. A loro volta, questi possono essere riferiti a comandi interni<br />

corrispondenti a funzionalità <strong>of</strong>ferte direttamente dall’interprete, oppure possono rappresentare<br />

la richiesta di avvio di un programma esterno.<br />

Figura 358.2. Riga di comando.<br />

C:\>DIR A: /W<br />

^ ^ ^ ^<br />

| | | |<br />

| | | opzione<br />

| | |<br />

| | argomento<br />

| |<br />

| comando<br />

|<br />

invito<br />

Il Dos ha ereditato da Unix anche il concetto di variabile di ambiente. Il meccanismo è lo stesso<br />

ed è fondamentale la variabile di ambiente ‘PATH’, con la quale si possono indicare i percorsi di<br />

ricerca degli eseguibili. Tuttavia, il Dos ha delle caratteristiche speciali, per cui, è il caso di fare<br />

alcuni esempi di comandi:<br />

• C:\>C:\PRIMO\SECONDO.EXE<br />

questo comando avvia l’esecuzione del file ‘C:\PRIMO\SECONDO.EXE’;


90 volume VIII Argomenti avanzati e accessori<br />

• C:\>C:\PRIMO\SECONDO<br />

questo comando potrebbe avviare l’esecuzione del primo dei file seguenti che riesce a<br />

trovare;<br />

– ‘C:\PRIMO\SECONDO.COM’<br />

– ‘C:\PRIMO\SECONDO.EXE’<br />

– ‘C:\PRIMO\SECONDO.BAT’<br />

• C:\>SECONDO<br />

questo comando potrebbe avviare l’esecuzione del primo dei file seguenti che dovesse riuscire<br />

a trovare, ma in mancanza può continuare la ricerca nei percorsi indicati nella variabile<br />

di ambiente ‘PATH’.<br />

– ‘C:.\SECONDO.COM’<br />

– ‘C:.\SECONDO.EXE’<br />

– ‘C:.\SECONDO.BAT’<br />

I percorsi indicati nella variabile di ambiente ‘PATH’ sono separati da un punto e virgola; per<br />

esempio:<br />

C:\;C:\DOS;C:\FDOS\BIN<br />

Di solito, il Dos dà per scontato che si cerchino gli eseguibili a cominciare dalla directory corrente.<br />

Per questo, occorre considerare che è sempre come se la variabile di ambiente ‘PATH’<br />

contenesse questa indicazione prima delle altre: ‘.;C:\;C:\DOS;C:\FDOS\BIN’. È da osservare<br />

che FreeDOS si comporta in maniera differente, in quanto richiede espressamente<br />

questa indicazione della directory corrente.<br />

358.5 Caratteri jolly<br />

Il Dos imita l’utilizzo dei caratteri jolly come avviene nei sistemi Unix per opera delle shell.<br />

Tuttavia, nel Dos non si tratta di un’espansione che avviene per opera della shell, ma vi deve<br />

provvedere ogni programma per conto proprio. Questo rappresenta una gravissima deficienza del<br />

Dos, che però è irrimediabile.<br />

Su questa base, i comandi tendono a richiedere l’indicazione di un argomento che rappresenta il<br />

nome di uno o più file prima delle opzioni eventuali.<br />

Ma c’è un altro problema. Il punto che divide in due i nomi dei file e delle directory è un muro<br />

insuperabile per i caratteri jolly.<br />

I simboli che si possono utilizzare sono solo l’asterisco e il punto interrogativo. L’asterisco vale<br />

per una sequenza qualunque di caratteri, escluso il punto; il punto interrogativo vale per un<br />

carattere qualunque. 1<br />

1 Ci sono programmi di origine Unix, portati in Dos, che non hanno questa limitazione riferita al punto che separa<br />

l’estensione.


Dos: introduzione 91<br />

Modello<br />

Tabella 358.3. Alcuni esempi.<br />

Corrispondenza<br />

*.* Corrisponde a un nome qualunque.<br />

*.COM Un nome che termina con l’estensione ‘.COM’.<br />

CIAO.X?X<br />

Tutti i nomi che iniziano per ‘CIAO’ e hanno un’estensione composta da un lettera<br />

«X» iniziale e finale, senza specificare cosa ci sia al secondo posto.<br />

* Tutti i nomi che non hanno estensione (che non contengono il punto).<br />

358.6 Invito dell’interprete dei comandi<br />

Esiste un’altra variabile di ambiente fondamentale per il Dos. Si tratta di ‘PROMPT’, che consente<br />

di modificare l’aspetto dell’invito dell’interprete dei comandi. La cosa funziona un po’ come nelle<br />

shell Unix, per cui si assegna una stringa che può contenere dei simboli speciali, praticamente<br />

delle sequenze di escape che vengono espanse prima della visualizzazione. La tabella 358.4 riepiloga<br />

questi simboli particolari. In origine, il Dos mostrava in modo predefinito un invito simile<br />

all’esempio seguente, in cui appare solo l’unità di memorizzazione corrente:<br />

C:><br />

Questo tipo di impostazione corrisponderebbe alla stringa ‘$N$G’. In seguito, si è passati a<br />

un invito simile al prossimo esempio, in cui si aggiunge anche l’informazione della directory<br />

corrente:<br />

C:\BIN\><br />

Questo corrisponde alla stringa ‘$P$G’.<br />

Tabella 358.4. Sequenze di escape per definire dei componenti speciali all’interno di<br />

una stringa di invito.<br />

Simbolo<br />

Corrispondenza<br />

$Q =<br />

$$ $<br />

$T Ora corrente.<br />

$D Data corrente.<br />

$V Numero della versione.<br />

$N Lettera dell’unità corrente.<br />

$G ><br />

$L <<br />

$B |<br />

$H (cancella il carattere precedente)<br />

$E (1B16)<br />

$_ Codice di interruzione di riga.<br />

Cancellando il contenuto della variabile di ambiente ‘PROMPT’ si ripristina la stringa di invito<br />

predefinita.


92 volume VIII Argomenti avanzati e accessori<br />

358.7 Comandi interni principali<br />

I comandi interni sono quelli che non corrispondono a programmi di servizio veri e propri,<br />

ma sono funzionalità svolte direttamente dall’interprete dei comandi. Nelle sezioni seguenti ne<br />

vengono descritti brevemente alcuni.<br />

358.7.1 CH, CHDIR<br />

CH [percorso]<br />

CHDIR [percorso]<br />

‘CH’, o ‘CHDIR’, è un comando interno dell’interprete dei comandi, che consente di visualizzare<br />

o di cambiare la directory corrente. È indifferente l’uso di ‘CD’ o di ‘CHDIR’; se il comando non<br />

è seguito dal percorso, si ottiene solo la visualizzazione della directory corrente. Si osservi che<br />

se si indica un percorso assoluto di unità di memorizzazione, se questa non corrisponde a quella<br />

attuale, si cambia la directory corrente di quella unità.<br />

Segue la descrizione di alcuni esempi.<br />

• C:\>CD<br />

Visualizza la directory corrente.<br />

• C:\>CD \TMP\LAVORO<br />

Sposta la directory corrente in ‘\TMP\LAVORO\’.<br />

• C:\TMP\LAVORO>CD DATI\LETTERE<br />

Sposta la directory corrente in ‘DATI\LETTERE\’ che a sua volta discende dalla posizione<br />

iniziale precedente.<br />

• C:\TMP\LAVORO\DATI\LETTERE>CD ..<br />

Sposta la directory corrente nella posizione della directory genitrice di quella iniziale.<br />

• C:\TMP\LAVORO\DATI>CD F:\TMP<br />

Cambia la directory corrente dell’unità ‘F:’, senza intervenire nell’unità corrente.<br />

358.7.2 X:<br />

{A|B| ...|Z}:<br />

Il Dos gestisce le unità di memorizzazione in modo speciale. Per cambiare l’unità di memorizzazione<br />

corrente, non esiste un comando analogo a ‘CD’: si deve indicare il nome dell’unità a cui si<br />

vuole accedere.<br />

Segue la descrizione di alcuni esempi.<br />

• C:\>A:<br />

Cambia l’unità di memorizzazione attuale, facendola diventare ‘A:’.


Dos: introduzione 93<br />

• A:\>F:<br />

Cambia l’unità di memorizzazione attuale, facendola diventare ‘F:’.<br />

358.7.3 MD, MKDIR<br />

MD directory<br />

MKDIR directory<br />

‘MD’, o ‘MKDIR’, è un comando interno dell’interprete dei comandi, che consente di creare una<br />

directory vuota.<br />

Segue la descrizione di alcuni esempi.<br />

• C:\>MD LAVORO<br />

Crea la directory ‘LAVORO\’ a partire da quella corrente.<br />

• C:\>MD \TMP\DATA<br />

Crea la directory ‘\TMP\DATA\’ nell’unità corrente.<br />

• C:\>MD F:\TMP\DATA<br />

Crea la directory ‘\TMP\DATA\’ nell’unità ‘F:’.<br />

358.7.4 RD, RMDIR<br />

RM directory<br />

RMDIR directory<br />

‘RD’, o ‘RMDIR’, è un comando interno dell’interprete dei comandi, che consente di cancellare<br />

una directory vuota.<br />

Segue la descrizione di alcuni esempi.<br />

• C:\>RD LAVORO<br />

Cancella la directory ‘LAVORO\’ a partire da quella corrente.<br />

• C:\>RD \TMP\DATA<br />

Cancella la directory ‘\TMP\DATA\’ nell’unità corrente.<br />

• C:\>RD F:\TMP\DATA<br />

Cancella la directory ‘\TMP\DATA\’ nell’unità ‘F:’.


94 volume VIII Argomenti avanzati e accessori<br />

358.7.5 DIR<br />

DIR [directory|file] [/P] [/W]<br />

‘DIR’ è un comando interno dell’interprete dei comandi, che consente di visualizzare l’elenco del<br />

contenuto di una directory o l’elenco di un gruppo di file. L’argomento del comando può essere<br />

composto utilizzando caratteri jolly, secondo lo standard del Dos, ovvero i simboli ‘*’ e ‘?’.<br />

Tabella 358.5. Alcune opzioni.<br />

Opzione Descrizione<br />

Blocca lo scorrimento dell’elenco in attesa della pressione di<br />

/P<br />

un tasto quando questo è più lungo del numero di righe che<br />

possono apparire sullo schermo.<br />

Visualizza solo i nomi dei file e delle directory, senza altre<br />

/W<br />

informazioni, permettendo così di vedere più nomi assieme in<br />

un’unica schermata.<br />

Segue la descrizione di alcuni esempi.<br />

• C:\>DIR *.*<br />

Visualizza l’elenco di tutti i file contenuti nella directory corrente.<br />

• C:\>DIR ESEMPIO.*<br />

Visualizza l’elenco di tutti i file il cui nome inizia per ‘ESEMPIO’ e continua con<br />

un’estensione qualunque.<br />

• C:\>DIR *.DOC<br />

Visualizza l’elenco di tutti i file il cui nome termina con l’estensione ‘.DOC’.<br />

• C:\>DIR F:\DOC\*.*<br />

Visualizza l’elenco di tutti i file contenuti nella directory ‘\DOC\’ dell’unità ‘F:’.<br />

• C:\>DIR F:<br />

Visualizza l’elenco di tutti i file contenuti nella directory corrente dell’unità ‘F:’.<br />

358.7.6 COPY<br />

COPY file_origine [file_destinazione] [opzioni]<br />

COPY file_1 + file_2 [+ ...] [file_destinazione] [opzioni]<br />

‘COPY’ è un comando interno dell’interprete dei comandi, che consente di copiare uno o più file<br />

(sono escluse le directory). Anche qui è consentito l’uso di caratteri jolly, ma al contrario dei<br />

sistemi Unix, i caratteri jolly possono essere usati anche nella destinazione. Il ‘COPY’ del Dos<br />

consente anche di unire assieme più file.


Dos: introduzione 95<br />

Tabella 358.6. Alcune opzioni.<br />

Opzione Descrizione<br />

/V Fa in modo che venga verificato il risultato della copia.<br />

a sì che la copia avvenga in modo «binario». Questa opzione<br />

può servire quando si copia un file su un dispositivo e si<br />

/B<br />

vuole evitare che alcuni codici vengano interpretati in modo<br />

speciale.<br />

Non chiede conferma prima di sovrascrivere i file, se questi<br />

/Y<br />

esistono già nella destinazione.<br />

Segue la descrizione di alcuni esempi.<br />

• C:\>COPY ESEMPIO PROVA<br />

Copia il file ‘ESEMPIO’ nella directory corrente ottenendo il file ‘PROVA’, sempre nella<br />

directory corrente.<br />

• C:\>COPY C:\DOS\*.* C:\TMP<br />

Copia tutto il contenuto della directory ‘\DOS\’ dell’unità ‘C:’ nella directory ‘\TMP\’<br />

nella stessa unità ‘C:’, mantenendo gli stessi nomi.<br />

• C:\>COPY TESTA+CORPO+CODA LETTERA<br />

Copia, unendoli, i file ‘TESTA’, ‘CORPO’ e ‘CODA’, ottenendo il file ‘LETTERA’.<br />

• C:\>COPY *.DOC *.TXT<br />

Copia tutti i file che nella directory corrente hanno un nome che termina con l’estensione<br />

‘.DOC’, generando altrettanti file, con lo stesso prefisso, ma con l’estensione ‘.TXT’.<br />

• C:\>COPY PROVA.PRN PRN: /B<br />

Copia il file ‘PROVA.PRN’ nel dispositivo ‘PRN:’, ovvero sulla stampante, assicurandosi<br />

che la copia avvenga senza alterare alcunché.<br />

358.7.7 DEL, ERASE<br />

DEL file<br />

ERASE file<br />

‘DEL’, o ‘ERASE’, è un comando interno dell’interprete dei comandi, che consente di cancellare<br />

uno o più file (sono escluse le directory). È da considerare che i file che hanno l’attributo di sola<br />

lettura attivo, non possono essere modificati e nemmeno cancellati.<br />

Segue la descrizione di alcuni esempi.<br />

• C:\TMP>DEL *.*<br />

Cancella tutti i file nella directory corrente.<br />

• C:\TMP>DEL ESEMPIO.*<br />

Cancella tutti i file contenuti nella directory corrente, il cui nome inizia per ‘ESEMPIO’ e<br />

termina con qualunque estensione.


96 volume VIII Argomenti avanzati e accessori<br />

• C:\TMP>DEL *.BAK<br />

Cancella tutti i file contenuti nella directory corrente, il cui nome termina con l’estensione<br />

‘.BAK’.<br />

358.7.8 REN, RENAME<br />

REN file_origine nome_nuovo<br />

RENAME file_origine nome_nuovo<br />

‘REN’, o ‘RENAME’, è un comando interno dell’interprete dei comandi, che consente di cambiare<br />

il nome di uno o più file (sono escluse le directory). Il primo argomento può essere un percorso<br />

relativo o assoluto, completo anche dell’indicazione dell’unità, mentre il secondo argomento è il<br />

nuovo nome, che implicitamente non può essere collocato altrove.<br />

Segue la descrizione di alcuni esempi.<br />

• C:\>REN ESEMPIO PROVA<br />

Cambia il nome del file ‘ESEMPIO’, che si trova nella directory corrente, in ‘PROVA’.<br />

• C:\>REN *.TXT *.DOC<br />

Cambia il nome di tutti i file che, nella directory corrente, hanno l’estensione ‘.TXT’,<br />

trasformandoli in modo tale da avere un’estensione ‘.DOC’.<br />

358.7.9 SET<br />

SET [variabile_di_ambiente=stringa]<br />

‘SET’ è un comando interno dell’interprete dei comandi che ha lo scopo di assegnare un valore<br />

a una variabile di ambiente, oppure di leggere lo stato di tutte le variabili di ambiente esistenti.<br />

Quando si assegna un valore a una variabile, questa viene creata simultaneamente; quando non<br />

si assegna nulla a una variabile, la si elimina.<br />

Segue la descrizione di alcuni esempi.<br />

• C:\>SET<br />

Elenca le variabili di ambiente esistenti assieme al loro valore.<br />

• C:\>SET PROMPT=$P$G$G<br />

Assegna alla variabile di ambiente ‘PROMPT’ la stringa ‘$P$G$G’. Questo si traduce nella<br />

modifica dell’aspetto dell’invito dell’interprete dei comandi.<br />

• C:\>SET PATH=.;C:\BIN;D:\BIN<br />

Assegna alla variabile di ambiente ‘PATH’ la stringa ‘.;C:\BIN;D:\BIN’.<br />

• C:\>SET PROMPT=<br />

Elimina la variabile di ambiente ‘PROMPT’, assegnandole la stringa nulla.


Dos: introduzione 97<br />

358.7.10 TYPE<br />

TYPE file<br />

‘TYPE’ è un comando interno dell’interprete dei comandi, che consente di leggere ed emettere<br />

il contenuto di un file attraverso lo standard output. Questo si traduce in pratica nella<br />

visualizzazione del file in questione.<br />

Segue la descrizione di alcuni esempi.<br />

• C:\>TYPE LETTERA<br />

Emette il contenuto del file ‘LETTERA’ che si trova nella directory e nell’unità corrente.<br />

• C:\>TYPE C:\DOC\MANUALE<br />

Emette il contenuto del file ‘MANUALE’ che si trova nella directory ‘\DOC\’ dell’unità ‘C:’.<br />

358.8 Flussi standard<br />

Il Dos ha ereditato da Unix anche i concetti legati ai flussi standard. In pratica, i programmi<br />

hanno a disposizione tre flussi predefiniti: uno in lettura rappresentato dallo standard input, due<br />

in scrittura rappresentati dallo standard output e dallo standard error. Il meccanismo è lo stesso di<br />

Unix, anche se non funziona altrettanto bene; infatti, non è possibile ridirigere lo standard error<br />

attraverso l’interprete dei comandi.<br />

Secondo la tradizione delle shell Unix, la ridirezione dello standard output si ottiene con il simbolo<br />

‘>’ posto alla fine del comando interessato, seguito poi dal nome del file che si vuole generare<br />

in questo modo. Per esempio,<br />

C:\>TYPE LETTERA > PRN:<br />

invece di visualizzare il contenuto del file ‘LETTERA’, lo invia al dispositivo di stampa<br />

corrispondente al nome ‘PRN:’; inoltre,<br />

C:\>DIR *.* > ELENCO<br />

invece di visualizzare l’elenco dei file che si trovano nella directory corrente, crea il file ‘ELENCO’<br />

con questi dati.<br />

La ridirezione dello standard output fatta in questo modo, va a cancellare completamente il contenuto<br />

del file di destinazione, se questo esiste già; al contrario, si può utilizzare anche ‘>>’, con<br />

il quale, il file di destinazione viene creato se non esiste, oppure viene solo esteso.<br />

Lo standard input viene ridiretto utilizzando il simbolo ‘SORT < ELENCO > ORDINATO<br />

In questo modo, ‘SORT’ riceve dallo standard input il file ‘ELENCO’ e genera attraverso la<br />

ridirezione dello standard output il file ‘ORDINATO’.


98 volume VIII Argomenti avanzati e accessori<br />

Per mettere in contatto lo standard output di un comando con lo standard input del successivo, si<br />

utilizza il simbolo ‘|’. L’esempio seguente mostra un modo alternativo di ottenere l’ordinamento<br />

di un file:<br />

C:\>TYPE ELENCO | SORT > ORDINATO<br />

In generale, tutti i comandi che generano un risultato visuale che scorre sullo schermo, utilizzano<br />

semplicemente lo standard output, che può essere ridiretto in questo modo. Si osservi ancora<br />

l’esempio seguente che riordina il risultato del comando ‘DIR’, mostrandolo comunque sullo<br />

schermo:<br />

C:\>DIR *.DOC | SORT<br />

Nelle sezioni seguenti vengono mostrati alcuni comandi filtro.<br />

358.8.1 SORT<br />

SORT [opzioni] < file_da_ordinare > file_ordinato<br />

Il comando ‘SORT’, che dovrebbe corrispondere a un programma di servizio vero e proprio, riordina<br />

il file di testo che ottiene dallo standard input, generando un risultato che emette attraverso<br />

lo standard output.<br />

Tabella 358.7. Alcune opzioni.<br />

Opzione Descrizione<br />

/R Riordina in modo decrescente<br />

Riordina in base al testo che inizia a partire dalla colonna in-<br />

/+n_colonna<br />

dicata come argomento (si tratta di un numero a partire da<br />

uno, per indicare la prima colonna).<br />

L’esempio seguente emette l’elenco della directory corrente riordinato in base all’estensione, che<br />

è un’informazione collocata a partire dalla decima colonna:<br />

C:\>DIR *.DOC | SORT /+10<br />

358.8.2 MORE<br />

MORE < file_da_leggere<br />

MORE file_da_leggere<br />

Il comando ‘MORE’ legge un file, fornito come argomento o attraverso lo standard input, mostrandolo<br />

poi sullo schermo una pagina dopo l’altra. In questo modo, è possibile leggere il contenuto<br />

dei file più lunghi delle righe a disposizione sullo schermo.<br />

Per passare alla pagina successiva, basta premere un tasto qualunque, oppure ciò che viene<br />

indicato espressamente.<br />

Segue la descrizione di alcuni esempi.<br />

• C:\>DIR | MORE<br />

Permette di controllare lo scorrimento a video del risultato del comando ‘DIR’.


Dos: introduzione 99<br />

• C:\>MORE LETTERA.TXT<br />

Permette di controllare lo scorrimento a video del contenuto del file ‘LETTERA.TXT’.<br />

• C:\>TYPE LETTERA.TXT | MORE<br />

Si ottiene lo stesso risultato dell’esempio precedente, attraverso l’uso di una pipeline.<br />

358.9 Accesso diretto ai dispositivi<br />

Il Dos <strong>of</strong>fre poche occasioni per accedere direttamente ai dispositivi. Si tratta generalmente solo<br />

della console e della porta parallela. L’esempio seguente mostra come «copiare» un file sul<br />

dispositivo di stampa, per ottenere così la sua stampa diretta:<br />

C:\>COPY LETTERA PRN:<br />

La stessa cosa avrebbe potuto essere ottenuta con la ridirezione dei flussi standard:<br />

C:\>TYPE LETTERA > PRN:<br />

Può essere interessante la possibilità di copiare il flusso di ingresso della console in un file:<br />

C:\>COPY CON: LETTERA<br />

In questo caso, l’inserimento nel file ‘LETTERA’ prosegue fino a quando viene ricevuto un codice<br />

EOF, che si ottiene qui con la combinazione di tasti [ Ctrl+z ] seguita da [ Invio ].<br />

È bene ricordare che la console, ovvero il dispositivo ‘CON:’, riceve dati in ingresso attraverso la<br />

tastiera ed emette dati in uscita utilizzando lo schermo. In pratica, quando un programma attende<br />

dati dallo standard input non ridiretto, li riceve dalla console, cioè dalla tastiera; nello stesso<br />

modo, quando un programma emette dati attraverso lo standard output non ridiretto, li invia alla<br />

console, cioè sullo schermo.<br />

358.10 Riferimenti<br />

• FreeDOS<br />

<br />

• OpenDOS Un<strong>of</strong>ficial Home Page<br />

<br />

Appunti di informatica libera 2003.06.29 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org


Dos: dischi, file system, directory e file<br />

Capitolo 359<br />

La gestione dei dischi, ovvero delle unità di memorizzazione di massa, è molto particolare nel<br />

Dos. In generale, si fa riferimento a queste cose attraverso un lettera che ne rappresenta il dispositivo;<br />

tuttavia, tale dispositivo può indicare un disco intero o solo una partizione, riferendosi<br />

sempre solo a dischi e partizioni Dos.<br />

359.1 Suddivisione in partizioni<br />

Nel Dos, tutti i dischi rimovibili, come i dischetti, non vanno suddivisi in partizioni, mentre i<br />

dischi fissi devono essere preparati in questo modo. Il programma che si usa per queste cose è<br />

‘FDISK’.<br />

Secondo il Dos, le partizioni di un disco possono essere solo quattro. Tuttavia, una partizione<br />

normale può essere suddivisa in sottopartizioni, che vengono definite tradizionalmente «estese»,<br />

dove anche queste possono essere al massimo quattro. Una tale struttura ha condizionato<br />

in pratica anche altri sistemi operativi, per esempio GNU/Linux. Bisogna tenere in considerazione<br />

l’origine storica per comprendere che altri sistemi operativi possono comportarsi in<br />

modo completamente differente.<br />

Di solito, ‘FDISK’ ha una visione delle partizioni tutta orientata verso il Dos. Infatti, consente<br />

di creare una sola partizione primaria (ovvero una partizione normale) e altre partizioni estese<br />

(ovvero altre sottopartizioni di una seconda partizione primaria).<br />

Bisogna considerare che il settore di avvio del Dos viene collocato nel primo settore della partizione<br />

primaria utilizzata per il Dos. In questo modo, manca la sistemazione del primo settore del<br />

disco, l’MBR, che deve contenere il codice necessario a raggiungere il settore di avvio.<br />

FDISK [/MBR]<br />

In generale, sembra che le varie edizioni di ‘FDISK’ per Dos funzionino solo con il primo disco<br />

fisso.<br />

Fondamentalmente, il programma è interattivo, per cui si avvia una maschera con la quale si<br />

interviene per mezzo di un menù. Di norma viene consentito di cancellare le partizioni, di crearne<br />

una primaria e probabilmente una sola di estesa.<br />

Di solito, è possibile riscrivere il settore di avvio MBR attraverso l’opzione ‘/MBR’.<br />

359.2 Inizializzazione di un’unità di memorizzazione<br />

L’inizializzazione di un’unità di memorizzazione, intesa come un dischetto o una partizione, si<br />

ottiene con il comando ‘FORMAT’. Questo si occupa anche di predisporre il file system Dos-FAT<br />

ed eventualmente anche di trasferire il kernel, per renderlo avviabile.<br />

FORMAT lettera_unità: [/N:settori] [/T:cilindri] [/S] [/U]<br />

In alcune edizioni del Dos, questo comando non inizializza l’unità di memorizzazione, ma si<br />

limita a sovrascrivere la parte iniziale. Ciò viene fatto per accelerare il procedimento e per<br />

permettere eventualmente il recupero dei dati, in caso di ripensamenti. In generale, sarebbe<br />

meglio evitare questa scorciatoia quando si tratta di unità corrispondenti ai dischetti; così, per<br />

confermare la richiesta di un’inizializzazione tradizionale, si può aggiungere l’opzione ‘/U’.<br />

100


Dos: dischi, file system, directory e file 101<br />

Segue la descrizione di alcuni esempi.<br />

• C:\>FORMAT A: /U<br />

Inizializza l’unità ‘A:’, corrispondente a un dischetto. L’inizializzazione avviene in modo<br />

completo, essendo stata usata l’opzione ‘/U’; inoltre, dal momento che non sono state<br />

indicate altre cose, il formato usato è quello predefinito in base alla configurazione del<br />

firmware.<br />

• C:\>FORMAT A: /N:9 /T:40 /U<br />

Come nell’esempio precedente, con l’aggiunta dell’indicazione della geometria: nove settori<br />

per traccia e 40 cilindri; si sottintende la presenza di due tracce per cilindro. Pertanto,<br />

dal momento che ogni settore è di 512 byte: 2 * 40 * 9 * 512 byte = 360 Kibyte.<br />

• C:\>FORMAT A: /N:9 /T:80 /U<br />

Come nell’esempio precedente, ma con 80 cilindri: 2 * 80 * 9 * 512 byte = 720 Kibyte.<br />

• C:\>FORMAT A: /N:15 /T:80 /U<br />

Come nell’esempio precedente, ma con 15 settori per traccia: 2 * 80 * 15 * 512 byte =<br />

1200 Kibyte.<br />

• C:\>FORMAT A: /N:18 /T:80 /U<br />

Come nell’esempio precedente, ma con 18 settori per traccia: 2 * 80 * 18 * 512 byte =<br />

1440 Kibyte.<br />

• C:\>FORMAT A: /S<br />

Inizializza il dischetto corrispondente all’unità ‘A:’, trasferendo successivamente il kernel<br />

e probabilmente anche l’interprete dei comandi (‘COMMAND.COM’). Ciò avviene perché è<br />

stata usata l’opzione ‘/S’.<br />

359.3 Etichetta di un’unità di memorizzazione<br />

Tradizionalmente, il Dos prevede la possibilità di attribuire un nome a un’unità di memorizzazione.<br />

Questo nome viene definito solitamente «etichetta» e di fatto viene annotato come un file<br />

speciale nella directory radice (anche se poi non appare nell’elenco). Per modificare o attribuire<br />

questo nome si utilizza il comando ‘LABEL’:<br />

LABEL [lettera_unità:][nome]<br />

Se non si indica la lettera dell’unità di memorizzazione su cui intervenire, si tratta implicitamente<br />

di quella da cui è stato avviato il sistema; se non si indica il nome da attribuire, ‘LABEL’ funziona<br />

in modo interattivo, chiedendo il da farsi.<br />

In linea di principio, l’etichetta di un’unità non serve, salvo il caso di qualche programma che<br />

potrebbe utilizzarla per uno scopo particolare (per esempio i programmi di installazione per<br />

identificare i dischetti).


102 volume VIII Argomenti avanzati e accessori<br />

Esiste anche un altro comando interno per la verifica del nome di un’unità; si tratta di ‘VOL’:<br />

VOL [lettera_unità:]<br />

Il risultato è solo l’informazione del nome stesso, con l’aggiunta del numero di serie se questo<br />

dato è disponibile.<br />

359.4 Analisi e correzione del file system<br />

Esistono pochi strumenti di analisi e correzione degli errori nel file system. In origine si tratta del<br />

comando ‘CHKDSK’, a cui in seguito si è aggiunto ‘SCANDISK’.<br />

CHKDSK lettera_unità: [/F]<br />

‘CHKDSK’ può essere usato solo con l’indicazione di un’unità di memorizzazione; in tal caso<br />

restituisce le informazioni disponibili su questa. Se si aggiunge l’opzione ‘/F’, si richiede<br />

esplicitamente la correzione, per quanto possibile, degli errori rilevati.<br />

L’errore tipico di un file system Dos-FAT si traduce in «concatenamenti perduti», ovvero file,<br />

interi o parziali, di cui non si può conoscere il nome. Questi file potrebbero essere solo dati<br />

temporanei che è bene siano cancellati, ma questa non è la regola. ‘CHKDSK’ tende a salvare<br />

questi file assegnando loro un nome più o meno casuale, lasciando all’utilizzatore l’onere di<br />

decidere cosa farne.<br />

359.5 Copia<br />

Nei sistemi Dos la copia è un’attività piuttosto articolata. In pratica, il comando interno ‘COPY’<br />

consente solo di copiare file puri e semplici. Per copiare un dischetto occorre il comando<br />

‘DISKCOPY’; per copiare file e directory occorre il comando ‘XCOPY’.<br />

359.5.1 DISKCOPY<br />

DISKCOPY unità_di_origine: unità_di_destinazione:<br />

‘DISKCOPY’ permette di eseguire la copia di un’unità di memorizzazione, purché si tratti di un<br />

dischetto. Il dischetto di destinazione dovrebbe essere inizializzato preventivamente.<br />

L’unità indicata come secondo argomento, che rappresenta la destinazione, può essere la stessa<br />

di quella di origine. In questo caso, i dischetti andranno alternati nel dispositivo che li ospita,<br />

seguendo le istruzioni che dà ‘DISKCOPY’ stesso.<br />

L’esempio seguente esegue la copia di un dischetto usando lo stesso dispositivo fisico:<br />

C:\>DISKCOPY A: A:<br />

359.5.2 XCOPY<br />

XCOPY percorso_origine [percorso_destinazione] [/E] [/S] [/H] [/V]<br />

‘XCOPY’ consente di copiare uno o più file assieme alla struttura di directory. In altri termini, ciò<br />

significa che è possibile copiare anche una directory intera.


Dos: dischi, file system, directory e file 103<br />

Tabella 359.1. Alcune opzioni.<br />

Opzione Descrizione<br />

/S Copia solo le directory e le sottodirectory non vuote.<br />

/E Copia tutte le sottodirectory, anche se vuote.<br />

/H Copia anche i file nascosti e di sistema.<br />

/V Verifica la copia.<br />

L’esempio seguente copia tutta la struttura che si articola a partire dalla directory ‘\PIPPO\’,<br />

nella directory ‘\PAPPA\’, includendo anche i file nascosti e quelli di sistema:<br />

C:\>XCOPY \PIPPO\*.* \PAPPA\*.* /E /S /H /V<br />

359.6 Trasferimento del sistema<br />

Il Dos è un sistema operativo elementare. L’essenziale in assoluto è costituito dal kernel e dall’interprete<br />

dei comandi. Per rendere «avviabile» un dischetto o una partizione basta copiare questi<br />

file e sistemare il settore di avvio, in modo che punti correttamente al kernel. Questo si può ottenere<br />

con il comando ‘FORMAT’, quando lo si usa con l’opzione ‘/S’ (cosa che naturalmente<br />

implica anche l’inizializzazione dell’unità), oppure con il comando ‘SYS’, fatto appositamente<br />

per questo:<br />

FORMAT lettera_unità: /S<br />

SYS lettera_unità:<br />

A seconda del tipo di Dos, vengono copiati solo i file del kernel, oppure anche l’interprete dei<br />

comandi (necessario per avviare il sistema).<br />

359.7 Modifica delle unità<br />

La caratteristica del Dos per cui si distinguono le unità di memorizzazione, introduce l’esigenza<br />

di comandi particolari, che vengono descritti brevemente nelle sezioni seguenti. In particolare,<br />

si tratta della possibilità di attribuire una lettera di unità differente e di poter inserire un’unità in<br />

una directory come avviene con l’innesto di un file system nei sistemi Unix.<br />

359.7.1 ASSIGN<br />

ASSIGN lettera_unità_1[:]=lettera_unità_2[:]<br />

ASSIGN /STATUS<br />

ASSIGN<br />

Il comando ‘ASSIGN’ permette di modifica il nome di un’unità di memorizzazione. Per ottenere<br />

questo risultato, rimane attivo come programma residente in memoria. Quando si usa senza<br />

argomenti, ‘ASSIGN’ elimina tutte le ridefinizioni; con l’opzione ‘/STATUS’ si ottiene lo stato<br />

attuale delle ridefinizioni; quando si indicano le lettere di unità, la prima è l’unità virtuale che<br />

viene creata come riproduzione della seconda.<br />

Segue la descrizione di alcuni esempi.<br />

• C:\>ASSIGN E:=A:<br />

Dopo questo comando, per accedere all’unità corrispondente al primo dischetto, si potrà<br />

indicare l’unità ‘E:’.


104 volume VIII Argomenti avanzati e accessori<br />

• C:\>ASSIGN<br />

Cancella tutte le ridefinizioni delle unità di memorizzazione.<br />

359.7.2 JOIN<br />

JOIN lettera_unità: percorso<br />

JOIN lettera_unità: /D<br />

JOIN<br />

Il comando ‘JOIN’ permette di attaccare un’unità di memorizzazione in corrispondenza di un<br />

percorso (una directory). Si tratta in pratica di montare l’unità, come avviene nei sistemi Unix.<br />

Quando si usa ‘JOIN’ senza argomenti, si ottiene un elenco degli innesti attivi; quando si usa<br />

l’opzione ‘/D’, si vuole annullare il collegamento dell’unità.<br />

Segue la descrizione di alcuni esempi.<br />

• C:\>JOIN A: C:\MNT\A<br />

Innesta l’unità ‘A:’ nella directory ‘C:\MNT\A\’.<br />

• C:\>JOIN A: /D<br />

Distacca l’unità ‘A:’ da un collegamento precedente.<br />

359.7.3 SUBST<br />

SUBST lettera_unità: percorso<br />

SUBST /D<br />

Il comando ‘SUBST’ permette di creare un’unità virtuale a partire da una directory di un’altra<br />

unità. In pratica, si fa in modo di permettere l’identificazione di una certa directory attraverso<br />

l’uso di una lettera di unità.<br />

Quando si usa ‘JOIN’ con l’opzione ‘/D’, si vuole annullare l’unità virtuale relativa.<br />

Segue la descrizione di alcuni esempi.<br />

• C:\>SUBST E: C:\EXTRA\E<br />

Crea l’unità virtuale ‘E:’ a partire dal contenuto delle directory ‘C:\EXTRA\E\’.<br />

• C:\>JOIN E: /D<br />

Elimina l’unità virtuale ‘E:’.


Dos: dischi, file system, directory e file 105<br />

359.8 Altre particolarità<br />

La gestione del Dos di file e directory è molto strana. Nelle sezioni seguenti vengono descritti<br />

alcuni programmi tipici dei sistemi Dos riguardanti la gestione di file e directory, che non hanno<br />

trovato un’altra collocazione in questo documento, a causa della loro particolarità.<br />

359.8.1 VERIFY<br />

VERIFY [ON|OFF]<br />

Il comando interno ‘VERIFY’ permette di richiedere al sistema operativo di verificare la registrazione<br />

nelle unità di memorizzazione. Come si vede dallo schema sintattico, si attiva o si disattiva<br />

la modalità, attraverso l’uso delle parole chiave ‘ON’ oppure ‘OFF’. Di solito, questa modalità è<br />

disabilitata ed è difficile definire la reale importanza di questa impostazione.<br />

Se si usa il comando senza alcun argomento, si ottiene di sapere quale sia l’impostazione attuale.<br />

359.8.2 APPEND<br />

APPEND directory<br />

APPEND ;<br />

APPEND<br />

Il comando ‘APPEND’ consente di definire un percorso per la ricerca dei file di dati. In pratica,<br />

si vuole permettere ai programmi di accedere a file di dati anche quando questi si trovano fuori<br />

della collocazione prevista. ‘APPEND’ può essere usato più volte, per aggiungere altre directory.<br />

Se viene usato con l’argomento ‘;’, si intende cancellare tutto l’elenco di directory di ricerca dei<br />

file di dati. Se viene usato senza argomenti, si ottiene l’elenco di queste directory.<br />

L’esempio seguente aggiunge la directory ‘C:\DATI\’ all’elenco dei percorsi di ricerca per i file<br />

di dati:<br />

C:\>APPEND C:\DATI<br />

359.8.3 ATTRIB<br />

ATTRIB [+R|-R] [+A|-A] [+S|-S] [+H|-H] file<br />

Il comando ‘ATTRIB’ permette di visualizzare o cambiare gli attributi del file. In pratica,<br />

utilizzando la forma ‘+x’ si attiva l’attributo x, mentre con ‘-x’ si disattiva l’attributo stesso.<br />

Segue la descrizione di alcuni esempi.<br />

• C:\>ATTRIB *.*<br />

Mostra gli attributi di tutti i file contenuti nella directory corrente.<br />

• C:\>ATTRIB +R *.*<br />

Imposta l’attributo di sola lettura per tutti i file della directory corrente.


106 volume VIII Argomenti avanzati e accessori<br />

359.8.4 DELTREE<br />

DELTREE directory<br />

Il comando ‘DELTREE’ consente di eliminare una directory con tutto il suo contenuto,<br />

ricorsivamente.<br />

L’esempio seguente elimina la directory ‘C:\TEMP\CIAO\’ assieme a tutto il suo contenuto:<br />

C:\>DELTREE C:\TEMP\CIAO<br />

359.8.5 FIND<br />

FIND [opzioni] "stringa" [file]<br />

Il comando ‘FIND’ è uno dei più complessi nei sistemi Dos. Serve per fare una ricerca di una<br />

stringa in uno o più file, in base a quanto indicato nell’ultimo argomento, oppure all’interno<br />

dello standard input. Il risultato normale della ricerca è l’emissione delle righe che contengono<br />

la stringa cercata, assieme all’indicazione del file a cui appartengono.<br />

Tabella 359.2. Alcune opzioni.<br />

Opzione Descrizione<br />

/V<br />

La ricerca avviene per le righe che non contengono la stringa<br />

cercata.<br />

/C<br />

Mostra solo il totale delle righe che contengono la stringa<br />

cercata.<br />

/N Mostra il numero di ogni riga che contiene la stringa cercata.<br />

Ignora la differenza tra maiuscole e minuscole per il confronto<br />

/I<br />

con la stringa di ricerca.<br />

In alcune edizioni del Dos, questa modalità di funzionamento<br />

è predefinita.<br />

Segue al descrizione di alcuni esempi.<br />

• C:\>FIND "ciao" *.*<br />

Cerca la stringa ‘ciao’ in tutti i file della directory corrente.<br />

• C:\>FIND "ciao" < MIO.TXT<br />

Cerca la stringa ‘ciao’ nel file ‘MIO.TXT’ che viene fornito attraverso lo standard input.<br />

359.8.6 MOVE<br />

MOVE file_origine directory_destinazione<br />

MOVE directory_origine directory_destinazione<br />

Il comando ‘MOVE’ consente di spostare file o directory in altre collocazioni. In generale, ‘MOVE’<br />

si occupa di spostare e non di rinominare i file, che invece è una funzione del comando ‘REN’.<br />

Il comando ‘MOVE’ è ambiguo e si comporta in maniera differente da una realizzazione all’altra<br />

dei sistemi Dos. In generale bisogna considerare che la destinazione può esistere o meno,<br />

implicando dei comportamenti differenti da valutare.


Dos: dischi, file system, directory e file 107<br />

L’esempio seguente sposta i file e le directory contenute in ‘C:\CIAO\’ nella directory ‘C:\<br />

MIA\’. Se la directory di destinazione non c’è, questa dovrebbe essere creata automaticamente,<br />

ma la cosa va verificata:<br />

C:\>MOVE C:\CIAO\*.* C:\MIA<br />

359.8.7 TREE<br />

TREE [directory]<br />

Il comando ‘TREE’ consente di visualizzare la struttura della directory corrente, oppure di un’altra<br />

directory indicata come argomento.<br />

L’esempio seguente mostra la struttura della directory ‘C:\CIAO\’:<br />

C:\>TREE C:\CIAO<br />

359.8.8 COMP e FC<br />

COMP file_1 file_2 [opzioni]<br />

FC file_1 file_2 [opzioni]<br />

I comandi ‘COMP’ e ‘FC’ permettono di verificare se due file sono identici, oppure no. Non sono<br />

molto facili da utilizzare, specialmente il primo; probabilmente vale la pena di sapere che ci sono,<br />

senza poi pretendere di sfruttare tutte le loro possibilità.<br />

‘FC’ assomiglia molto vagamente a un comando ‘diff’ di Unix, dal momento che di fronte a file<br />

di testo cerca di comprendere quale cambiamento è stato fatto. In questo senso, è probabile che<br />

‘FC’ sia il più utile tra questi due.<br />

Appunti di informatica libera 2003.06.29 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org


Dos: configurazione<br />

Capitolo 360<br />

Nel Dos è un po’ difficile scindere i concetti di configurazione e script, perché per configurare il<br />

sistema, occorre predisporre degli script. Si tratta dei file ‘\CONFIG.SYS’ e ‘\AUTOEXEC.BAT’,<br />

collocati nell’unità di avvio. Questo fatto è già stato accennato nel capitolo introduttivo; in questo<br />

si vuole appr<strong>of</strong>ondire un po’ la cosa.<br />

360.1 CONFIG.SYS<br />

Il file ‘CONFIG.SYS’, collocato nella directory radice dell’unità di avvio, è uno script speciale<br />

avviato dal kernel prima dell’interprete dei comandi. In linea di massima, si tratta di una sequenza<br />

di direttive che occupano ognuna una riga; alcune versioni recenti del Dos consentono di<br />

suddividere le direttive in sezioni da scegliere in base a un menù iniziale.<br />

Le direttive di ‘CONFIG.SYS’ hanno la forma seguente:<br />

nome=valore<br />

In pratica, si assegna una stringa (senza delimitatori espliciti) a un nome che ha un significato<br />

particolare.<br />

In questo file, vengono ignorate le righe vuote, quelle bianche e quelle che iniziano con la parola<br />

chiave ‘REM’:<br />

REM annotazione<br />

È importante osservare che i nomi delle direttive non fanno differenza tra lettere maiuscole<br />

e minuscole. In generale, questo vale anche per le stringhe che vengono assegnate a questi<br />

nomi.<br />

360.1.1 BREAK<br />

BREAK={ON|OFF}<br />

Teoricamente, questa istruzione consente di attivare o di disattivare la funzionalità abbinata alla<br />

combinazione di tasti [ Ctrl+c ]. In condizioni normali, quando si assegna la parola chiave ‘ON’, si<br />

attiva il funzionamento della combinazione [ Ctrl+c ].<br />

360.1.2 BUFFERS<br />

BUFFERS=n_buffer[,n_buffer_secondari]<br />

Questa istruzione consente di definire la quantità di memoria tampone per gli accessi ai dischi.<br />

Si assegnano uno o due valori numerici, separati da una virgola. Il primo valore va da 1 a 99 ed<br />

esprime il numero di aree da usare come memoria tampone; il secondo valore, facoltativo, indica<br />

delle memorie tampone secondarie, con valori che vanno da uno a otto.<br />

108


Dos: configurazione 109<br />

360.1.3 COUNTRY<br />

COUNTRY=n_codice_paese[,[n_codifica][,file_informazioni_nazionali]]<br />

Questa istruzione, attraverso quanto contenuto in un file che tradizionalmente si chiama<br />

‘COUNTRY.SYS’, permette di configurare il sistema in base alla nazionalità. Per la precisione,<br />

si può specificare un codice riferito alla nazionalità, attraverso il quale si ottiene una forma particolare<br />

per le date e gli orari, con l’aggiunta eventuale di un altro codice che specifica la codifica<br />

dei caratteri prescelta (codepage). La tabella 360.1 riepiloga questi codici che fanno riferimento<br />

tradizionalmente anche a paesi che non esistono più.<br />

Si può osservare che la stringa assegnata alla direttiva ‘COUNTRY’ può contenere l’indicazione<br />

di un file (con il percorso, completo di unità o meno). Questo file è quello che contiene poi<br />

le indicazioni relative alla nazionalità prescelta; come già accennato, di solito si tratta del file<br />

‘COUNTRY.SYS’.<br />

Tabella 360.1. Codici di nazionalità.<br />

Località Codice di nazionalità Codifiche utili<br />

USA 001 437, 850<br />

Canada francese 002 863, 850<br />

America latina 003 850, 437<br />

Russia 007 866, 437<br />

Olanda 031 850, 437<br />

Belgio 032 850, 437<br />

Francia 033 850, 437<br />

Spagna 034 850, 437<br />

Ungheria 036 850, 852<br />

Jugoslavia 038 850, 852<br />

Italia 039 850, 437<br />

Svizzera 041 850, 437<br />

Cecoslovacchia 042 850, 852<br />

Regno unito 044 850, 437<br />

Danimarca 045 850, 865<br />

Svezia 046 850, 437<br />

Norvegia 047 850, 865<br />

Polonia 048 850, 852<br />

Germania 049 850, 437<br />

Brasile 055 850, 860<br />

Australia 061 850, 437<br />

Giappone 081 932, 437, 850, 942<br />

Corea 082 934, 437, 850, 944<br />

Cina 088 938, 437, 850, 948<br />

Turchia 090 857, 850<br />

Asia (inglese) 099 850, 437<br />

Portogallo 351 850, 860<br />

Islanda 354 850, 861<br />

Finlandia 358 850, 437<br />

L’esempio seguente predispone l’impostazione nazionale per l’Italia, utilizzando la codifica 850,<br />

che ha il vantaggio di essere quella più comune dei paesi che usano l’alfabeto latino:<br />

COUNTRY=039,850,C:\DOS\COUNTRY.SYS


110 volume VIII Argomenti avanzati e accessori<br />

360.1.4 DEVICE, DEVICEHIGH<br />

DEVICE=programma_di_gestione_dispositivo [opzioni]<br />

DEVICEHIGH=programma_di_gestione_dispositivo [opzioni]<br />

Si tratta di un modo per avviare un programma speciale che ha lo scopo di rimanere residente<br />

in memoria. In generale, tali programmi servono per la gestione di qualche dispositivo,<br />

indispensabile prima di avviare l’interprete dei comandi.<br />

La differenza tra le due direttive sta nel fatto che la seconda cerca di caricare il programma nella<br />

memoria «alta».<br />

Le opzioni riguardano il programma.<br />

L’esempio seguente avvia il programma ‘MOUSE.SYS’ che presumibilmente gestisce il mouse<br />

(l’opzione ‘/2’ serve probabilmente a utilizzare il mouse collegato alla seconda porta seriale):<br />

DEVICE=C:\MOUSE\MOUSE.SYS /2<br />

360.1.5 DOS<br />

DOS={HIGH|LOW}[,{UMB|NOUMB}]<br />

DOS=[{HIGH|LOW},]{UMB|NOUMB}<br />

Questa istruzione richiede al kernel di allocarsi nella memoria convenzionale, ‘LOW’, o in quella<br />

alta, ‘HIGH’. La parola chiave ‘UMB’ richiede di mantenere un collegamento tra la UMB e la<br />

memoria convenzionale; la parola chiave ‘NOUMB’ fa sì che questo collegamento non abbia luogo.<br />

360.1.6 DRIVEPARM<br />

DRIVEPARM=[opzioni]<br />

Si tratta di una direttiva attraverso cui si possono definire i parametri relativi ai dispositivi a<br />

blocchi, per la precisione si tratta solo di dischi, se questo può essere necessario. Le opzioni<br />

assomigliano a quelle dei programmi di servizio, iniziando con una barra obliqua normale: ‘/x...’.<br />

Tabella 360.2. Alcune opzioni.<br />

Opzione Descrizione<br />

/d:n_dispositivo_fisico<br />

Consente di indicare il dispositivo attraverso un numero, da 0<br />

a 255. Lo zero corrisponde alla prima unità a dischetti.<br />

/c<br />

Se si utilizza questa opzione, si intende che l’unità fisica è in<br />

grado di sapere se il disco è inserito o meno.<br />

/f:n_formato<br />

Stabilisce il formato del dispositivo fisico; in pratica, fissa la<br />

geometria.<br />

/f:0 Dischetto 160 Kibyte, 180 Kibyte, 320 Kibyte, 360 Kibyte.<br />

/f:1 Dischetto 1200 Kibyte.<br />

/f:2 Dischetto 720 Kibyte.<br />

/f:5 Disco fisso.<br />

/f:6 Nastro.<br />

/f:7 Dischetto 1440 Kibyte.<br />

/f:9 Dischetto 2880 Kibyte.<br />

/h:n_testine Definisce il numero di testine.<br />

/i Indica che si tratta di un dischetto da 3,5 pollici.


Dos: configurazione 111<br />

Opzione Descrizione<br />

/n Si tratta di un disco fisso.<br />

/s:n_settori Definisce il numero di settori per traccia.<br />

/t:n_cilindri<br />

Definisce il numero dei cilindri (in altri termini: il numero di<br />

tracce per faccia).<br />

360.1.7 FCBS<br />

FCBS=n_blocchi<br />

Permette di definire il numero di blocchi di controllo dei file (file control block). Il valore va da 1<br />

a 255, mentre il valore normale è di quattro blocchi.<br />

360.1.8 FILES<br />

FILES=n_blocchi<br />

Permette di indicare il numero massimo di file aperti. Il numero che può essere assegnato va da<br />

8 a 255. Il valore predefinito dovrebbe essere di otto file.<br />

360.1.9 INSTALL<br />

INSTALL=programma [opzioni]<br />

Si tratta di un’istruzione con la quale si può avviare preventivamente un programma (che dovrebbe<br />

essere residente in memoria), prima dell’avvio dell’interprete dei comandi. In questo caso, a<br />

differenza della direttiva ‘DEVICE’, o ‘DEVICEHIGH’, si tratta di un programma normale.<br />

Le opzioni riguardano il programma.<br />

360.1.10 LASTDRIVE<br />

LASTDRIVE=lettera_unità_finale<br />

Consente di specificare l’ultima lettera di unità che può essere richiesta. Questo consente di<br />

risparmiare risorse, se si è consapevoli del fatto che non servono lettere oltre un certo punto. La<br />

lettera in questione può essere indifferentemente maiuscola o minuscola, senza che ciò possa fare<br />

differenza.<br />

360.1.11 SHELL<br />

SHELL=programma [opzioni]<br />

Permette di indicare esplicitamente il programma da avviare alla fine della procedura di avvio<br />

del kernel. In generale si tratta dell’interprete dei comandi. Questa direttiva può consentire di avviare<br />

un interprete alternativo a quello normale, oppure permette di avviarlo da una collocazione<br />

insolita; inoltre permette di dare al programma in questione delle opzioni particolari.<br />

L’esempio seguente avvia il programma ‘COMMAND.COM’ che si trova nella directory ‘C:\DOS\’:<br />

SHELL=C:\DOS\COMMAND.COM


112 volume VIII Argomenti avanzati e accessori<br />

360.1.12 STACK<br />

STACK=n_livelli[,dimensione_in_byte]<br />

Con questa istruzione è possibile fissare la dimensione dello stack, utilizzando valori da 8 a 64,<br />

oltre allo zero. Il valore dopo la virgola indica la dimensione in byte di ogni livello dello stack.<br />

In questo caso i valori vanno da 32 a 512.<br />

360.2 AUTOEXEC.BAT<br />

Il file ‘AUTOEXEC.BAT’ collocato nella directory radice dell’unità di avvio, è inteso essere uno<br />

script che viene eseguito dall’interprete dei comandi, ‘COMMAND.COM’, dopo l’avvio del sistema.<br />

Questo script viene realizzato normalmente in modo sequenziale, senza strutture di controllo.<br />

In generale è importante per due cose: impostare alcune variabili di ambiente fondamentali, per<br />

esempio ‘PATH’; avviare dei programmi che poi restano residenti in memoria, quando questo non<br />

si ottiene già attraverso il file ‘\CONFIG.SYS’.<br />

360.3 Comandi ridondanti<br />

Anche nel Dos è molto importante l’uso delle variabili di ambiente. È già stato mostrato il<br />

comando ‘SET’, attraverso il quale si impostano o si annullano le variabili di ambiente:<br />

SET nome_variabile=stringa_assegnata<br />

Alcune variabili hanno un’importanza particolare, per cui esiste un comando interno apposito<br />

(dell’interprete dei comandi), che serve a inizializzarle senza nemmeno l’uso del comando ‘SET’.<br />

• PROMPT stringa_di_invito<br />

Il comando interno ‘PROMPT’ rappresenta un modo alternativo per impostare la variabile di<br />

ambiente con lo stesso nome. Se si usa il comando senza l’argomento, si ripristina l’invito<br />

predefinito.<br />

• PATH [percorsi_degli_eseguibili]<br />

Il comando interno ‘PATH’ rappresenta un modo alternativo per impostare la variabile di<br />

ambiente con lo stesso nome. Se non si indica l’argomento, si ottiene la visualizzazione<br />

dell’elenco dei percorsi attivo.<br />

Esistono altri comandi particolari che si sovrappongono alle istruzioni del file ‘CONFIG.SYS’.<br />

• BREAK [ON|OFF]<br />

Abilita o disabilita la funzionalità abbinata alla combinazione di tasti [ Ctrl+c ]. Utilizzando<br />

il comando senza argomento, si ottiene la visualizzazione dello stato attuale.


Dos: configurazione 113<br />

360.4 Localizzazione<br />

La localizzazione del Dos si riduce alla configurazione della mappa della tastiera e alla definizione<br />

dell’insieme di caratteri. L’insieme di caratteri dipende dalla scelta della nazionalità, fatta<br />

nel file ‘CONFIG.SYS’, attraverso la direttiva ‘COUNTRY’.<br />

Nelle sezioni seguenti vengono mostrati alcuni comandi utili per le impostazioni che riguardano<br />

la localizzazione.<br />

360.4.1 CHCP<br />

CHCP [n_codifica]<br />

Si tratta di un comando interno dell’interprete dei comandi che interviene nella definizione della<br />

codifica utilizzata. In pratica, se si utilizza senza argomenti, mostra il numero della codifica attiva;<br />

se si indica un numero come argomento, cambia la codifica attiva, purché questa sia una di quelle<br />

ammissibili in base alla nazionalità stabilita con la direttiva ‘COUNTRY’ nel file di configurazione<br />

‘CONFIG.SYS’.<br />

L’esempio seguente fa in modo che sia attivata la codifica corrispondente al numero 850:<br />

C:\>CHCP 850<br />

360.4.2 KEYB<br />

KEYB [sigla_nazionale[,[n_codifica][,file_informazioni_tastiere]]]<br />

‘KEYB’ è un comando esterno che consente di cambiare la configurazione della tastiera secondo<br />

alcuni modelli di nazionalità predefiniti. La sigla nazionale è un codice di due lettere che, assieme<br />

alla nazionalità, dovrebbe indicare anche la lingua utilizzata. La tabella 360.3 elenca queste sigle.<br />

Tabella 360.3. Sigle nazionali-linguistiche per l’impostazione della mappa della<br />

tastiera.<br />

Segue la descrizione di alcuni esempi.<br />

Sigla Corrispondenza<br />

US USA (predefinito)<br />

FR Francia<br />

GR Germania<br />

IT Italia<br />

SP Spagna<br />

UK Gran Bretagna<br />

PO Portogallo<br />

SG Svizzera tedesca<br />

SF Svizzera francese<br />

DK Danimarca<br />

BE Belgio<br />

NL Olanda (Nederland)<br />

NO Norvegia<br />

LA America latina<br />

SV Svezia<br />

SU Finlandia (Suomi)<br />

CF Canada francese


114 volume VIII Argomenti avanzati e accessori<br />

• C:\>KEYB<br />

Mostra la configurazione attuale.<br />

• C:\>KEYB IT<br />

Predispone la mappa dei tasti per la disposizione italiana.<br />

• C:\>KEYB IT,850,C:\DOS\KEYBOARD.SYS<br />

Predispone la mappa dei tasti per la disposizione italiana, specificando l’uso della codifica<br />

850 e del file ‘C:\DOS\KEYBOARD.SYS’ per trovare le impostazioni standard delle tastiere.<br />

360.4.3 GRAFTABL<br />

GRAFTABL [n_codifica]<br />

GRAFTABL /STATUS<br />

‘GRAFTABL’ è un comando esterno che consente di cambiare la codifica per i caratteri visualizzati<br />

sullo schermo. L’opzione ‘/STATUS’ permette di conoscere la situazione attuale, mentre<br />

l’indicazione di un numero di codifica cambia l’impostazione.<br />

L’esempio seguente imposta l’uso della codifica 850:<br />

C:\>GRAFTABL 850<br />

360.5 Orologio<br />

Il Dos consente di accedere all’orologio dell’elaboratore, per leggere la data e l’ora, o per cambiare<br />

tali informazioni. In generale, il Dos non prevede la gestione di un orologio hardware allineato<br />

al tempo universale; pertanto, l’orologio hardware deve corrispondere necessariamente all’ora<br />

locale, lasciando all’utente il problema legato alle variazioni dell’ora estiva.<br />

I comandi per accedere all’orologio sono ‘DATE’ e ‘TIME’:<br />

DATE [data]<br />

TIME [orario]<br />

Se non si indica la data o l’orario, viene mostrato quello attuale e viene richiesto all’utente di<br />

modificarlo o di confermarlo.<br />

Il modo in cui va scritta da data o l’ora, dipende dalla localizzazione. Per conoscere quello giusto,<br />

basta osservare in che modo vengono visualizzate tali informazioni.<br />

Appunti di informatica libera 2003.06.29 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org


Dos: script dell’interprete dei comandi<br />

Capitolo 361<br />

Uno script dell’interprete dei comandi, conosciuto solitamente con il nome di file batch, potrebbe<br />

essere definito come un file di testo normale in cui può essere indicato un elenco di comandi da<br />

eseguire. Tuttavia, questi script consentono l’uso anche di strutture di controllo elementari, per<br />

cui si possono realizzare dei programmi molto semplici, senza troppe pretese.<br />

È interessante osservare che questi script vengono individuati solo attraverso l’estensione che ha<br />

il nome: ‘.BAT’. Inoltre, non esiste la necessità di renderli «eseguibili» come si fa nei sistemi<br />

Unix.<br />

361.1 Parametri, variabili ed espansione<br />

Gli script dell’interprete dei comandi hanno accesso agli argomenti che vengono loro forniti. Si<br />

possono gestire solo nove di questi argomenti alla volta, attraverso i parametri posizionali relativi,<br />

da ‘%1’ a ‘%9’. Come avviene nelle shell Unix, è disponibile il comando interno ‘SHIFT’ per fare<br />

scorrere in avanti gli argomenti nei parametri disponibili.<br />

Bisogna ricordare che in Dos i caratteri jolly non vengono espansi dalla shell, per cui la<br />

limitazione a soli nove parametri posizionali, non dovrebbe costituire un problema.<br />

Nell’ambito di uno script possono essere dichiarate e utilizzate delle variabili di ambiente. È già<br />

stato mostrato in precedenza l’uso del comando ‘SET’ per impostare o eliminare le variabili di<br />

ambiente. Per fare riferimento al contenuto di una variabile, si usa la notazione seguente:<br />

%nome_variabile%<br />

L’esempio seguente rappresenta il caso tipico di estensione di un percorso di ricerca degli<br />

eseguibili, quando si ritiene che la variabile ‘PATH’ sia già stata usata:<br />

SET PATH=%PATH%;C:\PIPPO<br />

361.2 Chiamate di altri script<br />

Tradizionalmente, il Dos ha un baco molto grave, ormai divenuto una caratteristica fondamentale,<br />

riguardante l’avvio di script all’interno di altri script. In generale, quando si chiama un<br />

programma che in realtà corrisponde a uno script, al termine di questo non riprende l’esecuzione<br />

di quello chiamante. Per ottenere la ripresa dell’interpretazione dello script di partenza occorre<br />

usare il comando speciale ‘CALL’.<br />

CALL nome_script [argomenti_dello_script]<br />

361.3 Strutture di controllo<br />

Le strutture di controllo per la programmazione attraverso gli script dell’interprete dei comandi<br />

sono molto limitate. È disponibile una struttura condizionale semplificata e un ciclo di scansione<br />

di file, che vengono descritti brevemente.<br />

115


116 volume VIII Argomenti avanzati e accessori<br />

361.3.1 IF<br />

IF [NOT] ERRORLEVEL valore_di_uscita_ultimo_comando comando<br />

IF [NOT] stringa_1==stringa_2 comando<br />

IF [NOT] EXIST file comando<br />

La struttura condizionale degli script dell’interprete dei comandi Dos è in pratica un comando<br />

interno dello stesso interprete. Come si può vedere dagli schemi sintattici, viene fornita una<br />

condizione che può essere invertita con la parola chiave ‘NOT’ e il risultato è solo l’esecuzione di<br />

un altro comando se la condizione risulta vera.<br />

Nel primo caso, la condizione si riferisce alla verifica del valore di uscita dell’ultimo comando<br />

eseguito. La condizione si verifica se il numero indicato è inferiore o uguale al valore restituito<br />

effettivamente da tale comando; nel secondo, la condizione si verifica se le due stringhe<br />

(non delimitate) sono identiche; nel terzo si verifica la condizione se il file indicato esiste<br />

effettivamente.<br />

Segue la descrizione di alcuni esempi.<br />

• IF ERRORLEVEL 1 GOTO :errore<br />

Se il comando precedente ha restituito un valore maggiore o uguale a uno, salta all’etichetta<br />

‘:errore’.<br />

• IF %1==ciao ECHO L’argomento è corretto<br />

In questo caso, se l’espansione del parametro ‘%1’, corrispondente al primo argomento<br />

ricevuto all’avvio, si traduce nella stringa ‘ciao’, viene emesso un messaggio per mezzo<br />

del comando ‘ECHO’.<br />

• IF %1x==x ECHO L’argomento è mancante<br />

Quello che si vede è il trucco necessario per poter verificare se un parametro contiene<br />

la stringa nulla: si aggiunge una lettera, in questo caso una «x», verificando che la<br />

corrispondenza avvenga solo con la stessa lettera.<br />

• IF NOT EXIST LETTERA.TXT ECHO Scrivi! > LETTERA.TXT<br />

Qui, se non esiste il file ‘LETTERA.TXT’ nella directory corrente, questo file viene creato<br />

attraverso il comando ‘ECHO’ che invia il suo standard output verso un file con lo stesso<br />

nome.<br />

361.3.2 FOR<br />

FOR [%]%x IN (nome...) DO comando [argomenti_del_comando]<br />

Si tratta di un comando interno che svolge un ciclo di scansione di un gruppo di nomi, generalmente<br />

file, attraverso il quale viene creato un parametro variabile speciale, il cui nome si compone<br />

di una sola lettera, a cui viene assegnato a ogni ciclo uno dei nomi contenuti tra parentesi tonde.<br />

A ogni ciclo viene eseguito il comando, che a sua volta può fare uso del parametro. 1<br />

1 Questo parametro assomiglia a una variabile di ambiente, ma non si comporta allo stesso modo. Si tratta di una<br />

particolarità del comando ‘FOR’.


Dos: script dell’interprete dei comandi 117<br />

Quando viene usato all’interno di uno script dell’interprete dei comandi, il parametro viene<br />

indicato con due simboli di percentuale (‘%%x’); al contrario, se il comando viene impartito<br />

dalla riga di comando, se ne usa uno solo.<br />

Segue la descrizione di alcuni esempi.<br />

• FOR %A IN (uno due tre) DO ECHO %A<br />

•<br />

In questo modo, si ottiene la visualizzazione delle parole ‘uno’, ‘due’ e ‘tre’. In pratica, è<br />

come se fosse stato fatto:<br />

ECHO uno<br />

ECHO due<br />

ECHO tre<br />

Volendo fare la stessa cosa dalla riga di comando, è necessario il raddoppio del simbolo ‘%’:<br />

C:\>FOR %%A IN (uno due tre) DO ECHO %%A<br />

• FOR %A IN (*.TMP *.BAD) DO DEL %A<br />

Cancella, uno a uno, tutti i file che terminano con le estensioni ‘.TMP’ e ‘.BAD’.<br />

361.3.3 GOTO<br />

GOTO etichetta<br />

Gli script dell’interprete dei comandi dispongono dell’istruzione di salto incondizionato, non<br />

avendo di meglio. Anche questa istruzione può essere presa come un comando interno<br />

dell’interprete, con la differenza che non c’è modo di utilizzarlo al di fuori di uno script.<br />

Nel corso di uno script del genere, possono apparire delle righe che contengono solo un’etichetta,<br />

nella forma:<br />

:nome_etichetta<br />

La posizione corrispondente a queste etichette può essere raggiunta con il comando ‘GOTO’, che<br />

può fare riferimento solo al nome dell’etichetta, oppure a tutta l’etichetta, includendo anche i due<br />

punti.<br />

Segue la descrizione di alcuni esempi.<br />

•<br />

•<br />

IF EXIST LETTERA.TXT GOTO riprendi<br />

ECHO Il file LETTERA.TXT è assente<br />

:riprendi<br />

In questo esempio, se il file ‘LETTERA.TXT’ esiste, si salta all’etichetta ‘:riprendi’;<br />

altrimenti si esegue il comando ‘ECHO’.<br />

IF EXIST LETTERA.TXT GOTO :riprendi<br />

ECHO Il file LETTERA.TXT è assente<br />

:riprendi<br />

Esattamente come nell’esempio precedente, con la differenza che il comando ‘GOTO’ indica<br />

l’etichetta con i suoi due punti iniziali.


118 volume VIII Argomenti avanzati e accessori<br />

361.3.4 Emulazione di un ciclo iterativo<br />

Dal momento che non è disponibile una struttura di controllo per il ciclo iterativo, questo può<br />

essere ottenuto solo attraverso l’uso del comando ‘GOTO’. Vale la pena di mostrare in che modo<br />

si può ottenere tale risultato.<br />

:etichetta_di_ingresso<br />

IF condizione GOTO :etichetta_di_uscita<br />

...<br />

...<br />

...<br />

GOTO etichetta_di_ingresso<br />

:etichetta_di_uscita<br />

:etichetta_di_ingresso<br />

...<br />

...<br />

...<br />

IF condizione GOTO :etichetta_di_ingresso<br />

:etichetta_di_uscita<br />

I due modelli sintattici mostrano due esempi di cicli iterativi. Nel primo caso si verifica una<br />

condizione, in base alla quale si decide se proseguire o se terminare il ciclo; nel secondo si<br />

esegue una volta il ciclo e quindi si verifica una condizione per decidere se ripeterlo o se uscire.<br />

361.4 Comandi utili negli script<br />

Alcuni comandi sono particolarmente utili all’interno di script dell’interprete dei comandi.<br />

Vengono descritti brevemente nelle sezioni seguenti.<br />

361.4.1 REM<br />

REM commento<br />

I commenti negli script dell’interprete dei comandi si indicano attraverso un comando apposito:<br />

‘REM’. Il funzionamento è evidente: tutto quello che segue il comando, fino alla fine della riga,<br />

viene ignorato.<br />

Alcune edizioni del Dos hanno introdotto anche l’uso del punto e virgola, come simbolo per<br />

indicare l’inizio di un commento. Segue un esempio tipico di utilizzo di questo comando:<br />

REM<br />

REM (c) 2000 Pinco pallino<br />

REM<br />

361.4.2 ECHO<br />

ECHO [ON|OFF]<br />

ECHO stringa<br />

Il comando interno ‘ECHO’ ha un significato duplice: da una parte consente di visualizzare un testo;<br />

dall’altra controlla la visualizzazione dei comandi contenuti in uno script. Infatti, si distingue<br />

il fatto che l’eco dei comandi sia attivo o meno. utilizzando il comando ‘ECHO’ senza argomenti,<br />

si ottiene l’informazione sul suo stato di attivazione. Di solito si disattiva l’eco dei comandi negli<br />

script.


Dos: script dell’interprete dei comandi 119<br />

Per disattivare l’eco di un comando particolare, senza disattivare l’eco in generale, basta<br />

inserire inizialmente il simbolo ‘@’.<br />

Segue la descrizione di alcuni esempi.<br />

• @ECHO OFF<br />

Disattiva l’eco dei comandi, facendo in modo che anche questo comando non venga<br />

visualizzato (si usa per questo il simbolo ‘@’).<br />

• ECHO Premi un tasto per continuare<br />

Mostra un messaggio per spiegare come comportarsi.<br />

361.4.3 PAUSE<br />

PAUSE<br />

Il comando interno ‘PAUSE’ sospende l’esecuzione di uno script in attesa della pressione di un<br />

tasto. Il comando emette attraverso lo standard output un messaggio di avvertimento in tal senso.<br />

Di solito, per evitare di vedere tale messaggio, si ridirige lo standard output in un file nullo.<br />

L’esempio seguente, prima mostra un messaggio in cui si avverte che per proseguire occorre<br />

premere un tasto, quindi si usa il comando ‘PAUSE’ che sospende l’esecuzione dello script, senza<br />

però mostrare altri messaggi:<br />

ECHO Premere un tasto per proseguire<br />

PAUSE > C:\NULL<br />

361.4.4 CLS<br />

CLS<br />

Il comando interno ‘CLS’ ripulisce lo schermo. Si utilizza senza argomenti.<br />

361.4.5 CHOICE<br />

CHOICE [opzioni] [testo_di_invito]<br />

Il comando ‘CHOICE’ serve a presentare una richiesta per l’inserimento di una lettera, tra un elenco<br />

determinato. La pressione del tasto corrispondente alla lettera scelta, da parte dell’utilizzatore,<br />

provoca la conclusione del funzionamento di ‘CHOICE’ che restituisce un valore corrispondente<br />

alla scelta: zero per la prima lettera, uno per la seconda,...<br />

Si osservi che l’ultimo argomento rappresenta un messaggio che serve all’utente per comprendere<br />

il senso della scelta che sta facendo.


120 volume VIII Argomenti avanzati e accessori<br />

Tabella 361.1. Alcune opzioni.<br />

Opzione Descrizione<br />

Permette di fissare l’elenco di lettere che possono essere usate<br />

/C:lettera[lettera...]<br />

nella risposta. Se non si indica questa opzione, la scelta sarà<br />

solo tra ‘y’ e ‘n’.<br />

Questa opzione fa in modo di escludere la visualizzazione<br />

delle lettere che possono essere scelte. In questo modo si fa<br />

/N<br />

affidamento esclusivamente sul testo indicato come ultimo<br />

argomento.<br />

Distingue tra maiuscole e minuscole per quanto riguarda le<br />

/S<br />

lettere tra cui scegliere.<br />

L’esempio seguente, salta a un punto differente dello script in base alla scelta di una lettera da «a»<br />

a «f». Si osservi che non sarebbe possibile eseguire l’analisi secondo una sequenza differente,<br />

perché ‘IF ERRORLEVEL’ prende in considerazione tutti i valori di uscita maggiori o uguali a<br />

quanto indicato nella condizione.<br />

CHOICE /C:abcdef Inserisci una lettera<br />

IF ERRORLEVEL 5 GOTO :f<br />

IF ERRORLEVEL 4 GOTO :e<br />

IF ERRORLEVEL 3 GOTO :d<br />

IF ERRORLEVEL 2 GOTO :c<br />

IF ERRORLEVEL 1 GOTO :b<br />

IF ERRORLEVEL 0 GOTO :a<br />

...<br />

Appunti di informatica libera 2003.06.29 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org


Dos: gestione della memoria centrale<br />

Capitolo 362<br />

Quando è nato il Dos non si prevedeva l’uso di memoria centrale oltre il singolo mebibyte (1 Mibyte).<br />

In base a questa considerazione veniva articolata l’architettura hardware degli elaboratori<br />

«XT» e poi «AT», dove si prevedeva l’uso di un massimo di 640 Kibyte di memoria centrale,<br />

riservando la parte successiva, fino alla fine di 1 Mibyte, per la memoria video e altri dispositivi<br />

fisici.<br />

In questo senso, il Dos tradizionale può operare con un massimo di 640 Kibyte di memoria<br />

centrale; per sfruttarne di più occorrono degli accorgimenti non facili da applicare.<br />

362.1 Gestione particolare<br />

Per sfruttare la memoria oltre il primo mebibyte, si fa uso normalmente di due programmi, avviati<br />

attraverso ‘CONFIG.SYS’, prima ancora dell’interprete di comandi. Si tratta di ‘HIMEM.SYS’ e di<br />

‘EMM386.EXE’. In generale, le cose si fanno nel modo seguente:<br />

DEVICE=C:\DOS\HIMEM.SYS<br />

DEVICE=C:\DOS\EMM386.EXE<br />

Il primo dei due programmi può essere utilizzato a partire da architetture i286, mentre il secondo<br />

si può inserire solo a partire da architetture i386.<br />

‘HIMEM.SYS’ è in grado di utilizzare solo una piccola parte di memoria aggiuntiva, mentre<br />

‘EMM386.EXE’ permette teoricamente di sfruttare tutto il resto.<br />

In generale, è molto difficile la gestione ottimale della memoria centrale, perché le applicazioni<br />

si comportano in maniera differente. Di solito si possono solo fare dei tentativi.<br />

362.2 Comandi appositi<br />

Per sfruttare la memoria centrale che supera la soglia convenzionale, sono disponibili alcuni comandi<br />

specifici. In generale, si comincia dalla configurazione con il file ‘CONFIG.SYS’: dopo<br />

l’attivazione dei gestori speciali della memoria, è possibile indicare di collocare parte dell’interprete<br />

dei comandi e dello spazio richiesto dai programmi residenti in memoria, oltre il limite<br />

della memoria convenzionale:<br />

DOS=HIGH,UMB<br />

In seguito, sempre nell’ambito del file ‘CONFIG.SYS’, si può richiedere esplicitamente l’avvio di<br />

programmi nella memoria alta attraverso la direttiva ‘DEVICEHIGH’, come si vede nell’esempio<br />

seguente:<br />

DEVICEHIGH=C:\MOUSE\MOUSE.SYS /2<br />

Per quanto riguarda i programmi avviati attraverso l’interprete dei comandi, è disponibile il<br />

comando ‘LH’, ovvero ‘LOADHIGH’:<br />

LH programma [argomenti_del_programma]<br />

LOADHIGH programma [argomenti_del_programma]<br />

Per esempio, si potrebbe tentare di avviare in questo modo il programma di gestione della tastiera:<br />

C:\>LH KEYB IT<br />

121


122 volume VIII Argomenti avanzati e accessori<br />

362.3 Verifica<br />

Il Dos <strong>of</strong>fre un solo programma molto semplice per la verifica dell’utilizzo della memoria: ‘MEM’.<br />

MEM [opzioni]<br />

Se ‘MEM’ viene usato senza opzioni, visualizza brevemente la quantità di memoria utilizzata rispetto<br />

al totale disponibile. È interessante l’opzione ‘/CLASSIFY’, attraverso la quale è possibile<br />

distinguere l’utilizzo della memoria da parte dei programmi residenti; inoltre è interessante<br />

l’opzione ‘/FREE’, con cui si hanno informazioni dettagliate sulla memoria libera.<br />

Le opzioni disponibili del comando ‘MEM’ variano molto da una realizzazione all’altra. In<br />

generale conviene verificare prima di utilizzarlo, per conoscere le possibilità effettive.<br />

Appunti di informatica libera 2003.06.29 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org


FreeDOS<br />

Capitolo 363<br />

FreeDOS è il nome di un progetto per la realizzazione di un sistema operativo libero compatibile<br />

con il Dos. Il Dos, per quanto limitato, ha delle caratteristiche che lo possono rendere ancora<br />

interessante per elaboratori con architettura i86 particolarmente poveri di risorse, come nel caso<br />

dei sistemi cosiddetti embedded.<br />

363.1 Installazione<br />

L’installazione della distribuzione standard di FreeDOS è abbastanza semplice. Si parte da un dischetto<br />

di avvio, con il quale si predispone la partizione e la si inizializza, quindi si prosegue con<br />

il programma di installazione che chiede l’inserimento dei dischetti successivi. La riproduzione<br />

del dischetto di avvio a partire dalla sua immagine avviene come al solito attraverso il programma<br />

‘RAWRITE.EXE’, oppure per mezzo di un sistema Unix nei modi già mostrati per GNU/Linux<br />

e altri sistemi simili.<br />

C:\>RAWRITE FULL.BIN A:<br />

L’esempio mostra l’uso di ‘RAWRITE.EXE’ per ottenere un dischetto dall’immagine<br />

rappresentata dal file ‘FULL.BIN’.<br />

La distribuzione standard di FreeDOS si compone di un file-immagine del dischetto di avvio,<br />

che potrebbe chiamarsi ‘FULL.BIN’, e da una serie di file con estensione ‘.ZIP’ che servono<br />

per ottenere i dischetti successivi. Ognuno di questi file compressi rappresenta il contenuto di un<br />

dischetto, che quindi deve essere prima estratto:<br />

C:\>A:<br />

A:\>UNZIP C:\TMP\BASE1.ZIP<br />

L’esempio mostra in breve il procedimento: ci si sposta nell’unità ‘A:’ e da lì si estrae il file<br />

compresso che probabilmente si trova da qualche parte nel disco fisso.<br />

Questi file compressi rappresentano una raccolta di applicativi e hanno una struttura particolare<br />

che viene descritta nel seguito.<br />

• nome_raccolta.1<br />

L’archivio compresso deve contenere un file che rappresenta il nome della raccolta, con<br />

un’estensione numerica. La raccolta potrebbe essere suddivisa in più archivi ed è per questo<br />

che si usa l’estensione numerica, che indica il numero di sequenza dell’archivio nell’ambito<br />

della raccolta.<br />

Il file contiene l’elenco dei pacchetti contenuti, con l’indicazione dell’opzione di installazione<br />

predefinita o meno. Si osservi l’estratto seguente (la lettera «Y» rappresenta la<br />

conferma all’installazione predefinita):<br />

asgn14x: Y<br />

attr063x: Y<br />

bwb210x: Y<br />

choic20x: Y<br />

• nome_raccolta.END<br />

Si tratta di un file vuoto, che rappresenta la conclusione della raccolta, nel senso che non ci<br />

sono altri dischetti ulteriori.<br />

123


124 volume VIII Argomenti avanzati e accessori<br />

• nome_pacchetto.LSM<br />

Si tratta di un file che descrive un pacchetto applicativo. Quello che segue è l’esempio del<br />

contenuto del file ‘DELTR10X.LSM’:<br />

Begin3<br />

Title: deltree<br />

Version: 1.02b<br />

Entered-date: 27 Jul 1999<br />

Description: Delete a directory and all directories under it<br />

Keywords: freedos delete<br />

Author: raster@highfiber.com<br />

Maintained-by: raster@highfiber.com<br />

Primary-site: http://www.highfiber.com/~raster/freeware.htm<br />

Alternate-site: www.freedos.org<br />

Original-site: http://www.highfiber.com/~raster/freeware.htm<br />

Platforms: dos<br />

Copying-policy: GPL<br />

End<br />

• nome_pacchetto.ZIP<br />

Si tratta dell’archivio compresso che contiene i file dell’applicativo. In base alla struttura<br />

standard di FreeDOS, potrebbe distribuirsi nelle directory ‘BIN\’, ‘DOC\’ e ‘HELP\’.<br />

Dopo aver preparato i dischetti, si può procedere con l’avvio del sistema attraverso il dischetto<br />

di avvio; quindi si passa a predisporre la partizione:<br />

A:\>FDISK<br />

Purtroppo, il kernel di FreeDOS non è in grado di gestire partizioni più grandi di 512 Mibyte,<br />

per cui occorre tenerne conto durante l’uso di ‘FDISK’. Dopo aver preparato la partizione la si<br />

inizializza:<br />

A:\>FORMAT C: /U<br />

Successivamente si trasferisce il sistema, con il comando ‘SYS’:<br />

A:\>SYS C:<br />

Infine si avvia il programma di installazione che provvederà a chiedere la sostituzione dei<br />

dischetti:<br />

A:\>INSTALL<br />

363.2 Impostazione e configurazione<br />

Da quanto è stato descritto sull’installazione di FreeDOS si intende che, pur trattandosi di un<br />

sistema Dos, si cerca di introdurre qualche buona idea proveniente da Unix. In particolare, è<br />

prevista una struttura per la collocazione dei file:<br />

• ‘BIN\’ per contenere i file eseguibili;<br />

• ‘DOC\’ per contenere la documentazione che si articola in altre sottodirectory successive,<br />

come avviene con GNU/Linux<br />

• ‘HELP\’ per contenere i file della guida interna relativa.


FreeDOS 125<br />

Questa struttura potrebbe essere collocata anche a partire da un punto differente della radice<br />

dell’unità, in base alle scelte fatte in fase di installazione. In ogni caso, occorre poi predisporre<br />

coerentemente alcune variabili di ambiente: ‘PAGER’ per indicare il programma da utilizzare per<br />

lo scorrimento dei file delle guide; ‘HELPPATH’ per indicare la directory contenente i file delle<br />

guide; ‘EMACS’ per indicare la directory contenente i file di Emacs.<br />

In condizioni normali, gli applicativi FreeDOS vengono installati a partire dalla directory<br />

‘\FDOS\’, per cui la configurazione si traduce nelle istruzioni seguenti nel file ‘AUTOEXEC.BAT’:<br />

SET PAGER=MORE<br />

SET HELPPATH=C:\FDOS\HELP<br />

SET EMACS=C:\FDOS\EMACS\<br />

In base alla documentazione originale, nel caso della variabile di ambiente ‘EMACS’ deve essere<br />

indicata la barra obliqua inversa finale.<br />

A seconda della distribuzione di FreeDOS, può darsi che il file ‘CONFIG.SYS’ debba essere<br />

sostituito con uno avente un nome differente. Potrebbe trattarsi del file ‘FDCONFIG.SYS’.<br />

363.3 RxDOS<br />

RxDOS è un altro progetto analogo a FreeDOS, scritto in maniera indipendente. È provvisto di<br />

un proprio interprete dei comandi e non ha ancora un suo sistema di installazione. Per provare il<br />

funzionamento di RxDOS ci si può avvalere solo di un dischetto, realizzato nel modo seguente:<br />

1. si inizializza il dischetto in qualche modo, assicurando che alla fine sia disponibile un<br />

file system Dos-FAT; 1<br />

2. si esegue lo script ‘MAKEBOOT.BAT’, il cui scopo è la predisposizione del settore di avvio<br />

nel dischetto;<br />

3. si copiano ordinatamente nel dischetto i file elencati qui sotto.<br />

• ‘RXDOSBIO.SYS’<br />

• ‘RXDOS.SYS’<br />

• ‘RXDOSCMD.EXE’<br />

• ‘RXDVDISK.SYS’<br />

• ‘AUTOEXEC.DEF’<br />

• ‘CONFIG.DEF’<br />

363.4 Riferimenti<br />

• FreeDOS<br />

<br />

Appunti di informatica libera 2003.06.29 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org<br />

1 Il dischetto non deve avere l’etichetta, ovvero non deve avere un nome.


Progetto GNUish<br />

Capitolo 364<br />

Il progetto «GNUish» è una sorta di derivazione povera del progetto GNU, con lo scopo di<br />

rendere disponibile parte del s<strong>of</strong>tware che compone il sistema GNU anche nei sistemi Dos. Il<br />

progetto ha un’importanza molto piccola, ma viene ancora mantenuto. Evidentemente, date le<br />

peculiarità dei sistemi Dos, il s<strong>of</strong>tware che viene adattato non può avere le stesse potenzialità che<br />

ha invece in un sistema Unix.<br />

I siti principali da cui si può ottenere copia del materiale prodotto dal progetto GNUish sono<br />

quelli elencati all’interno dal documento seguente:<br />

• <br />

In questo capitolo viene mostrato il funzionamento di alcuni programmi, nell’ambito del sistema<br />

Dos, per i quali è il caso di spendere qualche parola.<br />

364.1 Programmi di servizio vari<br />

Molti dei programmi di servizio del progetto GNU sono disponibili anche per Dos. Tuttavia, è il<br />

caso di osservare alcune particolarità che possono confondere chi è abituato a usare sistemi Dos.<br />

La prima cosa da notare è il fatto che i percorsi si possono indicare secondo lo stile Unix,<br />

utilizzando barre oblique normali. Per esempio:<br />

C:\>MV C:/PRIMO/SECONDO C:/TERZO<br />

Diversamente, utilizzando lo stesso comando, ma secondo l’indicazione tipica del Dos, la cosa<br />

può funzionare ugualmente, oppure si possono presentare delle segnalazioni di errore. Bisogna<br />

tenere presente la possibilità.<br />

Un’altra cosa da notare è l’uso dei caratteri jolly, che con questi programmi segue la logica<br />

di Unix, dove l’asterisco indica qualunque nome, senza trattare in modo speciale il punto di<br />

separazione dell’estensione:<br />

C:\>CP C:/PRIMO/SECONDO/* C:/TERZO<br />

L’esempio mostra proprio questo fatto: vengono copiati tutti i file contenuti nella directory ‘C:\<br />

PRIMO\SECONDO\’, nella directory ‘C:\TERZO\’.<br />

364.2 Gnuplot<br />

Il funzionamento generale di Gnuplot è descritto nel capitolo 337. Per funzionare, questa edizione<br />

di Gnuplot richiede due file: ‘GNUPLOT.EXE’ e ‘GNUPLOT.GIH’. Il primo dei due è l’eseguibile in<br />

grado di gestire la grafica VGA, mentre il secondo contiene le informazioni della guida interna.<br />

Se si vuole accedere alla guida interna, è necessario che il file ‘GNUPLOT.GIH’ si trovi nella<br />

directory corrente. Forse è sufficiente utilizzare il comando ‘APPEND’ del Dos per risolvere il<br />

problema.<br />

126


Progetto GNUish 127<br />

364.3 Spreadsheet Calculator<br />

Il funzionamento generale di SC (Spreadsheet Calculator) è descritto nel capitolo 336. La versione<br />

per Dos funziona correttamente (è sufficiente disporre dell’eseguibile ‘SC.EXE’), riconoscendo<br />

anche l’uso dei tasti freccia, per cui non si è più costretti a utilizzare le lettere ‘h’, ‘j’, ‘k’ e<br />

‘l’.<br />

364.4 Ispell<br />

Ispell è descritto in generale nel capitolo 273. Questa edizione di Ispell richiede due file:<br />

‘ISPELL.EXE’ e ‘ISPELL.DIC’. Come si intuisce, il primo è l’eseguibile, mentre il secondo<br />

è il file del dizionario. Purtroppo, il file ‘ISPELL.DIC’ non è sostituibile o eliminabile; l’unica<br />

cosa che si può fare è predisporre un dizionario personalizzato che si richiama con l’opzione<br />

‘-p’.<br />

ISPELL [-d dizionario_standard] [-p dizionario_personale] file<br />

Quella che si vede è la sintassi essenziale su cui si può contare nell’edizione di Ispell per Dos. Il<br />

file del dizionario standard, ‘ISPELL.DIC’, può essere collocato nella stessa directory in cui si<br />

trova il file eseguibile; altrimenti si deve usare l’opzione ‘-d’ per indicarlo esplicitamente.<br />

Il dizionario personale è un file di testo normale (Dos), che può anche essere creato inizialmente<br />

dallo stesso Ispell. L’esempio seguente, mostra il caso in cui si voglia analizzare il file<br />

‘LETTERA.TXT’ attraverso il dizionario standard e il dizionario personale ‘VOCAB.TXT’. Se il<br />

file ‘VOCAB.TXT’ non dovesse esistere, verrebbe creato per l’occasione.<br />

C:\LETTERE>ISPELL -p VOCAB.TXT LETTERA.TXT<br />

364.5 Perl<br />

Perl è un linguaggio di programmazione descritto in generale a partire dal capitolo 299. L’edizione<br />

Dos dell’interprete Perl richiede due file: ‘PERL.EXE’ e ‘PERLGLOB.EXE’. È sufficiente che<br />

questi siano disponibili nei percorsi degli eseguibili della variabile di ambiente ‘PATH’.<br />

Bisogna tenere a mente che si tratta di una versione molto vecchia del linguaggio, per cui alcune<br />

novità non saranno disponibili. Inoltre, l’avvio dei programmi può avvenire solo richiamando<br />

direttamente l’interprete:<br />

C:\ESERCIZI>PERL FATT.PL 5<br />

L’esempio mostra l’avvio del programma Perl contenuto nel file ‘FATT.PL’, che riceve un<br />

argomento costituito dal numero cinque.<br />

364.6 Riferimenti<br />

• François Pinard, GNUish MSDOS Project<br />

<br />

Appunti di informatica libera 2003.06.29 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org


The valuable DOS Freeware page<br />

Links to valuable free Dos programs working on low equipped computers.<br />

Chapter 365<br />

This material appeared originally at ‘http://www.geocities.com/SiliconValley/<br />

7737/’, in 1996. Now it is incorporated inside the Italian document ‘‘Appunti<br />

di informatica libera’’, and it might be reached at the URI .<br />

Questo materiale è apparso in origine, nel 1996, presso ‘http://www.geocities.com/<br />

SiliconValley/7737/’. Adesso viene incorporato nel documento «Appunti di<br />

informatica libera» e può essere raggiunto attraverso l’URI . L’intento dell’autore è solo quello di continuare a curare<br />

un vecchio lavoro che potrebbe essere ancora utile, nonostante si tratti di riferimenti a<br />

s<strong>of</strong>tware in parte libero e in parte solo gratuito, oltre che evidentemente obsoleto.<br />

365.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128<br />

365.2 OS and GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129<br />

365.3 Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129<br />

365.4 Network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130<br />

365.5 Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132<br />

365.6 Typesetting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132<br />

365.7 More Dos s<strong>of</strong>tware sources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133<br />

365.8 Search engines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133<br />

365.1 Introduction<br />

The Dos operating system meant much for many people. Today, proprietary Dos-like operating<br />

systems seem to be no more developed. In this situation, the only possible future for Dos is the<br />

‘‘free’’ s<strong>of</strong>tware, and it is not just a matter <strong>of</strong> money anymore.<br />

Unfortunately, ‘‘free’’ is a word with many meanings. Today, this is still the biggest obstacle to<br />

the future <strong>of</strong> the Dos world. There is so much s<strong>of</strong>tware for Dos, with so many different license<br />

agreements. The typical Dos user doesn’t mind to it. But this problem prevents the realization <strong>of</strong><br />

big serious projects based on it.<br />

Today, the Dos world needs philosophy, and the GNU idea is still the right one ().<br />

The author <strong>of</strong> this space would like to list here only ‘‘free s<strong>of</strong>tware’’ in the sense stated by the<br />

Free S<strong>of</strong>tware Foundation, but it is impossible, as there isn’t enough good real free s<strong>of</strong>tware for<br />

Dos.<br />

The listed s<strong>of</strong>tware is meant to work on i286 and below.<br />

It is attempted to give some kind <strong>of</strong> classification about the legal condition <strong>of</strong> the s<strong>of</strong>tware presented<br />

here. The definition used might be outdated, or there might be other wrong assumption.<br />

128


The valuable DOS Freeware page 129<br />

In particular, the definition ‘‘public domain’’ means here, in most cases, that there is the source,<br />

but there is no clear license statement.<br />

Beside the URI links <strong>of</strong> some FTP services there is an additional ‘‘search link’’ that queries a<br />

FTP search engine for the same file. These additional links should be used when there are troubles<br />

with the main links.<br />

Anyone can link this document anywhere, so, there is no need to ask for it. Anyway, it is better to<br />

link to this document using at the file name .<br />

In the future, many links may disappear on this page, because <strong>of</strong> more selective choices<br />

concerning s<strong>of</strong>tware license.<br />

365.2 OS and GUI<br />

• FreeDOS 1 <br />

• FreeGEM 2 <br />

365.3 Utility<br />

archive, backup<br />

• Gzip 3 - ‘.GZ’ archive compressor and extractor. <br />

• TAR 4 - portable TAR - DOS/UNIX backup, compressor, with hardware<br />

support. <br />

• Untgz 5 - ‘.TGZ’, ‘.TAR’, ‘.GZ’, ‘.ZIP’ file extractor. <br />

• Info-ZIP 6 - ‘.ZIP’ compatible compression and extraction utility. <br />

<br />

• Restaur 7 - Replacement for Dos Restore, <br />

communication<br />

• DosFax 8 - Send a fax using Dos command line <br />

• Bgfax 9 <br />

• Rifs 10 - Disk sharing over a serial line, <br />

<br />

1<br />

FreeDOS GNU GPL<br />

2<br />

FreeGEM GNU GPL<br />

3<br />

Gzip GNU GPL<br />

4<br />

TAR (Dos) public domain<br />

5<br />

Untgz GNU GPL<br />

6<br />

Info-ZIP free s<strong>of</strong>tware with special license<br />

7<br />

Restaur cannot be sold for pr<strong>of</strong>it<br />

8<br />

DosFax public domain<br />

9<br />

Bgfax promised to become free s<strong>of</strong>tware<br />

10<br />

Rifs cannot be sold for pr<strong>of</strong>it


130 volume VIII Argomenti avanzati e accessori<br />

directory, file<br />

disk<br />

help<br />

shell<br />

system<br />

text<br />

See also:<br />

• WCD 11 - Powerful chdir for Dos and Unix <br />

• Fips 12 - Non-destructive splitting <strong>of</strong> hard disk partitions <br />

• Part 13 - MBR partition manager <br />

• NG_clone 14 - Norton Guides clone <br />

<br />

• DC 15 - The Dos Controller - A Norton Commander clone <br />

• Cmos 16 - Save/Restore extended C/MOS <br />

• KGB 17 - Utility to monitor some Dos functions and reporting into a<br />

log file <br />

• Vim 18 - VI improved, a small text editor that can handle very big files with low<br />

RAM <br />

• Richard L. Green, Free s<strong>of</strong>tware for Dos<br />

<br />

365.4 Network<br />

packet driver<br />

11<br />

WCD GNU GPL<br />

12<br />

Fips GNU GPL<br />

13<br />

Part public domain<br />

14<br />

NG_clone public domain<br />

15<br />

DC public domain (no license at all, and no sources)<br />

16<br />

Cmos public domain<br />

17<br />

KGB public domain<br />

18<br />

Vim free s<strong>of</strong>tware with special license


The valuable DOS Freeware page 131<br />

TCP/IP<br />

See also:<br />

• PC/TCP Packet Driver Collection 19 <br />

• WATTCP 20 - TCP/IP library routines <br />

• DOS PPPD 21 - Dos port <strong>of</strong> Linux PPP packet driver <br />

• Comring 22 - packet driver emulating ethernet over serial link(s) <br />

• WATTCP apps 23 - some common client application using WATTCP library <br />

• MiniTelnet 24 - TELNET client <br />

• Bobcat 25 - Text based web browser (derived<br />

from DosLynx, )<br />

• PCroute 26 - IP routing program for IBM PC <br />

• PPRD 27 - Turn a dedicated PC (XT/AT) into a LPD server <br />

<br />

• NCSA Telnet 28 - Telnet, Ftp,... NCSA <br />

<br />

• NOS (KA9Q) 29 - A complete mini TCP/IP system <br />

To use NOS you need documentation, for example the package <br />

• SSHDOS 30 - SSH client for Dos <br />

• Talk 31 - Talk client for Dos <br />

• ABC-nslookup 32 - DNS query clients for Dos <br />

• Marc S. Ressl, Dos Internet Pages<br />

<br />

• Smash-Co Communications, TCP/IP for MS-DOS<br />

<br />

19<br />

Crynwr packet driver collection GNU GPL<br />

20<br />

WATTCP free <strong>of</strong> charge library<br />

21<br />

DOS PPPD mixed licenses<br />

22<br />

Comring GNU GPL<br />

23<br />

WATTCP apps cannot be sold<br />

24<br />

MiniTelnet free s<strong>of</strong>tware with a special license<br />

25<br />

Bobcat GNU GPL<br />

26<br />

PCroute cannot distribute modifications<br />

27<br />

PPRD s<strong>of</strong>tware non libero: licenza Artistic<br />

28<br />

NCSA Telnet public domain<br />

29<br />

NOS public domain<br />

30<br />

SSHDOS GNU GPL<br />

31<br />

Talk GNU GPL<br />

32<br />

ABC-nslookup UCB BSD


132 volume VIII Argomenti avanzati e accessori<br />

• The U-M S<strong>of</strong>tware Archive<br />

<br />

<br />

365.5 Compilers<br />

assembler<br />

batch<br />

C/C++<br />

Perl<br />

Rexx<br />

xBase<br />

See also:<br />

See the FreeDOS project () for assembler compilers.<br />

• BAT2EXE 33 - Compile batch files for speed <br />

See the FreeDOS project () for C and C++ compilers.<br />

Perl 34 - Practical Extraction Report Language <br />

• BREXX 35 - Rexx interpreter for Dos/Unix <br />

• nanoBase 36 - Mini, but nearly complete xBase <br />

• David Muir Sham<strong>of</strong>f, Catalog <strong>of</strong> free compilers and interpreters<br />

<br />

365.6 Typesetting<br />

• Nro 37 - A Nr<strong>of</strong>f implementation for Dos <br />

<br />

• Ghostscript 38 - ‘‘GNU’’ original edition - PostScript previewing, conversion, and printing<br />

<br />

• emTeX 39 - TeX-LaTeX distribution for Dos <br />

33 BAT2EXE public domain<br />

34 Perl GNU GPL or Artistic<br />

35 BREXX public domain<br />

36 nanoBase GNU GPL<br />

37 Nro public domain<br />

38 Ghostscript GNU GPL<br />

39 emTeX LPPL but some files have different conditions


The valuable DOS Freeware page 133<br />

365.7 More Dos s<strong>of</strong>tware sources<br />

• <br />

• <br />

365.8 Search engines<br />

• <br />

• <br />

Appunti di informatica libera 2003.06.29 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org


Clean the Clipper 5.2<br />

Chapter 366<br />

A different way to program using Clipper 5.2 without commands, that is, without the file<br />

‘STD.CH’.<br />

This material appeared originally at ‘http://www.geocities.com/SiliconValley/<br />

7737/clipper52clean.html’, in 1996. Now it is incorporated inside the Italian document<br />

‘‘Appunti di informatica libera’’, and might be reached at the URI .<br />

Questo materiale è apparso in origine, nel 1996, presso ‘http://www.geocities.com/<br />

SiliconValley/7737/clipper52clean.html’. Adesso viene incorporato nel documento<br />

«Appunti di informatica libera» e può essere raggiunto attraverso l’URI . L’intento dell’autore è solo quello di conservare un<br />

vecchio lavoro che potrebbe essere ancora utile, nonostante si tratti di considerazioni su un<br />

compilatore proprietario, ormai obsoleto.<br />

366.1 Step 1: try to compile with the /P parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135<br />

366.2 Step 2: understand well the use <strong>of</strong> code blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .136<br />

366.3 Step 3: understand the object programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137<br />

366.3.1 Classes and methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .137<br />

366.3.2 Class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137<br />

366.3.3 Object creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .137<br />

366.3.4 Instantiating an object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138<br />

366.3.5 The ‘‘send’’ symbol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138<br />

366.3.6 More about objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138<br />

366.4 Step 4: understand the get object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138<br />

366.5 Step 5: trying to stop using commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140<br />

366.5.1 ?/?? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141<br />

366.5.2 @...BOX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141<br />

366.5.3 @...GET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .141<br />

366.5.4 @...SAY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141<br />

366.5.5 @...TO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141<br />

366.5.6 APPEND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142<br />

366.5.7 APPEND FROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142<br />

366.5.8 CLEAR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142<br />

366.5.9 CLOSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142<br />

366.5.10 COMMIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142<br />

366.5.11 CONTINUE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143<br />

366.5.12 COPY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143<br />

366.5.13 COUNT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .143<br />

366.5.14 CREATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144<br />

134


Clean the Clipper 5.2 135<br />

366.5.15 DEFAULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .144<br />

366.5.16 DELETE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144<br />

366.5.17 EJECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144<br />

366.5.18 ERASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144<br />

366.5.19 FIND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144<br />

366.5.20 GO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144<br />

366.5.21 INDEX ON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144<br />

366.5.22 JOIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145<br />

366.5.23 KEYBOARD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145<br />

366.5.24 LABEL FORM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145<br />

366.5.25 LIST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .145<br />

366.5.26 LOCATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145<br />

366.5.27 PACK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .146<br />

366.5.28 QUIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146<br />

366.5.29 READ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146<br />

366.5.30 RECALL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .146<br />

366.5.31 REINDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146<br />

366.5.32 RELEASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146<br />

366.5.33 RENAME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147<br />

366.5.34 REPLACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147<br />

366.5.35 REPORT FORM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147<br />

366.5.36 RESTORE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147<br />

366.5.37 RESTORE FROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147<br />

366.5.38 RUN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147<br />

366.5.39 SAVE SCREEN TO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148<br />

366.5.40 SAVE TO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148<br />

366.5.41 SEEK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148<br />

366.5.42 SELECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148<br />

366.5.43 SET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148<br />

366.5.44 SKIP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152<br />

366.5.45 SORT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152<br />

366.5.46 STORE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152<br />

366.5.47 SUM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152<br />

366.5.48 TOTAL ON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152<br />

366.5.49 UNLOCK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152<br />

366.5.50 UPDATE FROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152<br />

366.5.51 USE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152<br />

366.5.52 ZAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153<br />

366.6 Step 6: free yourself from STD.CH - /U . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153<br />

366.7 Step 7: take control over all include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153


136 volume VIII Argomenti avanzati e accessori<br />

Clipper 5.2, as the xBase tradition imposes, is not an ordered, clear, simple programming language.<br />

The question is: which is the right way to write a Clipper program? If the intention is not<br />

to make a xBase program, but a Clipper program, maybe it can be decided that it is better to use<br />

Clipper without commands.<br />

366.1 Step 1: try to compile with the /P parameter<br />

Supposing to compile the file ‘TEST.PRG’ this way:<br />

C:\>CLIPPER TEST.PRG /P<br />

It generates a preprocessed output file (‘test.PPO’), that is a source file without comments,<br />

where commands are translated into real Clipper instructions. That is, all the ‘#COMMAND’ substitution<br />

are executed and the translation is sent to the ‘.PPO’ file. It may be difficult to read this<br />

file the first time.<br />

366.2 Step 2: understand well the use <strong>of</strong> code blocks<br />

The code block is a small piece <strong>of</strong> executable program code that can be stored inside a variable,<br />

or can be used as a literal constant. The good <strong>of</strong> it, is that pieces <strong>of</strong> code may be sent to functions.<br />

A code block is something like a little user defined function where only a sequence <strong>of</strong> expressions<br />

(functions and/or assignments) may appear: no loops, no conditional structures.<br />

A code block may receive arguments and return a value after execution, just like a function. The<br />

syntax is the following, where curly brackets are part <strong>of</strong> the code block:<br />

{ | [argument_list] | exp_list }<br />

That is: the argument_list is optional; the exp_list may contain one or more expressions separated<br />

with a comma.<br />

For example, calling the following code block will give the string ‘‘hello world’’ as result.<br />

{ || "hello world" }<br />

The following code block requires a numeric argument and returns the number passed as argument<br />

incremented:<br />

{ | n | n+1 }<br />

The following code block requires two numeric arguments and returns the sum <strong>of</strong> the two square<br />

radix:<br />

{ | nFirst, nSecond | SQRT(nFirst) + SQRT(nSecond) }<br />

But code blocks may contain more expressions and the result <strong>of</strong> the execution <strong>of</strong> the code block<br />

is the result <strong>of</strong> the last expression. The following code block executes in sequence some functions<br />

and gives ‘‘hello world’’ as a result.<br />

{ | a, b | functionOne(a), functionTwo(b), "hello world" }<br />

To start the execution <strong>of</strong> a code block a function is used: ‘EVAL()’. For example, a code block is<br />

assigned to a variable and then executed.<br />

B := { || "hello world" }<br />

EVAL( B ) == "hello world"


Clean the Clipper 5.2 137<br />

Another example with one parameter.<br />

B := { | n | n+1 }<br />

EVAL( B, 1 ) == 2<br />

Another example with two parameters.<br />

B := { | nFirst, nSecond | SQRT(nFirst) + SQRT(nSecond) }<br />

EVAL( B, 2, 4 ) == 20<br />

And so on.<br />

366.3 Step 3: understand the object programming<br />

Clipper 5.2 do not permit to create objects, but it gives some good objects to use: ‘GET’ and<br />

‘TBROWSE’. Before starting to clean programming from commands, it is necessary to understand<br />

how to use well the Clipper objects.<br />

366.3.1 Classes and methods<br />

A class defines the structure <strong>of</strong> a ‘‘black box’’, that is a data container; a method is an action<br />

to make on a piece <strong>of</strong> data contained inside the black box. There is no way to reach the data<br />

contained inside the black box without a method.<br />

The black box can be called object.<br />

The methods may be seen as they where special functions which interact with a specific piece <strong>of</strong><br />

data contained inside the object.<br />

366.3.2 Class definition<br />

Supposing that Clipper permits to define classes (unluckily only predefined classes can be used),<br />

the hypothetical syntax could be:<br />

CLASS ClassName [FROM ParentClass]<br />

VAR Var1 [,Var2[,...VarN]]<br />

METHOD {method_definition_1} [, ...{method_definition_n} ]<br />

ENDCLASS<br />

This way, the class defines a group <strong>of</strong> variables and a group <strong>of</strong> method to use with these variables.<br />

366.3.3 Object creation<br />

The presence <strong>of</strong> classes permits to create objects: the black boxes.<br />

Variable_name := ClassName<br />

This way, a variable contains (is) an object. Please note that inside Clipper, an object may be<br />

generated also from a function, that is, a function can return an object. This way the example can<br />

be:<br />

Variable_name := classfunction( ... )<br />

The next problem is to handle this object.


138 volume VIII Argomenti avanzati e accessori<br />

366.3.4 Instantiating an object<br />

As already stated before, methods are used to handle data contained inside an object. This is said<br />

to be instantiating an object. Clipper permits also to handle directly (apparently without methods)<br />

some variables contained inside objects. These are called ‘‘Exported Instance Variables’’. So, an<br />

object can be instantiated this way:<br />

object:exported_instance_variable := new_value<br />

object:method()<br />

An exported instance variable may be read and/or modified depending on the allowed access to it;<br />

a method, inside Clipper, is something like a function with or without parameters (if parameters<br />

are present, these are usually used to modify data inside the object), that normally returns a value.<br />

366.3.5 The ‘‘send’’ symbol<br />

To instantiate an object or simply to access an exported instance variable, the ‘‘send’’ symbol<br />

(colon) is used.<br />

366.3.6 More about objects<br />

If this is not enough to understand objects inside Clipper, the following document should be read:<br />

Peter M. Freese, o:Clip - An Object Oriented Extension to Clipper 5.01 1991, CyberS<strong>of</strong>t<br />

<br />

366.4 Step 4: understand the get object<br />

What happens with a command like the following:<br />

@ nTop, nLeft GET Var<br />

A get object is created containing all the necessary information for editing the variable Var at<br />

the screen position nTop, nLeft. After that, this get object is added to a get objects array (usually<br />

called ‘GetList’). The get objects array will contain all the get objects used during a ‘READ’.<br />

So, what happens when a ‘READ’ command is encountered. The get objects array (‘GetList’) is<br />

read and the editing <strong>of</strong> all get objects is executed. After that, the get objects array is cleared.<br />

This method hides what Clipper really makes. The suggestion here is to create a ‘GET()’ function<br />

that will substitute the ‘@...GET’ command and to use the ‘READMODAL()’ function to read the get<br />

objects array. Here is an example <strong>of</strong> it:<br />

function GET( aoGet, nRow, nCol, bVar, cGetPicture,<br />

cColorString, bPreValid, bPostValid )<br />

// declare a local get object<br />

local oGet<br />

// create the get object using the function GETENV()<br />

oGet := GETENV( nRow, nCol, bVar, NIL, cGetPicture, cGetColor )<br />

// send to the get object the pre-validation condition code block (WHEN)<br />

oGet:preBlock := bPreValid


Clean the Clipper 5.2 139<br />

// send to the get object the post-validation condition code block (VALID)<br />

oGet:postBlock := bPostValid<br />

// display the get on the screen using the display() method<br />

oGet:display()<br />

// add the get object to the get objects array<br />

AADD( aoGet, oGet )<br />

return NIL<br />

• ‘aoGet’ is the get objects array (so here is explicitly passed). This get objects array is<br />

modified (grown) and there is no need to return it as inside Clipper, arrays are always<br />

passed by reference to functions.<br />

• ‘nRow’ and ‘nCol’ are the screen coordinates where the get field should appear at, as it<br />

works with the ‘@...GET’ command.<br />

• ‘bVar’ is a special code block that permits the editing <strong>of</strong> a variable. If the variable ‘Var’ is<br />

to be edited, the code block is:<br />

{ |x| iif( pcount() > 0, Var := x, Var }<br />

• ‘cGetPicture’ is the picture to use: same as the ‘@...GET’ command.<br />

• ‘cColorString’ is the color string to use: same as the ‘@...GET’ command.<br />

• ‘bPreValid’ is a code block containing the condition that must be valid before the cursor<br />

can reach this get field. It is equivalent to the ‘WHEN’ condition used with the ‘@...GET’<br />

command, but it must be converted into a code block. For example, if the condition is<br />

‘A > B’, the code block is ‘{|| A > B}’<br />

• ‘bPostValid’ is a code block containing the condition that must be valid before the cursor<br />

can leave this get field. It is equivalent to the ‘VALID’ condition used with the ‘@...GET’<br />

command, but it must be converted into a code block. For example, if the condition is<br />

‘A > B’, the code block is ‘{|| A > B}’<br />

If there is a get function like the above one, screen I/O may be performed like the following<br />

example:<br />

function do_some_editing()<br />

// define a variable to use as a get objects array<br />

// and initialise it to the empty array<br />

local aoGet := {}<br />

...<br />

...<br />

// add a new get object to the get objects array<br />

get(;<br />

aoGet,;<br />

10, 10,;<br />

{ |x| iif( pcount() > 0, myVariable := x, myVariable },;<br />

"@s30@",;<br />

"gb+/b, n/w, n, n, w/n",;<br />

{ || .T. },;<br />

{ || .T. };<br />

)


140 volume VIII Argomenti avanzati e accessori<br />

...<br />

// read the get objects array<br />

readmodal( aoGet )<br />

// clear the get objects array<br />

aoGet := {}<br />

...<br />

return ...<br />

If the function ‘GET()’ is not liked, the above I/O may be done as it follows:<br />

function do_some_editing()<br />

// define a variable to use as a get object<br />

local aoGet<br />

// define a variable to use as a get objects array<br />

// and initialise it to the empty array<br />

local aoGet := {}<br />

...<br />

...<br />

// add a new get object to the get objects array<br />

oGet :=;<br />

GETENV(;<br />

10, 10,;<br />

{ |x| iif( pcount() > 0, myVariable := x, myVariable },;<br />

NIL,;<br />

"@s30@",;<br />

"gb+/b, n/w, n, n, w/n",;<br />

)<br />

AADD( aoGet, oGet )<br />

...<br />

// read the get objects array<br />

readmodal( aoGet )<br />

// clear the get objects array<br />

aoGet := {}<br />

...<br />

return ...<br />

366.5 Step 5: trying to stop using commands<br />

To stop using commands, it is important to understand how commands are or may be translated<br />

into functions. Sometimes Clipper uses some undocumented functions: these are functions that<br />

start with a underline.


Clean the Clipper 5.2 141<br />

366.5.1 ?/??<br />

? [exp_list]<br />

qout([exp_list])<br />

?? [exp_list]<br />

qqout([exp_list])<br />

366.5.2 @...BOX<br />

@ nTop, nLeft, nBottom, nRight BOX cnBoxString [COLOR cColorString]<br />

dispbox(nTop, nLeft, nBottom, nRight, [cnBoxString], [cColorString])<br />

366.5.3 @...GET<br />

@ nTop, nLeft GET Var [PICTURE cGetPicture] [COLOR cColorString] [WHEN lPreExpression] ←↪<br />

↩→[VALID lPostExpression]<br />

setpos(nTop, nLeft)<br />

aadd( GetList, _GET_( Var, "Var", cGetPicture, [{|| lPostExpression}],←↪<br />

↩→[{|| lPreExpression}] ):display() ) atail(GetList):colorDisp(cColorString)<br />

This is the command substitution made automatically, but it shouldn’t be used to make clean<br />

programs. The step 4 (366.1) suggests to create a get function.<br />

366.5.4 @...SAY<br />

@ nTop, nLeft SAY exp [COLOR cColorString]<br />

devpos(nTop, nLeft)<br />

devout(exp [, cColorString])<br />

@ nTop, nLeft SAY exp PICTURE cSayPicture [COLOR cColorString]<br />

devpos(nTop, nLeft)<br />

devoutpic(exp, cSayPicture, [cColorString])<br />

366.5.5 @...TO<br />

@ nTop, nLeft TO nBottom, nRight DOUBLE [COLOR cColorString]<br />

dispbox(nTop, nLeft, nBottom, nRight, 2 [,cColorString])<br />

@ nTop, nLeft TO nBottom, nRight [COLOR cColorString]<br />

dispbox(nTop, nLeft, nBottom, nRight, 1 [,cColorString])<br />

@ nTop, nLeft CLEAR [TO nBottom, nRight]<br />

scroll([nTop], [nLeft], [nBottom, nRight])<br />

setpos(nRow, nCol)


142 volume VIII Argomenti avanzati e accessori<br />

366.5.6 APPEND<br />

APPEND BLANK<br />

dbappend()<br />

366.5.7 APPEND FROM<br />

APPEND FROM xcFile [FIELDS idField_list] [scope] [WHILE lCondition]←↪<br />

↩→[FOR lCondition] [VIA xcDriver]<br />

__dbApp( cFileName, [acFields], [bForCondition], [bWhileCondition], [nNextRecords],←↪<br />

↩→[nRecord], [lRest], [cDriver] )<br />

APPEND FROM xcFile [FIELDS idField_list] [scope] [WHILE lCondition] [FOR lCondition]←↪<br />

↩→DELIMITED xcDelimiter<br />

__dbDelim( .f., cFileName, [cDelimiter], [acFields], [bForCondition], [bWhileCondition]<br />

,←↪<br />

↩→[nNextRecords], [nRecord], [lRest] )<br />

APPEND FROM xcFile [FIELDS idField_list] [scope] [WHILE lCondition]←↪<br />

↩→[FOR lCondition] SDF<br />

__dbSDF( .f., cFileName, [acFields], [bForCondition], [bWhileCondition], [nNextRecords]<br />

,←↪<br />

↩→[nRecord], [lRest] )<br />

366.5.8 CLEAR<br />

CLEAR<br />

Scroll()<br />

SetPos(0,0)<br />

ReadKill(.T.)<br />

GetList := {}<br />

CLEAR GETS<br />

ReadKill(.T.)<br />

GetList := {}<br />

CLEAR SCREEN | CLS<br />

Scroll()<br />

SetPos(0,0)<br />

366.5.9 CLOSE<br />

CLOSE<br />

dbCloseArea()<br />

CLOSE idAlias<br />

idAlias->( dbCloseArea() )<br />

CLOSE ALTERNATE<br />

Set(19, "")<br />

CLOSE DATABASES<br />

dbCloseAll()<br />

CLOSE INDEXES<br />

dbClear<strong>Index</strong>()


Clean the Clipper 5.2 143<br />

366.5.10 COMMIT<br />

COMMIT<br />

dbCommitAll()<br />

366.5.11 CONTINUE<br />

CONTINUE<br />

__dbContinue()<br />

366.5.12 COPY<br />

COPY FILE xcSourceFile TO xcTargetFile|xcDevice<br />

__CopyFile( cSourceFile, cTargetFile|cDevice )<br />

COPY STRUCTURE [FIELDS idField_list] TO xcDatabase<br />

__dbCopyStruct( cDatabase, [acFields] )<br />

COPY STRUCTURE EXTENDED TO xcExtendedDatabase<br />

__dbCopyXStruct( cExtendedDatabase )<br />

COPY TO xcFile [FIELDS idField_list] [scope] [WHILE lCondition]←↪<br />

↩→[FOR lCondition] [VIA xcDriver]<br />

__dbCopy( cFileName, [acFields], [bForCondition], [bWhileCondition], [nNextRecords],←↪<br />

↩→[nRecord], [lRest], [cDriver] )<br />

COPY TO xcFile [FIELDS idField_list] [scope] [WHILE lCondition] [FOR lCondition]←↪<br />

↩→DELIMITED xcDelimiter<br />

__dbDelim( .t., cFileName, [cDelimiter], [acFields], [bForCondition], [bWhileCondition]<br />

,←↪<br />

↩→[nNextRecords], [nRecord], [lRest] )<br />

COPY TO xcFile [FIELDS idField_list] [scope] [WHILE lCondition]←↪<br />

↩→[FOR lCondition] SDF<br />

__dbSDF( .t., cFileName, [acFields], [bForCondition], [bWhileCondition], [nNextRecords]<br />

,←↪<br />

↩→[nRecord], [lRest] )<br />

366.5.13 COUNT<br />

COUNT TO idVar [FOR lForCondition] [WHILE lWhileCondition] [NEXT nNextRecords]←↪<br />

↩→[RECORD nRecord] [REST] [ALL]<br />

dbeval( {||idVar:=idVar+1}, {||lForCondition}, {||lWhileCondition},←↪<br />

↩→nNextRecords, nRecord, lRest )


144 volume VIII Argomenti avanzati e accessori<br />

366.5.14 CREATE<br />

CREATE xcDatabase FROM xcExtendedDatabase [NEW] [ALIAS cAlias] [VIA cDriver]<br />

__dbCreate( cDatabase, cExtendedDatabase, [cDriver], [lNew], [cAlias] )<br />

366.5.15 DEFAULT<br />

DEFAULT xVar TO xDefaultValue<br />

if xVar == NIL<br />

xVar := xDefaultValue<br />

end<br />

366.5.16 DELETE<br />

DELETE<br />

dbDelete()<br />

DELETE [FOR lForCondition] [WHILE lWhileCondition] [NEXT nNextRecords]←↪<br />

↩→[RECORD nRecord] [REST] [ALL]<br />

dbeval( {||dbDelete()}, {||lForCondition}, {||lWhileCondition},←↪<br />

↩→nNextRecords, nRecord, lRest )<br />

DELETE FILE xcFile<br />

ferase( cFile )<br />

366.5.17 EJECT<br />

EJECT<br />

qqout( chr(13) )<br />

366.5.18 ERASE<br />

ERASE xcFile<br />

ferase( cFile )<br />

366.5.19 FIND<br />

FIND xcSearchString<br />

dbSeek( cSearchString )<br />

366.5.20 GO<br />

GO[TO] nRecord<br />

dbgoto(nRecord)<br />

GO[TO] BOTTOM<br />

dbGoBottom()<br />

GO[TO] TOP<br />

dbgotop()


Clean the Clipper 5.2 145<br />

366.5.21 INDEX ON<br />

INDEX ON expKey TO xc<strong>Index</strong>Name [UNIQUE] [FOR lForCondition]←↪<br />

↩→[WHILE lWhileCondition] [[EVAL lEvalCondition] [EVERY nRecords]] [ASCENDING|<br />

DESCENDING]<br />

ordCondSet( [cForCondition], [bForCondition], , [bWhileCondition],←↪<br />

↩→[bEvalCondition], [nRecords], RECNO(), , , , lDescending )<br />

ordCreate( c<strong>Index</strong>Name, , cExpKey, bExpKey, lUnique )<br />

366.5.22 JOIN<br />

JOIN WITH xcAlias TO xcDatabase [FOR lCondition] [FIELDS idField_list]<br />

__dbJoin( cAlias, cDatabase, [acFields], [bForCondition] )<br />

366.5.23 KEYBOARD<br />

KEYBOARD cString<br />

__Keyboard( [cString] ) --> NIL<br />

366.5.24 LABEL FORM<br />

LABEL FORM xcLabel [TO PRINTER] [TO FILE xcFile] [NOCONSOLE] [scope]←↪<br />

↩→[WHILE lCondition] [FOR lCondition] [SAMPLE]<br />

__LabelForm( cLabel, [lToPrinter], [cFile], [lNoConsole],←↪<br />

↩→[bForCondition], [bWhileCondition], [nNextRecords], [nRecord],←↪<br />

↩→[lRest], [lSample] )<br />

366.5.25 LIST<br />

LIST exp_list [TO PRINTER] [TO FILE xcFile] [scope]←↪<br />

↩→[WHILE lCondition] [FOR lCondition] [OFF]<br />

__dbList( [lToDisplay], abListColumns, [lAll], [bForCondition], [bWhileCondition],←↪<br />

↩→[nNextRecords], [nRecord], [lRest], [lToPrinter], [cFileName] )<br />

366.5.26 LOCATE<br />

LOCATE [scope] FOR lCondition [WHILE lCondition]<br />

__dbLocate( [bForCondition], [bWhileCondition], [nNextRecords], [nRecord], [lRest] )


146 volume VIII Argomenti avanzati e accessori<br />

366.5.27 PACK<br />

PACK<br />

__dbPack()<br />

366.5.28 QUIT<br />

QUIT<br />

__Quit()<br />

366.5.29 READ<br />

READ<br />

ReadModal(GetList)<br />

GetList := {}<br />

READ SAVE<br />

ReadModal(GetList)<br />

366.5.30 RECALL<br />

RECALL<br />

dbRecall()<br />

RECALL [FOR lForCondition] [WHILE lWhileCondition] [NEXT nNextRecords]←↪<br />

↩→[RECORD nRecord] [REST] [ALL]<br />

dbeval( {||dbRecall()}, {||lForCondition}, {||lWhileCondition},←↪<br />

↩→nNextRecords, nRecord, lRest )<br />

366.5.31 REINDEX<br />

REINDEX [EVAL lEvalCondition] [EVERY nRecords]<br />

ordCondSet(, , , , [bEvalCondition], [nRecords], , , , , , , )<br />

ordListRebuild()<br />

366.5.32 RELEASE<br />

RELEASE idMemvar<br />

__MXRelease( "idMemvar" )<br />

RELEASE ALL<br />

__MRelease("*", .t.)<br />

RELEASE ALL LIKE skeleton<br />

__MRelease( "skeleton", .t. )<br />

RELEASE ALL EXCEPT skeleton<br />

__MRelease( "skeleton", .F. )


Clean the Clipper 5.2 147<br />

366.5.33 RENAME<br />

RENAME xcOldFile TO xcNewFile<br />

frename( cOldFile, cNewFile )<br />

366.5.34 REPLACE<br />

REPLACE idField1 WITH exp1 [, idField2 WITH exp2...]←↪<br />

↩→[FOR lForCondition] [WHILE lWhileCondition] [NEXT nNextRecords]←↪<br />

↩→[RECORD nRecord] [REST] [ALL]<br />

dbeval( {|| idField1 := exp1 [, idField2 := exp2...]},←↪<br />

↩→{||lForCondition}, {||lWhileCondition}, nNextRecords,←↪<br />

↩→nRecord, lRest )<br />

REPLACE idField1 WITH exp1<br />

idField1 := exp1<br />

366.5.35 REPORT FORM<br />

REPORT FORM xcReport [TO PRINTER] [TO FILE xcFile] [NOCONSOLE] [scope]←↪<br />

↩→[WHILE lCondition] [FOR lCondition] [PLAIN | HEADING cHeading] [NOEJECT] ←↪<br />

↩→[SUMMARY]<br />

__ReportForm( cForm, [lToPrinter], [cToFile], [lNoConsole], [bForCondition], ←↪<br />

↩→[bWhileCondition], [nNext], [nRecord], [lRest], [lPlain], [cbHeading], ←↪<br />

↩→[lBeforeEject], [lSummary] )<br />

366.5.36 RESTORE<br />

RESTORE SCREEN FROM cScreen<br />

restscreen( 0, 0, Maxrow(), Maxcol(), cScreen )<br />

366.5.37 RESTORE FROM<br />

RESTORE FROM xcMemFile [ADDITIVE]<br />

__MRestore( cMemFileName, [lAdditive] )<br />

366.5.38 RUN<br />

RUN xcCommandLine<br />

__Run( cCommand )


148 volume VIII Argomenti avanzati e accessori<br />

366.5.39 SAVE SCREEN TO<br />

SAVE SCREEN TO cScreen<br />

cScreen := savescreen( 0, 0, maxrow(), maxcol() )<br />

366.5.40 SAVE TO<br />

SAVE TO xcMemFile [ALL [LIKE|EXCEPT skeleton]]<br />

_MSave( cMemFileName, [cSkeleton], [lLike] )<br />

366.5.41 SEEK<br />

SEEK expSearch [SOFTSEEK]<br />

dbSeek( expSearch [, lS<strong>of</strong>tSeek] )<br />

366.5.42 SELECT<br />

SELECT xnWorkArea | idAlias<br />

dbSelectArea( nWorkArea | cIdAlias )<br />

366.5.43 SET<br />

Most <strong>of</strong> the ‘SET...’ commands are translated into the ‘SET()’ function that distinguishes different<br />

modes depending on a number. As this number is difficult to handle during programming<br />

(essentially because it is difficult to remember the meaning <strong>of</strong> it), Clipper <strong>of</strong>fers the ‘SET.CH’<br />

include file that helps with manifest constants.<br />

#define _SET_EXACT 1<br />

#define _SET_FIXED 2<br />

#define _SET_DECIMALS 3<br />

#define _SET_DATEFORMAT 4<br />

#define _SET_EPOCH 5<br />

#define _SET_PATH 6<br />

#define _SET_DEFAULT 7<br />

#define _SET_EXCLUSIVE 8<br />

#define _SET_SOFTSEEK 9<br />

#define _SET_UNIQUE 10<br />

#define _SET_DELETED 11<br />

#define _SET_CANCEL 12<br />

#define _SET_DEBUG 13<br />

#define _SET_TYPEAHEAD 14<br />

#define _SET_COLOR 15<br />

#define _SET_CURSOR 16<br />

#define _SET_CONSOLE 17<br />

#define _SET_ALTERNATE 18<br />

#define _SET_ALTFILE 19<br />

#define _SET_DEVICE 20<br />

#define _SET_EXTRA 21<br />

#define _SET_EXTRAFILE 22<br />

#define _SET_PRINTER 23


Clean the Clipper 5.2 149<br />

#define _SET_PRINTFILE 24<br />

#define _SET_MARGIN 25<br />

#define _SET_BELL 26<br />

#define _SET_CONFIRM 27<br />

#define _SET_ESCAPE 28<br />

#define _SET_INSERT 29<br />

#define _SET_EXIT 30<br />

#define _SET_INTENSITY 31<br />

#define _SET_SCOREBOARD 32<br />

#define _SET_DELIMITERS 33<br />

#define _SET_DELIMCHARS 34<br />

#define _SET_WRAP 35<br />

#define _SET_MESSAGE 36<br />

#define _SET_MCENTER 37<br />

#define _SET_SCROLLBREAK 38<br />

SET ALTERNATE TO xcFile [ADDITIVE]<br />

Set( _SET_ALTFILE, cFile, lAdditive )<br />

SET ALTERNATE ON | OFF | xlToggle<br />

Set( _SET_ALTERNATE, "ON" | "OFF" | lToggle )<br />

SET BELL ON | OFF | xlToggle<br />

Set( _SET_BELL, "ON" | "OFF" | lToggle )<br />

SET COLOR | COLOUR TO (cColorString)<br />

SetColor( cColorString )<br />

SET CONFIRM ON | OFF | xlToggle<br />

Set( _SET_CONFIRM, "ON" | "OFF" | lToggle )<br />

SET CONSOLE ON | OFF | xlToggle<br />

Set( _SET_CONSOLE, "ON" | "OFF" | lToggle )<br />

SET CURSOR ON | OFF | xlToggle<br />

SetCursor( 1 | 0 | iif( lToggle, 1, 0 ) )<br />

SET DATE FORMAT [TO] cDateFormat<br />

Set( _SET_DATEFORMAT, cDateFormat )<br />

SET DECIMALS TO<br />

Set( _SET_DECIMALS, 0 )<br />

SET DECIMALS TO nDecimals<br />

Set( _SET_DECIMALS, nDecimals )<br />

SET DEFAULT TO<br />

Set( _SET_DEFAULT, "" )<br />

SET DEFAULT TO xcPathspec<br />

Set( _SET_DEFAULT, cPathspec )<br />

SET DELETED ON | OFF | xlToggle<br />

Set( _SET_DELETED, "ON" | "OFF" | lToggle )


150 volume VIII Argomenti avanzati e accessori<br />

SET DELIMITERS ON | OFF | xlToggle<br />

Set( _SET_DELIMITERS, "ON" | "OFF" | lToggle )<br />

SET DELIMITERS TO [DEFAULT]<br />

Set( _SET_DELIMCHARS, "::" )<br />

SET DELIMITERS TO cDelimiters<br />

Set( _SET_DELIMCHARS, cDelimiters )<br />

SET DEVICE TO SCREEN | PRINTER<br />

Set( _SET_DEVICE, "SCREEN" | "PRINTER" )<br />

SET EPOCH TO nYear<br />

Set( _SET_EPOCH, nYear )<br />

SET ESCAPE ON | OFF | xlToggle<br />

Set( _SET_ESCAPE, "ON" | "OFF" | lToggle )<br />

SET EXACT ON | OFF | xlToggle<br />

Set( _SET_EXACT, "ON" | "OFF" | lToggle )<br />

SET EXCLUSIVE ON | OFF | xlToggle<br />

Set( _SET_EXCLUSIVE, "ON" | "OFF" | lToggle )<br />

SET FILTER TO<br />

dbclearfilter()<br />

SET FILTER TO lCondition<br />

dbsetfilter( bCondition, cCondition )<br />

SET FIXED ON | OFF | xlToggle<br />

Set( _SET_FIXED, "ON" | "OFF" | lToggle )<br />

SET FUNCTION nFunctionKey TO cString<br />

__SetFunction( nFunctionKey, cString )<br />

SET INDEX TO [xc<strong>Index</strong> [, xc<strong>Index</strong>1... ] ]<br />

ordListClear()<br />

ordListAdd( c<strong>Index</strong> )<br />

ordListAdd( c<strong>Index</strong>1 )<br />

...<br />

SET INTENSITY ON | OFF | xlToggle<br />

Set( _SET_INTENSITY, "ON" | "OFF" | lToggle )<br />

SET KEY nInkeyCode [TO]<br />

SetKey( nInkeyCode, NIL )<br />

SET KEY nInkeyCode TO [idProcedure]<br />

SetKey( nInkeyCode, { |p, l, v| idProcedure(p, l, v)} )<br />

SET MARGIN TO<br />

Set( _SET_MARGIN, 0 )<br />

SET MARGIN TO [nPageOffset]<br />

Set( _SET_MARGIN, nPageOffset )


Clean the Clipper 5.2 151<br />

SET MESSAGE TO<br />

Set( _SET_MESSAGE, 0 )<br />

Set( _SET_MCENTER, .F. )<br />

SET MESSAGE TO [nRow [CENTER | CENTRE]]<br />

Set( _SET_MESSAGE, nRow )<br />

Set( _SET_MCENTER, lCenter )<br />

SET ORDER TO [n<strong>Index</strong>]<br />

ordSetFocus( n<strong>Index</strong> )<br />

SET PATH TO<br />

Set( _SET_PATH, "" )<br />

SET PATH TO [xcPathspec [, cPathspec1... ] ]<br />

Set( _SET_PATH, cPathspec [, cPathspec1... ] )<br />

SET PRINTER ON | OFF | xlToggle<br />

Set( _SET_PRINTER, "ON" | "OFF" | lToggle )<br />

SET PRINTER TO<br />

Set( _SET_PRINTFILE, "" )<br />

SET PRINTER TO [xcDevice|xcFile [ADDITIVE]]<br />

Set( _SET_PRINTFILE, cDevice|cFile, lAdditive )<br />

SET RELATION TO<br />

dbclearrelation()<br />

SET RELATION TO [expKey1 INTO xcAlias1] [, [TO] expKey2 INTO xcAlias2...]<br />

dbClearRel()<br />

dbSetRelation( cAlias1, {||expKey1}, ["expKey1"] )<br />

dbSetRelation( cAlias2, {||expKey2}, ["expKey1"] )<br />

SET RELATION TO [expKey1 INTO xcAlias1]←↪<br />

↩→[, [TO] expKey2 INTO xcAlias2...] ADDITIVE<br />

dbSetRelation( cAlias1, {||expKey1}, ["expKey1"] )<br />

dbSetRelation( cAlias2, {||expKey2}, ["expKey1"] )<br />

SET SCOREBOARD ON | OFF | xlToggle<br />

Set( _SET_SCOREBOARD, "ON" | "OFF" | lToggle )<br />

SET SOFTSEEK ON | OFF | xlToggle<br />

Set( _SET_SOFTSEEK, "ON" | "OFF" | lToggle )<br />

SET TYPEAHEAD TO nKeyboardSise<br />

Set( _SET_TYPEAHEAD, nKeyboardSise )<br />

SET UNIQUE ON | OFF | xlToggle<br />

Set( _SET_UNIQUE, "ON" | "OFF" | lToggle )<br />

SET WRAP ON | OFF | xlToggle<br />

Set( _SET_WRAP, "ON" | "OFF" | lToggle )


152 volume VIII Argomenti avanzati e accessori<br />

366.5.44 SKIP<br />

SKIP [nRecords] [ALIAS idAlias|nWorkArea]<br />

[idAlias|nWorkArea -> ]( dbSkip([nRecords]) )<br />

366.5.45 SORT<br />

SORT TO xcDatabase ON idField1 [/[A|D][C]] [, idField2 [/[A|D][C]] ...]←↪<br />

↩→[scope] [WHILE lCondition] [FOR lCondition]<br />

__dbSort( cDatabase, [acFields], [bForCondition], [bWhileCondition],←↪<br />

↩→[nNextRecords], [nRecord], [lRest] )<br />

366.5.46 STORE<br />

STORE value TO variable<br />

variable := value<br />

366.5.47 SUM<br />

SUM nExp1 [, nExp2...] TO idVar1 [, idVar2...] [FOR lForCondition]←↪<br />

↩→[WHILE lWhileCondition] [NEXT nNextRecords] [RECORD nRecord] [REST] [ALL]<br />

dbeval( {||idVar1:=idVar1+nExp1 [, idVar2:=idVar2+nExp2...] },←↪<br />

↩→{||lForCondition}, {||lWhileCondition}, nNextRecords, nRecord, lRest )<br />

366.5.48 TOTAL ON<br />

TOTAL ON expKey [FIELDS idField_list] TO xcDatabase [scope]←↪<br />

↩→[WHILE lCondition] [FOR lCondition]<br />

__dbTotal( cDatabase, bKey, [acFields], [bForCondition], [bWhileCondition],←↪<br />

↩→[nNextRecords], [nRecord], [lRest] )<br />

366.5.49 UNLOCK<br />

UNLOCK<br />

dbUnlock()<br />

UNLOCK ALL<br />

dbUnlockAll()<br />

366.5.50 UPDATE FROM<br />

UPDATE FROM xcAlias ON expKey [RANDOM] REPLACE idField1←↪<br />

↩→WITH exp [, idField2 WITH exp ...]<br />

__dbUpdate( cAlias, bKey, [lRandom], [bReplacement] )<br />

Example:


Clean the Clipper 5.2 153<br />

__dbUpdate( "INVOICE", {|| LAST}, .T.,; {|| FIELD->TOTAL1 := ←↪<br />

↩→INVOICE->SUM1,; FIELD->TOTAL2 := INVOICE->SUM2 } )<br />

366.5.51 USE<br />

USE<br />

dbclosearea()<br />

USE [xcDatabase]←↪<br />

↩→[INDEX xc<strong>Index</strong>1 [, xc<strong>Index</strong>2...] [ALIAS xcAlias] [EXCLUSIVE|SHARED] [NEW] ←↪<br />

↩→[READONLY] [VIA cDriver]]<br />

dbUseArea( [lNewArea], [cDriver], cDatabase, [cAlias], [lShared], [lReadOnly] )<br />

[dbSet<strong>Index</strong>( c<strong>Index</strong>1 )]<br />

[dbSet<strong>Index</strong>( c<strong>Index</strong>2 )]<br />

...<br />

366.5.52 ZAP<br />

ZAP<br />

dbZap()<br />

366.6 Step 6: free yourself from STD.CH - /U<br />

Now that no command is used, the standard include file ‘STD.CH’ is no more necessary. Clipper<br />

uses ‘STD.CH’ automatically, unless specified differently. Just compile this way:<br />

C:>CLIPPER TEST.PRG /U<br />

366.7 Step 7: take control over all include files<br />

Clipper comes with so many include files (‘ * .CH’). To avoid confusion, a single ‘STANDARD.CH’<br />

file containing all what is needed for the application may be prepared. At least, it is necessary the<br />

following.<br />

*=================================================================<br />

* DISPBOX()<br />

*=================================================================<br />

* Single-line box<br />

#define BOX_SINGLE;<br />

(;<br />

CHR(218) +;<br />

CHR(196) +;<br />

CHR(191) +;<br />

CHR(179) +;<br />

CHR(217) +;<br />

CHR(196) +;<br />

CHR(192) +;<br />

CHR(179);<br />

)<br />

* Double-line box


154 volume VIII Argomenti avanzati e accessori<br />

#define BOX_DOUBLE;<br />

(;<br />

CHR(201) +;<br />

CHR(205) +;<br />

CHR(187) +;<br />

CHR(186) +;<br />

CHR(188) +;<br />

CHR(205) +;<br />

CHR(200) +;<br />

CHR(186);<br />

)<br />

* Single-line top, double-line sides<br />

#define BOX_SINGLE_DOUBLE;<br />

(;<br />

CHR(214) +;<br />

CHR(196) +;<br />

CHR(183) +;<br />

CHR(186) +;<br />

CHR(189) +;<br />

CHR(196) +;<br />

CHR(211) +;<br />

CHR(186);<br />

)<br />

* Double-line top, single-line sides<br />

#define BOX_DOUBLE_SINGLE;<br />

(;<br />

CHR(213) +;<br />

CHR(205) +;<br />

CHR(184) +;<br />

CHR(179) +;<br />

CHR(190) +;<br />

CHR(205) +;<br />

CHR(212) +;<br />

CHR(179);<br />

)<br />

*=================================================================<br />

* ERRORS<br />

*=================================================================<br />

* Severity levels (e:severity)<br />

#define ERROR_SEVERITY_WHOCARES 0<br />

#define ERROR_SEVERITY_WARNING 1<br />

#define ERROR_SEVERITY_ERROR 2<br />

#define ERROR_SEVERITY_CATASTROPHIC 3<br />

* Generic error codes (e:genCode)<br />

#define ERROR_GENERIC_ARG 1<br />

#define ERROR_GENERIC_BOUND 2<br />

#define ERROR_GENERIC_STROVERFLOW 3<br />

#define ERROR_GENERIC_NUMOVERFLOW 4<br />

#define ERROR_GENERIC_ZERODIV 5<br />

#define ERROR_GENERIC_NUMERR 6<br />

#define ERROR_GENERIC_SYNTAX 7<br />

#define ERROR_GENERIC_COMPLEXITY 8<br />

#define ERROR_GENERIC_MEM 11<br />

#define ERROR_GENERIC_NOFUNC 12<br />

#define ERROR_GENERIC_NOMETHOD 13<br />

#define ERROR_GENERIC_NOVAR 14<br />

#define ERROR_GENERIC_NOALIAS 15


Clean the Clipper 5.2 155<br />

#define ERROR_GENERIC_NOVARMETHOD 16<br />

#define ERROR_GENERIC_BADALIAS 17<br />

#define ERROR_GENERIC_DUPALIAS 18<br />

#define ERROR_GENERIC_CREATE 20<br />

#define ERROR_GENERIC_OPEN 21<br />

#define ERROR_GENERIC_CLOSE 22<br />

#define ERROR_GENERIC_READ 23<br />

#define ERROR_GENERIC_WRITE 24<br />

#define ERROR_GENERIC_PRINT 25<br />

#define ERROR_GENERIC_UNSUPPORTED 30<br />

#define ERROR_GENERIC_LIMIT 31<br />

#define ERROR_GENERIC_CORRUPTION 32<br />

#define ERROR_GENERIC_DATATYPE 33<br />

#define ERROR_GENERIC_DATAWIDTH 34<br />

#define ERROR_GENERIC_NOTABLE 35<br />

#define ERROR_GENERIC_NOORDER 36<br />

#define ERROR_GENERIC_SHARED 37<br />

#define ERROR_GENERIC_UNLOCKED 38<br />

#define ERROR_GENERIC_READONLY 39<br />

#define ERROR_GENERIC_APPENDLOCK 40<br />

#define ERROR_GENERIC_LOCK 41<br />

*=================================================================<br />

* INKEY()<br />

*=================================================================<br />

#define K_UP 5 // Up arrow, Ctrl-E<br />

#define K_DOWN 24 // Down arrow, Ctrl-X<br />

#define K_LEFT 19 // Left arrow, Ctrl-S<br />

#define K_RIGHT 4 // Right arrow, Ctrl-D<br />

#define K_HOME 1 // Home, Ctrl-A<br />

#define K_END 6 // End, Ctrl-F<br />

#define K_PGUP 18 // PgUp, Ctrl-R<br />

#define K_PGDN 3 // PgDn, Ctrl-C<br />

#define K_CTRL_UP 397 // * Ctrl-Up arrow<br />

#define K_CTRL_DOWN 401 // * Ctrl-Down arrow<br />

#define K_CTRL_LEFT 26 // Ctrl-Left arrow, Ctrl-Z<br />

#define K_CTRL_RIGHT 2 // Ctrl-Right arrow, Ctrl-B<br />

#define K_CTRL_HOME 29 // Ctrl-Home, Ctrl-<br />

#define K_CTRL_END 23 // Ctrl-End, Ctrl-W<br />

#define K_CTRL_PGUP 31 // Ctrl-PgUp, Ctrl-Hyphen<br />

#define K_CTRL_PGDN 30 // Ctrl-PgDn, Ctrl-^<br />

#define K_ALT_UP 408 // * Alt-Up arrow<br />

#define K_ALT_DOWN 416 // * Alt-Down arrow<br />

#define K_ALT_LEFT 411 // * Alt-Left arrow<br />

#define K_ALT_RIGHT 413 // * Alt-Right arrow<br />

#define K_ALT_HOME 407 // * Alt-Home<br />

#define K_ALT_END 415 // * Alt-End<br />

#define K_ALT_PGUP 409 // * Alt-PgUp<br />

#define K_ALT_PGDN 417 // * Alt-PgDn<br />

#define K_ENTER 13 // Enter, Ctrl-M<br />

#define K_RETURN 13 // Return, Ctrl-M<br />

#define K_SPACE 32 // Space bar<br />

#define K_ESC 27 // Esc, Ctrl-<br />

#define K_CTRL_ENTER 10 // Ctrl-Enter<br />

#define K_CTRL_RETURN 10 // Ctrl-Return


156 volume VIII Argomenti avanzati e accessori<br />

#define K_CTRL_RET 10 // Ctrl-Return (Compat.)<br />

#define K_CTRL_PRTSCR 379 // * Ctrl-Print Screen<br />

#define K_CTRL_QUESTION 309 // Ctrl-?<br />

#define K_ALT_ENTER 284 // * Alt-Enter<br />

#define K_ALT_RETURN 284 // * Alt-Return<br />

#define K_ALT_EQUALS 387 // * Alt-Equals<br />

#define K_ALT_ESC 257 // * Alt-Esc<br />

#define KP_ALT_ENTER 422 // * Keypad Alt-Enter<br />

#define KP_CTRL_5 399 // * Keypad Ctrl-5<br />

#define KP_CTRL_SLASH 405 // * Keypad Ctrl-/<br />

#define KP_CTRL_ASTERISK 406 // * Keypad Ctrl-*<br />

#define KP_CTRL_MINUS 398 // * Keypad Ctrl--<br />

#define KP_CTRL_PLUS 400 // * Keypad Ctrl-+<br />

#define KP_ALT_5 5 // * Keypad Alt-5<br />

#define KP_ALT_SLASH 420 // * Keypad Alt-/<br />

#define KP_ALT_ASTERISK 311 // * Keypad Alt-*<br />

#define KP_ALT_MINUS 330 // * Keypad Alt--<br />

#define KP_ALT_PLUS 334 // * Keypad Alt-+<br />

#define K_INS 22 // Ins, Ctrl-V<br />

#define K_DEL 7 // Del, Ctrl-G<br />

#define K_BS 8 // Backspace, Ctrl-H<br />

#define K_TAB 9 // Tab, Ctrl-I<br />

#define K_SH_TAB 271 // Shift-Tab<br />

#define K_CTRL_INS 402 // * Ctrl-Ins<br />

#define K_CTRL_DEL 403 // * Ctrl-Del<br />

#define K_CTRL_BS 127 // Ctrl-Backspace<br />

#define K_CTRL_TAB 404 // * Ctrl-Tab<br />

#define K_ALT_INS 418 // * Alt-Ins<br />

#define K_ALT_DEL 419 // * Alt-Del<br />

#define K_ALT_BS 270 // * Alt-Backspace<br />

#define K_ALT_TAB 421 // * Alt-Tab<br />

#define K_CTRL_A 1 // Ctrl-A, Home<br />

#define K_CTRL_B 2 // Ctrl-B, Ctrl-Right arrow<br />

#define K_CTRL_C 3 // Ctrl-C, PgDn, Ctrl-ScrollLock<br />

#define K_CTRL_D 4 // Ctrl-D, Right arrow<br />

#define K_CTRL_E 5 // Ctrl-E, Up arrow<br />

#define K_CTRL_F 6 // Ctrl-F, End<br />

#define K_CTRL_G 7 // Ctrl-G, Del<br />

#define K_CTRL_H 8 // Ctrl-H, Backspace<br />

#define K_CTRL_I 9 // Ctrl-I, Tab<br />

#define K_CTRL_J 10 // Ctrl-J<br />

#define K_CTRL_K 11 // Ctrl-K<br />

#define K_CTRL_L 12 // Ctrl-L<br />

#define K_CTRL_M 13 // Ctrl-M, Return<br />

#define K_CTRL_N 14 // Ctrl-N<br />

#define K_CTRL_O 15 // Ctrl-O<br />

#define K_CTRL_P 16 // Ctrl-P<br />

#define K_CTRL_Q 17 // Ctrl-Q<br />

#define K_CTRL_R 18 // Ctrl-R, PgUp<br />

#define K_CTRL_S 19 // Ctrl-S, Left arrow<br />

#define K_CTRL_T 20 // Ctrl-T<br />

#define K_CTRL_U 21 // Ctrl-U<br />

#define K_CTRL_V 22 // Ctrl-V, Ins<br />

#define K_CTRL_W 23 // Ctrl-W, Ctrl-End<br />

#define K_CTRL_X 24 // Ctrl-X, Down arrow<br />

#define K_CTRL_Y 25 // Ctrl-Y


Clean the Clipper 5.2 157<br />

#define K_CTRL_Z 26 // Ctrl-Z, Ctrl-Left arrow<br />

#define K_ALT_A 286 // Alt-A<br />

#define K_ALT_B 304 // Alt-B<br />

#define K_ALT_C 302 // Alt-C<br />

#define K_ALT_D 288 // Alt-D<br />

#define K_ALT_E 274 // Alt-E<br />

#define K_ALT_F 289 // Alt-F<br />

#define K_ALT_G 290 // Alt-G<br />

#define K_ALT_H 291 // Alt-H<br />

#define K_ALT_I 279 // Alt-I<br />

#define K_ALT_J 292 // Alt-J<br />

#define K_ALT_K 293 // Alt-K<br />

#define K_ALT_L 294 // Alt-L<br />

#define K_ALT_M 306 // Alt-M<br />

#define K_ALT_N 305 // Alt-N<br />

#define K_ALT_O 280 // Alt-O<br />

#define K_ALT_P 281 // Alt-P<br />

#define K_ALT_Q 272 // Alt-Q<br />

#define K_ALT_R 275 // Alt-R<br />

#define K_ALT_S 287 // Alt-S<br />

#define K_ALT_T 276 // Alt-T<br />

#define K_ALT_U 278 // Alt-U<br />

#define K_ALT_V 303 // Alt-V<br />

#define K_ALT_W 273 // Alt-W<br />

#define K_ALT_X 301 // Alt-X<br />

#define K_ALT_Y 277 // Alt-Y<br />

#define K_ALT_Z 300 // Alt-Z<br />

#define K_ALT_1 376 // Alt-1<br />

#define K_ALT_2 377 // Alt-2<br />

#define K_ALT_3 378 // Alt-3<br />

#define K_ALT_4 379 // Alt-4<br />

#define K_ALT_5 380 // Alt-5<br />

#define K_ALT_6 381 // Alt-6<br />

#define K_ALT_7 382 // Alt-7<br />

#define K_ALT_8 383 // Alt-8<br />

#define K_ALT_9 384 // Alt-9<br />

#define K_ALT_0 385 // Alt-0<br />

#define K_F1 28 // F1, Ctrl-Backslash<br />

#define K_F2 -1 // F2<br />

#define K_F3 -2 // F3<br />

#define K_F4 -3 // F4<br />

#define K_F5 -4 // F5<br />

#define K_F6 -5 // F6<br />

#define K_F7 -6 // F7<br />

#define K_F8 -7 // F8<br />

#define K_F9 -8 // F9<br />

#define K_F10 -9 // F10<br />

#define K_F11 -40 // * F11<br />

#define K_F12 -41 // * F12<br />

#define K_CTRL_F1 -20 // Ctrl-F1<br />

#define K_CTRL_F2 -21 // Ctrl-F2<br />

#define K_CTRL_F3 -22 // Ctrl-F4<br />

#define K_CTRL_F4 -23 // Ctrl-F3<br />

#define K_CTRL_F5 -24 // Ctrl-F5<br />

#define K_CTRL_F6 -25 // Ctrl-F6<br />

#define K_CTRL_F7 -26 // Ctrl-F7<br />

#define K_CTRL_F8 -27 // Ctrl-F8<br />

#define K_CTRL_F9 -28 // Ctrl-F9<br />

#define K_CTRL_F10 -29 // Ctrl-F10<br />

#define K_CTRL_F11 -44 // * Ctrl-F11<br />

#define K_CTRL_F12 -45 // * Ctrl-F12


158 volume VIII Argomenti avanzati e accessori<br />

#define K_ALT_F1 -30 // Alt-F1<br />

#define K_ALT_F2 -31 // Alt-F2<br />

#define K_ALT_F3 -32 // Alt-F3<br />

#define K_ALT_F4 -33 // Alt-F4<br />

#define K_ALT_F5 -34 // Alt-F5<br />

#define K_ALT_F6 -35 // Alt-F6<br />

#define K_ALT_F7 -36 // Alt-F7<br />

#define K_ALT_F8 -37 // Alt-F8<br />

#define K_ALT_F9 -38 // Alt-F9<br />

#define K_ALT_F10 -39 // Alt-F10<br />

#define K_ALT_F11 -46 // * Alt-F11<br />

#define K_ALT_F12 -47 // * Alt-F12<br />

#define K_SH_F1 -10 // Shift-F1<br />

#define K_SH_F2 -11 // Shift-F2<br />

#define K_SH_F3 -12 // Shift-F3<br />

#define K_SH_F4 -13 // Shift-F4<br />

#define K_SH_F5 -14 // Shift-F5<br />

#define K_SH_F6 -15 // Shift-F6<br />

#define K_SH_F7 -16 // Shift-F7<br />

#define K_SH_F8 -17 // Shift-F8<br />

#define K_SH_F9 -18 // Shift-F9<br />

#define K_SH_F10 -19 // Shift-F10<br />

#define K_SH_F11 -42 // * Shift-F11<br />

#define K_SH_F12 -43 // * Shift-F12<br />

*=================================================================<br />

* MEMOEDIT()<br />

*=================================================================<br />

* User function entry modes<br />

#define MEMOEDIT_IDLE 0 // idle, all keys processed<br />

#define MEMOEDIT_UNKEY 1 // unknown key, memo unaltered<br />

#define MEMOEDIT_UNKEYX 2 // unknown key, memo altered<br />

#define MEMOEDIT_INIT 3 // initialization mode<br />

* User function return codes<br />

#define MEMOEDIT_DEFAULT 0 // perform default action<br />

#define MEMOEDIT_IGNORE 32 // ignore unknown key<br />

#define MEMOEDIT_DATA 33 // treat unknown key as data<br />

#define MEMOEDIT_TOGGLEWRAP 34 // toggle word-wrap mode<br />

#define MEMOEDIT_TOGGLESCROLL 35 // toggle scrolling mode<br />

#define MEMOEDIT_WORDRIGHT 100 // perform word-right operation<br />

#define MEMOEDIT_BOTTOMRIGHT 101 // perform bottom-right operation<br />

*=================================================================<br />

* SET()<br />

*=================================================================<br />

#define _SET_EXACT 1<br />

#define _SET_FIXED 2<br />

#define _SET_DECIMALS 3<br />

#define _SET_DATEFORMAT 4<br />

#define _SET_EPOCH 5<br />

#define _SET_PATH 6<br />

#define _SET_DEFAULT 7<br />

#define _SET_EXCLUSIVE 8<br />

#define _SET_SOFTSEEK 9<br />

#define _SET_UNIQUE 10


Clean the Clipper 5.2 159<br />

#define _SET_DELETED 11<br />

#define _SET_CANCEL 12<br />

#define _SET_DEBUG 13<br />

#define _SET_TYPEAHEAD 14<br />

#define _SET_COLOR 15<br />

#define _SET_CURSOR 16<br />

#define _SET_CONSOLE 17<br />

#define _SET_ALTERNATE 18<br />

#define _SET_ALTFILE 19<br />

#define _SET_DEVICE 20<br />

#define _SET_EXTRA 21<br />

#define _SET_EXTRAFILE 22<br />

#define _SET_PRINTER 23<br />

#define _SET_PRINTFILE 24<br />

#define _SET_MARGIN 25<br />

#define _SET_BELL 26<br />

#define _SET_CONFIRM 27<br />

#define _SET_ESCAPE 28<br />

#define _SET_INSERT 29<br />

#define _SET_EXIT 30<br />

#define _SET_INTENSITY 31<br />

#define _SET_SCOREBOARD 32<br />

#define _SET_DELIMITERS 33<br />

#define _SET_DELIMCHARS 34<br />

#define _SET_WRAP 35<br />

#define _SET_MESSAGE 36<br />

#define _SET_MCENTER 37<br />

#define _SET_SCROLLBREAK 38<br />

*=================================================================<br />

* SETCURSOR()<br />

*=================================================================<br />

#define SETCURSOR_NONE 0 // No cursor<br />

#define SETCURSOR_NORMAL 1 // Normal cursor (underline)<br />

#define SETCURSOR_INSERT 2 // Insert cursor (lower half block)<br />

#define SETCURSOR_SPECIAL1 3 // Special cursor (full block)<br />

#define SETCURSOR_SPECIAL2 4 // Special cursor (upper half block)<br />

*=================================================================<br />

* RDD REQUESTs<br />

*=================================================================<br />

external dbfndx<br />

external dbfntx // default<br />

Appunti di informatica libera 2003.06.29 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org


nanoBase 1997<br />

A free xBase for Dos.<br />

Chapter 367<br />

This material appeared originally at ‘http://www.geocities.com/SiliconValley/<br />

7737/nanobase.html’, in 1997. Now it is incorporated inside the Italian document<br />

‘‘Appunti di informatica libera’’, and might be reached at the URI .<br />

Questo materiale è apparso in origine, nel 1997, presso ‘http://www.geocities.com/<br />

SiliconValley/7737/nanobase.html’. Adesso viene incorporato nel documento «Appunti<br />

di informatica libera» e può essere raggiunto attraverso l’URI .<br />

367.1 What is it<br />

nanoBase 1 is a Dos program that works essentially as:<br />

• a dot command line xBase,<br />

• a menu driven xBase,<br />

• a xBase program interpreter.<br />

nanoBase 1997 is compiled in two versions: a small one to be used with old computers (i86 with<br />

640 Kibyte RAM), and a second one to be used with better computers, at least i286 (or better)<br />

with 2 Mibyte RAM.<br />

367.2 The dot command line<br />

Figure 367.1. The dot line.<br />

The dot command line is the first face <strong>of</strong> nanoBase, the one that appears starting the program<br />

normally. It recalls the dot line command <strong>of</strong> the old xBases.<br />

Please note that nanoBase recognise only expressions (that is: no commands).<br />

1 nanoBase GNU GPL<br />

160


nanoBase 1997 161<br />

367.3 The menu<br />

Figure 367.2. The file menu.<br />

Pressing [ F10 ] the nanoBase menu appears.<br />

From this menu the operations are easier than writing all commands on a prompt line, but it is<br />

always possible to come back to the dot line to do an operation not available from the menu.<br />

367.4 The macro recording, compiling and execution<br />

Figure 367.3. The macro menu.<br />

nanoBase is able to record some actions made with the menu and all what is correctly typed from<br />

the dot prompt. This may be the begin for a little program (called macro inside nanoBase) that<br />

can be executed as it is (ASCII), or compiled into another format, faster to execute.<br />

Macros for nanoBase are made with a reduced set <strong>of</strong> the Clipper syntax. The statements recognised<br />

from nanoBase are:<br />

PROCEDURE procedure_name<br />

statements...<br />

[RETURN]<br />

statements...<br />

ENDPROCEDURE


162 volume VIII Argomenti avanzati e accessori<br />

DO PROCEDURE procedure_name<br />

BEGIN SEQUENCE<br />

statements...<br />

[BREAK]<br />

statements...<br />

END<br />

DO CASE<br />

CASE lCondition1<br />

statements...<br />

[CASE <strong>lCondition2</strong>]<br />

statements...<br />

[OTHERWISE]<br />

statements...<br />

END<br />

WHILE lCondition<br />

statements...<br />

[EXIT]<br />

statements...<br />

[LOOP]<br />

statements...<br />

END<br />

IF lCondition1<br />

statements...<br />

[ELSE]<br />

statements...<br />

END<br />

• the ‘FOR’ loop is not available (too difficult to implement),<br />

• there may be no user defined functions (code blocks may be created instead),<br />

• procedure calls cannot transfer variables,<br />

• there are only public (global) variables.<br />

Beside these limitations, there are many added functions to the standard language that make the<br />

programming easier.<br />

All you need is inside ‘NB.EXE’:<br />

• the utility to handle manually the data,<br />

• the macro compiler,<br />

• the macro executor.


nanoBase 1997 163<br />

367.5 The report system<br />

Figure 367.4. The report menu.<br />

nanoBase can handle label (‘.LBL’) and form (‘.FRM’) files in the dBaseIII format. Labels and<br />

forms may be created and edited inside nanoBase. Beside these old report system there is another<br />

way to make a little bit complicated reports without making a complex macro: it is called RPT.<br />

A RPT file is a ASCII file with text mixed with code. The text may contain variables (usually a<br />

field or an expression containing fields).<br />

To make a complex report some work is needed, but surely less than the time needed to make a<br />

report program.<br />

The main purpose <strong>of</strong> it was to be able to print text with variables (typically names and addresses)<br />

for every record <strong>of</strong> a particular ‘.DBF’ file. Now the RPT system makes something more.<br />

367.6 The integrated text editor<br />

Figure 367.5. The integrated text editor.<br />

nanoBase contains an integrated text editor not particularly good, but very usefull for RPT files<br />

(as the expression insertion is very easy with the use <strong>of</strong> the [ F2 ] key) and whenever there isn’t<br />

any other editor there.


164 volume VIII Argomenti avanzati e accessori<br />

367.7 The internal documentation<br />

Figure 367.6. The internal documentation.<br />

nanoBase’s documentation si translated also inside the HTF format: ‘NB.HLP’. Pressing [ F1 ],<br />

normally, a contextual piece <strong>of</strong> the manual appears.<br />

Some standard functions have its own internal help, contained inside the ‘.EXE’ file. This was<br />

made to help programming with nanoBase.<br />

367.8 Download it<br />

Here is the 1997 edition <strong>of</strong> nanoBase.<br />

• EXE for small computers.<br />

<br />

<br />

• EXE for i286 with more than 2 Mibyte.<br />

<br />

<br />

• Runtime for small computers.<br />

<br />

<br />

• Documentation in many different formats.<br />

<br />

<br />

• Macro programming examples.<br />

<br />

<br />

• Source for version 96.06.16, without mouse support (1996).<br />

<br />


nanoBase 1997 165<br />

• Source for version 1997.<br />

<br />

<br />

367.9 Bugs and known problems<br />

Here is the list <strong>of</strong> known bugs and problems.<br />

• Comparison with floating point numbers may fail. It is better to convert numbers into string<br />

before comparing them.<br />

• Macros may be contained inside ASCII files or a ‘‘compiled’’ ‘.DBF’ file. In the second<br />

case, when nanoBase executes the macro, a work area (the last available one) is used, so it<br />

should not be closed or the macro execution will be stopped. A ‘dbcloseall()’ will stop<br />

execution <strong>of</strong> the macro. In substitution <strong>of</strong> ‘dbcloseall()’, ‘DBCLOSE()’ should be used.<br />

• To simplify the macro interpretation, lines such as this:<br />

qqout( "You can’t do that // you can’t do that!" )<br />

will generate an error as the interpreter will read only:<br />

qqout( "You can’t do that<br />

• nanoBase works good also if you have a screen configuration that permits you to show more<br />

than the usual 80 columns and 25 lines, but the library used to handle the mouse is not able<br />

to work outside the 80×25 area.<br />

Appunti di informatica libera 2003.06.29 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org


nanoBase 1997 user manual<br />

Chapter 368<br />

This is the documentation <strong>of</strong> nanoBase 1997, with minor modifications, that appeared originally<br />

at ‘http://www.geocities.com/SiliconValley/7737/nb.htm’. Now it is incorporated<br />

inside the Italian document ‘‘Appunti di informatica libera’’, and might be reached at<br />

the URI .<br />

Questo è il manuale di nanoBase 1997, modificato leggermente, che è apparso inizialmente<br />

presso ‘http://www.geocities.com/SiliconValley/7737/nb.htm’. Adesso<br />

viene incorporato nel documento «Appunti di informatica libera» e può essere raggiunto attraverso<br />

l’URI .<br />

368.1 Dos xBase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166<br />

368.2 Composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171<br />

368.3 How to use nB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173<br />

368.4 Status line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174<br />

368.5 The dot line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175<br />

368.6 The menu system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175<br />

368.7 The text editor DOC() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187<br />

368.8 The help text file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187<br />

368.9 Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188<br />

368.10 Data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192<br />

368.11 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .200<br />

368.12 Delimiters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201<br />

368.13 Code blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202<br />

368.14 Standard functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202<br />

368.15 nB functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261<br />

368.16 Normal command substitution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299<br />

368.17 nB command substitution functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305<br />

368.18 RPT: the nB print function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310<br />

368.19 How can I... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313<br />

368.20 The source files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314<br />

nB (‘‘nano Base’’: ‘‘n’’ = ‘‘nano’’ = 10**(-9) = ‘‘very little’’) is a little Dos xBase written in<br />

Clipper 5.2 that can help to access ‘.DBF’ file created with different standards.<br />

nB is:<br />

• a dot command interpreter,<br />

166


nanoBase 1997 user manual 167<br />

• a menu driven xBase,<br />

• a xBase program interpreter.<br />

368.1 Dos xBase<br />

This section is a brief description <strong>of</strong> the functionality <strong>of</strong> a typical Dos xBase.<br />

The first purpose <strong>of</strong> a xBase program is to handle data inside a ‘.DBF’ file. These files may be<br />

indexed with the help <strong>of</strong> index files and more ‘.DBF’ files may be linked with a relation to obtain<br />

something like a relational database.<br />

368.1.1 .DBF files<br />

‘.DBF’ files are files organised in a table structure:<br />

.--------------------------.<br />

| field1 | field2 | field3 | record1<br />

|--------|--------|--------|<br />

| | | | record2<br />

|--------|--------|--------|<br />

| | | | record3<br />

|--------|--------|--------|<br />

| | | | record4<br />

|--------|--------|--------|<br />

| | | | record5<br />

|--------|--------|--------|<br />

| | | | record6<br />

‘--------------------------’<br />

The lines <strong>of</strong> this table are records and the columns are fields. Records are numbered starting from<br />

the first that is number 1.<br />

Columns are defined as fields and fields are distinguished by name and these names are saved<br />

inside the ‘.DBF’ file.<br />

Every field (column) can contain only one specified kind <strong>of</strong> data with a specified dimension:<br />

• ‘C’, character, originally the maximum dimension was 254 characters, minimum is 1;<br />

• ‘N’, numeric, a numeric field that can contain also sign and decimal values;<br />

• ‘D’, date, a field dedicated to date information;<br />

• ‘L’, logic, a filed that may contain only ‘T’ for True or ‘F’ for False used as a boolean<br />

variable;<br />

• ‘M’, memo, a character field with no predefined dimension, not allocated directly inside the<br />

‘.DBF’, but inside a ‘.DBT’ file, automatically linked.<br />

No other field type is available for a typical xBase ‘.DBF’ file.<br />

To access the data contained inside a ‘.DBF’ file the following list <strong>of</strong> action may be followed:<br />

• Open a ‘.DBF’ file inside the current area, where these areas are something like file handlers.<br />

• After the ‘.DBF’ file is opened, it referenced only by the alias name that usually correspond<br />

to the original filename without extention.


168 volume VIII Argomenti avanzati e accessori<br />

• Move the record pointer to the desired location.<br />

• Lock the current record to avoid access from other users.<br />

• Do some editing with the data contained inside the current record using the field names like<br />

they were variables.<br />

• Release the lock.<br />

• Move the record pointer to another desired location.<br />

• Lock the current record to avoid access from other users.<br />

• ...<br />

• Close the alias.<br />

Before you go further, you have to understand that:<br />

• A ‘.DBF’ file is opened using a free WORK AREA that may be associated to the concept<br />

<strong>of</strong> the file handler.<br />

• The ‘.DBF’ file is opened with a alias name that permit to open the same ‘.DBF’ file more<br />

times when using different alias names.<br />

• After the ‘.DBF’ file is opened, we don’t speak any more <strong>of</strong> file, but alias.<br />

• If the work area "n" is used from the alias "myAlias", speaking <strong>of</strong> work area "n" or <strong>of</strong> alias<br />

"myAlias" is the same thing.<br />

368.1.2 <strong>Index</strong> files<br />

‘.DBF’ files are organised with record number, that is, you can reach a specific record and not a<br />

specific information unless that you scan record by record.<br />

To obtain to "see" a ‘.DBF’ file somehow logically ordered (when physically it is not), index files<br />

are used.<br />

A index file, also called INDEX BAG, is a file that contains one or more indexes<br />

<strong>Index</strong>es are rules by which a ‘.DBF’ file may be seen ordered.<br />

A typical index file may contain only one index.<br />

A index file may have the following extention:<br />

• ‘.NDX’, single index, dBase III and dBase III plus;<br />

• ‘.NTX’, single index, Clipper;<br />

• ‘.MBX’, multiple index, dBase IV;<br />

• ‘.CDX’, multiple index, FoxPro.<br />

Every index file may be used only in association with the ‘.DBF’ for what it was made. The<br />

problem is that normally there is no way to avoid errors when the user try to associate the right<br />

‘.DBF’ file with the wrong index.


nanoBase 1997 user manual 169<br />

To access the data contained inside a ‘.DBF’ file the following list <strong>of</strong> action may be followed:<br />

• Open a ‘.DBF’ file.<br />

• Open a index file.<br />

• Select a particular order.<br />

• Search for a key or move the record pointer on a different way.<br />

• Lock the current record to avoid access from other users.<br />

• Do some editing with the data contained inside the current record using the field names like<br />

they were variables.<br />

• Release the lock.<br />

• Move the record pointer to another desired location.<br />

• Lock the current record to avoid access from other users.<br />

• ...<br />

• Close the alias.<br />

Before you go further, you have to understand that:<br />

• As orders are contained inside a INDEX BAG file physically distinguished form the ‘.DBF’<br />

file, it may happen that a ‘.DBF’ file is wrongly opened and edited without the index. In<br />

this case, the INDEX BAG is not updated and when the INDEX BAG will be opened, the<br />

records contained inside the ‘.DBF’ file may not correspond.<br />

• For the same reason, an improper program termination may result in an incomplete data<br />

update. That is: ‘.DBF’ file may be all right, INDEX BAG not.<br />

• This is why xBase programs are "weak" relational databases or they are not relational<br />

databases at all.<br />

• When troubles occurs, indexes must be rebuild.<br />

368.1.3 Relations<br />

Many ‘.DBF’ files with indexes may be opened simultaneously. Data contained inside more<br />

‘.DBF’ files may be somehow connected together. See the example.


170 volume VIII Argomenti avanzati e accessori<br />

.----------------------------------------.<br />

| Date | Time IN | Time OUT | Employee # |<br />

|------|---------|-----------------------|<br />

| xxxx | xxxxxxx | xxxxxxxx | 01 | -------->.<br />

|------|---------|----------|------------| |<br />

| yyyy | yyyyyyy | yyyyyyyy | 02 | |<br />

|------|---------|----------|------------| |<br />

| zzzz | zzzzzzz | zzzzzzzz | 01 | -------->|<br />

‘----------------------------------------’ |<br />

[...] |<br />

|<br />

.| 01 | aaaaaaa | aaaaaaa |.....|<br />

|------------|---------|---------|-----|<br />

| 02 | bbbbbbb | bbbbbbb |.....|<br />

|------------|---------|---------|-----|<br />

| 03 | ccccccc | ccccccc |.....|<br />

‘--------------------------------------’<br />

The first ‘.DBF’ file contains some data that refers to an Employee number that may appear<br />

repeated on more records.<br />

Employee informations are stored inside another ‘.DBF’ file that contains only one record for<br />

every employee.<br />

Establishing a relation from the first ‘.DBF’ file to the second, moving the record pointer <strong>of</strong> the<br />

first ‘.DBF’ file, that is the first alias, the record pointer <strong>of</strong> the second, the child alias, is moved<br />

automatically to the record containing the right data.<br />

The relation is an expression that should result in a number if the child alias is opened without<br />

index, or in a valid index key if the child alias is opened with an index.<br />

To relate two ‘.DBF’ files the following list <strong>of</strong> action may be followed:<br />

• Open the first ‘.DBF’ file.<br />

• Open a index file for the first alias.<br />

• Select a particular order.<br />

• Open the second ‘.DBF’ file.<br />

• Open a index file for the second alias.<br />

• Select a particular order.<br />

• Select the first alias.<br />

• Define a relation form the first alias and the second alias: the child alias.<br />

• Search for a key or move the record pointer <strong>of</strong> the first alias (don’t care about the Child<br />

alias).<br />

• Lock the current record to avoid access from other users.<br />

• If data contained inside the Child alias should be edited (usually it doesn’t happen), lock<br />

the current record <strong>of</strong> the Child alias.


nanoBase 1997 user manual 171<br />

• Do some editing with the data contained inside the current record using the field names like<br />

they were variables.<br />

• Release the lock (also with the Child alias if a lock was made).<br />

• Move the record pointer to another desired location.<br />

• Lock the current record to avoid access from other users.<br />

• [...]<br />

• Release the relation.<br />

• Close the Child alias.<br />

• Close the first alias.<br />

As may be seen, relations are not saved inside files, but are obtained with lines <strong>of</strong> code.<br />

368.2 Composition<br />

nB is composed from the following files, where xx is the the version code.<br />

NBASExx1.ZIP EXEs for small PCs<br />

NBASExx2.ZIP Runtime EXEs for small PCs<br />

NBASExx3.ZIP EXEs for i286 with 2M+<br />

NBASExx4.ZIP DOCs<br />

NBASExx5.ZIP EXAMPLEs<br />

NBASExx6.ZIP SRCs for version 96.06.16<br />

NBASExx7.ZIP SRCs for the current version<br />

Every archive file contains:<br />

‘COPYING.TXT’ GNU General Public License version 2 in Dos text format.<br />

‘README.TXT’ the readme file.<br />

‘FILE_ID.DIZ’ definition.<br />

The file ‘NBASExx1.ZIP’ contains also the following files.<br />

‘NB.EXE’<br />

the executable program for DBFNTX and DBFNDX files,<br />

linked with RTLINK.<br />

‘NB.HLP’ this manual in "Help Text File" format.<br />

The file NBASExx2.ZIP contains also the following files.<br />

‘NB.EXE’<br />

The file ‘NBASExx3.ZIP’ contains also the following files.<br />

the run-time to execute macro programs for DBFNTX and<br />

DBFNDX files handling, linked with RTLINK.<br />

‘NB.EXE’<br />

the executable program for DBFCDX, DBFMDX, DBFNDX<br />

and DBFNTX files, linked with EXOSPACE.<br />

‘NB.HLP’ the user manual in "Help Text File" format.


172 volume VIII Argomenti avanzati e accessori<br />

The file ‘NBASExx4.ZIP’ contains also the following files.<br />

‘NB.PRN’ the user manual in printed text format.<br />

‘NB.RTF’ the user manual in RTF format.<br />

‘NB.TXT’ the user manual in ASCII text format.<br />

‘NB.HTM’ the user manual in HTML format.<br />

The file ‘NBASExx5.ZIP’ contains also the following files.<br />

‘_ADDRESS.DBF’ an example database file.<br />

‘_ADDRESS.NTX’ index file associated to ‘_ADDRESS.DBF’.<br />

‘_ADDRESS.LBL’<br />

a label form file used to print data contained inside<br />

‘_ADDRESS.DBF’ .<br />

‘_ADDRESS.FRM’<br />

a report form file used to print data contained inside<br />

‘_ADDRESS.DBF’ .<br />

‘_ADDRESS.RPT’<br />

a RPT text file<br />

‘_ADDRESS.DBF’ .<br />

used to print data contained inside<br />

‘_MAINMNU.&’<br />

a macro program source example <strong>of</strong> a menu that executes<br />

some others macro programs. This example is made to<br />

demonstrate how nB can execute directly a source code without<br />

compiling it. This example is made only to taste it: it is<br />

very slow and only a speedy machine can give the idea <strong>of</strong> it.<br />

a macro program source example <strong>of</strong> a menu that executes<br />

‘0MAINMNU.&’<br />

some others macro programs. It is the same as ‘_MAINMNU.&’<br />

but it is made to start the execution <strong>of</strong> the compiled macros.<br />

‘0MAINMNU.NB’ compiled macro program ‘0MAINMNU.&’<br />

‘0MAINMNU.BAT’<br />

a batch file to<br />

‘0MAINMNU.NB’<br />

show how to run the execution <strong>of</strong><br />

‘1ADDRESS.&’<br />

a macro program source example for handling a ‘.DBF’ file<br />

containing addresses in various ways.<br />

‘1ADDRESS.NB’ compiled macro ‘1ADDRESS.&’ .<br />

a macro program source example for handling a ‘.DBF’ file<br />

‘2ADDRESS.&’<br />

containing addresses in various ways: a little bit more complicated<br />

than 1ADDRESS.&.<br />

‘2ADDRESS.NB’ compiled macro ‘2ADDRESS.&’ .<br />

a macro program source example for handling a ‘.DBF’ file<br />

‘3ADDRESS.&’<br />

containing addresses in various ways: a little bit more complicated<br />

than ‘2ADDRESS.&’ .<br />

‘3ADDRESS.NB’ compiled macro ‘3ADDRESS.&’.<br />

a macro program source example for handling a ‘.DBF’ file<br />

‘4ADDRESS.&’<br />

containing addresses in various ways: a little bit more complicated<br />

than ‘3ADDRESS.&’ .<br />

‘4ADDRESS.NB’ compiled macro ‘4ADDRESS.&’ .<br />

‘ABIORITM.&’<br />

a macro program source example for calculating the personal<br />

bio wave.<br />

‘ABIORITM.NB’ compiled macro ‘ABIORITM.&’ .<br />

‘_STUDENT.DBF’ a ‘.DBF’ file used inside the BSTUDENT macro example.<br />

‘_STUDENT.NTX’ index file used for ‘_STUDENT.DBF’ .<br />

‘_STUDSTD.DBF’ a ‘.DBF’ file used inside the BSTUDENT macro example.<br />

‘_STUDENT.RPT’<br />

a RPT text file<br />

‘_STUDENT.DBF’ .<br />

used to print data contained inside<br />

‘_STUDSTD.RPT’<br />

a RPT text file<br />

‘_STUDSTD.DBF’ .<br />

used to print data contained inside<br />

‘BSTUDENT.&’<br />

a macro program source example for students evaluation: a<br />

description about students is obtained linking other standard<br />

descriptions.<br />

‘BSTUDENT.NB’ compiled macro ‘BSTUDENT.&’ .


nanoBase 1997 user manual 173<br />

‘CBATMAKE.&’<br />

a macro program source example to generate a batch file to be<br />

used to back up an entire hard disk.<br />

‘CBATMAKE.NB’ compiled macro ‘CBATMAKE.&’ .<br />

‘BROWSE.&’<br />

‘BROWSE.NB’ compiled macro ‘BROWSE.&’ .<br />

a macro program source example to start an automatic<br />

browse.<br />

‘BROWSE.BAT’<br />

batch file to start a ‘.DBF’ browse with the BROWSE macro<br />

program.<br />

‘MENU.&’ a macro program source example for a Dos menu.<br />

‘MENU.NB’ compiled macro ‘MENU.&’ .<br />

‘MENU.BAT’ batch file to use the MENU macro.<br />

The file ‘NBASExx6.ZIP’ contains also the following files: source code for the version 96.06.16.<br />

‘NB.PRG’ the main source file for version 96.06.16.<br />

‘NB_REQ.PRG’ the source file containing links to all the standard functions.<br />

‘NB.LNK’ link file for compilation.<br />

‘NB_NRMAL.RMK’ rmake file to compile with RTLink.<br />

‘NB_EXOSP.RMK’ rmake file to compile with Exospace.<br />

‘NB_RUNTI.RMK’<br />

rmake file to compile with RTLink defining RUNTIME to obtain<br />

a small nB runtime version.<br />

‘MACRO.LNK’ link file to compile and link a macro.<br />

‘MACRO.RMK’ rmake file to compile and link a macro.<br />

The file ‘NBASExx7.ZIP’ contains also the following files: source code for the current version.<br />

‘NB.PRG’ the main source file.<br />

‘REQUEST.PRG’ the source file containing links to all the Clipper functions.<br />

‘STANDARD.PRG’ the source file for standard functions.<br />

‘EXTRA.PRG’ the source file for other standard functions.<br />

‘STANDARD.CH’<br />

general include file that substitutes all include file normally<br />

used for normal Clipper compilations.<br />

‘NB.CH’ include file specific for nB.<br />

‘NB.LNK’ link file for compilation.<br />

‘NB_RUNTI.LNK’ link file for runtime compilation.<br />

‘NB_NRMAL.RMK’ rmake file to compile with RTLink.<br />

‘NB_EXOSP.RMK’ rmake file to compile with Exospace.<br />

‘NB_RUNTI.RMK’<br />

rmake file to compile with RTLink defining RUNTIME to obtain<br />

a small nB runtime version.<br />

‘MACRO.CH’ include file to compile and link a macro.<br />

‘MACRO.LNK’ link file to compile and link a macro.<br />

‘MACRO.RMK’ rmake file to compile and link a macro.<br />

‘CLIPMOUSE.ZIP’<br />

368.3 How to use nB<br />

nB normal syntax is:<br />

nB [nB_parameters] [macro_filename] [macro_parameters]<br />

a simple free library for mouse support under Clipper (c) 1992<br />

Martin Brousseau.<br />

To run nB, just type the word "NB" and press [ Enter ] to execute. It will run in command mode,<br />

this means that it will look like an old xBASE command prompt.


174 volume VIII Argomenti avanzati e accessori<br />

To run the program as a macro interpreter, type the word NB followed from the macro file name<br />

with extention (no default extention is supposed). If parameters are given, after the macro file<br />

name, these will be available inside the public variables: c_Par1, c_Par2, ..., c_Par9. c_Par0 will<br />

contain the macro file name (see the macro file BROWSE.&). nB will terminate execution when<br />

the macro terminates.<br />

These parameters are available for nB:<br />

-c<br />

-w<br />

-?<br />

nB macro "compilation" syntax is:<br />

nB -m source_macro_filename [destination_macro_filename]<br />

Suppress the copyright notice. It is usefull when using nB for<br />

macro interpretation.<br />

Suppress the "Wait-Wheel" if not desired. It is the "Wheel"<br />

that appears at top-left when a macro is interpreted or other<br />

long elaborations are executed.<br />

Shows a short help.<br />

With the -m parameter, nB "compiles" the ASCII source_macro_filename into<br />

destination_macro_filename.<br />

368.4 Status line<br />

nB shows a "status line" at the top <strong>of</strong> the screen when the nB command prompt or the menu<br />

system is active. It shows some important informations.<br />

| |DBFNTX ||*| 1|ADDRESS | 1/ 4|ADDRESS.NTX |<br />

| | | | | | |<br />

| | | | | | |<br />

| | | | | | Last record (7).<br />

| | | | | |<br />

| | | | | Record pointer position (6).<br />

| | | | |<br />

| | | | Active alias (5).<br />

| | | |<br />

| | | Current Work Area (4)<br />

| | |<br />

| | Deleted record appearance (3)<br />

| |<br />

| Actual default database driver (2).<br />

|<br />

Macro recorder indicator (1).<br />

| 1/ 4|ADDRESS.NTX | 1|ADDRESS |<br />

| | |<br />

| | |<br />

| | Order Tag Name (10)<br />

| |<br />

| Order number (9)<br />

|<br />

Order Bag name (8)<br />

(1) This is the place for the macro recorder indicator. The symbol used is "&". Blank means that<br />

the macro recorder is OFF; & blinking means that the macro recorder is ON; & fixed means that<br />

the macro recorder is PAUSED.<br />

(2) The name <strong>of</strong> the default database driver. It is not necessarily the database driver for the active<br />

alias; it is only the database driver that will be used for the next open/create operation.


nanoBase 1997 user manual 175<br />

(3) An asterisk (*) at this position indicates that SET DELETED is OFF. This means that deleted<br />

records are not filtered. When a BLANK is in this place, SET DELETED is ON, so that deleted<br />

records are filtered.<br />

(4) The active work area number, that is, the area <strong>of</strong> the active alias.<br />

(5) The active alias name. Note that the alias name is not necessarily equal to the ‘.DBF’ file<br />

name.<br />

(6) The actual record pointer position for the active alias.<br />

(7) The number <strong>of</strong> records contained inside the active alias.<br />

(8) The Order Bag name; that is the index file name.<br />

(9) The order number.<br />

(10) The order tag (name). When DBFNTX database driver is used, it correspond to the Order<br />

Bag name.<br />

368.5 The dot line<br />

Starting nB without parameters, the dot line appears. This is the place where commands in form<br />

<strong>of</strong> functions may be written and executed like a old xBase.<br />

The functions written inside the command line that don’t result in an error, are saved inside a<br />

history list. This history list may be recalled with [ F2 ] and then the selected history line may be<br />

reused (eventually edited). Key [ up ]/[ down ] may be used to scroll inside the history list without<br />

showing the all list with [ F2 ].<br />

[ Enter ] is used to tell nB to execute the written function.<br />

As the dot line is not an easy way to use such a program, a menu is available pressing [ F10 ] or<br />

[ Alt+M ]. The [ F10 ] key starts the ASSIST() menu. This menu may be started also entering the<br />

name <strong>of</strong> the function: "ASSIST()".<br />

nB includes a simple built-in text editor: DOC(). It may be started from the dot line entering<br />

"DOT()". No special key is dedicated to start this function.<br />

368.6 The menu system<br />

The nB menu system appears differently depending on the place where it is "called". When<br />

available, the menu system appears pressing [ Alt+M ] or [ F10 ].<br />

The Menu system is organised into horizontal menu, vertical menu, and pop-up menu.<br />

The horizontal menu contains selectable items organised horizontally:<br />

One Two Three Four Five<br />

The cursor may be moved on a different position using arrow keys [ Left ]/[ Right ]; [ Esc ] terminates<br />

the menu; [ Enter ] opens a vertical menu.<br />

The vertical menu contains selectable items organised vertically:<br />

One Two Three Four Five<br />

.----------.<br />

|First |<br />

|Second |<br />

|Third |<br />

‘----------’


176 volume VIII Argomenti avanzati e accessori<br />

The cursor may be moved on a different position using arrow keys [ Up ]/[ Down ]; the arrow keys<br />

[ Left ]/[ Right ] change the vertical menu; [ Esc ] closes the vertical the menu; [ Enter ] starts the selected<br />

menu function.<br />

The vertical menu contains selectable items organised vertically:<br />

One Two Three Four Five<br />

.----------.<br />

|First |<br />

|Second >|--------------.<br />

|Third |Sub function 1|<br />

‘----------|Sub function 2|<br />

‘--------------’<br />

The cursor may be moved on a different position using arrow keys [ Up ]/[ Down ]; [ Esc ] closes the<br />

pop-up the menu; [ Enter ] starts the selected menu function.<br />

The following sections describe the menu system.<br />

368.6.1 Menu File<br />

The menu File contains important function on ‘.DBF’ file, indexes, relations and Replaceable<br />

database drivers.<br />

For database files are considered two aspects: the physical aspect, and the logical alias. When a<br />

‘.DBF’ file is opened, it becomes a alias.<br />

<strong>Index</strong>es are considered as index files and index orders.<br />

It follows a brief menu function description.<br />

Change directory<br />

Changes the actual drive and directory.<br />

File .DBF<br />

Contains a pop-up menu for ‘.DBF’ operations.<br />

New .DBF<br />

A ‘.DBF’ file is a table where columns, called Fields, must be specified and lines,<br />

called records, are added, edited and deleted by the program.<br />

Field characteristics are:<br />

the field name must be unique inside the same file, it is<br />

NAME<br />

composed <strong>of</strong> letters, number and underscore (_), but it<br />

must start with a letter and it is not case sensitive.<br />

TYPE the field type determinates the type <strong>of</strong> data it can hold.<br />

is the field total length in characters; it doesn’t matter<br />

LENGTH<br />

DECIMAL<br />

Field Types:<br />

<strong>of</strong> the type <strong>of</strong> data.<br />

is the length <strong>of</strong> positions after decimal point. This information<br />

is used normally for numeric fields. In this<br />

case, take note that the DECIMAL length, together<br />

with the decimal point, will subtract space for the integer<br />

part <strong>of</strong> the number from the total LENGTH <strong>of</strong> the<br />

filed.


nanoBase 1997 user manual 177<br />

C Character<br />

it is a text field long LENGTH characters.<br />

it is a numeric field long LENGTH characters with<br />

DECIMAL characters for decimal positions. Note that<br />

if LENGTH is 4 and DECIMAL is 0 (zero), the<br />

N Numeric<br />

field may contain integers from -999 to 9999; but if<br />

LENGTH is 4 and DECIMAL 1, the field may contain<br />

numbers from -9.9 to 99.9: two position for the integer<br />

part, one position for the decimal point and one position<br />

for decimal.<br />

D Date<br />

it is a date field: it contains only dates; the length<br />

should not be specified as it is automatically 8.<br />

it is a logical (boolean) field: it contains only TRUE,<br />

L Logic<br />

represented by "Y" or "T", or FALSE, represented by<br />

"N" or "F". The length should not be specified as it is<br />

automatically 1.<br />

it is a character field with unknown dimension. It is<br />

recorded into a parallel file with ‘.DBT’ extention. The<br />

M Memo<br />

original ‘.DBF’ file holds a space for a pointer inside<br />

the ‘.DBT’ file. The length <strong>of</strong> a Memo field is automatically<br />

10 and is referred to the memo pointer.<br />

After the function "NEW .DBF" is selected, a table for the field specifications appears.<br />

+--------------------------------+<br />

| Database file structure |<br />

| |<br />

| Field Name Type Length Decimal |<br />

|--------------------------------|<br />

| | | 0| 0 |<br />

| | | | |<br />

| | | | |<br />

| | | | |<br />

| | | | |<br />

| | | | |<br />

| | | | |<br />

To navigate and to edit the table use the following keys:<br />

[ Up ]/[ Down ]/[ Left ][ Right ] move the cursor one position (up, down, left or right);<br />

[ PgUp ] move to previous screen page;<br />

[ PgDn ] move to next screen page;<br />

[ Ctrl+PgUp ] move to top <strong>of</strong> table;<br />

[ Ctrl+PgDn ] move to bottom <strong>of</strong> table;<br />

[ Ctrl+Home ] move to first column;<br />

[ Ctrl+End ] move to last column;<br />

[ Ctrl+Enter ] append a new empty line;<br />

[ Ctrl+F1 ]<br />

delete (cut) the current line and save a copy into the<br />

"clipboard";<br />

[ Ctrl+F2 ] copy current line into the table "clipboard";<br />

insert (paste) the content <strong>of</strong> the "clipboard" in the cur-<br />

[ Ctrl+F3 ]<br />

rent position;<br />

[ Enter ] start editing in the current position;<br />

[ Esc ] terminate;<br />

[ x ] any other key will be written in the current position.<br />

When the editing is terminated, press [ Esc ] and a dialog box will ask for the file name<br />

and the RDD.<br />

xBase files (.DBF) are not all equal, this way, when a new ‘.DBF’ file si created, the<br />

RDD (Replaceable Database Driver) is asked. The normal RDD is DBFNTX, the one<br />

used by Clipper.


178 volume VIII Argomenti avanzati e accessori<br />

Modify .DBF structure<br />

The modification <strong>of</strong> a ‘.DBF’ file structure is a delicate matter if it contains data.<br />

In fact, it is a data transfer from a source ‘.DBF’ file to a destination ‘.DBF’ file with<br />

a different structure. This way, the destination ‘.DBF’ will be updated only for the<br />

fields with the same name <strong>of</strong> the source one. The position may be different, but names<br />

cannot be changed (not so easily).<br />

Mistakes may be dangerous, so, before doing it, it is recommended a backup copy <strong>of</strong><br />

the original ‘.DBF’ file.<br />

Open .DBF<br />

When a ‘.DBF’ file is opened, it becomes a alias, a logical file, placed inside a work<br />

area. The same ‘.DBF’ file may be opened inside different areas with different alias<br />

names.<br />

The required information to open the file are:<br />

File .NTX<br />

FILENAME<br />

ALIAS<br />

RDD<br />

SHARED<br />

READ ONLY<br />

Contains a pop-up menu for physical indexes operations.<br />

the physical file name.<br />

the alias name. If not assigned, it becomes automatically<br />

the same <strong>of</strong> FILENAME without extention.<br />

the Replaceable Database Driver to use to access to this<br />

file.<br />

a logical value: TRUE means that the file will be accessible<br />

to other users, FALSE means use exclusive.<br />

a logical value: TRUE means that the file will be only<br />

readable and no modification will be allowed, FALSE<br />

means that no restriction on editing will be made.<br />

New .NTX / new tag<br />

If the active area is used we have an active alias. In this case a index may be created.<br />

The index is a way to see the active alias ordered without changing the physical<br />

position <strong>of</strong> records.<br />

There are two words to understand: ORDER and INDEX-BAG. The index bag is the<br />

file that contains the information on the record ordering, the order is the rule followed<br />

to order the records. A index bag may contains one or more orders depending on the<br />

Replaceable Database Driver in use.<br />

Typical ‘.NTX’ file are index bag containing only one order.<br />

Depending on the RDD in use the following field may be filled.<br />

INDEX FILENAME<br />

this is the name <strong>of</strong> the index bag.<br />

the expression that defines the rule for the record or-<br />

KEY EXPRESSION<br />

dering.<br />

this is the name to give to the order (tag) when the RDD<br />

permits to have a index bag containing more than one<br />

ORDER NAME<br />

order. In the other case, the index bag name correspond<br />

to the order name.<br />

FOR EXPRESSION<br />

a FOR condition to filter records before indexing.<br />

Open index<br />

If a index file already exists, it can be associated to the active alias simply opening it.<br />

Take note that the system is not able to verify if the index belong the active alias<br />

and if it is not so a error will result.


nanoBase 1997 user manual 179<br />

Alias<br />

Order<br />

INDEX NAME<br />

is the name <strong>of</strong> the index bag file to open.<br />

Contains a pop-up menu for logical databases (alias) operations.<br />

Select<br />

Only one may be the active alias and with this function the active alias may be changed<br />

choosing from the list <strong>of</strong> used areas.<br />

Selecting the area number zero, no alias is active.<br />

Display structure<br />

With this function the active alias structure may be viewed.<br />

Close active alias<br />

Selecting this function the active alias is closed. That is: the ‘.DBF’ file and eventual<br />

indexes are closed.<br />

Close all aliases<br />

With this function all Aliases are closed.<br />

Contains a pop-up menu for logical indexes (orders).<br />

Relation<br />

Order list rebuild<br />

This function rebuild the indexes opened and associated to the active alias.<br />

Order set focus<br />

This function permits to change the active order selecting form the ones opened and<br />

associated to the active alias.<br />

Order list clear<br />

This function closes all orders associated to the active alias.<br />

Contains a pop-up menu for relations (links with other Aliases).<br />

Set relation<br />

This function permits to establish a relation between a alias and a Child alias showing<br />

as a result a unique database.<br />

CHILD is the alias name to connect to the active alias.<br />

is the relation expression that specify the rule for the relation.<br />

The value <strong>of</strong> this expression is the key to access<br />

EXPRESSION<br />

the Child alias: if this Child alias is accessed without<br />

index, it must be the record number, if this Child alias<br />

is accessed via index, it must be a valid index key.<br />

Clear relation<br />

This function eliminates any relation that originate form the active alias.<br />

RDD default<br />

Contains a pop-up menu for Replaceable Database Driver defaults.<br />

Show actual RDD default<br />

It simply shows the actual Replaceable Database Driver.


180 volume VIII Argomenti avanzati e accessori<br />

Set default RDD<br />

Select a new default Replaceable Database Driver.<br />

368.6.2 Menu Edit<br />

The menu Edit contains functions to access data from the active alias (the actual area).<br />

View<br />

This function permits you to view the active alias with eventual relations as a table.<br />

No edit is allowed.<br />

To navigate the table use the following keys.<br />

[ Enter ] start field editing.<br />

[ PgUp ] show previous screen page.<br />

[ PgDn ] show next screen page.<br />

[ Ctrl+PgUp ] show top <strong>of</strong> alias.<br />

[ Ctrl+PgDn ] show bottom <strong>of</strong> file.<br />

[ Ctrl+Home ] show the first column.<br />

[ Ctrl+End ] show last column.<br />

Edit/browse<br />

This function permits you to edit the active alias with eventual relations as a table.<br />

To navigate and edit the table use the following keys.<br />

[ Enter ] start field editing.<br />

[ PgUp ] show previous screen page.<br />

[ PgDn ] show next screen page.<br />

[ Ctrl+PgUp ] show top <strong>of</strong> alias.<br />

[ Ctrl+PgDn ] show bottom <strong>of</strong> file.<br />

[ Ctrl+Home ] show the first column.<br />

[ Ctrl+End ] show last column.<br />

[ Ctrl+Enter ] append a new empty record.<br />

[ Ctrl+F2 ] copy the current record.<br />

[ Ctrl+F3 ] append and paste a record.<br />

[ Ctrl+F4 ]<br />

paste a previously copied record, overwriting the content<br />

<strong>of</strong> the current one.<br />

[ Ctrl+Y ] delete or recall the current record.<br />

[ Ctrl+Del ] delete or recall the current record.<br />

When a memo field is edited:<br />

Replace<br />

[ Esc ] cancel and close the memo window.<br />

[ Ctrl+Y ] line delete.<br />

[ Ctrl+W ] save and close the memo window.<br />

The content <strong>of</strong> a Field <strong>of</strong> the active alias may be replaced with an expression.<br />

The required data is:


nanoBase 1997 user manual 181<br />

Recall<br />

Delete<br />

Pack<br />

FIELD TO REPLACE<br />

NEW VALUE EXPRESSION<br />

WHILE EXPRESSION<br />

FOR EXPRESSION<br />

the Field name to be replaced.<br />

the expression that obtain the new value for the selected<br />

Field.<br />

the WHILE condition expression: the replacement continue<br />

until this expression results True. The constant ‘.T.’<br />

is ever True and is the default.<br />

the FOR condition expression: the replacement is made<br />

for all records that satisfy the condition. The constant<br />

‘.T.’ is ever True and is the default.<br />

The records signed for deletion (deleted but still there), may be recalled (undeleted).<br />

The required data is:<br />

WHILE EXPRESSION<br />

FOR EXPRESSION<br />

the WHILE condition expression: the record recall continue<br />

until this expression results True. The constant ‘.T.’<br />

is ever True and is the default.<br />

the FOR condition expression: the record recall is made<br />

for all records that satisfy the condition. The constant<br />

‘.T.’ is ever True and is the default.<br />

Deletes (sign for deletion) a group <strong>of</strong> record depending on the required conditions.<br />

The required data is:<br />

WHILE EXPRESSION<br />

FOR EXPRESSION<br />

the WHILE condition expression: the record deletion continue<br />

until this expression results True. The constant ‘.T.’<br />

is ever True and is the default.<br />

the FOR condition expression: the record deletion is made<br />

for all records that satisfy the condition. The constant<br />

‘.T.’ is ever True and is the default.<br />

This function eliminates definitely records previously deleted (signed for deletion).<br />

It may work only if the active alias was opened in exclusive mode.<br />

368.6.3 Menu Report<br />

The menu Report contains functions for data report (print). In particular, label files ‘.LBL’ and<br />

report file ‘.RPT’ may be created and used for printing. There is also another way to print, with<br />

the RPT() system that is available inside the nB internal editor DOC().<br />

DBGOTOP()<br />

Moves the record pointer for the active alias at the first logical record.<br />

New label<br />

With this function can be created a standard label file (.LBL under the dBaseIII standard).<br />

Labels may be printed in more than one column and can contain 16 lines maximum.<br />

The label data is the following.


182 volume VIII Argomenti avanzati e accessori<br />

REMARK<br />

a label remark that will not be printed.<br />

HEIGHT the label vertical dimension.<br />

WIDTH the label horizontal dimension.<br />

MARGIN<br />

the left margin in characters.<br />

LINES<br />

the vertical spacing between labels.<br />

SPACES<br />

the horizontal spacing between labels in characters.<br />

ACROSS the number <strong>of</strong> label columns.<br />

LINE 1 The first line inside labels.<br />

LINE n The n-th line inside labels.<br />

LINE 16 The 16th line inside labels.<br />

The number <strong>of</strong> lines inside the labels depend on the HEIGHT and the maximum value is<br />

16.<br />

The label lines can contain constant string and/or string expressions.<br />

See the example below.<br />

Modify label<br />

Margin<br />

<br />

XXXXXXX|XXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX<br />

XXXXXXX|XXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX<br />

XXXX Height XXXX XXXXXXXXXXXXXXXX<br />

XXXXXXX|XXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX<br />

XXXXXXX|XXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX<br />

|<br />

| Lines <br />

| Spaces<br />

XX Line 1 XXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX<br />

XX Line 2 XXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX<br />

XX Line 3 XXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX<br />

XX Line 4 XXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX<br />

XX Line 5 XXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX<br />

XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX<br />

XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX<br />

XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX<br />

XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX<br />

XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX<br />

| | |<br />

| | |<br />

| | |<br />

+---------------- Across ---------------+<br />

This function permits you to modify a label file.<br />

Label form<br />

This function permits you to print labels with the data provided by the active alias: one<br />

label each record.<br />

The following data is required.<br />

LABEL FILENAME the label filename.<br />

WHILE<br />

the WHILE condition: the label printing goes on as long<br />

as this condition remain True.<br />

FOR<br />

the FOR condition: only the records from the active alias<br />

that satisfy the condition are used for the label print.


nanoBase 1997 user manual 183<br />

New report<br />

This function permits you to create a standard report form file (.FRM under the dBaseIII<br />

standard).<br />

The informations to create a ‘.FRM’ file are divided into two parts: the head and groups; the<br />

columns.<br />

The first part: head and groups, requires the folliwing informations:<br />

PAGE WIDTH<br />

the page width in characters.<br />

LINES PER PAGE<br />

the usable lines per per page.<br />

LEFT MARGIN<br />

the left margin in characters.<br />

DOUBLE SPACED?<br />

double spaced print, yes or no.<br />

PAGE EJECT BEFORE PRINT? form feed before print, yes or no.<br />

PAGE EJECT AFTER PRINT? form feed after print, yes or no.<br />

PLAIN PAGE?<br />

plain page, yes or no.<br />

PAGE HEADER<br />

the page header, max 4 lines (the separation between one<br />

line and the other is obtained writing a semicolon, ";").<br />

GROUP HEADER<br />

the group title.<br />

GROUP EXPRESSION<br />

the group expression (when it changes, the group changes)<br />

SUMMARY REPORT ONLY? only totals and no columns, yes or no.<br />

PAGE EJECT AFTER GROUP? form feed when the group changes, yes or no.<br />

SUB GROUP HEADER<br />

sub group title.<br />

SUB GROUP EXPRESSION the sub group expression.<br />

The second part: columns, requires the following informations structured in table form:<br />

COLUMN HEADER<br />

column head description (it can contain 4 lines separated<br />

with a semicolon).<br />

CONTENT<br />

the column expression.<br />

WIDTH the column width.<br />

DEC.<br />

the decimal length for numeric columns.<br />

TOTALS<br />

totals to be calculated, yes or no (usefull only for numeric<br />

columns).<br />

To navigate and to edit the table use the following keys:<br />

[ Up ]/[ Down ]/[ Left ][ Right ] move the cursor one position (up, down, left or right);<br />

[ PgUp ] move to previous screen page;<br />

[ PgDn ] move to next screen page;<br />

[ Ctrl+PgUp ] move to top <strong>of</strong> table;<br />

[ Ctrl+PgDn ] move to bottom <strong>of</strong> table;<br />

[ Ctrl+Home ] move to first column;<br />

[ Ctrl+End ] move to last column;<br />

[ Ctrl+Enter ] append a new empty line;<br />

[ Ctrl+F1 ]<br />

delete (cut) the current line and save a copy into the "clipboard";<br />

[ Ctrl+F2 ] copy current line into the table "clipboard";<br />

[ Ctrl+F3 ]<br />

insert (paste) the content <strong>of</strong> the "clipboard" in the current<br />

position;<br />

[ Enter ] start editing in the current position;<br />

[ Esc ] terminate;<br />

[ x ] any other key will be written in the current position.<br />

When the editing is terminated, press [ Esc ] and a dialog box will ask for the name to give<br />

to the report form file.<br />

Modify report<br />

This function permits you to modify a standard report form file (.FRM under the dBaseIII


184 volume VIII Argomenti avanzati e accessori<br />

standard).<br />

Report form<br />

This function permits you to print a report form with the data provided by the active alias.<br />

The following data is required.<br />

REPORT FORM FILENAME the label filename.<br />

WHILE<br />

the WHILE condition: the form printing goes on as long<br />

as this condition remain True.<br />

FOR<br />

the FOR condition: only the records from the active alias<br />

that satisfy the condition are used for the report form print.<br />

Create/modify/print text<br />

This function activates the text editor.<br />

368.6.4 Menu HTF<br />

The menu Htf helps on creating and accessing the "Help Text Files". This name, help text file, is<br />

just the name given to it.<br />

A text (Ascii) file prepared like this manual may be transformed into a "Help Text File" that is a<br />

simple text with pointers.<br />

Open help text file<br />

This function permits to open a Help Text File and browse it. The Help Text File name is<br />

required.<br />

New help text file<br />

This function permits to create a new "Help Text File" that is a help file under the nB style.<br />

The source is an Ascii file where three kind <strong>of</strong> information are available: Normal text,<br />

<strong>Index</strong>es and pointers.<br />

<strong>Index</strong>es and Pointers are word or phrases delimited with user defined delimiters; indexes<br />

are placed inside the text to indicate an argument, pointers are placed inside the text to<br />

indicate a reference to indexes.<br />

Inside this manual, indexes are delimited with ## and ##, so the titles are here indexes;<br />

pointers are delimited with < and >.<br />

Only one index per line is allowed, only one pointer per line is allowed.<br />

The Delimiters used do identify indexes and pointers are user defined; the _start_ identifier<br />

symbol can be equal to the _end_ identifier symbol. The symbols used for indexes cannot<br />

be used for the pointers.<br />

So, the informations required are:<br />

SOURCE TEXT FILENAME the filename <strong>of</strong> the text source file.<br />

DESTINATION FILENAME<br />

the filename <strong>of</strong> the destination Help Text File (suggested<br />

‘.HLP’ extention).<br />

INDEX START CODE<br />

the index start symbol; suggested ##.<br />

INDEX END CODE<br />

the index end symbol; suggested ##.<br />

POINTER START CODE<br />

the pointer start symbol; suggested .


nanoBase 1997 user manual 185<br />

New HTML file<br />

This function permits to create a new HTML file form a text file formatted to obtain a HTF<br />

file.<br />

The informations required are:<br />

SOURCE TEXT FILENAME the filename <strong>of</strong> the text source file.<br />

DESTINATION FILENAME<br />

the filename <strong>of</strong> the destination Help Text File (suggested<br />

‘.HLP’ extention).<br />

INDEX START CODE<br />

the index start symbol; suggested ##.<br />

INDEX END CODE<br />

the index end symbol; suggested ##.<br />

POINTER START CODE<br />

the pointer start symbol; suggested .<br />

HTML TITLE the title for the html page.<br />

368.6.5 Menu Macro<br />

The menu Macro helps on creating macros (programs) with a macro recorder, a macro "compiler"<br />

and a macro executor.<br />

Start recording<br />

This function simply starts or pause the macro recording. The menu items that end with<br />

"&", may be recorded by this macro recorder.<br />

Save recording<br />

A recorded macro may be saved into a ASCII file that may be later modified or simply used<br />

as it is. The filename is requested.<br />

Erase recording<br />

While recording or when the macro recorder is paused, it is possible to erase all previous<br />

recording with this function.<br />

Edit recording<br />

While recording or when the macro recorder is paused, it is possible to edit all previous<br />

recording, for example adding more comments or simply to see what the recorder does.<br />

Macro compilation<br />

A macro file (a program) contained inside a ASCII file, may be compiled into a different<br />

file format to speed up execution. The source filename and the destination filename are<br />

requested.<br />

Load + execute macro<br />

A macro file (a program) in ASCII form or compiled, may be executed.<br />

A macro file may require some parameters.<br />

This function asks for the macro filename to start and the possible parameter to pass to it.


186 volume VIII Argomenti avanzati e accessori<br />

368.6.6 Menu Info<br />

The menu Info is the information menu.<br />

ABOUT<br />

a brief copyright notice.<br />

starts the browse <strong>of</strong> ‘NB.HLP’ , the nB Help Text File manual<br />

MANUAL BROWSE<br />

if it is present in the current directory or it is found in the<br />

PATH (the Dos SET PATH).<br />

[F1] HELP [F1] reminder.<br />

[F3] ALIAS INFO<br />

[F3] reminder. It shows all the available information on the<br />

active alias.<br />

[F5] SET OUTPUT TO [F5] reminder. It defines the output peripheral or file.<br />

368.6.7 Menu Doc<br />

This menu actually appears only inside the DOC() function, the nB text editor.<br />

New<br />

Open<br />

Save<br />

Save as<br />

It starts the editing <strong>of</strong> a new empty text.<br />

It opens for editing a new textfile.<br />

It saves the text file under editing.<br />

It saves the text file under editing asking for a new name.<br />

Set output to<br />

It permits to change the default output peripheral: the default is the screen.<br />

Print as it is<br />

It prints on the output peripheral the content <strong>of</strong> the text as it is.<br />

Print with RPT() once<br />

It prints on the output peripheral the content <strong>of</strong> the text only once replacing possible text<br />

variables.<br />

Print with RPT() std<br />

It prints on the output peripheral the content <strong>of</strong> the text repeating this print for every record<br />

contained inside the archive alias.<br />

Exit DOC()<br />

Terminates the use <strong>of</strong> DOC() the text/document editing/print function.


nanoBase 1997 user manual 187<br />

368.7 The text editor DOC()<br />

The function Doc() activates a simple text editor usefull to build some simple reports.<br />

Inside this function a menu is available and is activated pressing [ Alt+M ] or [ F10 ]. The Doc()<br />

menu is part <strong>of</strong> the nB menu system.<br />

DOC() may handle text files <strong>of</strong> a teorical maximum <strong>of</strong> 64K.<br />

DOC() may be particularly useful to create formatted text with variables identified by CHR(174)<br />

and CHR(175) delimiters: when an active alias exists, [ F2 ] gives a list <strong>of</strong> insertable fields.<br />

[ Esc ] Exit DOC().<br />

[ F1 ] Call the help.<br />

[ F2 ] Field list.<br />

[ up ] / [ Ctrl+E ] Line up.<br />

[ down ] / [ Ctrl+X ] Line down.<br />

[ left ] / [ Ctrl+S ] Character left.<br />

[ right ] / [ Ctrl+D ] Character right.<br />

[ Ctrl+right ] / [ Ctrl+A ] Word left.<br />

[ Ctrl+left ] / [ Ctrl+F ] Word right.<br />

[ Home ] Line start.<br />

[ End ] Line end.<br />

[ Ctrl+Home ] Top window.<br />

[ Ctrl+End ] Bottom window.<br />

[ PgUp ] Previous window.<br />

[ PgDn ] Next window.<br />

[ Ctrl+PgUp ] Document start.<br />

[ Ctrl+PgDn ] End document.<br />

[ Del ] Delete character (right).<br />

[ Backspace ] Delete character Left.<br />

[ Tab ] Insert tab.<br />

[ Ins ] Toggle insert/overwrite.<br />

[ Enter ] Next line.<br />

[ Ctrl+Y ] Delete line.<br />

[ Ctrl+T ] Delete word right.<br />

[ F10 ] / [ Alt+M ] DOC() menu.<br />

368.8 The help text file<br />

nB provides a basic hypertext system to build simple help files. A source text file with "indexes"<br />

and "pointers" to indexes is translated into a "help text file" (a ‘.DBF’ file); then, this file is<br />

browsed by nB.<br />

The source file can have a maximum line width <strong>of</strong> 80 characters; each line can terminate with<br />

CR or CR+LF.<br />

"<strong>Index</strong>es" are string delimited by index delimiters (default "##"); "pointers" are string delimited<br />

by pointer delimiters (default "") and refers to indexes.<br />

Inside a text, indexes must be unique; pointers can be repeated anywhere. A text can contain a<br />

maximum <strong>of</strong> 4000 indexes.<br />

Inside this manual, titles are delimited with "##" as they are indexes; strings delimited with "" identify a reference to a title with the same string.


188 volume VIII Argomenti avanzati e accessori<br />

To browse a previously created Help Text File, use the following keys:<br />

[ Esc ] Exit.<br />

[ UpArrow ] Move cursor up.<br />

[ DownArrow ] Move cursor down.<br />

[ PgUp ] Move cursor PageUp.<br />

[ PgDn ] Move cursor Pagedown.<br />

[ Ctrl+PgUp ] Move cursor Top.<br />

[ Ctrl+PgDn ] Move cursor Bottom.<br />

[ Enter ] Select a reference (pointer).<br />

[ ] Go to next selected reference (pointer).<br />

[ Shift+F3 ] Search for a new pattern.<br />

[ F3 ] Repeat previous search.<br />

368.9 Macro<br />

nB can execute (run) macro files. There may be three kind <strong>of</strong> macro files: ASCII (usually with<br />

.& extention); "compiled" (usually with .NB extention); EXE files (compiled with Clipper and<br />

linked).<br />

"Compiled" macro files are executed faster then the ASCII source files.<br />

EXE macro files are the fastest.<br />

368.9.1 Macro statements<br />

The statements recognised from nB are very similar to Clipper, with some restrictions.<br />

Note that: the FOR statement is not included; there is no function declaration; procedure calls<br />

cannot transfer variables; only public variables are allowed.<br />

PROCEDURE<br />

Procedures are the basic building blocks <strong>of</strong> a nB macro.<br />

Procedures are visible only inside the current macro file.<br />

The procedure structure is as follows:<br />

PROCEDURE procedure_name<br />

statements...<br />

[RETURN]<br />

statements...<br />

ENDPROCEDURE<br />

A procedure definition begins with a PROCEDURE declaration followed with the<br />

procedure_name and ends with ENDPROCEDURE.<br />

Inside the PROCEDURE - ENDPROCEDURE declaration are placed the executable<br />

statements which are executed when the procedure is called.<br />

Inside the PROCEDURE - ENDPROCEDURE declaration, the RETURN statement may<br />

appear. In this case, encountering this RETURN statement, the procedure execution is immediately<br />

terminated and control is passed to the statement following the calling one.<br />

The procedure definition do not permit to receive parameters from the calling statement.


nanoBase 1997 user manual 189<br />

DO PROCEDURE<br />

There is only one way to call a procedure:<br />

DO PROCEDURE procedure_name<br />

When the statement DO PROCEDURE is encountered, the control is passed to the begin <strong>of</strong><br />

the called PROCEDURE. After the PROCEDURE execution, the control is returned to the<br />

statement following DO PROCEDURE.<br />

The procedure call do not permit to send parameters to the procedure.<br />

BEGIN SEQUENCE<br />

The BEGIN SEQUENCE - END structure permits to define a sequence <strong>of</strong> operation that<br />

may be broken.<br />

Inside nB, this control structure is useful only because there is the possibility to break the<br />

execution and pass control over the end <strong>of</strong> it.<br />

This way, encountering BREAK means: "go to end".<br />

BEGIN SEQUENCE<br />

statements...<br />

[BREAK]<br />

statements...<br />

END<br />

Inside nB, error exception handling is not supported.<br />

DO CASE<br />

This is a control structure where only the statements following a True CASE condition are<br />

executed.<br />

When the DO CASE statement is encountered, the following CASE statements are tested.<br />

The first time that a condition returns True, the CASE’s statements are executed and then<br />

control is passed over the END case.<br />

That is: only one CASE is taken into consideration.<br />

If no condition is True, the statements following OTHERWISE are executed.<br />

DO CASE<br />

CASE lCondition1<br />

statements...<br />

[CASE <strong>lCondition2</strong>]<br />

statements...<br />

[OTHERWISE]<br />

statements...<br />

END<br />

WHILE<br />

The structure WHILE - END defines a loop based on a condition: the loop is repeated until<br />

the condition is True.<br />

The loop execution may be broken with the EXIT statement: it transfer control after the<br />

END while.<br />

The LOOP statement may be use to repeat the loop: it transfer the control to the beginning<br />

<strong>of</strong> the loop.<br />

WHILE lCondition<br />

statements...<br />

[EXIT]<br />

statements...<br />

[LOOP]<br />

statements...<br />

END


190 volume VIII Argomenti avanzati e accessori<br />

IF<br />

The IF - END control structure executes a section <strong>of</strong> code if a specified condition is True.<br />

The structure can also specify alternative code to execute if the condition is False.<br />

IF lCondition1<br />

statements...<br />

[ELSE]<br />

statements...<br />

END<br />

368.9.2 Variable declaration<br />

Inside nB, variables are created using a specific function:<br />

MEMPUBLIC( "cVarName" )<br />

For example,<br />

MEMPUBLIC( "Name" )<br />

creates the variable Name.<br />

The scope <strong>of</strong> the created variable is global and there is no way to restrict the visibility <strong>of</strong> it.<br />

When a variable is no more needed or desired, it can be released:<br />

MEMRELEASE( "cVarName" )<br />

The variable declaration do not defines the variable type. Every variable may receive any kind <strong>of</strong><br />

data; that is that the type depends on the type <strong>of</strong> data contained.<br />

368.9.3 Macro structure<br />

A nB macro must be organised as follow. There may be two situations: Macros with procedures<br />

and macros without procedures.<br />

Macro with procedures:<br />

PROCEDURE procedure_name_1<br />

statements...<br />

[RETURN]<br />

statements...<br />

ENDPROCEDURE<br />

PROCEDURE procedure_name_2<br />

statements...<br />

[RETURN]<br />

statements...<br />

ENDPROCEDURE<br />

...<br />

...<br />

DO PROCEDURE procedure_name_n<br />

Macro without procedures:<br />

statements...<br />

statements...<br />

statements...<br />

statements...<br />

statements...<br />

nB Macros may be compiled with Clipper. To do so, the first structure example must be changed<br />

as follows:


nanoBase 1997 user manual 191<br />

#INCLUDE MACRO.CH<br />

DO PROCEDURE procedure_name_nth<br />

...<br />

PROCEDURE procedure_name_1<br />

statements...<br />

[RETURN]<br />

statements...<br />

ENDPROCEDURE<br />

PROCEDURE procedure_name_2<br />

statements...<br />

[RETURN]<br />

statements...<br />

ENDPROCEDURE<br />

...<br />

...<br />

To compile a macro with Clipper, the macro file name can be changed into ‘MACRO.PRG’ and<br />

RTLINK MACRO.RMK [Enter]<br />

should be started.<br />

368.9.4 Macro comments<br />

A nB Macro source file can contain comments. only the "//" comment is recognised! This way:<br />

* and /*...*/ will generate errors!<br />

ATTENTION: to simplify the macro interpretation, lines such as this:<br />

qqout( "You can’t do that // you can’t do that!" )<br />

will generate an error as the interpreter will read only:<br />

qqout( "You can’t do that<br />

Sorry!<br />

368.9.5 Macro long lines split<br />

Inside a nB macro, long lines may be splitted using ";" (semicolon). Please note that: lines can<br />

only be splitted and not joined; a resulting command line cannot be longer then 254 characters.<br />

368.9.6 The macro recorder<br />

Inside the functions ASSIST() and DOC() is available the Macro recorder menu.<br />

When a macro recording is started, a "&" appears on the left side <strong>of</strong> the status bar. It it blinks, the<br />

recording is active, if it is stable, the recording is paused.<br />

The macro recording is not exactly a step-by-step recording <strong>of</strong> all action taken, but a translation<br />

(as good as possible) <strong>of</strong> what you have done.


192 volume VIII Argomenti avanzati e accessori<br />

The macro recorder is able to record only the menu functions that terminates with the "&" symbol<br />

and all what is inserted at the dot command line.<br />

The macro recording can be viewed and edited during the recording. The macro recording can<br />

be saved into a text file (a macro file).<br />

368.10 Data types<br />

The data types supported in the nB macro language are the same as Clipper:<br />

Array<br />

Character<br />

Code Block<br />

Numeric<br />

Date<br />

Logical<br />

Memo<br />

NIL<br />

368.10.1 Character<br />

The character data type identifies character strings <strong>of</strong> a fixed length. The character set corresponds<br />

to: CHR(32) through CHR(255) and the null character, CHR(0).<br />

Valid character strings consist <strong>of</strong> zero or more characters with a theoretical maximum <strong>of</strong> 65535<br />

characters. The real maximum dimension depends on the available memory.<br />

Character string constants are formed by enclosing a valid string <strong>of</strong> characters within a designed<br />

pair <strong>of</strong> delimiters. There are three possible delimiter pairs:<br />

two single quotes like ‘’string_constant’’;<br />

two double quotes like ‘"string_constant"’;<br />

left and right square brackets like ‘[string_constant]’.<br />

These three different kind <strong>of</strong> delimiters are available to resolve some possible problems:<br />

I don’t want it -> "I don’t want it"<br />

She said, "I love hin" -> ’She said, "I love hin"’<br />

He said, "I don’t want it" -> [He said, "I don’t want it"]<br />

The following table shows all operations available inside nB for character data types. These<br />

operations act on one or more character expressions and the result is not necessarily a character<br />

data type.<br />

+ Concatenate.<br />

- Concatenate without intervening spaces.<br />

== Compare for exact equity.<br />

!=, , # Compare for inequity.<br />

< Compare for sorts before


nanoBase 1997 user manual 193<br />

Compare for sorts after.<br />

>= Compare for sorts after or same as.<br />

:= In line assign.<br />

$ Test for substring existence.<br />

ALLTRIM() Remove leading and trailing spaces.<br />

ASC() Convert to numeric ASCII code equivalent.<br />

AT() Locate substring position.<br />

CTOD() Convert to date.<br />

DESCEND() Convert to complemented form.<br />

EMPTY() Test for null or blank string.<br />

ISALPHA() Test for initial letter.<br />

ISDIGIT() Test for initial digit.<br />

ISLOWER() Test for initial lowercase letter.<br />

ISUPPER() Test for initial uppercase letter.<br />

LEFT() Extract substring form the left.<br />

LEN() Compute string length in characters.<br />

LOWER() Convert letters to lowercase.<br />

LTRIM() Remove leading spaces.<br />

PADC() Pad with leading and trailing spaces.<br />

PADL() Pad with leading spaces.<br />

PADR() Pad with trailing spaces.<br />

RAT() Locate substring position starting from the right.<br />

RIGHT() Extract substring form the right.<br />

RTRIM() Remove trailing spaces.<br />

SOUNDEX() Convert to soundex equivalent.<br />

SPACE() Create a blank string <strong>of</strong> a defined length.<br />

STRTRAN() Search and replace substring.<br />

STUFF() Replace substring.<br />

SUBSTR() Extract substring.<br />

TRANSFORM() Convert to formatted string.<br />

UPPER() Convert letters to uppercase<br />

VAL() Convert to numeric.<br />

VALTYPE() Evaluates data type directly.<br />

368.10.2 Memo<br />

The memo data type is used to represent variable length character data that can only exist in the<br />

form <strong>of</strong> a database field.<br />

Memo fields are not stored inside the main database file (.DBF) but inside a separate file (.DBT).<br />

A memo field can contain up to 65535 characters, that is the same maximum dimension <strong>of</strong> character<br />

fields. In fact, originally xBases, couldn’t have character string longer than 254 characters.<br />

As here memo fields are very similar to long character strings, you may forget that there is a<br />

difference.<br />

All the operations that may be applied to character strings, may be used with memo fields; the<br />

following functions may be use especially for memo fields or long character strings.<br />

HARDCR() Replace s<strong>of</strong>t with hard carriage returns.<br />

MEMOEDIT() Edit contents.<br />

MEMOLINE() Extract a line <strong>of</strong> a text.


194 volume VIII Argomenti avanzati e accessori<br />

MEMOREAD() Read form a disk text file.<br />

MEMOTRAN() Replace s<strong>of</strong>t and hard carriage returns.<br />

MEMOWRIT() Write to disk text file.<br />

MLCOUNT() Count lines.<br />

MLPOS() Compute position.<br />

368.10.3 Date<br />

The date data type is used to represent calendar dates.<br />

Supported dates are from 0100.01.01 to 2999.12.31 and null or blank date.<br />

The appearance <strong>of</strong> a date is controlled from SETVERB("DATEFORMAT"). The default is<br />

"dd/mm/yyyy" and it may easily changed for example with SETVERB("DATEFORMAT",<br />

"MM/DD/YYYY") to the US standard.<br />

There is no way to represent date constants; these must be replaced with the CTOD() function.<br />

For example if the date 11/11/1995 is to be written, the right way is:<br />

CTOD( "11/11/1995" )<br />

The character string "11/11/1995" must respect the date format defined as before explained.<br />

The function CTOD() will accept only valid dates, and null dates:<br />

CTOD( "" )<br />

A null date is ever less than any other valid date.<br />

The following table shows all operations available inside nB for date data types. These operations<br />

act on one or more date expressions and the result is not necessarily a character data type.<br />

+ Add a number <strong>of</strong> days to a date.<br />

- Subtract days to a date.<br />

== Compare for equity.<br />

!=, , # Compare for inequity.<br />

< Compare for earlier<br />

Compare for later.<br />

>= Compare for later or same as.<br />

:= In line assign.<br />

CDOW() Compute day <strong>of</strong> week name.<br />

CMONTH() Compute month name.<br />

DAY() Extract day number.<br />

DESCEND() Convert to complemented form.<br />

DOW() Compute day <strong>of</strong> week.<br />

DTOC()<br />

Convert to character string with the format defined with<br />

SETVERB( "DATEFORMAT" ).<br />

DOTOS() Convert to character string in sorting format (YYYYMMDD).<br />

EMPTY() Test for null date.<br />

MONTH() Extract month number.<br />

VALTYPE() Evaluates data type directly.<br />

YEAR() Extract entire year number, including century.


nanoBase 1997 user manual 195<br />

368.10.4 Numeric<br />

The numeric data type identifies real number. The theoretical range is form 10^-308 to 10^308<br />

but the numeric precision is guaranteed up to 16 significant digits, and formatting a numeric<br />

value for display is guaranteed up to a length <strong>of</strong> 32 (30 digits, a sign, and a decimal point). That<br />

is: numbers longer than 32 bytes may be displayed as asterisks, and digits other then most 16<br />

significant ones are displayed as zeroes.<br />

Numeric constants are written without delimiters. The following are valid constant numbers:<br />

12345<br />

12345.678<br />

-156<br />

+1256.789<br />

-.789<br />

If a numeric constant is delimited like character strings, it becomes a character string.<br />

The following table shows all operations available inside nB for numeric data types. These operations<br />

act on one or more numeric expressions and the result is not necessarily a numeric data<br />

type.<br />

+ Add or Unary Positive.<br />

- Subtract or Unary Negative.<br />

*<br />

Multiply.<br />

/ Divide.<br />

% Modulus.<br />

^, ** Exponentiate.<br />

== Compare for equity.<br />

!=, , # Compare for inequity.<br />

< Compare for less than.<br />

>= Compare for less than or equal.<br />

> Compare for greater than.<br />

>= Compare for greater than or equal.<br />

:= In line assign.<br />

ABS() Compute absolute value.<br />

CHR() Convert to ASCII character equivalent.<br />

DESCEND() Convert to complemented form.<br />

EMPTY() Test for zero.<br />

EXP() Exponentiate with e as the base.<br />

INT() Convert to integer.<br />

LOG() Compute natural logarithm.<br />

MAX() Compute maximum.<br />

MIN() Compute minimum.<br />

ROUND() Round up or down()<br />

SQRT() Compute square root.<br />

STR() Convert to character.<br />

TRANSFORM() Convert to formatted string.<br />

VALTYPE() Evaluates data type directly.<br />

Number appearence may be affected by SETVERB("FIXED") and consequently by<br />

SETVERB("DECIMALS"). If SETVERB("FIXED") is True, numbers are displayed with a fixed<br />

decimal position. The number <strong>of</strong> decimal positions is defined by SETVERB("DECIMALS"). For


196 volume VIII Argomenti avanzati e accessori<br />

that reason, the default is SETVERB("FIXED", .F.) and SETVERB("DECIMALS", 2), that is,<br />

no fixed decimal position, but if they will be activated, the default is two decimal digits.<br />

368.10.5 Logical<br />

The logical data type identifies Boolean values.<br />

Logical constants are:<br />

‘.T.’ True.<br />

‘.F.’ False.<br />

When editing a logical field, inputs may be:<br />

y, Y, t, T for True<br />

n, N, f, F for False<br />

The following table shows all operations available inside nB for logical data types. These operations<br />

act on one or more logical expressions and the result is not necessarily a logical data<br />

type.<br />

.AND. And.<br />

.OR. Or.<br />

.NOT. or !<br />

Negate.<br />

== Compare for equity.<br />

!=, , or # Compare for inequity.<br />

Comparing two logical values, False (‘.F.’) is always less than True (‘.T.’).<br />

368.10.6 NIL<br />

NIL is not properly a data type, it represent the value <strong>of</strong> an uninitialised variable.<br />

Inside nB (like what it happens inside Clipper), variables are not declared with the data type that<br />

they will contain. This means that a variable can contain any kind <strong>of</strong> data. In fact, nB variables<br />

are pointer to data and a pointer to "nothing" is NIL.<br />

NIL may be used as constant for assignment or comparing purpose:<br />

NIL<br />

Fields (database fields) cannot contain NIL.<br />

The following table shows all operations available inside nB for the NIL data type. Except for<br />

these operations, attempting to operate on a NIL results in a runtime error.<br />

== Compare for equity.<br />

!=, , # Compare for inequity.<br />

< Compare for less than.<br />

Compare for greater than.<br />

>= Compare for greater than or equal.<br />

:= In line assign.<br />

EMPTY() Test for NIL.<br />

VALTYPE() Evaluates data type directly.


nanoBase 1997 user manual 197<br />

For the purpose <strong>of</strong> comparison, NIL is the only value that is equal to NIL. All other values are<br />

greater than NIL.<br />

Variables are created inside nB with MEMPUBLIC(). This function creates variables which will<br />

be automatically initialised to NIL.<br />

368.10.7 Array<br />

The array data type identifies a collection <strong>of</strong> related data items that share the same name. Each<br />

value in an array is referred to as an element.<br />

Array elements can be <strong>of</strong> any data type except memo (memo is available only inside database<br />

fields). For example the first element can be a character string, the second a number, the third a<br />

date and so on. Arrays can contain other arrays and code blocks as elements.<br />

The variable containing the array does not contains the entire array, but the reference to it.<br />

When the NIL type was described, it was cleared that variables doesn’t contains real data,<br />

but pointer to data. But this happens in a transparent way, that is that when the a variable is<br />

assigned to another (for example A := B) the variable receiving the assignment will receive<br />

a pointer to a new copy <strong>of</strong> the source data. This is not the same with arrays: assigning to a<br />

variable an array, will assign to that variable a pointer to the same source array and not to a<br />

new copy <strong>of</strong> it.<br />

If arrays are to be duplicated, the ACLONE() function is to be used.<br />

An array constant may be expressed using curly brackets {}. See the examples below.<br />

A := { "first_element", "second_element", "third_element" }<br />

With this example, the variable A contain the reference to an array with three element containing<br />

character string.<br />

A[1] == "first_element"<br />

A[2] == "second_element"<br />

A[3] == "third_element"<br />

Arrays may contain also no element: empty array and may be expressed as:<br />

{}<br />

The array element is identified by a number enclosed with square brackets, following the variable<br />

name containing the reference to the array. The first array element is one.<br />

If an array contains arrays, we obtain a multidimensional array. For example:<br />

A := { { 1, 2 }, { 3, 4 }, { 5, 6 } }<br />

is equivalent to the following table.<br />

1 2<br />

3 4<br />

5 6


198 volume VIII Argomenti avanzati e accessori<br />

With this example, the variable A contain the reference to a bidimensional array containing numbers.<br />

A[1,1] or A[1][1] contains 1<br />

A[1,2] or A[1][2] contains 2<br />

A[2,1] or A[2][1] contains 3<br />

and so on.<br />

As arrays may contain mixed data, it is the user who have to handle correctly the element numbers.<br />

For example:<br />

A := { "hello", { 3, 4 }, 1234 }<br />

A[1] == "hello"<br />

A[2] == reference to { 3, 4 }<br />

A[3] == 1234<br />

A[2,1] or A[2][1] contains 3<br />

A[2,2] or A[2][2] contains 4<br />

A[1,1] is an error!<br />

The following table shows all operations available inside nB for arrays.<br />

:= In line assign.<br />

AADD() Add dynamically an element to an array.<br />

ACLONE() Create a copy <strong>of</strong> an array.<br />

ACOPY() Copy element by element an array to another.<br />

ADEL() Delete one element inside an array.<br />

AFILL() Fill all array elements with a value.<br />

AINS() Insert an element inside an array.<br />

ARRAY() Creates an array <strong>of</strong> empty elements.<br />

ASCAN() Scan the array elements.<br />

ASIZE() Resize an array.<br />

ASORT() Sort the array elements.<br />

EMPTY() Test for no elements.<br />

VALTYPE() Evaluates data type directly.<br />

368.10.8 Code block<br />

The code block data type identifies a small piece <strong>of</strong> executable program code.<br />

A code block is something like a little user defined function where only a sequence <strong>of</strong> functions<br />

or assignments may appear: no loops, no IF ELSE END.<br />

A code block may receive argument and return a value after execution, just like a function.<br />

The syntax is:<br />

{ | [argument_list] | exp_list }<br />

That is: the argument_list is optional; the exp_list may contain one or more expressions separated<br />

with a comma.


nanoBase 1997 user manual 199<br />

For example, calling the following code block will give the string "hello world" as result.<br />

{ || "hello world" }<br />

The following code block require a numeric argument an returns the number passed as argument<br />

incremented:<br />

{ | n | n+1 }<br />

The following code block requires two numeric arguments and returns the sum <strong>of</strong> the two square<br />

radix:<br />

{ | nFirst, nSecond | SQRT(nFirst) + SQRT(nSecond) }<br />

But code blocks may contains more expressions and the result <strong>of</strong> the execution <strong>of</strong> the code block<br />

is the result <strong>of</strong> the last expression.<br />

The following code block executes in sequence some functions and give ever "hello world" as a<br />

result.<br />

{ | a, b | functionOne(a), functionTwo(b), "hello world" }<br />

To start the execution <strong>of</strong> a code block a function is used: EVAL()<br />

For example, a code block is assigned to a variable and then executed.<br />

B := { || "hello world" }<br />

EVAL( B ) == "hello world"<br />

Another example with a parameter.<br />

B := { | n | n+1 }<br />

EVAL( B, 1 ) == 2<br />

Another example with two parameters.<br />

B := { | nFirst, nSecond | SQRT(nFirst) + SQRT(nSecond) }<br />

EVAL( B, 2, 4 ) == 20<br />

And so on.<br />

The following table shows some operations available inside nB for code blocks: many functions<br />

use code blocks as argument.<br />

:= In line assign.<br />

AEVAL() Evaluate (execute) a code block for each element in an array.<br />

BCOMPILE() Convert (compile) a character string into a code block.<br />

DBEVAL()<br />

Evaluate (execute) a code block for each record in the active<br />

alias.<br />

EVAL() Evaluate a code block once.<br />

VALTYPE() Evaluates data type directly.


200 volume VIII Argomenti avanzati e accessori<br />

368.11 Operators<br />

Here is a list with a brief description <strong>of</strong> the operators available inside nB.<br />

cString1 $ cString2<br />

Substring comparison.<br />

If cString1 is contained inside cString2 the result is true (‘.T.’).<br />

nNumber1 % nNumber2<br />

Modulus.<br />

The result is the remainder <strong>of</strong> nNumber1 divided by nNuber2.<br />

()<br />

Function or grouping indicator.<br />

nNumber1 * nNumber2<br />

Multiplication.<br />

nNumber1 ** nNumber2<br />

nNumber1 ^ nNumber2<br />

Exponentiation.<br />

nNumber1 + nNumber2<br />

dDate + nNumber<br />

Addition, unary positive.<br />

cString1 + cString2<br />

String concatenation.<br />

The result is a string beginning with the content <strong>of</strong> cString1 and following with the content <strong>of</strong><br />

cString2.<br />

nNumber1 - nNumber2<br />

dDate1 - dDate2<br />

dDate - nNumber<br />

Subtraction, unary negative.<br />

cString1 - cString2<br />

String concatenation.<br />

The result is a string containing cString1 after trimming trailing blanks and cString2.<br />

idAlias->idField<br />

FIELD->idVar<br />

MEMVAR->idVar<br />

Alias assignment.<br />

The alias operator implicitly SELECTs the idAlias before evaluating idField. When the evaluation<br />

is complete, the original work area is SELECTed again.<br />

lCondition1 .AND. <strong>lCondition2</strong><br />

Logical AND.<br />

.NOT. lCondition


nanoBase 1997 user manual 201<br />

Logical NOT.<br />

lCondition1 .OR. <strong>lCondition2</strong><br />

Logical OR.<br />

nNumber1 / nNumber2<br />

Division.<br />

object:message[(argument list)]<br />

Send.<br />

idVar := exp<br />

Inline assign.<br />

exp1 exp2<br />

Greater than.<br />

exp1 >= exp2<br />

Greater than or equal.<br />

@idVar<br />

Pass-by-reference.<br />

[]<br />

aArray[nSubscript, ...]<br />

aArray[nSubscript1][nSubscript2] ...<br />

Array element indicator.<br />

368.12 Delimiters<br />

Here is the delimiter list recognised from nB.<br />

{ exp_list }<br />

Literal array delimiters.<br />

{ |param_list| exp_list }<br />

Code block delimiters.<br />

"cString"<br />

’cString’<br />

[cString]


202 volume VIII Argomenti avanzati e accessori<br />

String delimiters.<br />

368.13 Code blocks<br />

A code block is a sequence <strong>of</strong> function, assignments and constant like the following:<br />

sqrt(10)<br />

nResult := 10 * n<strong>Index</strong><br />

Suppose that the above sequence <strong>of</strong> operations has a meaning for you. We want to create a box<br />

containing this sequence <strong>of</strong> operation. This box is contained inside a variable:<br />

bBlackBox := { || sqrt(10), nResult := 10 * n<strong>Index</strong> }<br />

Note the comma used as separator.<br />

Now bBlackBox contains the small sequence seen before. To execute this sequence, the function<br />

EVAL() is used:<br />

EVAL(bBlackBox)<br />

The execution <strong>of</strong> the code block gives a result: the value <strong>of</strong> the last operation contained inside<br />

the code block. In this case it is the result <strong>of</strong> 10*n<strong>Index</strong>. For that reason, if the execution <strong>of</strong> the<br />

code block must give a fixed result, it can terminate with a constant.<br />

A code block may receive parameters working like a function. Try to imagine that we need to do<br />

the following.<br />

function multiply( nVar1, nVar2 )<br />

return nVar * nVar2<br />

endfunction<br />

A code block that does the same is:<br />

bMultiply := { | nVar1, nVar2 | nVar1 * nVar2 }<br />

To evaluate it, for example trying to multiply 10 * 5:<br />

nResult := EVAL( bMultiply, 10, 5 )<br />

and nResult will contain 50.<br />

368.14 Standard functions<br />

With nB all Clipper standard functions may be used. Here follows a short description.<br />

368.14.1 AADD()<br />

Array add<br />

AADD(aTarget, expValue) ⇒ Value<br />

aTarget is the array to add a new element to.<br />

expValue is the value assigned to the new element.<br />

It increases the actual length <strong>of</strong> the target array by one. The newly created array element is


nanoBase 1997 user manual 203<br />

assigned the value specified by expValue.<br />

368.14.2 ABS()<br />

Absolute<br />

ABS(nExp) ⇒ nPositive<br />

nExp is the numeric expression to evaluate.<br />

ABS() returns a number representing the absolute value <strong>of</strong> its argument.<br />

368.14.3 ACLONE()<br />

Array clone<br />

ACLONE(aSource) ⇒ aDuplicate<br />

aSource<br />

ACLONE() returns a duplicate <strong>of</strong> aSource.<br />

368.14.4 ACOPY()<br />

Array copy<br />

is the array to duplicate.<br />

ACOPY(aSource, aTarget,<br />

[nStart], [nCount], [nTargetPos]) ⇒ aTarget<br />

aSource<br />

is the array to copy elements from.<br />

aTarget is the array to copy elements to.<br />

is the starting element position in the aSource array. If not<br />

nStart<br />

specified, the default value is one.<br />

is the number <strong>of</strong> elements to copy from the aSource array<br />

beginning at the nStart position. If nCount is not specified,<br />

nCount<br />

all elements in aSource beginning with the starting element<br />

are copied.<br />

is the starting element position in the aTarget array to receive<br />

nTargetPos<br />

elements from aSource. If not specified, the default value is<br />

one.<br />

ACOPY() is an array function that copies elements from the aSource array to the aTarget array.<br />

The aTarget array must already exist and be large enough to hold the copied elements.


204 volume VIII Argomenti avanzati e accessori<br />

368.14.5 ADEL()<br />

Array delete<br />

ADEL(aTarget, nPosition) ⇒ aTarget<br />

aTarget is the array to delete an element from.<br />

nPosition<br />

is the position <strong>of</strong> the target array element to delete.<br />

ADEL() is an array function that deletes an element from an array. The contents <strong>of</strong> the specified<br />

array element is lost, and all elements from that position to the end <strong>of</strong> the array are shifted up one<br />

element. The last element in the array becomes NIL.<br />

368.14.6 AEVAL()<br />

Array evaluation<br />

AEVAL(aArray, bBlock,<br />

[nStart], [nCount]) ⇒ aArray<br />

aArray is the array to be evaluated.<br />

bBlock is a code block to execute for each element encountered.<br />

nStart<br />

is the starting element. If not specified, the default is element<br />

one.<br />

nCount<br />

is the number <strong>of</strong> elements to process from nStart. If not specified,<br />

the default is all elements to the end <strong>of</strong> the array.<br />

AEVAL() is an array function that evaluates a code block once for each element <strong>of</strong> an array,<br />

passing the element value and the element index as block parameters. The return value <strong>of</strong> the<br />

block is ignored. All elements in aArray are processed unless either the nStart or the nCount<br />

argument is specified.<br />

368.14.7 AFILL()<br />

Array fill<br />

AFILL(aTarget, expValue,<br />

[nStart], [nCount]) ⇒ aTarget<br />

aTarget is the array to fill.<br />

expValue<br />

is the value to place in each array element. It can be an expression<br />

<strong>of</strong> any valid data type.<br />

nStart<br />

is the position <strong>of</strong> the first element to fill. If this argument is<br />

omitted, the default value is one.<br />

is the number <strong>of</strong> elements to fill starting with element nStart.<br />

nCount<br />

If this argument is omitted, elements are filled from the starting<br />

element position to the end <strong>of</strong> the array.<br />

AFILL() is an array function that fills the specified array with a single value <strong>of</strong> any data type<br />

(including an array, code block, or NIL) by assigning expValue to each array element in the<br />

specified range.


nanoBase 1997 user manual 205<br />

368.14.8 AINS()<br />

Array insert<br />

AINS(aTarget, nPosition) ⇒ aTarget<br />

aTarget is the array into which a new element will be inserted.<br />

nPosition<br />

is the position at which the new element will be inserted.<br />

AINS() is an array function that inserts a new element into a specified array. The newly inserted<br />

element is NIL data type until a new value is assigned to it. After the insertion, the last element<br />

in the array is discarded, and all elements after the new element are shifted down one position.<br />

368.14.9 ALERT()<br />

ALERT( cMessage, [aOptions] ) ⇒ nChoice<br />

is the message text displayed, centered, in the alert box. If the<br />

cMessage<br />

message contains one or more semicolons, the text after the<br />

semicolons is centered on succeeding lines in the dialog box.<br />

aOptions defines a list <strong>of</strong> up to 4 possible responses to the dialog box.<br />

ALERT() returns a numeric value indicating which option was chosen. If the Esc key is pressed,<br />

the value returned is zero. The ALERT() function creates a simple modal dialog. The user can<br />

respond by moving a highlight bar and pressing the Return or SpaceBar keys, or by pressing<br />

the key corresponding to the first letter <strong>of</strong> the option. If aOptions is not supplied, a single "Ok"<br />

option is presented.<br />

368.14.10 ALIAS()<br />

ALIAS([nWorkArea]) ⇒ cAlias<br />

nWorkArea<br />

is any work area number.<br />

ALIAS() returns the alias <strong>of</strong> the specified work area as a character string. If nWorkArea is not<br />

specified, the alias <strong>of</strong> the current work area is returned. If there is no database file in USE for the<br />

specified work area, ALIAS() returns a null string ("").<br />

368.14.11 ALLTRIM()<br />

ALLTRIM(cString) ⇒ cTrimmedString<br />

cString is the character expression to trim.<br />

ALLTRIM() returns a character string with leading and trailing spaces removed.


206 volume VIII Argomenti avanzati e accessori<br />

368.14.12 ARRAY()<br />

ARRAY(nElements [, nElements...]) ⇒ aArray<br />

nElements<br />

is the number <strong>of</strong> elements in the specified dimension.<br />

ARRAY() is an array function that returns an uninitialized array with the specified number <strong>of</strong><br />

elements and dimensions.<br />

368.14.13 ASC()<br />

ASCII<br />

ASC(cExp) ⇒ nCode<br />

cExp is the character expression to convert to a number.<br />

ASC() returns an integer numeric value in the range <strong>of</strong> zero to 255 , representing the ASCII value<br />

<strong>of</strong> cExp.<br />

368.14.14 ASCAN()<br />

Array scan<br />

ASCAN(aTarget, expSearch,<br />

[nStart], [nCount]) ⇒ nStoppedAt<br />

aTarget is the array to scan.<br />

is either a simple value to scan for, or a code block. If<br />

expSearch<br />

expSearch is a simple value it can be character, date, logical,<br />

or numeric type.<br />

is the starting element <strong>of</strong> the scan. If this argument is not spec-<br />

nStart<br />

ified, the default starting position is one.<br />

is the number <strong>of</strong> elements to scan from the starting position.<br />

nCount<br />

If this argument is not specified, all elements from the starting<br />

element to the end <strong>of</strong> the array are scanned.<br />

ASCAN() returns a numeric value representing the array position <strong>of</strong> the last element scanned.<br />

If expSearch is a simple value, ASCAN() returns the position <strong>of</strong> the first matching element, or<br />

zero if a match is not found. If expSearch is a code block, ASCAN() returns the position <strong>of</strong> the<br />

element where the block returned true (‘.T.’).<br />

368.14.15 ASIZE()<br />

Array size<br />

ASIZE(aTarget, nLength) ⇒ aTarget<br />

aTarget is the array to grow or shrink.<br />

nLength is the new size <strong>of</strong> the array.


nanoBase 1997 user manual 207<br />

ASIZE() is an array function that changes the actual length <strong>of</strong> the aTarget array. The array is<br />

shortened or lengthened to match the specified length. If the array is shortened, elements at the<br />

end <strong>of</strong> the array are lost. If the array is lengthened, new elements are added to the end <strong>of</strong> the array<br />

and assigned NIL.<br />

368.14.16 ASORT()<br />

Array sort<br />

ASORT(aTarget, [nStart],<br />

[nCount], [bOrder]) ⇒ aTarget<br />

aTarget is the array to sort.<br />

nStart<br />

is the first element <strong>of</strong> the sort. If not specified, the default<br />

starting position is one.<br />

nCount<br />

is the number <strong>of</strong> elements to sort. If not specified, all elements<br />

in the array beginning with the starting element are sorted.<br />

bOrder<br />

is an optional code block used to determine sorting order. If<br />

not specified, the default order is ascending.<br />

ASORT() is an array function that sorts all or part <strong>of</strong> an array containing elements <strong>of</strong> a single data<br />

type. Data types that can be sorted include character, date, logical, and numeric. If the bOrder<br />

argument is not specified, the default order is ascending. Each time the block is evaluated, two<br />

elements from the target array are passed as block parameters. The block must return true (‘.T.’)<br />

if the elements are in sorted order.<br />

368.14.17 AT()<br />

AT(cSearch, cTarget) ⇒ nPosition<br />

cSearch<br />

is the character substring for which to search.<br />

cTarget is the character string to search.<br />

AT() returns the position <strong>of</strong> the first instance <strong>of</strong> cSearch within cTarget as an integer numeric<br />

value. If cSearch is not found, AT() returns zero.<br />

AT() is a character function used to determine the position <strong>of</strong> the first occurrence <strong>of</strong> a character<br />

substring within another string.<br />

368.14.18 ATAIL()<br />

Array TAIL<br />

ATAIL(aArray) ⇒ Element<br />

aArray is the array.<br />

ATAIL() is an array function that returns the highest numbered element <strong>of</strong> an array. It can be used<br />

in applications as shorthand for aArray[LEN(aArray)] when you need to obtain the last element<br />

<strong>of</strong> an array.


208 volume VIII Argomenti avanzati e accessori<br />

368.14.19 BIN2I()<br />

Binary to integer<br />

BIN2I(cSignedInt) ⇒ nNumber<br />

cSignedInt<br />

is a character string in the form <strong>of</strong> a 16-bit signed integer<br />

number--least significant byte first.<br />

BIN2I() returns an integer obtained converting the first two byte contained inside cSignedInt.<br />

368.14.20 BIN2L()<br />

Binary to long<br />

BIN2L(cSignedInt) ⇒ nNumber<br />

cSignedInt<br />

is a character string in the form <strong>of</strong> a 32-bit signed integer<br />

number--least significant byte first.<br />

BIN2L() returns an integer obtained from the first tour characters contained in cSignedInt.<br />

368.14.21 BIN2W()<br />

Binary to word<br />

BIN2W(cUnsignedInt) ⇒ nNumber<br />

cUnsignedInt<br />

is a character string in the form <strong>of</strong> a 16-bit unsigned integer<br />

number--least significant byte first.<br />

BIN2W() returns an integer obtained from the first two characters contained in cSignedInt.<br />

368.14.22 BOF()<br />

Begin <strong>of</strong> file<br />

BOF() ⇒ lBoundary<br />

BOF() returns true (‘.T.’) after an attempt to SKIP backward beyond the first logical record in<br />

a database file; otherwise, it returns false (‘.F.’). If there is no database file open in the current<br />

work area, BOF() returns false (‘.F.’). If the current database file contains no records, BOF()<br />

returns true (‘.T.’).


nanoBase 1997 user manual 209<br />

368.14.23 CDOW()<br />

Character day <strong>of</strong> week<br />

CDOW(dExp) ⇒ cDayName<br />

dExp is the date value to convert.<br />

CDOW() returns the name <strong>of</strong> the day <strong>of</strong> the week as a character string. The first letter is uppercase<br />

and the rest <strong>of</strong> the string is lowercase. For a null date value, CDOW() returns a null string ("").<br />

368.14.24 CHR()<br />

Character<br />

CHR(nCode) ⇒ cChar<br />

nCode<br />

is an ASCII code in the range <strong>of</strong> zero to 255.<br />

CHR() returns a single character value whose ASCII code is specified by nCode.<br />

368.14.25 CMONTH()<br />

Character month<br />

CMONTH(dDate) ⇒ cMonth<br />

dDate is the date value to convert.<br />

CMONTH() returns the name <strong>of</strong> the month as a character string from a date value with the first<br />

letter uppercase and the rest <strong>of</strong> the string lowercase. For a null date value, CMONTH() returns a<br />

null string ("").<br />

368.14.26 COL()<br />

Column<br />

COL() ⇒ nCol<br />

COL() is a screen function that returns the current column position <strong>of</strong> the cursor. The value <strong>of</strong><br />

COL() changes whenever the cursor position changes on the screen.<br />

368.14.27 COLORSELECT()<br />

COLORSELECT(nColor<strong>Index</strong>) ⇒ NIL<br />

nColor<strong>Index</strong><br />

is a number corresponding to the ordinal positions in the current<br />

list <strong>of</strong> color attributes, as set by SETCOLOR().<br />

COLORSELECT() activates the specified color pair from the current list <strong>of</strong> color attributes (es-


210 volume VIII Argomenti avanzati e accessori<br />

tablished by SETCOLOR()).<br />

368.14.28 CTOD()<br />

Character to date<br />

CTOD(cDate) ⇒ dDate<br />

cDate<br />

is a character string consisting <strong>of</strong> numbers representing the<br />

month, day, and year separated by any character other than a<br />

number. The month, day, and year digits must be specified in<br />

accordance with the SET DATE format. If the century digits<br />

are not specified, the century is determined by the rules <strong>of</strong><br />

SET EPOCH.<br />

CTOD() returns a date value. If cDate is not a valid date, CTOD() returns an empty date.<br />

368.14.29 CURDIR()<br />

Current directory<br />

CURDIR([cDrivespec]) ⇒ cDirectory<br />

cDrivespec<br />

specifies the letter <strong>of</strong> the disk drive to query. If not specified,<br />

the default is the current DOS drive.<br />

CURDIR() returns the current DOS directory <strong>of</strong> the drive specified by cDrivespec as a character<br />

string without either leading or trailing backslash (\) characters.<br />

368.14.30 DATE()<br />

DATE() ⇒ dSystemDate<br />

DATE() returns the system date as a date value.<br />

368.14.31 DAY()<br />

DAY(dDate) ⇒ nDay<br />

dDate is a date value to convert.<br />

DAY() returns the day number from dDate.


nanoBase 1997 user manual 211<br />

368.14.32 DBAPPEND()<br />

DBAPPEND([lReleaseRecLocks]) ⇒ NIL<br />

lReleaseRecLocks<br />

DBAPPEND() adds a new empty record to the active alias.<br />

368.14.33 DBCLEARFILTER()<br />

DBCLEARFILTER() ⇒ NIL<br />

is a logical data type that if true (‘.T.’), clears all<br />

pending record locks, then appends the next record. If<br />

lReleaseRecLocks is false (‘.F.’), all pending record locks<br />

are maintained and the new record is added to the end <strong>of</strong><br />

the Lock List. The default value <strong>of</strong> lReleaseRecLocks is true<br />

(‘.T.’).<br />

DBCLEARFILTER() clears the logical filter condition, if any, for the current work area.<br />

368.14.34 DBCLEARINDEX()<br />

DBCLEARINDEX() ⇒ NIL<br />

DBCLEARINDEX() closes any active indexes for the active alias.<br />

368.14.35 DBCLEARRELATION()<br />

DBCLEARRELATION() ⇒ NIL<br />

DBCLEARRELATION() clears any active relations for the active alias.<br />

368.14.36 DBCLOSEALL()<br />

DBCLOSEALL() ⇒ NIL<br />

DBCLOSEALL() releases all occupied work areas from use. It is equivalent to calling DB-<br />

CLOSEAREA() on every occupied work area.<br />

Attention: DBCLOSEALL() cannot be used inside a "compiled" macro as this will stop the<br />

macro execution. In substitution, DBCLOSE() should be used.<br />

368.14.37 DBCLOSEAREA()<br />

DBCLOSEAREA() ⇒ NIL<br />

DBCLOSEAREA() releases the current work area from use.


212 volume VIII Argomenti avanzati e accessori<br />

368.14.38 DBCOMMIT()<br />

DBCOMMIT() ⇒ NIL<br />

DBCOMMIT() causes all updates to the current work area to be written to disk. All updated<br />

database and index buffers are written to DOS and a DOS COMMIT request is issued for the<br />

database (.dbf) file and any index files associated with the work area. Inside a network environment,<br />

DBCOMMIT() makes database updates visible to other processes. To insure data integrity,<br />

issue DBCOMMIT() before an UNLOCK operation.<br />

368.14.39 DBCOMMITALL()<br />

DBCOMMITALL() ⇒ NIL<br />

DBCOMMITALL() causes all pending updates to all work areas to be written to disk. It is equivalent<br />

to calling DBCOMMIT() for every occupied work area.<br />

368.14.40 DBCREATE()<br />

DBCREATE(cDatabase, aStruct, [cDriver]) ⇒ NIL<br />

cDatabase<br />

aStruct<br />

cDriver<br />

is the name <strong>of</strong> the new database file, with an optional drive and<br />

directory, specified as a character string. If specified without<br />

an extension (.dbf) is assumed.<br />

is an array that contains the structure <strong>of</strong> cDatabase as a series<br />

<strong>of</strong> subarrays, one per field. Each subarray contains the definition<br />

<strong>of</strong> each field’s attributes and has the following structure:<br />

aStruct[n][1] == cName<br />

aStruct[n][2] == cType<br />

aStruct[n][3] == nLength<br />

aStruct[n][4] == nDecimals<br />

specifies the replaceable database driver (RDD) to use to process<br />

the current work area. cDriver is name <strong>of</strong> the RDD specified<br />

as a character expression.<br />

DBCREATE() is a database function that creates a database file from an array containing the<br />

structure <strong>of</strong> the file.<br />

368.14.41 DBCREATEINDEX()<br />

DBCREATEINDEX(c<strong>Index</strong>Name, cKeyExpr, bKeyExpr, [lUnique])<br />

⇒ NIL<br />

c<strong>Index</strong>Name<br />

cKeyExpr<br />

bKeyExpr<br />

lUnique<br />

is a character value that specifies the filename <strong>of</strong> the index file<br />

(order bag) to be created.<br />

is a character value that expresses the index key expression in<br />

textual form.<br />

is a code block that expresses the index key expression in executable<br />

form.<br />

is an optional logical value that specifies whether a unique<br />

index is to be created. If lUnique is omitted, the current global<br />

_SET_UNIQUE setting is used.


nanoBase 1997 user manual 213<br />

DBCREATEINDEX() creates an index for the active alias. If the alias has active indexes, they<br />

are closed.<br />

368.14.42 DBDELETE()<br />

DBDELETE() ⇒ NIL<br />

DBDELETE() marks the current record as deleted (*). Records marked for deletion can be filtered<br />

using SET DELETED or removed from the file using the PACK command.<br />

368.14.43 DBEVAL()<br />

DB evaluate<br />

DBEVAL(bBlock,<br />

[bForCondition],<br />

[bWhileCondition],<br />

[nNextRecords],<br />

[nRecord],<br />

[lRest]) ⇒ NIL<br />

bBlock<br />

bForCondition<br />

bWhileCondition<br />

nNextRecords<br />

nRecord<br />

lRest<br />

is a code block to execute for each record processed.<br />

the FOR condition expressed as code block.<br />

the WHILE condition expressed as code block.<br />

is an optional number that specifies the number <strong>of</strong> records to<br />

process starting with the current record. It is the same as the<br />

NEXT clause.<br />

is an optional record number to process. If this argument is<br />

specified, bBlock will be evaluated for the specified record.<br />

This argument is the same as the RECORD clause.<br />

is an optional logical value that determines whether the scope<br />

<strong>of</strong> DBEVAL() is all records, or, starting with the current<br />

record, all records to the end <strong>of</strong> file.<br />

DBEVAL() is a database function that evaluates a single block for each record within the active<br />

alias.<br />

368.14.44 DBFILTER()<br />

DBFILTER() ⇒ cFilter<br />

BFILTER() returns the filter condition defined in the current work area as a character string. If<br />

no FILTER has been SET, DBFILTER() returns a null string ("").<br />

368.14.45 DBGOBOTTOM()<br />

DBGOBOTTOM() ⇒ NIL<br />

DBGOBOTTOM() moves to last logical record in the active alias.


214 volume VIII Argomenti avanzati e accessori<br />

368.14.46 DBGOTO()<br />

DBGOTO(nRecordNumber) ⇒ NIL<br />

nRecordNumber<br />

is a numeric value that specifies the record number <strong>of</strong> the desired<br />

record.<br />

DBGOTO() moves to the record whose record number is equal to nRecordNumber. If no such<br />

record exists, the work area is positioned to LASTREC() + 1 and both EOF() and BOF() return<br />

true (‘.T.’).<br />

368.14.47 DBGOTOP()<br />

DBGOTOP() ⇒ NIL<br />

DBGOTOP() moves to the first logical record in the current work area.<br />

368.14.48 DBRECALL()<br />

DBRECALL() ⇒ NIL<br />

DBRECALL() causes the current record to be reinstated if it is marked for deletion.<br />

368.14.49 DBREINDEX()<br />

DBREINDEX() ⇒ NIL<br />

DBREINDEX() rebuilds all active indexes associated with the active alias.<br />

368.14.50 DBRELATION()<br />

DBRELATION(nRelation) ⇒ cLinkExp<br />

nRelation<br />

is the position <strong>of</strong> the desired relation in the list <strong>of</strong> active alias<br />

relations.<br />

DBRELATION() returns a character string containing the linking expression <strong>of</strong> the relation specified<br />

by nRelation. If there is no RELATION SET for nRelation, DBRELATION() returns a null<br />

string ("").<br />

368.14.51 DBRLOCK()<br />

DB record lock<br />

DBRLOCK([nRecNo]) ⇒ lSuccess<br />

nRecNo<br />

is the record number to be locked. The default is the current<br />

record.<br />

DBRLOCK() is a database function that locks the record identified by nRecNo or the current


nanoBase 1997 user manual 215<br />

record.<br />

368.14.52 DBRLOCKLIST()<br />

DBRLOCKLIST() ⇒ aRecordLocks<br />

DBRLOCKLIST() returns a one-dimensional array <strong>of</strong> the locked records in the active alias.<br />

368.14.53 DBRSELECT()<br />

DB relation select<br />

DBRSELECT(nRelation) ⇒ nWorkArea<br />

nRelation<br />

is the position <strong>of</strong> the desired relation in the list <strong>of</strong> current work<br />

area relations.<br />

DBRSELECT() returns the work area number <strong>of</strong> the relation specified by nRelation as an integer<br />

numeric value. If there is no RELATION SET for nRelation, DBRSELECT() returns zero.<br />

368.14.54 DBRUNLOCK()<br />

DB relation unlock<br />

DBRUNLOCK([nRecNo]) ⇒ NIL<br />

nRecNo<br />

is the record number to be unlocked. The default is all previously<br />

locked records.<br />

DBRUNLOCK() is a database function that unlocks the record identified by nRecNo or all<br />

locked records.<br />

368.14.55 DBSEEK()<br />

DBSEEK(expKey, [lS<strong>of</strong>tSeek]) ⇒ lFound<br />

expKey<br />

lS<strong>of</strong>tSeek<br />

is a value <strong>of</strong> any type that specifies the key value associated<br />

with the desired record.<br />

is an optional logical value that specifies whether a s<strong>of</strong>t seek<br />

is to be performed. This determines how the work area is positioned<br />

if the specified key value is not found. If lS<strong>of</strong>tSeek is<br />

omitted, the current global _SET_SOFTSEEK setting is used.<br />

DBSEEK() returns true (‘.T.’) if the specified key value was found; otherwise, it returns false<br />

(‘.F.’).


216 volume VIII Argomenti avanzati e accessori<br />

368.14.56 DBSELECTAREA()<br />

DBSELECTAREA(nArea | cAlias) ⇒ NIL<br />

nArea<br />

cAlias<br />

is a numeric value between zero and 250, inclusive, that specifies<br />

the work area being selected.<br />

is a character value that specifies the alias <strong>of</strong> a currently occupied<br />

work area being selected.<br />

DBSELECTAREA() causes the specified work area to become the current work area. All subsequent<br />

database operations will apply to this work area unless another work area is explicitly<br />

specified for an operation.<br />

368.14.57 DBSETDRIVER()<br />

DBSETDRIVER([cDriver]) ⇒ cCurrentDriver<br />

cDriver<br />

DBSETDRIVER() returns the name <strong>of</strong> the current default driver.<br />

368.14.58 DBSETFILTER()<br />

DBSETFILTER(bCondition, [cCondition]) ⇒ NIL<br />

bCondition<br />

cCondition<br />

is an optional character value that specifies the name <strong>of</strong> the<br />

database driver that should be used to activate and manage<br />

new work areas when no driver is explicitly specified.<br />

is a code block that expresses the filter condition in executable<br />

form.<br />

is a character value that expresses the filter condition in textual<br />

form. If cCondition is omitted, the DBSETFILTER()<br />

function will return an empty string for the work area.<br />

DBSETFILTER() sets a logical filter condition for the current work area. When a filter is set,<br />

records which do not meet the filter condition are not logically visible. That is, database operations<br />

which act on logical records will not consider these records. The filter expression supplied<br />

to DBSETFILTER() evaluates to true (‘.T.’) if the current record meets the filter condition;<br />

otherwise, it should evaluate to false (‘.F.’).<br />

368.14.59 DBSETINDEX()<br />

DBSETINDEX(cOrderBagName) ⇒ NIL<br />

cOrderBagName<br />

is a character value that specifies the filename <strong>of</strong> the index file<br />

(index bag) to be opened.<br />

DBSETINDEX() is a database function that adds the contents <strong>of</strong> an Order Bag into the Order List<br />

<strong>of</strong> the current work area. Any Orders already associated with the work area continue to be active.


nanoBase 1997 user manual 217<br />

If the newly opened Order Bag is the only Order associated with the work area, it becomes the<br />

controlling Order; otherwise, the controlling Order remains unchanged. If the Order Bag contains<br />

more than one Order, and there are no other Orders associated with the work area, the first Order<br />

in the new Order Bag becomes the controlling Order.<br />

368.14.60 DBSETORDER()<br />

DBSETORDER(nOrderNum) ⇒ NIL<br />

nOrderNum<br />

is a numeric value that specifies which <strong>of</strong> the active indexes is<br />

to be the controlling index.<br />

DBSETORDER() controls which <strong>of</strong> the active alias’ active indexes is the controlling index.<br />

368.14.61 DBSETRELATION()<br />

DBSETRELATION(nArea | cAlias, bExpr, [cExpr]) ⇒ NIL<br />

nArea<br />

cAlias<br />

bExpr<br />

cExpr<br />

is a numeric value that specifies the work area number <strong>of</strong> the<br />

child work area.<br />

is a character value that specifies the alias <strong>of</strong> the child work<br />

area.<br />

is a code block that expresses the relational expression in executable<br />

form.<br />

is an optional character value that expresses the relational expression<br />

in textual form. If cExpr is omitted, the DBRELA-<br />

TION() function returns an empty string for the relation.<br />

DBSETRELATION() relates the work area specified by nArea or cAlias (the child work area),<br />

to the current work area (the parent work area). Any existing relations remain active.<br />

368.14.62 DBSKIP()<br />

DBSKIP([nRecords]) ⇒ NIL<br />

nRecords<br />

is the number <strong>of</strong> logical records to move, relative to the current<br />

record. A positive value means to skip forward, and a<br />

negative value means to skip backward. If nRecords is omitted,<br />

a value <strong>of</strong> 1 is assumed.<br />

DBSKIP() moves either forward or backward relative to the current record. Attempting to skip<br />

forward beyond the last record positions the work area to LASTREC() + 1 and EOF() returns<br />

true (‘.T.’). Attempting to skip backward beyond the first record positions the work area to the<br />

first record and BOF() returns true (‘.T.’).


218 volume VIII Argomenti avanzati e accessori<br />

368.14.63 DBSTRUCT()<br />

DBSTRUCT() ⇒ aStruct<br />

DBSTRUCT() returns the structure <strong>of</strong> the current database file in an array whose length is equal<br />

to the number <strong>of</strong> fields in the database file. Each element <strong>of</strong> the array is a subarray containing<br />

information for one field. The subarrays have the following format:<br />

aStruct[n][1] == cName<br />

aStruct[n][2] == cType<br />

aStruct[n][3] == nLength<br />

aStruct[n][4] == nDecimals<br />

If there is no database file in USE in the current work area, DBSTRUCT() returns an empty array<br />

({}).<br />

368.14.64 DBUNLOCK()<br />

DBUNLOCK() ⇒ NIL<br />

DBUNLOCK() releases any record or file locks obtained by the current process for the current<br />

work area. DBUNLOCK() is only meaningful on a shared database in a network environment.<br />

368.14.65 DBUNLOCKALL()<br />

DBUNLOCKALL() ⇒ NIL<br />

DBUNLOCKALL() releases any record or file locks obtained by the current process for any work<br />

area. DBUNLOCKALL() is only meaningful on a shared database in a network environment.<br />

368.14.66 DBUSEAREA()<br />

DBUSEAREA( [lNewArea], [cDriver], cName, [xcAlias],<br />

[lShared], [lReadonly]) ⇒ NIL<br />

lNewArea<br />

cDriver<br />

cName<br />

xcAlias<br />

lShared<br />

is an optional logical value. A value <strong>of</strong> true (‘.T.’) selects the<br />

lowest numbered unoccupied work area as the current work<br />

area before the use operation. If lNewArea is false (‘.F.’)<br />

or omitted, the current work area is used; if the work area is<br />

occupied, it is closed first.<br />

is an optional character value. If present, it specifies the name<br />

<strong>of</strong> the database driver which will service the work area. If<br />

cDriver is omitted, the current default driver is used.<br />

specifies the name <strong>of</strong> the database (.dbf) file to be opened.<br />

is an optional character value. If present, it specifies the alias<br />

to be associated with the work area. The alias must constitute<br />

a valid identifier. A valid xcAlias may be any legal identifier<br />

(i.e., it must begin with an alphabetic character and may contain<br />

numeric or alphabetic characters and the underscore). If<br />

xcAlias is omitted, a default alias is constructed from cName.<br />

is an optional logical value. If present, it specifies whether the<br />

database (.dbf) file should be accessible to other processes<br />

on a network. A value <strong>of</strong> true (‘.T.’) specifies that other processes<br />

should be allowed access; a value <strong>of</strong> false (‘.F.’) specifies<br />

that the current process is to have exclusive access. If<br />

lShared is omitted, the current global _SET_EXCLUSIVE<br />

setting determines whether shared access is allowed.


nanoBase 1997 user manual 219<br />

lReadonly<br />

DBUSEAREA() opens the specified database (.DBF).<br />

368.14.67 DBDELETE()<br />

DELETED() ⇒ lDeleted<br />

is an optional logical value that specifies whether updates to<br />

the work area are prohibited. A value <strong>of</strong> true (‘.T.’) prohibits<br />

updates; a value <strong>of</strong> false (‘.F.’) permits updates. A value<br />

<strong>of</strong> true (‘.T.’) also permits read-only access to the specified<br />

database (.dbf) file. If lReadonly is omitted, the default value<br />

is false (‘.F.’).<br />

DELETED() returns true (‘.T.’) if the current record is marked for deletion; otherwise, it returns<br />

false (‘.F.’). If there is no database file in USE in the current work area, DELETED() returns<br />

false (‘.F.’).<br />

368.14.68 DESCEND()<br />

DESCEND(exp) ⇒ ValueInverted<br />

exp<br />

is any valid expression <strong>of</strong> character, date, logical, or numeric<br />

type.<br />

DESCEND() returns an inverted expression <strong>of</strong> the same data type as the exp, except for dates<br />

which return a numeric value. A DESCEND() <strong>of</strong> CHR(0) always returns CHR(0).<br />

368.14.69 DEVOUT()<br />

Device output<br />

DEVOUT(exp, [cColorString]) ⇒ NIL<br />

exp is the value to display.<br />

cColorString is an optional argument that defines the display color <strong>of</strong> exp.<br />

DEVOUT() is a full-screen display function that writes the value <strong>of</strong> a single expression to the<br />

current device at the current cursor or printhead position.<br />

368.14.70 DEVOUTPICT()<br />

Device output picture<br />

DEVOUTPICT(exp, cPicture, [cColorString]) ⇒ NIL<br />

exp is the value to display.<br />

cPicture<br />

defines the formatting control for the display <strong>of</strong> exp.<br />

cColorString is an optional argument that defines the display color <strong>of</strong> exp.


220 volume VIII Argomenti avanzati e accessori<br />

DEVOUTPICT() is a full-screen display function that writes the value <strong>of</strong> a single expression to<br />

the current device at the current cursor or printhead position.<br />

368.14.71 DEVPOS()<br />

Device position<br />

DEVPOS(nRow, nCol) ⇒ NIL<br />

nRow, nCol<br />

are the new row and column positions <strong>of</strong> the cursor or printhead.<br />

DEVPOS() is an environment function that moves the screen or printhead depending on the<br />

current DEVICE.<br />

368.14.72 DIRECTORY()<br />

DIRECTORY(cDirSpec, [cAttributes]) ⇒ aDirectory<br />

cDirSpec<br />

cAttributes<br />

identifies the drive, directory and file specification for the directory<br />

search. Wildcards are allowed in the file specification.<br />

If cDirSpec is omitted, the default value is *.*.<br />

specifies inclusion <strong>of</strong> files with special attributes in the returned<br />

information. cAttributes is a string containing one or<br />

more <strong>of</strong> the following characters:<br />

H Include hidden files<br />

S Include system files<br />

D Include directories<br />

V Search for the DOS volume label only<br />

Normal files are always included in the search, unless you<br />

specify V.<br />

DIRECTORY() returns an array <strong>of</strong> subarrays, with each subarray containing information about<br />

each file matching cDirSpec. The subarray has the following structure:<br />

aDirectory[n][1] == cName<br />

aDirectory[n][2] == cSize<br />

aDirectory[n][3] == dDate<br />

aDirectory[n][4] == cTime<br />

aDirectory[n][5] == cAttributes<br />

If no files are found matching cDirSpec or if cDirSpec is an illegal path or file specification,<br />

DIRECTORY() returns an empty ({}) array.<br />

368.14.73 DISKSPACE()<br />

DISKSPACE([nDrive]) ⇒ nBytes<br />

nDrive<br />

is the number <strong>of</strong> the drive to query, where one is drive A, two<br />

is B, three is C, etc. The default is the current DOS drive if<br />

nDrive is omitted or specified as zero.


nanoBase 1997 user manual 221<br />

DISKSPACE() returns the number <strong>of</strong> bytes <strong>of</strong> empty space on the specified disk drive as an<br />

integer numeric value.<br />

368.14.74 DISPBOX()<br />

Display box<br />

DISPBOX(nTop, nLeft, nBottom, nRight,<br />

[cnBoxString], [cColorString]) ⇒ NIL<br />

nTop, nLeft, nBottom, nRight define the coordinates <strong>of</strong> the box.<br />

is a numeric or character expression that defines the border<br />

characters <strong>of</strong> the box. If specified as a numeric expression, a<br />

value <strong>of</strong> 1 displays a single-line box and a value <strong>of</strong> 2 displays<br />

cnBoxString<br />

a double-line box. All other numeric values display a singleline<br />

box. If cnBoxString is a character expression, it specifies<br />

the characters to be used in drawing the box. This is a string<br />

<strong>of</strong> eight border characters and a fill character.<br />

cColorString defines the display color <strong>of</strong> the box that is drawn.<br />

DISPBOX() is a screen function that draws a box at the specified display coordinates in the<br />

specified color.<br />

368.14.75 DISPOUT()<br />

Display out<br />

DISPOUT(exp, [cColorString]) ⇒ NIL<br />

exp is the value to display.<br />

cColorString is an optional argument that defines the display color <strong>of</strong> exp.<br />

cColorString is a character expression containing the standard color setting.<br />

DISPOUT() is a simple output function that writes the value <strong>of</strong> a single expression to the display<br />

at the current cursor position. This function ignores the SET DEVICE setting; output always goes<br />

to the screen.<br />

368.14.76 DOW()<br />

Day <strong>of</strong> week<br />

DOW(dDate) ⇒ nDay<br />

dDate is a date value to convert.<br />

DOW() returns the day <strong>of</strong> the week as a number between zero and seven. The first day <strong>of</strong> the<br />

week is one (Sunday) and the last day is seven (Saturday). If dDate is empty, DOW() returns<br />

zero.


222 volume VIII Argomenti avanzati e accessori<br />

368.14.77 DTOC()<br />

Date to character<br />

DTOC(dDate) ⇒ cDate<br />

dDate is the date value to convert.<br />

DTOC() returns a character string representation <strong>of</strong> a date value. The return value is formatted in<br />

the current date format. A null date returns a string <strong>of</strong> spaces equal in length to the current date<br />

format.<br />

368.14.78 DTOS()<br />

Date to sort<br />

DTOS(dDate) ⇒ cDate<br />

dDate is the date value to convert.<br />

DTOS() returns a character string eight characters long in the form, yyyymmdd. When dDate is<br />

a null date (CTOD("")), DTOS() returns a string <strong>of</strong> eight spaces.<br />

368.14.79 EMPTY()<br />

EMPTY(exp) ⇒ lEmpty<br />

exp is an expression <strong>of</strong> any data type.<br />

EMPTY() returns true (‘.T.’) if the expression results in an empty value; otherwise, it returns<br />

false (‘.F.’):<br />

Array {}<br />

Character/Memo<br />

Spaces, tabs, CR/LF, or ""<br />

Numeric 0<br />

Date CTOD("")<br />

Logical ‘.F.’<br />

NIL NIL<br />

368.14.80 EOF()<br />

End <strong>of</strong> file<br />

EOF() ⇒ lBoundary<br />

EOF() returns true (‘.T.’) when an attempt is made to move the record pointer beyond the last<br />

logical record in a database file; otherwise, it returns false (‘.F.’). If there is no database file<br />

open in the current work area, EOF() returns false (‘.F.’). If the current database file contains<br />

no records, EOF() returns true (‘.T.’).


nanoBase 1997 user manual 223<br />

368.14.81 EVAL()<br />

Code block evaluation<br />

EVAL(bBlock, [BlockArg_list]) ⇒ LastBlockValue<br />

bBlock is the code block to evaluate.<br />

BlockArg_list<br />

is a list <strong>of</strong> arguments to send to the code block before it is<br />

evaluated.<br />

To execute or evaluate a code block, call EVAL() with the block value and any parameters.<br />

The parameters are supplied to the block when it is executed. Code blocks may be a series <strong>of</strong><br />

expressions separated by commas. When a code block is evaluated, the returned value is the<br />

value <strong>of</strong> the last expression in the block.<br />

368.14.82 EXP()<br />

Exponent<br />

EXP(nExponent) ⇒ nAntilogarithm<br />

nExponent<br />

is the natural logarithm for which a numeric value is to be<br />

calculated.<br />

EXP() returns a numeric value that is equivalent to the value e raised to the specified power.<br />

368.14.83 FCLOSE()<br />

File close<br />

FCLOSE(nHandle) ⇒ lError<br />

nHandle<br />

is the file handle obtained previously from FOPEN() or<br />

FCREATE().<br />

FCLOSE() is a low-level file function that closes binary files and forces the associated DOS<br />

buffers to be written to disk. If the operation fails, FCLOSE() returns false (‘.F.’). FERROR()<br />

can then be used to determine the reason for the failure.<br />

368.14.84 FCOUNT()<br />

Field count<br />

FCOUNT() ⇒ nFields<br />

FCOUNT() returns the number <strong>of</strong> fields in the database file in the active alias as an integer<br />

numeric value. If there is no database file open, FCOUNT() returns zero.


224 volume VIII Argomenti avanzati e accessori<br />

368.14.85 FCREATE()<br />

Field create<br />

FCREATE(cFile, [nAttribute]) ⇒ nHandle<br />

cFile<br />

nAttribute<br />

is the name <strong>of</strong> the file to create. If the file already exists, its<br />

length is truncated to zero without warning.<br />

is the binary file attribute, the default value is zero.<br />

nAttribute = 0 Normal (default)<br />

nAttribute = 1 Read-only<br />

nAttribute = 2 Hidden<br />

nAttribute = 4 System<br />

FCREATE() returns the DOS file handle number <strong>of</strong> the new binary file in the range <strong>of</strong> zero to<br />

65,535. If an error occurs, FCREATE() returns -1 and FERROR() is set to indicate an error code.<br />

368.14.86 FERASE()<br />

File erase<br />

FERASE(cFile) ⇒ nSuccess<br />

cFile<br />

is the name (with or without path) <strong>of</strong> the file to be deleted<br />

from disk.<br />

FERASE() is a file function that deletes a specified file from disk. FERASE() returns -1 if the<br />

operation fails and zero if it succeeds.<br />

368.14.87 FERROR()<br />

File error<br />

FERROR() ⇒ nErrorCode<br />

FERROR() returns the DOS error from the last file operation as an integer numeric value. If there<br />

is no error, FERROR() returns zero.<br />

nErrorCode value<br />

Meaning<br />

0 Successful<br />

2 File not found<br />

3 Path not found<br />

4<br />

Too many files open<br />

5 Access denied<br />

6 Invalid handle<br />

8<br />

Insufficient memory<br />

15<br />

Invalid drive specified<br />

19 Attempted to write to a write-protected disk<br />

21<br />

Drive not ready<br />

23 Data CRC error<br />

29 Write fault<br />

30 Read fault<br />

32<br />

Sharing violation<br />

33 Lock Violation


nanoBase 1997 user manual 225<br />

FERROR() is a low-level file function that indicates a DOS error after a file function is used.<br />

368.14.88 FIELDBLOCK()<br />

FIELDBLOCK(cFieldName) ⇒ bFieldBlock<br />

cFieldName<br />

is the name <strong>of</strong> the field to which the set-get block will refer.<br />

FIELDBLOCK() returns a code block that, when evaluated, sets (assigns) or gets (retrieves) the<br />

value <strong>of</strong> the given field. If cFieldName does not exist in the current work area, FIELDBLOCK()<br />

returns NIL.<br />

368.14.89 FIELDGET()<br />

FIELDGET(nField) ⇒ ValueField<br />

nField<br />

is the ordinal position <strong>of</strong> the field in the record structure for<br />

the current work area.<br />

FIELDGET() returns the value <strong>of</strong> the specified field. If nField does not correspond to the position<br />

<strong>of</strong> any field in the current database file, FIELDGET() returns NIL.<br />

368.14.90 FIELDNAME()<br />

FIELDNAME(nPosition) ⇒ cFieldName<br />

nPosition<br />

is the position <strong>of</strong> a field in the database file structure.<br />

FIELDNAME() returns the name <strong>of</strong> the specified field as a character string. If nPosition does<br />

not correspond to an existing field in the current database file or if no database file is open in the<br />

current work area, FIELDNAME() returns a null string ("").<br />

368.14.91 FIELDPOS()<br />

Field position<br />

FIELDPOS(cFieldName) ⇒ nFieldPos<br />

cFieldName<br />

is the name <strong>of</strong> a field in the current or specified work area.<br />

FIELDPOS() returns the position <strong>of</strong> the specified field within the list <strong>of</strong> fields associated with<br />

the current or specified work area. If the current work area has no field with the specified name,<br />

FIELDPOS() returns zero.


226 volume VIII Argomenti avanzati e accessori<br />

368.14.92 FIELDPUT()<br />

FIELDPUT(nField, expAssign) ⇒ ValueAssigned<br />

nField<br />

expAssign<br />

is the ordinal position <strong>of</strong> the field in the current database file.<br />

is the value to assign to the given field. The data type <strong>of</strong> this<br />

expression must match the data type <strong>of</strong> the designated field<br />

variable.<br />

FIELDPUT() is a database function that assigns expAssign to the field at ordinal position nField<br />

in the current work area. This function allows you to set the value <strong>of</strong> a field using its position<br />

within the database file structure rather than its field name.<br />

368.14.93 FIELDWBLOCK()<br />

Field work area block<br />

FIELDWBLOCK(cFieldName, nWorkArea) ⇒ bFieldWBlock<br />

cFieldName<br />

nWorkArea<br />

is the name <strong>of</strong> the field specified as a character string.<br />

is the work area number where the field resides specified as a<br />

numeric value.<br />

FIELDWBLOCK() returns a code block that, when evaluated, sets (assigns) or gets (retrieves)<br />

the value <strong>of</strong> cFieldName in the work area designated by nWorkArea. If cFieldName does not<br />

exist in the specified work area, FIELDWBLOCK() returns NIL.<br />

368.14.94 FILE()<br />

FILE(cFilespec) ⇒ lExists<br />

cFilespec<br />

is in the current default directory and path. It is a standard file<br />

specification that can include the wildcard characters * and ?<br />

as well as a drive and path reference.<br />

FILE() returns true (‘.T.’) if there is a match for any file matching the cFilespec pattern; otherwise,<br />

it returns false (‘.F.’).<br />

368.14.95 FLOCK()<br />

File lock<br />

FLOCK() ⇒ lSuccess<br />

FLOCK() tries to lock the active alias and returns true (‘.T.’) if it succeeds; otherwise, it returns<br />

false (‘.F.’).


nanoBase 1997 user manual 227<br />

368.14.96 FOPEN()<br />

File open<br />

FOPEN(cFile, [nMode]) ⇒ nHandle<br />

cFile<br />

nMode<br />

is the name <strong>of</strong> the file to open including the path if there is<br />

one.<br />

is the requested DOS open mode indicating how the opened<br />

file is to be accessed. The open mode is composed <strong>of</strong> the sum<br />

<strong>of</strong> two elements: the Open mode and the Sharing mode.<br />

Open mode:<br />

0 Open for reading (default)<br />

1 Open for writing<br />

2 Open for reading or writing<br />

Sharing mode:<br />

0 Compatibility mode (default)<br />

16 Exclusive use<br />

32 Prevent others from writing<br />

48 Prevent others from reading<br />

64 Allow others to read or write<br />

FOPEN() returns the file handle <strong>of</strong> the opened file in the range <strong>of</strong> zero to 65,535. If an error<br />

occurs, FOPEN() returns -1.<br />

368.14.97 FOUND()<br />

FOUND() ⇒ lSuccess<br />

FOUND() returns true (‘.T.’) if the last search command was successful; otherwise, it returns<br />

false (‘.F.’).<br />

368.14.98 FREAD()<br />

File read<br />

FREAD(nHandle, @cBufferVar, nBytes) ⇒ nBytes<br />

is the file handle obtained from FOPEN(), FCREATE(), or<br />

nHandle<br />

predefined by DOS.<br />

is the name <strong>of</strong> an existing and initialized character variable<br />

used to store data read from the specified file. The length<br />

cBufferVar<br />

<strong>of</strong> this variable must be greater than or equal to nBytes.<br />

cBufferVar must be passed by reference and, therefore, must<br />

be prefaced by the pass-by-reference operator (@).<br />

nBytes is the number <strong>of</strong> bytes to read into the buffer.<br />

FREAD() tries to read nBytes <strong>of</strong> the binary file nHandle inside cBufferVar. It returns the number<br />

<strong>of</strong> bytes successfully read as an integer numeric value. A return value less than nBytes or<br />

zero indicates end <strong>of</strong> file or some other read error.


228 volume VIII Argomenti avanzati e accessori<br />

368.14.99 FREADSTR()<br />

File read string<br />

FREADSTR(nHandle, nBytes) ⇒ cString<br />

nHandle<br />

nBytes<br />

is the file handle obtained from FOPEN(), FCREATE(), or<br />

predefined by DOS.<br />

is the number <strong>of</strong> bytes to read, beginning at the current DOS<br />

file pointer position.<br />

FREADSTR() returns a character string up to 65,535 (64K) bytes. A null return value ("") indicates<br />

an error or end <strong>of</strong> file. FREADSTR() is a low-level file function that reads characters from<br />

an open binary file beginning with the current DOS file pointer position. Characters are read up<br />

to nBytes or until a null character (CHR(0)) is encountered. All characters are read including<br />

control characters except for CHR(0). The file pointer is then moved forward nBytes. If nBytes<br />

is greater than the number <strong>of</strong> bytes from the pointer position to the end <strong>of</strong> the file, the file pointer<br />

is positioned to the last byte in the file.<br />

368.14.100 FRENAME()<br />

File rename<br />

FRENAME(cOldFile, cNewFile) ⇒ nSuccess<br />

cOldFile<br />

cNewFile<br />

is the name <strong>of</strong> the file to rename, including the file extension.<br />

A drive letter and/or path name may also be included as part<br />

<strong>of</strong> the filename.<br />

is the new name <strong>of</strong> the file, including the file extension. A<br />

drive letter and/or path name may also be included as part <strong>of</strong><br />

the name.<br />

FRENAME() returns -1 if the operation fails and zero if it succeeds.<br />

368.14.101 FSEEK()<br />

File seek<br />

FSEEK(nHandle, nOffset, [nOrigin]) ⇒ nPosition<br />

is the file handle obtained from FOPEN(), FCREATE(), or<br />

nHandle<br />

predefined by DOS.<br />

is the number <strong>of</strong> bytes to move the file pointer from the position<br />

defined by nOrigin. It can be a positive or negative<br />

nOffset<br />

number. A positive number moves the pointer forward, and<br />

a negative number moves the pointer backward in the file.<br />

defines the starting location <strong>of</strong> the file pointer before FSEEK()<br />

is executed. The default value is zero, representing the begin-<br />

nOrigin<br />

ning <strong>of</strong> file. If nOrigin is the end <strong>of</strong> file, nOffset must be zero<br />

or negative.<br />

nOrigin == 0 Seek from beginning <strong>of</strong> file<br />

nOrigin == 1 Seek from the current pointer position<br />

nOrigin == 2 Seek from end <strong>of</strong> file


nanoBase 1997 user manual 229<br />

FSEEK() returns the new position <strong>of</strong> the file pointer relative to the beginning <strong>of</strong> file (position<br />

0) as an integer numeric value. This value is without regard to the original position <strong>of</strong> the file<br />

pointer. FSEEK() is a low-level file function that moves the file pointer forward or backward<br />

in an open binary file without actually reading the contents <strong>of</strong> the specified file. The beginning<br />

position and <strong>of</strong>fset are specified as function arguments, and the new file position is returned.<br />

368.14.102 FWRITE()<br />

File write<br />

FWRITE(nHandle, cBuffer, [nBytes]) ⇒ nBytesWritten<br />

nHandle<br />

is the file handle obtained from FOPEN(), FCREATE(), or<br />

predefined by DOS.<br />

cBuffer is the character string to write to the specified file.<br />

nBytes<br />

indicates the number <strong>of</strong> bytes to write beginning at the current<br />

file pointer position. If omitted, the entire content <strong>of</strong> cBuffer<br />

is written.<br />

FWRITE() returns the number <strong>of</strong> bytes written as an integer numeric value. If the value returned<br />

is equal to nBytes, the operation was successful. If the return value is less than nBytes or zero,<br />

either the disk is full or another error has occurred.<br />

368.14.103 GETENV()<br />

Get environment<br />

GETENV(cEnvironmentVariable) ⇒ cString<br />

cEnvironmentVariable<br />

is the name <strong>of</strong> the DOS environment variable. When specifying<br />

this argument, you can use any combination <strong>of</strong> upper and<br />

lowercase letters; GETENV() is not case- sensitive.<br />

GETENV() returns the contents <strong>of</strong> the specified DOS environment variable as a character string.<br />

If the variable cannot be found, GETENV() returns a null string ("").<br />

368.14.104 HARDCR()<br />

Hard carriage return<br />

HARDCR(cString) ⇒ cConvertedString<br />

cString is the character string or memo field to convert.<br />

HARDCR() is a memo function that replaces all s<strong>of</strong>t carriage returns (CHR(141)) with hard carriage<br />

returns (CHR(13)). It is used to display long character strings and memo fields containing<br />

s<strong>of</strong>t carriage returns with console commands.


230 volume VIII Argomenti avanzati e accessori<br />

368.14.105 HEADER()<br />

HEADER() ⇒ nBytes<br />

HEADER() returns the number <strong>of</strong> bytes in the header <strong>of</strong> the current database file as an integer<br />

numeric value. If no database file is in use, HEADER() returns a zero (0).<br />

368.14.106 I2BIN()<br />

Integer to binary<br />

I2BIN(nInteger) ⇒ cBinaryInteger<br />

nInteger<br />

is an integer numeric value to convert. Decimal digits are truncated.<br />

I2BIN() returns a two-byte character string containing a 16-bit binary integer.<br />

368.14.107 IF()<br />

[I]IF(lCondition, expTrue, expFalse) ⇒ Value<br />

lCondition<br />

expTrue<br />

expFalse<br />

is a logical expression to be evaluated.<br />

is the value, a condition-expression, <strong>of</strong> any data type, returned<br />

if lCondition is true (‘.T.’).<br />

is the value, <strong>of</strong> any date type, returned if lCondition is false<br />

(‘.F.’). This argument need not be the same data type as<br />

expTrue.<br />

IF() returns the evaluation <strong>of</strong> expTrue if lCondition evaluates to true (‘.T.’) and expFalse if it<br />

evaluates to false (‘.F.’).<br />

368.14.108 INDEXEXT()<br />

<strong>Index</strong> extention<br />

INDEXEXT() ⇒ cExtension<br />

INDEXEXT() returns the default index file extension by determining which database driver is<br />

currently linked.<br />

368.14.109 INDEXKEY()<br />

INDEXKEY(nOrder) ⇒ cKeyExp<br />

nOrder<br />

is the ordinal position <strong>of</strong> the index in the list <strong>of</strong> index files<br />

opened by the last USE...INDEX or SET INDEX TO command<br />

for the current work area. A zero value specifies the<br />

controlling index, without regard to its actual position in the<br />

list.


nanoBase 1997 user manual 231<br />

INDEXKEY() returns the key expression <strong>of</strong> the specified index as a character string. If there is<br />

no corresponding index or if no database file is open, INDEXKEY() returns a null string ("").<br />

368.14.110 INDEXORD()<br />

<strong>Index</strong> order<br />

INDEXORD() ⇒ nOrder<br />

INDEXORD() returns an integer numeric value. The value returned is equal to the position <strong>of</strong> the<br />

controlling index in the list <strong>of</strong> open indexes for the current work area. A value <strong>of</strong> zero indicates<br />

that there is no controlling index and records are being accessed in natural order. If no database<br />

file is open, INDEXORD() will also return a zero.<br />

368.14.111 INKEY()<br />

Input key<br />

INKEY([nSeconds]) ⇒ nInkeyCode<br />

nSeconds<br />

specifies the number <strong>of</strong> seconds INKEY() waits for a keypress.<br />

You can specify the value in increments as small as<br />

one-tenth <strong>of</strong> a second. Specifying zero halts the program until<br />

a key is pressed. If nSeconds is omitted, INKEY() does not<br />

wait for a keypress.<br />

INKEY() returns an integer numeric value from -39 to 386, identifying the key extracted from<br />

the keyboard buffer. If the keyboard buffer is empty, INKEY() returns zero. INKEY() returns<br />

values for all ASCII characters, function, Alt+function, Ctrl+function, Alt+letter, and Ctrl+letter<br />

key combinations.<br />

nInkeyCode value Key or key combination<br />

5 [ Up arrow ], [ Ctrl ]+E<br />

24 [ Down arrow ], [ Ctrl ]+X<br />

19 [ Left arrow ], [ Ctrl ]+S<br />

4 [ Right arrow ], [ Ctrl ]+D<br />

1 [ Home ], [ Ctrl ]+A<br />

6 [ End ], [ Ctrl ]+F<br />

18 [ PgUp ], [ Ctrl ]+R<br />

3 [ PgDn ], [ Ctrl ]+C<br />

397<br />

[ Ctrl ]+[ Up arrow ]<br />

401<br />

[ Ctrl ]+[ Down arrow ]<br />

26 [ Ctrl ]+[ Left arrow ], [ Ctrl ]+Z<br />

2 [ Ctrl ]+[ Right arrow ], [ Ctrl ]+B<br />

29<br />

[ Ctrl ]+[ Home ]<br />

23 [ Ctrl ]+[ End ], [ Ctrl ]+W<br />

31<br />

[ Ctrl ]+[ PgUp ], [ Ctrl ]+Hyphen<br />

30 [ Ctrl ]+[ PgDn ], [ Ctrl ]+^<br />

408<br />

[ Alt ]+[ Up arrow ]<br />

416<br />

[ Alt ]+[ Down arrow ]<br />

411<br />

[ Alt ]+[ Left arrow ]<br />

413<br />

[ Alt ]+[ Right arrow ]<br />

407<br />

[ Alt ]+[ Home ]


232 volume VIII Argomenti avanzati e accessori<br />

nInkeyCode value Key or key combination<br />

415<br />

[ Alt ]+[ End ]<br />

409<br />

[ Alt ]+[ PgUp ]<br />

417<br />

[ Alt ]+[ PgDn ]<br />

13 [ Enter ], [ Ctrl ]+M<br />

32<br />

Space bar<br />

27 Esc<br />

10<br />

[ Ctrl ]+[ Enter ]<br />

379 [ Ctrl ]+Print Screen<br />

309 [ Ctrl ]+?<br />

284<br />

[ Alt ]+[ Enter ]<br />

387<br />

[ Alt ]+Equals<br />

257 [ Alt ]+Esc<br />

422<br />

Keypad [ Alt ]+[ Enter ]<br />

399 Keypad [ Ctrl ]+5<br />

405<br />

Keypad [ Ctrl ]+/<br />

406<br />

Keypad [ Ctrl ]+*<br />

398 Keypad [ Ctrl ]+-<br />

400<br />

Keypad [ Ctrl ]++<br />

5<br />

Keypad [ Alt ]+5<br />

420<br />

Keypad [ Alt ]+/<br />

311<br />

Keypad [ Alt ]+*<br />

330<br />

Keypad [ Alt ]+-<br />

334<br />

Keypad [ Alt ]++<br />

22 [ Ins ], [ Ctrl ]+V<br />

7 [ Del ], [ Ctrl ]+G<br />

8 [ Backspace ], [ Ctrl ]+H<br />

9 [ Tab ], [ Ctrl ]+I<br />

271<br />

[ Shift ]+[ Tab ]<br />

402<br />

[ Ctrl ]+[ Ins ]<br />

403<br />

[ Ctrl ]+[ Del ]<br />

127<br />

[ Ctrl ]+[ Backspace ]<br />

404<br />

[ Ctrl ]+[ Tab ]<br />

418<br />

[ Alt ]+[ Ins ]<br />

419<br />

[ Alt ]+[ Del ]<br />

270<br />

[ Alt ]+[ Backspace ]<br />

421<br />

[ Alt ]+[ Tab ]<br />

1 [ Ctrl ]+A, [ Home ]<br />

2 [ Ctrl ]+B, [ Ctrl ]+[ Right arrow ]<br />

3 [ Ctrl ]+C, [ PgDn ], [ Ctrl ]+[ ScrollLock ]<br />

4 [ Ctrl ]+D, [ Right arrow ]<br />

5 [ Ctrl ]+E, [ Up arrow ]<br />

6 [ Ctrl ]+F, [ End ]<br />

7 [ Ctrl ]+G, [ Del ]<br />

8 [ Ctrl ]+H, [ Backspace ]<br />

9 [ Ctrl ]+I, [ Tab ]<br />

10 [ Ctrl ]+J<br />

11 [ Ctrl ]+K<br />

12 [ Ctrl ]+L<br />

13 [ Ctrl ]+M, Return<br />

14 [ Ctrl ]+N<br />

15 [ Ctrl ]+O<br />

16 [ Ctrl ]+P<br />

17 [ Ctrl ]+Q


nanoBase 1997 user manual 233<br />

nInkeyCode value Key or key combination<br />

18 [ Ctrl ]+R, [ PgUp ]<br />

19 [ Ctrl ]+S, [ Left arrow ]<br />

20 [ Ctrl ]+T<br />

21 [ Ctrl ]+U<br />

22 [ Ctrl ]+V, [ Ins ]<br />

23 [ Ctrl ]+W, [ Ctrl ]+[ End ]<br />

24 [ Ctrl ]+X, [ Down arrow ]<br />

25 [ Ctrl ]+Y<br />

26 [ Ctrl ]+Z, [ Ctrl ]+[ Left arrow ]<br />

286 [ Alt ]+A<br />

304 [ Alt ]+B<br />

302 [ Alt ]+C<br />

288 [ Alt ]+D<br />

274 [ Alt ]+E<br />

289 [ Alt ]+F<br />

290 [ Alt ]+G<br />

291 [ Alt ]+H<br />

279 [ Alt ]+I<br />

292 [ Alt ]+J<br />

293 [ Alt ]+K<br />

294 [ Alt ]+L<br />

306 [ Alt ]+M<br />

305 [ Alt ]+N<br />

280 [ Alt ]+O<br />

281 [ Alt ]+P<br />

272 [ Alt ]+Q<br />

275 [ Alt ]+R<br />

287 [ Alt ]+S<br />

276 [ Alt ]+T<br />

278 [ Alt ]+U<br />

303 [ Alt ]+V<br />

273 [ Alt ]+W<br />

301 [ Alt ]+X<br />

277 [ Alt ]+Y<br />

300 [ Alt ]+Z<br />

376 [ Alt ]+1<br />

377 [ Alt ]+2<br />

378 [ Alt ]+3<br />

379 [ Alt ]+4<br />

380 [ Alt ]+5<br />

381 [ Alt ]+6<br />

382 [ Alt ]+7<br />

383 [ Alt ]+8<br />

384 [ Alt ]+9<br />

385 [ Alt ]+0<br />

28 F1, [ Ctrl ]+[ Backslash ]<br />

-1 F2<br />

-2 F3<br />

-3 F4<br />

-4 F5<br />

-5 F6<br />

-6 F7<br />

-7 F8


234 volume VIII Argomenti avanzati e accessori<br />

nInkeyCode value Key or key combination<br />

-8 F9<br />

-9 F10<br />

-40 F11<br />

-41 F12<br />

-20 [ Ctrl ]+F1<br />

-21 [ Ctrl ]+F2<br />

-22 [ Ctrl ]+F4<br />

-23 [ Ctrl ]+F3<br />

-24 [ Ctrl ]+F5<br />

-25 [ Ctrl ]+F6<br />

-26 [ Ctrl ]+F7<br />

-27 [ Ctrl ]+F8<br />

-28 [ Ctrl ]+F9<br />

-29 [ Ctrl ]+F10<br />

-44 [ Ctrl ]+F11<br />

-45 [ Ctrl ]+F12<br />

-30 [ Alt ]+F1<br />

-31 [ Alt ]+F2<br />

-32 [ Alt ]+F3<br />

-33 [ Alt ]+F4<br />

-34 [ Alt ]+F5<br />

-35 [ Alt ]+F6<br />

-36 [ Alt ]+F7<br />

-37 [ Alt ]+F8<br />

-38 [ Alt ]+F9<br />

-39 [ Alt ]+F10<br />

-46 [ Alt ]+F11<br />

-47 [ Alt ]+F12<br />

-10 [ Shift ]+F1<br />

-11 [ Shift ]+F2<br />

-12 [ Shift ]+F3<br />

-13 [ Shift ]+F4<br />

-14 [ Shift ]+F5<br />

-15 [ Shift ]+F6<br />

-16 [ Shift ]+F7<br />

-17 [ Shift ]+F8<br />

-18 [ Shift ]+F9<br />

-19 [ Shift ]+F10<br />

-42 [ Shift ]+F11<br />

-43 [ Shift ]+F12<br />

368.14.112 INT()<br />

Integer<br />

INT(nExp) ⇒ nInteger<br />

nExp is a numeric expression to convert to an integer.<br />

INT() is a numeric function that converts a numeric value to an integer by truncating all digits<br />

to the right <strong>of</strong> the decimal point. INT() is useful in operations where the decimal portion <strong>of</strong> a


nanoBase 1997 user manual 235<br />

number is not needed.<br />

368.14.113 ISALPHA()<br />

ISALPHA(cString) ⇒ lBoolean<br />

cString is the character string to examine.<br />

ISALPHA() returns true (‘.T.’) if the first character in cString is alphabetic; otherwise, it returns<br />

false (‘.F.’).<br />

368.14.114 ISCOLOR()<br />

ISCOLOR() | ISCOLOUR() ⇒ lBoolean<br />

ISCOLOR() returns true (‘.T.’) if there is a color graphics card installed; otherwise, it returns<br />

false (‘.F.’).<br />

368.14.115 ISDIGIT()<br />

ISDIGIT(cString) ⇒ lBoolean<br />

cString is the character string to examine.<br />

ISDIGIT() returns true (‘.T.’) if the first character <strong>of</strong> the character string is a digit between zero<br />

and nine; otherwise, it returns false (‘.F.’).<br />

368.14.116 ISLOWER()<br />

ISLOWER(cString) ⇒ lBoolean<br />

cString is the character string to examine.<br />

ISLOWER() returns true (‘.T.’) if the first character <strong>of</strong> the character string is a lowercase letter;<br />

otherwise, it returns false (‘.F.’).<br />

368.14.117 ISPRINTER()<br />

ISPRINTER() ⇒ lReady<br />

ISPRINTER() returns true (‘.T.’) if ‘LPT1:’ is ready; otherwise, it returns false (‘.F.’).


236 volume VIII Argomenti avanzati e accessori<br />

368.14.118 ISUPPER()<br />

ISUPPER(cString) ⇒ lBoolean<br />

cString is the character string to examine.<br />

ISUPPER() returns true (‘.T.’) if the first character is an uppercase letter; otherwise, it returns<br />

false (‘.F.’).<br />

368.14.119 L2BIN()<br />

Long to binary<br />

L2BIN(nExp) ⇒ cBinaryInteger<br />

nExp is the numeric value to convert. Decimal digits are truncated.<br />

L2BIN() returns a four-byte character string formatted as a 32- bit binary integer.<br />

368.14.120 LASTKEY()<br />

LASTKEY() ⇒ nInkeyCode<br />

LASTKEY() is a keyboard function that reports the INKEY() value <strong>of</strong> the last key fetched from<br />

the keyboard buffer by the INKEY() function, or a wait state. LASTKEY() retains its current<br />

value until another key is fetched from the keyboard buffer.<br />

368.14.121 LASTREC()<br />

Last record<br />

LASTREC() ⇒ nRecords<br />

LASTREC() returns the number <strong>of</strong> physical records in the active alias as an integer numeric<br />

value.<br />

368.14.122 LEFT()<br />

LEFT(cString, nCount) ⇒ cSubString<br />

cString is a character string from which to extract characters.<br />

nCount is the number <strong>of</strong> characters to extract.<br />

LEFT() returns the leftmost nCount characters <strong>of</strong> cString as a character string. If nCount is<br />

negative or zero, LEFT() returns a null string (""). If nCount is larger than the length <strong>of</strong> the<br />

character string, LEFT() returns the entire string.


nanoBase 1997 user manual 237<br />

368.14.123 LEN()<br />

Length<br />

LEN(cString | aTarget) ⇒ nCount<br />

cString is the character string to count.<br />

aTarget is the array to count.<br />

LEN() returns the length <strong>of</strong> a character string or the number <strong>of</strong> elements in an array as an integer<br />

numeric value.<br />

368.14.124 LOG()<br />

LOG(nExp) ⇒ nNaturalLog<br />

nExp<br />

is a numeric value greater than zero to convert to its natural<br />

logarithm.<br />

LOG() returns the natural logarithm as a numeric value. If nExp is less than or equal to zero,<br />

LOG() returns a numeric overflow (displayed as a row <strong>of</strong> asterisks).<br />

368.14.125 LOWER()<br />

LOWER(cString) ⇒ cLowerString<br />

cString is a character string to convert to lowercase.<br />

LOWER() returns a copy <strong>of</strong> cString with all alphabetic characters converted to lowercase.<br />

368.14.126 LTRIM()<br />

Left trim<br />

LTRIM(cString) ⇒ cTrimString<br />

cString is the character string to copy without leading spaces.<br />

LTRIM() returns a copy <strong>of</strong> cString with the leading spaces removed.<br />

368.14.127 LUPDATE()<br />

Last update<br />

LUPDATE() ⇒ dModification<br />

LUPDATE() returns the date <strong>of</strong> last change to the open database file in the current work area.


238 volume VIII Argomenti avanzati e accessori<br />

368.14.128 MAX()<br />

MAX(nExp1, nExp2) ⇒ nLarger<br />

MAX(dExp1, dExp2) ⇒ dLarger<br />

nExp1, nExp2 are the numeric values to compare.<br />

dExp1, dExp2 are the date values to compare.<br />

MAX() returns the larger <strong>of</strong> the two arguments. The value returned is the same type as the arguments.<br />

368.14.129 MAXCOL()<br />

Max column<br />

MAXCOL() ⇒ nColumn<br />

MAXCOL() returns the column number <strong>of</strong> the rightmost visible column for display purposes.<br />

368.14.130 MAXROW()<br />

MAXROW() ⇒ nRow<br />

MAXROW() returns the row number <strong>of</strong> the bottommost visible row for display purposes.<br />

368.14.131 MEMOEDIT()<br />

MEMOEDIT([cString],<br />

[nTop], [nLeft],<br />

[nBottom], [nRight],<br />

[lEditMode],<br />

[cUserFunction],<br />

[nLineLength],<br />

[nTabSize],<br />

[nTextBufferRow],<br />

[nTextBufferColumn],<br />

[nWindowRow],<br />

[nWindowColumn]) ⇒ cTextBuffer<br />

cString<br />

nTop, nLeft, nBottom, nRight<br />

lEditMode<br />

cUserFunction<br />

nLineLength<br />

is the character string or memo field to copy to the MEM-<br />

OEDIT() text buffer.<br />

are window coordinates. The default coordinates are 0, 0,<br />

MAXROW(), and MAXCOL().<br />

determines whether the text buffer can be edited or merely<br />

displayed. If not specified, the default value is true (‘.T.’).<br />

is the name <strong>of</strong> a user-defined function that executes when the<br />

user presses a key not recognized by MEMOEDIT() and when<br />

no keys are pending in the keyboard buffer.<br />

determines the length <strong>of</strong> lines displayed in the MEMOEDIT()<br />

window. If a line is greater than nLineLength, it is word<br />

wrapped to the next line in the MEMOEDIT() window. The<br />

default line length is (nRight - nLeft).


nanoBase 1997 user manual 239<br />

nTabSize<br />

nTextBufferRow,<br />

nTextBufferColumn<br />

nWindowRow, nWindowColumn<br />

determines the size <strong>of</strong> a tab character to insert when the user<br />

presses Tab. The default is four.<br />

define the display position <strong>of</strong> the cursor within the text buffer<br />

when MEMOEDIT() is invoked. nTextBufferRow begins<br />

with one and nTextBufferColumn begins with zero. Default<br />

is the beginning <strong>of</strong> MEMOEDIT() window.<br />

define the initial position <strong>of</strong> the cursor within the MEM-<br />

OEDIT() window. Row and column positions begin with zero.<br />

If these arguments are not specified, the initial window position<br />

is row zero and the current cursor column position.<br />

MEMOEDIT() is a user interface and general purpose text editing function that edits memo fields<br />

and long character strings. Editing occurs within a specified window region placed anywhere on<br />

the screen.<br />

[ Uparrow ]/[ Ctrl ]+E Move up one line<br />

[ Dnarrow ]/[ Ctrl ]+X Move down one line<br />

[ Leftarrow ]/[ Ctrl ]+S Move left one character<br />

[ Rightarrow ]/[ Ctrl ]+D Move right one character<br />

[ Ctrl ]-[ Leftarrow ]/[ Ctrl ]+A Move left one word<br />

[ Ctrl ]-[ Rightarrow ]/[ Ctrl ]+F Move right one word<br />

[ Home ] Move to beginning <strong>of</strong> current line<br />

[ End ] Move to end <strong>of</strong> current line<br />

[ Ctrl ]+[ Home ] Move to beginning <strong>of</strong> current window<br />

[ Ctrl ]+[ End ] Move to end <strong>of</strong> current window<br />

[ PgUp ] Move to previous edit window<br />

[ PgDn ] Move to next edit window<br />

[ Ctrl ]+[ PgUp ] Move to beginning <strong>of</strong> memo<br />

[ Ctrl ]+[ PgDn ] Move to end <strong>of</strong> memo<br />

[ Return ] Move to beginning <strong>of</strong> next line<br />

[ Delete ] Delete character at cursor<br />

[ Backspace ] Delete character to left <strong>of</strong> cursor<br />

[ Tab ] Insert tab character or spaces<br />

Printable characters Insert character<br />

[ Ctrl ]+Y Delete the current line<br />

[ Ctrl ]+T Delete word right<br />

[ Ctrl ]+B Reform paragraph<br />

[ Ctrl ]+V/[ Ins ] Toggle insert mode<br />

[ Ctrl ]+W Finish editing with save<br />

[ Esc ] Abort edit and return original<br />

368.14.132 MEMOLINE()<br />

MEMOLINE(cString,<br />

[nLineLength],<br />

[nLineNumber],<br />

[nTabSize],<br />

[lWrap]) ⇒ cLine<br />

cString<br />

nLineLength<br />

is the memo field or character string from which to extract a<br />

line <strong>of</strong> text.<br />

specifies the number <strong>of</strong> characters per line and can be between<br />

four and 254 . If not specified, the default line length is 79.


240 volume VIII Argomenti avanzati e accessori<br />

nLineNumber<br />

is the line number to extract. If not specified, the default value<br />

is one.<br />

nTabSize defines the tab size. If not specified, the default value is four.<br />

lWrap<br />

toggles word wrap on and <strong>of</strong>f. Specifying true (‘.T.’) toggles<br />

word wrap on; false (‘.F.’) toggles it <strong>of</strong>f. If not specified, the<br />

default value is true (‘.T.’).<br />

MEMOLINE() returns the line <strong>of</strong> text specified by nLineNumber in cString as a character string.<br />

If the line has fewer characters than the indicated length, the return value is padded with blanks.<br />

If the line number is greater than the total number <strong>of</strong> lines in cString, MEMOLINE() returns a<br />

null string (""). If lWrap is true (‘.T.’) and the indicated line length breaks the line in the middle<br />

<strong>of</strong> a word, that word is not included as part <strong>of</strong> the return value but shows up at the beginning <strong>of</strong><br />

the next line extracted with MEMOLINE(). If lWrap is false (‘.F.’), MEMOLINE() returns only<br />

the number <strong>of</strong> characters specified by the line length. The next line extracted by MEMOLINE()<br />

begins with the character following the next hard carriage return, and all intervening characters<br />

are not processed.<br />

368.14.133 MEMOREAD()<br />

MEMOREAD(cFile) ⇒ cString<br />

cFile<br />

is the name <strong>of</strong> the file to read from disk. It must include an<br />

extension if there is one, and can optionally include a path.<br />

MEMOREAD() returns the contents <strong>of</strong> a text file as a character string.<br />

368.14.134 MEMORY()<br />

MEMORY(nExp) ⇒ nKbytes<br />

nExp<br />

is a numeric value that determines the type <strong>of</strong> value MEM-<br />

ORY() returns.<br />

MEMORY() returns an integer numeric value representing the amount <strong>of</strong> memory available.<br />

MEMORY(0) Estimated total space available for character values<br />

MEMORY(1) Largest contiguous block available for character values<br />

MEMORY(2) Area available for RUN commands<br />

368.14.135 MEMOTRAN()<br />

Memo translate<br />

MEMOTRAN(cString,<br />

[cReplaceHardCR],<br />

[cReplaceS<strong>of</strong>tCR]) ⇒ cNewString<br />

cString is the character string or memo field to search.<br />

cReplaceHardCR<br />

is the character to replace a hard carriage return/linefeed pair<br />

with. If not specified, the default value is a semicolon (;).


nanoBase 1997 user manual 241<br />

cReplaceS<strong>of</strong>tCR<br />

is the character to replace a s<strong>of</strong>t carriage return/linefeed pair<br />

with. If not specified, the default value is a space.<br />

MEMOTRAN() returns a copy <strong>of</strong> cString with the specified carriage return/linefeed pairs replaced.<br />

368.14.136 MEMOWRIT()<br />

Memo write<br />

MEMOWRIT(cFile, cString) ⇒ lSuccess<br />

cFile<br />

is the name <strong>of</strong> the target disk file including the file extension<br />

and optional path and drive designator.<br />

cString is the character string or memo field to write to cFile.<br />

MEMOWRIT() is a memo function that writes a character string or memo field to a disk file.<br />

If a path is not specified, MEMOWRIT() writes cFile to the current DOS directory and not the<br />

current DEFAULT directory. If cFile already exists, it is overwritten. MEMOWRIT() returns true<br />

(‘.T.’) if the writing operation is successful; otherwise, it returns false (‘.F.’).<br />

368.14.137 MEMVARBLOCK()<br />

MEMVARBLOCK(cMemvarName) ⇒ bMemvarBlock<br />

cMemvarName<br />

is the name <strong>of</strong> the variable referred to by the set-get block,<br />

specified as a character string.<br />

MEMVARBLOCK() returns a code block that when evaluated sets (assigns) or gets (retrieves)<br />

the value <strong>of</strong> the given memory variable. If cMemvarName does not exist, MEMVARBLOCK()<br />

returns NIL.<br />

368.14.138 MIN()<br />

MIN(nExp1, nExp2) ⇒ nSmaller<br />

MIN(dExp1, dExp2) ⇒ dSmaller<br />

nExp1, nExp2 are the numeric values to compare.<br />

dExp1, dExp2 are the date values to compare.<br />

MIN() returns the smaller <strong>of</strong> the two arguments. The value returned is the same data type as the<br />

arguments.


242 volume VIII Argomenti avanzati e accessori<br />

368.14.139 MLCOUNT()<br />

Memo line count<br />

MLCOUNT(cString, [nLineLength],<br />

[nTabSize], [lWrap]) ⇒ nLines<br />

cString is the character string or memo field to count.<br />

nLineLength<br />

specifies the number <strong>of</strong> characters per line and can range from<br />

four to 254 . If not specified, the default line length is 79.<br />

nTabSize defines the tab size. If not specified, the default value is four.<br />

toggles word wrap on and <strong>of</strong>f. Specifying true (‘.T.’) toggles<br />

lWrap<br />

word wrap on; false (‘.F.’) toggles it <strong>of</strong>f. If not specified, the<br />

default value is true (‘.T.’).<br />

MLCOUNT() returns the number <strong>of</strong> lines in cString depending on the nLineLength, the<br />

nTabSize, and whether word wrapping is on or <strong>of</strong>f.<br />

368.14.140 MLCTOPOS()<br />

Memo line column to position<br />

MLCTOPOS(cText, nWidth, nLine,<br />

nCol, [nTabSize], [lWrap]) ⇒ nPosition<br />

cText<br />

nWidth<br />

nLine<br />

nCol<br />

nTabSize<br />

lWrap<br />

is the text string to scan.<br />

is the line length formatting width.<br />

is the line number counting from 1.<br />

is the column number counting from 0.<br />

is the number <strong>of</strong> columns between tab stops. If not specified,<br />

the default is 4.<br />

is the word wrap flag. If not specified, the default is true<br />

(‘.T.’).<br />

MLCTOPOS() returns the byte position within cText counting from 1.<br />

368.14.141 MLPOS()<br />

Memo line position<br />

MLPOS(cString, nLineLength,<br />

nLine, [nTabSize], [lWrap]) ⇒ nPosition<br />

cString is a character string or memo field.<br />

nLineLength specifies the number <strong>of</strong> characters per line.<br />

nLine<br />

specifies the line number.<br />

nTabSize defines the tab size. The default is four.<br />

toggles word wrap on and <strong>of</strong>f. Specifying true (‘.T.’) toggles<br />

lWrap<br />

word wrap on, and false (‘.F.’) toggles it <strong>of</strong>f. The default is<br />

true (‘.T.’).<br />

MLPOS() returns the character position <strong>of</strong> nLine in cString as an integer numeric value. If<br />

nLine is greater than the number <strong>of</strong> lines in cString, MLPOS() returns the length <strong>of</strong> cString.


nanoBase 1997 user manual 243<br />

368.14.142 MONTH()<br />

MONTH(dDate) ⇒ nMonth<br />

dDate is the date value to convert.<br />

MONTH() returns an integer numeric value in the range <strong>of</strong> zero to 12. Specifying a null date<br />

(CTOD("")) returns zero.<br />

368.14.143 MPOSTOLC()<br />

Memo position to line column<br />

MPOSTOLC(cText, nWidth, nPos,<br />

[nTabSize], [lWrap]) ⇒ aLineColumn<br />

cText<br />

nWidth<br />

nPos<br />

nTabSize<br />

lWrap<br />

is a text string.<br />

is the length <strong>of</strong> the formatted line.<br />

is the byte position within text counting from one.<br />

is the number <strong>of</strong> columns between tab stops. If not specified,<br />

the default is four.<br />

is the word wrap flag. If not specified, the default is true<br />

(‘.T.’).<br />

MPOSTOLC() returns an array containing the line and the column values for the specified byte<br />

position, nPos. MPOSTOLC() is a memo function that determines the formatted line and column<br />

corresponding to a particular byte position within cText. Note that the line number returned is<br />

one-relative, the column number is zero-relative. This is compatible with MEMOEDIT(). nPos<br />

is one-relative, compatible with AT(), RAT(), and other string functions.<br />

368.14.144 NETERR()<br />

Net error<br />

NETERR([lNewError]) ⇒ lError<br />

lNewError<br />

if specified sets the value returned by NETERR() to the specified<br />

status. lNewError can be either true (‘.T.’) or false<br />

(‘.F.’). Setting NETERR() to a specified value allows the<br />

runtime error handler to control the way certain file errors are<br />

handled.<br />

NETERR() returns true (‘.T.’) if a USE or APPEND BLANK fails. The initial value <strong>of</strong><br />

NETERR() is false (‘.F.’). If the current process is not running under a network operating system,<br />

NETERR() always returns false (‘.F.’).


244 volume VIII Argomenti avanzati e accessori<br />

368.14.145 NETNAME()<br />

NETNAME() ⇒ cWorkstationName<br />

NETNAME() returns the workstation identification as a character string up to 15 characters in<br />

length. If the workstation identification was never set or the application is not operating under<br />

the IBM PC Network, it returns a null string ("").<br />

368.14.146 NEXTKEY()<br />

NEXTKEY() ⇒ nInkeyCode<br />

NEXTKEY() returns an integer numeric value ranging from -39 to 386. If the keyboard buffer<br />

is empty, NEXTKEY() returns zero. If SET TYPEAHEAD is zero, NEXTKEY() always returns<br />

zero. NEXTKEY() is like the INKEY() function, but differs in one fundamental respect.<br />

INKEY() removes the pending key from the keyboard buffer and updates LASTKEY() with the<br />

value <strong>of</strong> the key. NEXTKEY(), by contrast, reads, but does not remove the key from the keyboard<br />

buffer and does not update LASTKEY().<br />

368.14.147 NOSNOW()<br />

NOSNOW(lToggle) ⇒ NIL<br />

lToggle<br />

NOSNOW() is used to suppress snow on old CGA monitors.<br />

368.14.148 ORDBAGEXT()<br />

ORDBAGEXT() ⇒ cBagExt<br />

is a logical value that toggles the current state <strong>of</strong> snow suppression.<br />

A value <strong>of</strong> true (‘.T.’) enables the snow suppression<br />

on, while a value <strong>of</strong> false (‘.F.’) disables snow suppression.<br />

ORDBAGEXT() returns a character expression that is the default Order Bag extension <strong>of</strong> the<br />

current work area. cBagExt is determined by the RDD active in the current work area.<br />

368.14.149 ORDBAGNAME()<br />

ORDBAGNAME(nOrder | cOrderName) ⇒ cOrderBagName<br />

nOrder<br />

cOrderName<br />

is an integer that identifies the position in the Order List <strong>of</strong> the<br />

target Order whose Order Bag name is sought.<br />

is a character string that represents the name <strong>of</strong> the target Order<br />

whose Order Bag name is sought.<br />

ORDBAGNAME() returns a character string, the Order Bag name <strong>of</strong> the specific Order.


nanoBase 1997 user manual 245<br />

368.14.150 ORDCREATE()<br />

ORDCREATE(cOrderBagName,[cOrderName], cExpKey, [bExpKey],<br />

[lUnique]) ⇒ NIL<br />

cOrderBagName is the name <strong>of</strong> a disk file containing one or more Orders.<br />

cOrderName is the name <strong>of</strong> the Order to be created.<br />

is an expression that returns the key value to place in the Order<br />

cExpKey<br />

for each record in the current work area. The maximum length<br />

<strong>of</strong> the index key expression is determined by the database<br />

driver.<br />

bExpKey<br />

is a code block that evaluates to a key value that is placed in<br />

the Order for each record in the current work area.<br />

lUnique<br />

specifies whether a unique Order is to be created. Default is<br />

the current global _SET_UNIQUE setting.<br />

ORDCREATE() is an Order management function that creates an Order in the current work area.<br />

It works like DBCREATEINDEX() except that it lets you create Orders in RDDs that recognize<br />

multiple Order Bags.<br />

368.14.151 ORDDESTROY()<br />

ORDDESTROY(cOrderName [, cOrderBagName ]) ⇒ NIL<br />

cOrderName<br />

is the name <strong>of</strong> the Order to be removed from the current or<br />

specified work area.<br />

cOrderBagName is the name <strong>of</strong> a disk file containing one or more Orders.<br />

ORDDESTROY() is an Order management function that removes a specified Order from<br />

multiple-Order Bags. ORDDESTROY() is not supported for DBFNDX and DBFNTX.<br />

368.14.152 ORDFOR()<br />

ORDFOR(cOrderName | nOrder [, cOrderBagName]) ⇒ cForExp<br />

cOrderName<br />

is the name <strong>of</strong> the target Order, whose cForExp is sought.<br />

nOrder<br />

is an integer that identifies the position in the Order List <strong>of</strong> the<br />

target Order whose cForExp is sought.<br />

cOrderBagName is the name <strong>of</strong> an Order Bag containing one or more Orders.<br />

ORDFOR() returns a character expression, cForExp, that represents the FOR condition <strong>of</strong> the<br />

specified Order. If the Order was not created using the FOR clause the return value will be an<br />

empty string (""). If the database driver does not support the FOR condition, it may either return<br />

an empty string ("") or raise an "unsupported function" error, depending on the driver.


246 volume VIII Argomenti avanzati e accessori<br />

368.14.153 ORDKEY()<br />

ORDKEY(cOrderName | nOrder [, cOrderBagName]) ⇒ cExpKey<br />

cOrderName<br />

is the name <strong>of</strong> an Order, a logical ordering <strong>of</strong> a database.<br />

nOrder<br />

is an integer that identifies the position in the Order List <strong>of</strong> the<br />

target Order whose cExpKey is sought.<br />

cOrderBagName is the name <strong>of</strong> a disk file containing one or more Orders.<br />

ORDKEY() is an Order management function that returns a character expression, cExpKey, that<br />

represents the key expression <strong>of</strong> the specified Order.<br />

368.14.154 ORDLISTADD()<br />

ORDLISTADD(cOrderBagName [, cOrderName]) ⇒ NIL<br />

cOrderBagName is the name <strong>of</strong> a disk file containing one or more Orders.<br />

the name <strong>of</strong> the specific Order from the Order Bag to be added<br />

to the Order List <strong>of</strong> the current work area. If you do not spec-<br />

cOrderName<br />

ify cOrderName, all orders in the Order Bag are added to the<br />

Order List <strong>of</strong> the current work area.<br />

ORDLISTADD() is an Order management function that adds the contents <strong>of</strong> an Order Bag , or<br />

a single Order in an Order Bag, to the Order List. Any Orders already associated with the work<br />

area continue to be active. If the newly opened Order Bag contains the only Order associated<br />

with the work area, it becomes the controlling Order; otherwise, the controlling Order remains<br />

unchanged.<br />

368.14.155 ORDLISTCLEAR()<br />

ORDLISTCLEAR() ⇒ NIL<br />

ORDLISTCLEAR() is an Order management function that removes all Orders from the Order<br />

List for the current work area.<br />

368.14.156 ORDLISTREBUILD()<br />

ORDLISTREBUILD() ⇒ NIL<br />

ORDLISTREBUILD() is an Order management function that rebuilds all the orders in the current<br />

Order List.<br />

368.14.157 ORDNAME()<br />

ORDNAME(nOrder[,cOrderBagName]) ⇒ cOrderName<br />

nOrder<br />

is an integer that identifies the position in the Order List <strong>of</strong> the<br />

target Order whose database name is sought.<br />

cOrderBagName is the name <strong>of</strong> a disk file containing one or more Orders.


nanoBase 1997 user manual 247<br />

ORDNAME() returns the name <strong>of</strong> the specified Order in the current Order List or the specified<br />

Order Bag if opened in the Current Order list.<br />

368.14.158 ORDNUMBER()<br />

ORDNUMBER(cOrderName [, cOrderBagName]) ⇒ nOrderNo<br />

cOrderName<br />

the name <strong>of</strong> the specific Order whose position in the Order<br />

List is sought.<br />

cOrderBagName is the name <strong>of</strong> a disk file containing one or more Orders.<br />

ORDNUMBER() returns nOrderNo, an integer that represents the position <strong>of</strong> the specified Order<br />

in the Order List.<br />

368.14.159 ORDSETFOCUS()<br />

ORDSETFOCUS([cOrderName | nOrder] [,cOrderBagName])<br />

⇒ cPrevOrderNameInFocus<br />

cOrderName<br />

is the name <strong>of</strong> the selected Order, a logical ordering <strong>of</strong> a<br />

database.<br />

nOrder<br />

is a number representing the position in the Order List <strong>of</strong> the<br />

selected Order.<br />

cOrderBagName is the name <strong>of</strong> a disk file containing one or more Orders.<br />

ORDSETFOCUS() is an Order management function that returns the Order Name <strong>of</strong> the previous<br />

controlling Order and optionally sets the focus to an new Order.<br />

368.14.160 OS()<br />

OS() ⇒ cOsName<br />

OS() returns the operating system name as a character string.<br />

368.14.161 OUTERR()<br />

Output error<br />

OUTERR(exp_list) ⇒ NIL<br />

exp_list<br />

is a list <strong>of</strong> values to display and can consist <strong>of</strong> any combination<br />

<strong>of</strong> data types including memo.<br />

OUTERR() is identical to OUTSTD() except that it writes to the standard error device rather<br />

than the standard output device. Output sent to the standard error device bypasses the console<br />

and output devices as well as any DOS redirection. It is typically used to log error messages in a<br />

manner that will not interfere with the standard screen or printer output.


248 volume VIII Argomenti avanzati e accessori<br />

368.14.162 OUTSTD()<br />

Output standard<br />

OUTSTD(exp_list) ⇒ NIL<br />

exp_list<br />

is a list <strong>of</strong> values to display and can consist <strong>of</strong> any combination<br />

<strong>of</strong> data types including memo.<br />

OUTSTD() is a simple output function similar to QOUT(), except that it writes to the STDOUT<br />

device (instead <strong>of</strong> to the console output stream).<br />

368.14.163 PAD?()<br />

PADL(exp, nLength, [cFillChar]) ⇒ cPaddedString<br />

PADC(exp, nLength, [cFillChar]) ⇒ cPaddedString<br />

PADR(exp, nLength, [cFillChar]) ⇒ cPaddedString<br />

exp<br />

is a character, numeric, or date value to pad with a fill character.<br />

nLength is the length <strong>of</strong> the character string to return.<br />

cFillChar<br />

is the character to pad exp with. If not specified, the default is<br />

a space character.<br />

PADC(), PADL(), and PADR() are character functions that pad character, date, and numeric<br />

values with a fill character to create a new character string <strong>of</strong> a specified length. PADC() centers<br />

exp within nLength adding fill characters to the left and right sides; PADL() adds fill characters<br />

on the left side; and PADR() adds fill characters on the right side.<br />

368.14.164 PCOL()<br />

Printed column<br />

PCOL() ⇒ nColumn<br />

PCOL() returns an integer numeric value representing the last printed column position, plus one.<br />

The beginning column position is zero.<br />

368.14.165 PROW()<br />

Printed row<br />

PROW() ⇒ nRow<br />

PROW() returns an integer numeric value that represents the number <strong>of</strong> the current line sent to<br />

the printer. The beginning row position is zero.


nanoBase 1997 user manual 249<br />

368.14.166 QOUT()<br />

QOUT([exp_list]) ⇒ NIL<br />

QQOUT([exp_list]) ⇒ NIL<br />

exp_list<br />

is a comma-separated list <strong>of</strong> expressions (<strong>of</strong> any data type<br />

other than array or block) to display to the console. If no argument<br />

is specified and QOUT() is specified, a carriage return/linefeed<br />

pair is displayed. If QQOUT() is specified without<br />

arguments, nothing displays.<br />

QOUT() and QQOUT() are console functions. They display the results <strong>of</strong> one or more expressions<br />

to the console. QOUT() outputs carriage return and linefeed characters before displaying<br />

the results <strong>of</strong> exp_list. QQOUT() displays the results <strong>of</strong> exp_list at the current ROW() and COL()<br />

position. When QOUT() and QQOUT() display to the console, ROW() and COL() are updated.<br />

368.14.167 RAT()<br />

Right at<br />

RAT(cSearch, cTarget) ⇒ nPosition<br />

cSearch<br />

is the character string to locate.<br />

cTarget is the character string to search.<br />

RAT() returns the position <strong>of</strong> cSearch within cTarget as an integer numeric value, starting the<br />

search from the right. If cSearch is not found, RAT() returns zero.<br />

368.14.168 RDDLIST()<br />

RDDLIST([nRDDType]) ⇒ aRDDList<br />

nRDDType<br />

is an integer that represents the type <strong>of</strong> the RDD you wish to<br />

list.<br />

nRDDType = 1 Full RDD implementation<br />

nRDDType = 2 Import/Export only driver.<br />

RDDLIST() returns a one-dimensional array <strong>of</strong> the RDD names registered with the application<br />

as nRDDType.<br />

368.14.169 RDDNAME()<br />

RDDNAME() ⇒ cRDDName<br />

RDDNAME() returns a character string, cRDDName, the registered name <strong>of</strong> the active RDD in<br />

the current or specified work area.


250 volume VIII Argomenti avanzati e accessori<br />

368.14.170 RDDSETDEFAULT()<br />

RDDSETDEFAULT([cNewDefaultRDD]) ⇒ cPreviousDefaultRDD<br />

cNewDefaultRDD<br />

is a character string, the name <strong>of</strong> the RDD that is to be made<br />

the new default RDD in the application.<br />

RDDSETDEFAULT() is an RDD function that sets or returns the name <strong>of</strong> the previous default<br />

RDD driver and, optionally, sets the current driver to the new RDD driver specified by<br />

cNewDefaultRDD.<br />

368.14.171 READINSERT()<br />

READINSERT([lToggle]) ⇒ lCurrentMode<br />

lToggle<br />

toggles the insert mode on or <strong>of</strong>f. True (‘.T.’) turns insert on,<br />

while false (‘.F.’) turns insert <strong>of</strong>f. The default is false (‘.F.’)<br />

or the last user-selected mode in READ or MEMOEDIT().<br />

READINSERT() returns the current insert mode state as a logical value.<br />

368.14.172 READMODAL()<br />

READMODAL(aGetList) ⇒ NIL<br />

aGetList<br />

is an array containing a list <strong>of</strong> Get objects to edit.<br />

READMODAL() is like the READ command, but takes a GetList array as an argument and does<br />

not reinitialize the GetList array when it terminates. The GET system is implemented using a<br />

public array called GetList. Each time an @...GET command executes, it creates a Get object and<br />

adds to the currently visible GetList array. The standard READ command is preprocessed into a<br />

call to READMODAL() using the GetList array as its argument.<br />

368.14.173 READVAR()<br />

READVAR() ⇒ cVarName<br />

READVAR() returns the name <strong>of</strong> the variable associated with the current Get object or the variable<br />

being assigned by the current MENU TO command as an uppercase character string.<br />

368.14.174 RECNO()<br />

Record number<br />

RECNO() ⇒ nRecord<br />

RECNO() returns the current record number as an integer numeric value. If the work area contains<br />

a database file with zero records, RECNO() returns one, BOF() and EOF() both return<br />

true (‘.T.’), and LASTREC() returns zero. If the record pointer is moved past the last record,


nanoBase 1997 user manual 251<br />

RECNO() returns LASTREC() + 1 and EOF() returns true (‘.T.’). If an attempt is made to<br />

move before the first record, RECNO() returns the record number <strong>of</strong> the first logical record in the<br />

database file and BOF() returns true (‘.T.’). If no database file is open, RECNO() will return a<br />

zero.<br />

368.14.175 RECSIZE()<br />

Record size<br />

RECSIZE() ⇒ nBytes<br />

RECSIZE() returns, as a numeric value, the record length, in bytes, <strong>of</strong> the database file open in<br />

the current work area. RECSIZE() returns zero if no database file is open.<br />

368.14.176 REPLICATE()<br />

REPLICATE(cString, nCount) ⇒ cRepeatedString<br />

cString is the character string to repeat.<br />

nCount<br />

is the number <strong>of</strong> times to repeat cString.<br />

REPLICATE() returns a character string. Specifying a zero as the nCount argument returns a<br />

null string ("").<br />

368.14.177 RESTSCREEN()<br />

Restore screen<br />

RESTSCREEN([nTop], [nLeft],<br />

[nBottom], [nRight], cScreen) ⇒ NIL<br />

nTop, nLeft, nBottom, nRight<br />

cScreen<br />

define the coordinates <strong>of</strong> the screen information contained in<br />

cScreen. If the cScreen was saved without coordinates to preserve<br />

the entire screen, no screen coordinates are necessary<br />

with RESTSCREEN().<br />

is a character string containing the saved screen region.<br />

RESTSCREEN() is a screen function that redisplays a screen region saved with SAVE-<br />

SCREEN(). The target screen location may be the same as or different than the original location<br />

when the screen region was saved.<br />

368.14.178 RIGHT()<br />

RIGHT(cString, nCount) ⇒ cSubString<br />

cString is the character string from which to extract characters.<br />

nCount is the number <strong>of</strong> characters to extract.<br />

RIGHT() returns the rightmost nCount characters <strong>of</strong> cString. If nCount is zero, RIGHT() returns<br />

a null string (""). If nCount is negative or larger than the length <strong>of</strong> the character string,


252 volume VIII Argomenti avanzati e accessori<br />

RIGHT() returns cString.<br />

368.14.179 RLOCK()<br />

Record lock<br />

RLOCK() ⇒ lSuccess<br />

RLOCK() is a network function that locks the current record, preventing other users from updating<br />

the record until the lock is released. RLOCK() provides a shared lock, allowing other users<br />

read-only access to the locked record while allowing only the current user to modify it. A record<br />

lock remains until another record is locked, an UNLOCK is executed, the current database file is<br />

closed, or an FLOCK() is obtained on the current database file.<br />

368.14.180 ROUND()<br />

ROUND(nNumber, nDecimals) ⇒ nRounded<br />

nNumber is the numeric value to round.<br />

nDecimals<br />

defines the number <strong>of</strong> decimal places to retain. Specifying a<br />

negative nDecimals value rounds whole number digits.<br />

ROUND() is a numeric function that rounds nNumber to the number <strong>of</strong> places specified by<br />

nDecimals. Specifying a zero or negative value for nDecimals allows rounding <strong>of</strong> whole numbers.<br />

A negative nDecimals indicates the number <strong>of</strong> digits to the left <strong>of</strong> the decimal point to<br />

round. Digits between five to nine, inclusive, are rounded up. Digits below five are rounded<br />

down.<br />

368.14.181 ROW()<br />

ROW() ⇒ nRow<br />

ROW() returns the cursor row position as an integer numeric value. The range <strong>of</strong> the return value<br />

is zero to MAXROW().<br />

368.14.182 RTRIM()<br />

Right trim<br />

[R]TRIM(cString) ⇒ cTrimString<br />

cString is the character string to copy without trailing spaces.<br />

RTRIM() returns a copy <strong>of</strong> cString with the trailing spaces removed. If cString is a null string<br />

("") or all spaces, RTRIM() returns a null string ("").


nanoBase 1997 user manual 253<br />

368.14.183 SAVESCREEN()<br />

SAVESCREEN([nTop], [nLeft],<br />

[nBottom], [nRight]) ⇒ cScreen<br />

nTop, nLeft, nBottom, nRight<br />

define the coordinates <strong>of</strong> the screen region to save. Default is<br />

the entire screen.<br />

SAVESCREEN() returns the specified screen region as a character string.<br />

368.14.184 SCROLL()<br />

SCROLL([nTop], [nLeft],<br />

[nBottom], [nRight], [nVert] [nHoriz]) ⇒ NIL<br />

nTop, nLeft, nBottom, nRight define the scroll region coordinates.<br />

nVert<br />

nHoriz<br />

defines the number <strong>of</strong> rows to scroll, vertically. A positive<br />

value scrolls up the specified number <strong>of</strong> rows. A negative<br />

value scrolls down the specified number <strong>of</strong> rows. A value <strong>of</strong><br />

zero disables vertical scrolling. If nVert is not specified, zero<br />

is assumed.<br />

defines the number <strong>of</strong> rows to scroll horizontally. A positive<br />

value scrolls left the specified number <strong>of</strong> columns. A negative<br />

value scrolls right the specified number <strong>of</strong> columns. A value<br />

<strong>of</strong> zero disables horizontal scrolling. If nHoriz is not specified,<br />

zero is assumed. If you supply neither nVert or nHoriz<br />

parameters to SCROLL(), the area specified by the first four<br />

parameters will be blanked.<br />

SCROLL() is a screen function that scrolls a screen region up or down a specified number <strong>of</strong><br />

rows. When a screen scrolls up, the first line <strong>of</strong> the region is erased, all other lines are moved<br />

up, and a blank line is displayed in the current standard color on the bottom line <strong>of</strong> the specified<br />

region. If the region scrolls down, the operation is reversed. If the screen region is scrolled more<br />

than one line, this process is repeated.<br />

368.14.185 SECONDS()<br />

SECONDS() ⇒ nSeconds<br />

SECONDS() returns the system time as a numeric value in the form seconds.hundredths. The numeric<br />

value returned is the number <strong>of</strong> seconds elapsed since midnight, and is based on a twentyfour<br />

hour clock in a range from zero to 86399.<br />

368.14.186 SELECT()<br />

SELECT([cAlias]) ⇒ nWorkArea<br />

cAlias<br />

is the target work area alias name.


254 volume VIII Argomenti avanzati e accessori<br />

SELECT() returns the work area <strong>of</strong> the specified alias as a integer numeric value.<br />

368.14.187 SET()<br />

SET(nSpecifier, [expNewSetting], [lOpenMode])<br />

⇒ CurrentSetting<br />

nSpecifier<br />

expNewSetting<br />

lOpenMode<br />

SET() returns the current value <strong>of</strong> the specified setting.<br />

is a numeric value that identifies the setting to be inspected or<br />

changed.<br />

is an optional argument that specifies a new value for<br />

the nSpecifier. The type <strong>of</strong> expNewSetting depends on<br />

nSpecifier.<br />

is a logical value that indicates whether or not files are opened<br />

for some settings. A value <strong>of</strong> false (‘.F.’) means the file<br />

should be truncated. A value <strong>of</strong> true (‘.T.’) means the file<br />

should be opened in append mode. In either case, if the file<br />

does not exist, it is created. If this argument is not specified,<br />

the default is append mode.<br />

Inside nB, the function SET() is not so easy to use as inside the Clipper environment. This<br />

because nB cannot support manifest constants and a numeric specifier nSpecifier is not easy to<br />

manage. Instead <strong>of</strong> SET() you can use SETVERB().<br />

368.14.188 SETBLINK()<br />

SETBLINK([lToggle]) ⇒ lCurrentSetting<br />

lToggle<br />

SETBLINK() returns the current setting as a logical value.<br />

368.14.189 SETCANCEL()<br />

SETCANCEL([lToggle]) ⇒ lCurrentSetting<br />

lToggle<br />

SETCANCEL() returns the current setting as a logical value.<br />

changes the meaning <strong>of</strong> the asterisk (*) character when it<br />

is encountered in a SETCOLOR() string. Specifying true<br />

(‘.T.’) sets character blinking on and false (‘.F.’) sets background<br />

intensity. The default is true (‘.T.’).<br />

changes the availability <strong>of</strong> Alt-C and Ctrl-Break as termination<br />

keys. Specifying true (‘.T.’) allows either <strong>of</strong> these keys<br />

to terminate an application and false (‘.F.’) disables both<br />

keys. The default is true (‘.T.’).


nanoBase 1997 user manual 255<br />

368.14.190 SETCOLOR()<br />

SETCOLOR([cColorString]) ⇒ cColorString<br />

cColorString<br />

368.14.191 SETCURSOR()<br />

SETCURSOR([nCursorShape]) ⇒ nCurrentSetting<br />

nCursorShape<br />

is a character string containing a list <strong>of</strong> color attribute settings<br />

for subsequent screen painting.<br />

is a number indicating the shape <strong>of</strong> the cursor.<br />

nCursorShape == 0 None<br />

nCursorShape == 1 Underline<br />

nCursorShape == 2 Lower half block<br />

nCursorShape == 3 Full block<br />

nCursorShape == 4 Upper half block<br />

SETCURSOR() returns the current cursor shape as a numeric value.<br />

368.14.192 SETKEY()<br />

SETKEY(nInkeyCode, [bAction]) ⇒ bCurrentAction<br />

nInkeyCode is the INKEY() value <strong>of</strong> the key to be associated or queried.<br />

bAction<br />

specifies a code block that is automatically executed whenever<br />

the specified key is pressed during a wait state.<br />

SETKEY() returns the action block currently associated with the specified key, or NIL if the<br />

specified key is not currently associated with a block.<br />

368.14.193 SETMODE()<br />

SETMODE(nRows, nCols) ⇒ lSuccess<br />

nRows<br />

nCols<br />

is the number <strong>of</strong> rows in the desired display mode.<br />

is the number <strong>of</strong> columns in the desired display mode.<br />

SETMODE() is an environment function that attempts to change the mode <strong>of</strong> the display hardware<br />

to match the number <strong>of</strong> rows and columns specified. The change in screen size is reflected<br />

in the values returned by MAXROW() and MAXCOL().


256 volume VIII Argomenti avanzati e accessori<br />

368.14.194 SETPOS()<br />

Set position<br />

SETPOS(nRow, nCol) ⇒ NIL<br />

nRow, nCol<br />

define the new screen position <strong>of</strong> the cursor. These values may<br />

range from 0, 0 to MAXROW(), MAXCOL().<br />

SETPOS() is an environment function that moves the cursor to a new position on the screen.<br />

After the cursor is positioned, ROW() and COL() are updated accordingly.<br />

368.14.195 SETPRC()<br />

Set printer row column<br />

SETPRC(nRow, nCol) ⇒ NIL<br />

nRow is the new PROW() value.<br />

nCol is the new PCOL() value.<br />

SETPRC() is a printer function that sends control codes to the printer without changing the<br />

tracking <strong>of</strong> the printhead position.<br />

368.14.196 SOUNDEX()<br />

SOUNDEX(cString) ⇒ cSoundexString<br />

cString is the character string to convert.<br />

SOUNDEX() returns a four-digit character string in the form A999.<br />

368.14.197 SPACE()<br />

SPACE(nCount) ⇒ cSpaces<br />

nCount<br />

is the number <strong>of</strong> spaces to return.<br />

SPACE() returns a character string. If nCount is zero, SPACE() returns a null string ("").<br />

368.14.198 SQRT()<br />

SQRT(nNumber) ⇒ nRoot<br />

nNumber<br />

is a positive number to take the square root <strong>of</strong>.<br />

SQRT() returns a numeric value calculated to double precision. The number <strong>of</strong> decimal places<br />

displayed is determined solely by SET DECIMALS regardless <strong>of</strong> SET FIXED. A negative


nanoBase 1997 user manual 257<br />

nNumber returns zero.<br />

368.14.199 STR()<br />

String<br />

STR(nNumber, [nLength], [nDecimals]) ⇒ cNumber<br />

nNumber<br />

nLength<br />

nDecimals<br />

STR() returns nNumber formatted as a character string.<br />

368.14.200 STRTRAN()<br />

STRTRAN(cString, cSearch,<br />

[cReplace], [nStart], [nCount]) ⇒ cNewString<br />

is the numeric expression to convert to a character string.<br />

is the length <strong>of</strong> the character string to return, including decimal<br />

digits, decimal point, and sign.<br />

is the number <strong>of</strong> decimal places to return.<br />

cString is the character string or memo field to search.<br />

cSearch<br />

is the sequence <strong>of</strong> characters to locate.<br />

is the sequence <strong>of</strong> characters with which to replace cSearch.<br />

cReplace<br />

If this argument is not specified, the specified instances <strong>of</strong> the<br />

search argument are replaced with a null string ("").<br />

nStart<br />

is the first occurrence that will be replaced. If this argument is<br />

omitted, the default is one.<br />

nCount<br />

is the number <strong>of</strong> occurrences to replace. If this argument is<br />

not specified, the default is all.<br />

STRTRAN() returns a new character string with the specified instances <strong>of</strong> cSearch replaced with<br />

cReplace.<br />

368.14.201 STUFF()<br />

STUFF(cString, nStart,<br />

nDelete, cInsert) ⇒ cNewString<br />

cString<br />

is the target character string into which characters are inserted<br />

and deleted.<br />

nStart<br />

is the starting position in the target string where the insertion/deletion<br />

occurs.<br />

nDelete is the number <strong>of</strong> characters to delete.<br />

cInsert<br />

is the string to insert.<br />

STUFF() returns a copy <strong>of</strong> cString with the specified characters deleted and with cInsert inserted.


258 volume VIII Argomenti avanzati e accessori<br />

368.14.202 SUBSTR()<br />

Sub string<br />

SUBSTR(cString, nStart, [nCount]) ⇒ cSubstring<br />

cString is the character string from which to extract a substring.<br />

is the starting position in cString. If nStart is positive, it is<br />

nStart<br />

relative to the leftmost character in cString. If nStart is negative,<br />

it is relative to the rightmost character in the cString.<br />

is the number <strong>of</strong> characters to extract. If omitted, the substring<br />

begins at nStart and continues to the end <strong>of</strong> the string. If<br />

nCount<br />

nCount is greater than the number <strong>of</strong> characters from nStart<br />

to the end <strong>of</strong> cString, the extra is ignored.<br />

SUBSTR() is a character function that extracts a substring from another character string or memo<br />

field.<br />

368.14.203 TIME()<br />

TIME() ⇒ cTimeString<br />

TIME() returns the system time as a character string in the form hh:mm:ss. hh is hours in 24-hour<br />

format, mm is minutes, and ss is seconds.<br />

TIME() is a time function that displays the system time on the screen or prints it on a report.<br />

368.14.204 TONE()<br />

TONE(nFrequency, nDuration) ⇒ NIL<br />

nFrequency<br />

nDuration<br />

is a positive numeric value indicating the frequency <strong>of</strong> the<br />

tone to sound.<br />

is a positive numeric value indicating the duration <strong>of</strong> the tone<br />

measured in increments <strong>of</strong> 1/18 <strong>of</strong> a second. For example, an<br />

nDuration value <strong>of</strong> 18 represents one second.<br />

For both arguments, noninteger values are truncated (not rounded) to their integer portion.<br />

368.14.205 TRANSFORM()<br />

TRANSFORM(exp, cSayPicture) ⇒ cFormatString<br />

exp<br />

cSayPicture<br />

is the value to format. This expression can be any valid data<br />

type except array, code block, and NIL.<br />

is a string <strong>of</strong> picture and template characters that describes the<br />

format <strong>of</strong> the returned haracter string.<br />

TRANSFORM() converts exp to a formatted character string as defined by cSayPicture.


nanoBase 1997 user manual 259<br />

368.14.206 TYPE()<br />

TYPE(cExp) ⇒ cType<br />

cExp<br />

TYPE() returns one <strong>of</strong> the following characters:<br />

A<br />

Array<br />

B Block<br />

C Character<br />

D Date<br />

L Logical<br />

M Memo<br />

N Numeric<br />

O<br />

Object<br />

U NIL, local, or static<br />

UE Error syntactical<br />

UI Error indeterminate<br />

is a character expression whose type is to be determined.<br />

cExp can be a field, with or without the alias, a private or<br />

public variable, or an expression <strong>of</strong> any type.<br />

TYPE() is a system function that returns the type <strong>of</strong> the specified expression. TYPE() is like<br />

VALTYPE() but uses the macro operator (&) to determine the type <strong>of</strong> the argument. VALTYPE(),<br />

by contrast, evaluates an expression and determines the data type <strong>of</strong> the return value.<br />

368.14.207 UPDATED()<br />

UPDATED() ⇒ lChange<br />

UPDATED() returns true (‘.T.’) if data in a GET is added or changed; otherwise, it returns false<br />

(‘.F.’).<br />

368.14.208 UPPER()<br />

UPPER(cString) ⇒ cUpperString<br />

cString is the character string to convert.<br />

UPPER() returns a copy <strong>of</strong> cString with all alphabetical characters converted to uppercase. All<br />

other characters remain the same as in the original string.<br />

368.14.209 USED()<br />

USED() ⇒ lDbfOpen<br />

USED() returns true (‘.T.’) if there is a database file in USE in the current work area; otherwise,<br />

it returns false (‘.F.’).


260 volume VIII Argomenti avanzati e accessori<br />

368.14.210 VAL()<br />

Value<br />

VAL(cNumber) ⇒ nNumber<br />

cNumber<br />

is the character expression to convert.<br />

VAL() is a character conversion function that converts a character string containing numeric<br />

digits to a numeric value. When VAL() is executed, it evaluates cNumber until a second decimal<br />

point, the first non-numeric character, or the end <strong>of</strong> the expression is encountered.<br />

368.14.211 VALTYPE()<br />

Value type<br />

VALTYPE(exp) ⇒ cType<br />

exp is an expression <strong>of</strong> any type.<br />

VALTYPE() returns a single character representing the data type returned by exp. VALTYPE()<br />

returns one <strong>of</strong> the following characters:<br />

A<br />

Array<br />

B Block<br />

C Character<br />

D Date<br />

L Logical<br />

M Memo<br />

N Numeric<br />

O<br />

Object<br />

U NIL<br />

VALTYPE() is a system function that takes a single argument, evaluates it, and returns a one<br />

character string describing the data type <strong>of</strong> the return value.<br />

368.14.212 YEAR()<br />

YEAR(dDate) ⇒ nYear<br />

dDate is the date value to convert.<br />

YEAR() returns the year <strong>of</strong> the specified date value including the century digits as a four-digit<br />

numeric value. The value returned is not affected by the current DATE or CENTURY format.<br />

Specifying a null date (CTOD("")) returns zero.


nanoBase 1997 user manual 261<br />

368.15 nB functions<br />

Some functions made into nB are available for macro use. Not all available functions are here<br />

documented.<br />

368.15.1 ACCEPT()<br />

ACCEPT( Field, [cMessage], [cHeader] ) ⇒ updatedField|NIL<br />

It is a prompt function that shows cMessage asking to type something into Field. It returns the<br />

updated data or NIL if [ Esc ] was pressed. The string cHeader is showed centered at the top<br />

window.<br />

368.15.2 ACHOICE()<br />

ACHOICE(nTop, nLeft, nBottom, nRight,<br />

acMenuItems,<br />

[alSelectableItems],<br />

[nInitialItem],<br />

[lButtons | aButtons]) ⇒ nPosition<br />

nTop, nLeft, nBottom, nRight are the window coordinates.<br />

acMenuItems<br />

is an array <strong>of</strong> character strings to display as the menu items.<br />

is a parallel array <strong>of</strong> logical values (one element for each item<br />

in acMenuItems) that specify the selectable menu items. Elements<br />

can be logical values or character strings. If the ele-<br />

alSelectableItems<br />

ment is a character string, it is evaluated as a macro expression<br />

which should evaluate to a logical data type. A value <strong>of</strong><br />

false (‘.F.’) means that the corresponding menu item is not<br />

available, and a value <strong>of</strong> true (‘.T.’) means that it is available.<br />

By default, all menu items are available for selection.<br />

nInitialItem<br />

is the position in the acMenuItems array <strong>of</strong> the item that will<br />

be highlighted when the menu is initially displayed.<br />

lButtons<br />

if True means that default buttons will appear.<br />

aButtons<br />

is an array <strong>of</strong> buttons.<br />

aButtons[n][1] == N the nth button row position;<br />

aButtons[n][2] == N the nth button column position;<br />

aButtons[n][3] == C the nth button text;<br />

aButtons[n][4] == B the nth button code block.<br />

ACHOICE() returns the numeric position in the acMenuItems array <strong>of</strong> the menu item selected.<br />

If no choice is made, ACHOICE() returns zero.<br />

368.15.3 ACHOICEWINDOW()<br />

ACHOICEWINDOW( acMenuItems, [cDescription],<br />

nTop, nLeft, nBottom, nRight,<br />

[alSelectableItems],<br />

[nInitialItem] ) ⇒ nPosition<br />

acMenuItems<br />

is an array <strong>of</strong> character strings to display as the menu items.


262 volume VIII Argomenti avanzati e accessori<br />

cDescription is a header to be shown at the top <strong>of</strong> window.<br />

nTop, nLeft, nBottom, nRight are the window coordinates.<br />

is a parallel array <strong>of</strong> logical values (one element for each item<br />

in acMenuItems) that specify the selectable menu items. Elements<br />

can be logical values or character strings. If the element<br />

is a character string, it is evaluated as a macro expres-<br />

alSelectableItems<br />

sion which should evaluate to a logical data type. A value <strong>of</strong><br />

false (‘.F.’) means that the corresponding menu item is not<br />

available, and a value <strong>of</strong> true (‘.T.’) means that it is available.<br />

By default, all menu items are available for selection.<br />

is the position in the acMenuItems array <strong>of</strong> the item that will<br />

nInitialItem<br />

be highlighted when the menu is initially displayed.<br />

ACHOICEWINDOW() calls ACHOICE() with a window border around the ACHOICE() screen<br />

area.<br />

368.15.4 ALERTBOX()<br />

ALERTBOX( cMessage, [aOptions] ) ⇒ nChoice<br />

is the message text displayed, centered, in the alert box. If the<br />

cMessage<br />

message contains one or more semicolons, the text after the<br />

semicolons is centered on succeeding lines in the dialog box.<br />

aOptions defines a list <strong>of</strong> up to 4 possible responses to the dialog box.<br />

ALERTBOX() returns a numeric value indicating which option was chosen. If the [ Esc ] key is<br />

pressed, the value returned is zero. The ALERTBOX() function creates a simple modal dialog.<br />

The user can respond by moving a highlight bar and pressing the Return or SpaceBar keys, or<br />

by pressing the key corresponding to the first letter <strong>of</strong> the option. If aOptions is not supplied, a<br />

single "Ok" option is presented.<br />

ALERTBOX() is similar to ALERT() but it accept mouse input.<br />

368.15.5 ATB()<br />

ATB( [nTop], [nLeft], [nBottom], [nRight],<br />

aArray, [nSubscript],<br />

[acColSayPic],<br />

[acColTopSep], [acColBodySep], [acColBotSep],<br />

[acColHead], [acColFoot],<br />

[abColValid],<br />

[abColMsg],<br />

[cColor], [abColColors],<br />

[lModify],<br />

[lButtons | aButtons] ) ⇒ NIL<br />

nTop, nLeft, nBottom, nRight defines the screen area where browse have to take place.<br />

aArray bidimensional array to be browsed.<br />

nSubscript starting array position.<br />

acColSayPic is the picture array.<br />

acColTopSep is the top separation array: default is chr(194)+chr(196).


nanoBase 1997 user manual 263<br />

acColBodySep is the body separation array: default is chr(179).<br />

acColBotSep is the bottom separation array: default is chr(193)+chr(196).<br />

acColHead<br />

is the header array for every column.<br />

acColFoot<br />

is the footer array for every column.<br />

abColValid<br />

is the validation array that specify when a field is properly<br />

filled. The condition must be specified in code block format.<br />

is the message array that permits to show information at the<br />

abColMsg<br />

bottom <strong>of</strong> browse area. The array must be composed with<br />

code blocks which result with a character string.<br />

cColor<br />

is the color string: it may be longer than the usual 5 elements.<br />

is the color code block array. The code block receive as pa-<br />

abColColors<br />

rameter the value contained inside the field and must return<br />

an array containing two numbers: they correspond to the two<br />

color couple from cColor.<br />

lModify indicates whether the browse can modify data.<br />

lButtons<br />

if True, default buttons are displayed.<br />

aButtons<br />

array <strong>of</strong> buttons.<br />

aButtons[n][1] N the nth button row position;<br />

aButtons[n][2] N the nth button column position;<br />

aButtons[n][3] C the nth button text;<br />

aButtons[n][4] B the nth button code block.<br />

This function starts the browse <strong>of</strong> a bidimensional array. Only arrays containing monodimensional<br />

array containing the same kind <strong>of</strong> editable data are allowed. The function can handle a<br />

maximum <strong>of</strong> 61 columns.<br />

368.15.6 BCOMPILE()<br />

BCOMPILE( cString ) ⇒ bBlock<br />

Compiles the string cString and returns the code block bBlock<br />

368.15.7 BUTTON()<br />

BUTTON( @aButtons,<br />

[nRow], [nCol], [cText], [cColor],<br />

[bAction] ) ⇒ NIL<br />

aButtons<br />

the array <strong>of</strong> buttons to be increased with a new button array.<br />

nRow and nCol<br />

is the row and column starting position for the button string.<br />

cText<br />

is the text that make up the button.<br />

cColor<br />

is the color string.<br />

bAction is the code block associated to the button.<br />

This function adds to aButtons a new button array. Please note that the button array added is<br />

compatible only with the READ() function and not the other function using array <strong>of</strong> buttons: the<br />

others do not have a color string.


264 volume VIII Argomenti avanzati e accessori<br />

368.15.8 COLORARRAY()<br />

COLORARRAY( cColor ) ⇒ aColors<br />

cColors<br />

a color string to be translated into a color array.<br />

This function transform a color string into a color array. The array has as many elements as the<br />

colors contained inside cColor string.<br />

368.15.9 COORDINATE()<br />

COORDINATE( [@nTop, @nLeft], @nBottom, @nRight,<br />

[cHorizontal], [cVertical] ) ⇒ NIL<br />

nTop, nLeft, nBottom and nRight<br />

cHorozontal<br />

cVertical<br />

are the starting position <strong>of</strong> a window that is to be differently<br />

aligned.<br />

determinates the horizontal alignment:<br />

"L" all left;<br />

"l" middle left;<br />

"C" center;<br />

"c" center;<br />

"R" all right;<br />

"r" middle right.<br />

determinate the vertical alignment:<br />

"T" top;<br />

"t" up;<br />

"C" center;<br />

"c" center;<br />

"B" bottom;<br />

"b" down.<br />

This function helps with the windows alignment recalculating and modifying nTop, nLeft,<br />

nBottom and nRight in the way to obtain the desired alignment.<br />

368.15.10 COPYFILE()<br />

COPYFILE( cSourceFile, cTargetFile|cDevice ) ⇒ NIL<br />

cSourceFile the source filename.<br />

cTargetFile the target filename.<br />

cDevice<br />

the target devicename.<br />

This function copies the cSourceFile to cTargetFile or to cDevice.


nanoBase 1997 user manual 265<br />

368.15.11 DBAPP()<br />

DBAPP( cFileName, [acFields],<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords],<br />

[nRecord],<br />

[lRest],<br />

[cDriver] ) ⇒ NIL<br />

cFileName<br />

acFields<br />

bForCondition<br />

bWhileCondition<br />

nNextRecord<br />

nRecord<br />

lRest<br />

cDriver<br />

the filename containing data to append to the active alias.<br />

array <strong>of</strong> fieldnames indicating the fields that should be updated<br />

on the active alias (default is all).<br />

a code block containing the FOR condition to respect for the<br />

data append. Will be appended data that makes the evaluation<br />

<strong>of</strong> this code block True.<br />

a code block containing the WHILE condition to respect for<br />

the data append. Will be appended data as long as the evaluation<br />

<strong>of</strong> this code block is True: the first time it becomes False,<br />

the data appending is terminated.<br />

if used, means that only the first nNextRecords will be appended.<br />

if used, means that that only the record nRecord will be appended.<br />

this option is not available here also if the function saves a<br />

place for it.<br />

is the optional driver name to use to open the cFileName file.<br />

This function is used to append data to the active alias using data from the cFileName file, that<br />

in this case is a ‘.DBF’ file.<br />

368.15.12 DBCLOSE()<br />

DBCLOSE() ⇒ NIL<br />

It is a substitution function <strong>of</strong> DBCLOSEALL() to use inside "compiled" macros, as a true DB-<br />

CLOSEALL() will close the macro file too.<br />

368.15.13 DBCONTINUE()<br />

DBCONTINUE() ⇒ NIL<br />

This function resumes a pending DBLOCATE().<br />

368.15.14 DBCOPY()<br />

DBCOPY( cFileName, [acFields],<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords],<br />

[nRecord],<br />

[lRest],<br />

[cDriver] ) ⇒ NIL


266 volume VIII Argomenti avanzati e accessori<br />

cFileName<br />

acFields<br />

bForCondition<br />

bWhileCondition<br />

nNextRecord<br />

nRecord<br />

lRest<br />

cDriver<br />

the target filename for the data contained inside the active<br />

alias.<br />

array <strong>of</strong> fieldnames indicating the fields that should be used<br />

from the active alias (default is all).<br />

a code block containing the FOR condition to respect for the<br />

data copy. Will be copied the data that makes the evaluation<br />

<strong>of</strong> this code block True.<br />

a code block containing the WHILE condition to respect for<br />

the data copy. Will be copied data as long as the evaluation<br />

<strong>of</strong> this code block is True: the first time it becomes False, the<br />

data copying is terminated.<br />

if used, means that only the first nNextRecords will be<br />

copied.<br />

if used, means that that only the record nRecord will be<br />

copied.<br />

if used means that only the remaining records inside the active<br />

alias are copied.<br />

is the optional driver name to use to open the cFileName file.<br />

This function is used to copy data to cFileName form the active alias.<br />

368.15.15 DBCOPYSTRUCT()<br />

DBCOPYSTRUCT( cDatabase, [acFields] ) ⇒ NIL<br />

cDatabase<br />

acFields<br />

is a structure ‘.DBF’ file that will be filled with structure information<br />

about the active alias.<br />

is an array <strong>of</strong> fieldnames that should be taken into consideration.<br />

This function creates a structure ‘.DBF’ file copying the structure <strong>of</strong> the active alias.<br />

368.15.16 DBCOPYXSTRUCT()<br />

DBCOPYXSTRUCT( cExtendedDatabase ) ⇒ NIL<br />

cExtendedDatabase<br />

is a structure ‘.DBF’ file that will be filled with structure information<br />

about the active alias, accepting extended structure<br />

informations.<br />

This function creates a structure ‘.DBF’ file copying the structure <strong>of</strong> the active alias. This function<br />

accept non-standard structure, that is, the extended structure available inside Clipper.<br />

368.15.17 DBDELIM()<br />

DBDELIM( lCopyTo, cFileName, [cDelimiter], [acFields],<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord], [lRest] ) ⇒ NIL


nanoBase 1997 user manual 267<br />

lCopyTo<br />

cFileName<br />

cDelimiter<br />

acFields<br />

bForCondition<br />

bWhileCondition<br />

nNextRecord<br />

nRecord<br />

lRest<br />

if True the function work copying data to cFileName from the<br />

active alias, if False the function work appending data from<br />

cFileName to the active alias.<br />

the filename containing data to append to the active alias or<br />

to use as the target <strong>of</strong> the data copy from the active alias.<br />

the delimiter string (or character) used to separate fields inside<br />

cFileName.<br />

array <strong>of</strong> fieldnames indicating the fields <strong>of</strong> the active alias that<br />

should be taken into consideration (default is all).<br />

a code block containing the FOR condition to respect. The operation<br />

will be made for all records that respect the condition.<br />

a code block containing the WHILE condition to respect. The<br />

first time it becomes False, the operation is terminated.<br />

if used, means that only the first nNextRecords will be appended/copied.<br />

if used, means that that only the record nRecord will be ap-<br />

pended/copied.<br />

if used means that only the remaining records will be taken<br />

into consideration.<br />

This function is used to append data to the active alias using data from the cFileName file or to<br />

copy data into cFileName using the active alias as the source. cFileName is a delimited ASCII<br />

file.<br />

368.15.18 DBISTATUS()<br />

DBISTATUS() ⇒ cDBInformations<br />

This function returns the informations on the active alias in a text form.<br />

368.15.19 DBISTRUCTURE()<br />

DBISTRUCTURE() ⇒ cTextStructure | NIL<br />

This function returns the structure information on the active alias in a text form.<br />

368.15.20 DBJOIN()<br />

DBJOIN( cAlias, cDatabase,<br />

[acFields], [bForCondition] ) ⇒ NIL<br />

cAlias<br />

cDatabase<br />

acFields<br />

the name <strong>of</strong> the alias to use to merge with records from the<br />

active alias.<br />

the target ‘.DBF’ filename.<br />

the array <strong>of</strong> fieldnames which represent the projection <strong>of</strong><br />

fields form both Aliases into the new ‘.DBF’ file. If not specified,<br />

all fields from the primary work area are included in the<br />

target ‘.DBF’ file.<br />

This function creates a new database file by merging selected records and fields form two work<br />

areas (Aliases) based on a general condition. It works by making a complete pass through the<br />

secondary work area cAlias for each record in the primary work area (the active alias), evaluating


268 volume VIII Argomenti avanzati e accessori<br />

the condition for each record in the secondary work area. When bForCondition is evaluated True,<br />

a new record is created in the target database file cDatabase using the fields specified from both<br />

work areas inside acFields.<br />

368.15.21 DBLABELFORM()<br />

DBLABELFORM( cLabel, [lToPrinter], [cFile],<br />

[lNoConsole], [bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord], [lRest], [lSample] )<br />

⇒ NIL<br />

cLabel<br />

is the name <strong>of</strong> the label file (.LBL) that contains the label<br />

format definition.<br />

lToPrinter<br />

if True, the output is copied to printer (‘LPT1:’).<br />

cFile<br />

if present, it is the name <strong>of</strong> a ASCII file where the output is<br />

copied.<br />

lNoConsole<br />

if True, the output is not sent to the console.<br />

a code block containing the FOR condition to respect for label<br />

bForCondition<br />

print. Only the records contained inside the active alias that<br />

respect the condition will be used for labels.<br />

a code block containing the WHILE condition to respect for<br />

bWhileCondition<br />

the label print. The first time that the condition is False, the<br />

label print terminates.<br />

nNextRecord<br />

if used, means that only the first nNextRecords will be used.<br />

nRecord<br />

if used, means that that only the record nRecord will be used.<br />

lRest<br />

if used means that only the remaining records inside the active<br />

alias will be used.<br />

lSample if True displays test labels as rows <strong>of</strong> asterisks.<br />

This function prints labels to the console.<br />

368.15.22 DBLIST()<br />

DBLIST( [lToDisplay], abListColumns,<br />

[lAll],<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord], [lRest],<br />

[lToPrinter], [cFileName] )<br />

lToDisplay if True the printout is sent to the console screen.<br />

abListColumns<br />

is an array <strong>of</strong> columns expressions to list.<br />

lAll<br />

if True prints all the records contained inside the active alias.<br />

a code block containing the FOR condition to respect. Only<br />

bForCondition<br />

the records contained inside the active alias that respect the<br />

condition will be used for list.<br />

bWhileCondition<br />

a code block containing the WHILE condition to respect. The<br />

first time that the condition is False, the list terminates.<br />

nNextRecord<br />

if used, means that only the first nNextRecords will be used.<br />

nRecord<br />

if used, means that that only the record nRecord will be used.<br />

lRest<br />

if used means that only the remaining records inside the active<br />

alias will be used.<br />

lToPrinter<br />

if True, the output is copied to printer (‘LPT1:’).<br />

cFileName<br />

if present, it is the name <strong>of</strong> a ASCII file where the output is<br />

copied.


nanoBase 1997 user manual 269<br />

This function prints a list <strong>of</strong> records to the console.<br />

368.15.23 DBLOCATE()<br />

DBLOCATE( [bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord], [lRest] ) ⇒ NIL<br />

bForCondition<br />

bWhileCondition<br />

nNextRecord<br />

nRecord<br />

lRest<br />

a code block containing the FOR condition to respect. Only<br />

the records contained inside the active alias that respect the<br />

condition will be taken into consideration.<br />

a code block containing the WHILE condition to respect. The<br />

first time that the condition is False, the locate terminates.<br />

if used, means that only the first nNextRecords will be used.<br />

if used, means that that only the record nRecord will be used.<br />

if used means that only the remaining records inside the active<br />

alias will be used.<br />

This function searches sequentially for the first record matching the FOR and WHILE conditions.<br />

Once a DBLOCATE() has been issued you can resume the search from the current record pointer<br />

position with DBCONTINUE().<br />

The WHILE condition and the scope (nNextRecord, nRecord and lRest) apply only to the initial<br />

DBLOCATE() and are not operational for any subsequent DBCONTINUE() call.<br />

368.15.24 DBOLDCREATE()<br />

DBOLDCREATE( cDatabase, cExtendedDatabase,<br />

[cDriver], [lNew], [cAlias] ) ⇒ NIL<br />

cDatabase<br />

cExtendedDatabase<br />

cDriver<br />

lNew<br />

cAlias<br />

is the name <strong>of</strong> the new database file, with an optional drive and<br />

directory, specified as a character string. If specified without<br />

an extension (.dbf) is assumed.<br />

is a ‘.DBF’ file containing the structure information <strong>of</strong> the file<br />

to create.<br />

specifies the replaceable database driver (RDD) to use to process<br />

the current work area. cDriver is the name <strong>of</strong> the RDD<br />

specified as a character expression.<br />

if True the newly created ‘.DBF’ file is opened using the next<br />

available work area making it the current work area (the active<br />

alias).<br />

if lNew is set to True, this is the alias name to use to open the<br />

file.<br />

This function is a old database function (superseded form DBCREATE() ) that creates a database<br />

file from the structure information contained inside a structure file.


270 volume VIII Argomenti avanzati e accessori<br />

368.15.25 DBPACK()<br />

DBPACK() ⇒ NIL<br />

This function eliminates definitively the active alias records previously signed for deletion. It<br />

works only if the active alias is opened in exclusive mode.<br />

368.15.26 DBSDF()<br />

DBSDF( lCopyTo, cFileName, [acFields],<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord], [lRest] ) ⇒ NIL<br />

lCopyTo<br />

cFileName<br />

acFields<br />

bForCondition<br />

bWhileCondition<br />

nNextRecord<br />

nRercord<br />

lReset<br />

if True the function works copying data to cFileName from<br />

the active alias, if False the function work appending data<br />

from cFileName to the active alias.<br />

the filename containing data to append to the active alias or to<br />

use as the target <strong>of</strong> the data copy from the active alias.<br />

array <strong>of</strong> fieldnames indicating the fields <strong>of</strong> the active alias that<br />

should be taken into consideration (default is all).<br />

a code block containing the FOR condition to respect. The operation<br />

will be made for all records that respect the condition.<br />

a code block containing the WHILE condition to respect. The<br />

first time it becomes False, the operation is terminated.<br />

if used, means that only the first nNextRecords will be appended/copied.<br />

if used, means that that only the record nRecord will be ap-<br />

pended/copied.<br />

if used means that only the remaining records will be taken<br />

into consideration.<br />

This function is used to append data to the active alias using data from the cFileName file or to<br />

copy data into cFileName using the active alias as the source. cFileName is a SDF ASCII file.<br />

368.15.27 DBSORT()<br />

DBSORT( cDatabase, [acFields],<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord], [lRest] ) ⇒ NIL<br />

cDatabase the ‘.DBF’ file to create.<br />

acFields<br />

the array <strong>of</strong> fields to be used to create the new sorted<br />

cDatabase file.<br />

a code block containing the FOR condition to respect. Only<br />

bForCondition<br />

the records contained inside the active alias that respect the<br />

condition will be taken into consideration.<br />

bWhileCondition<br />

a code block containing the WHILE condition to respect. The<br />

first time that the condition is False, the sort terminates.<br />

nNextRecord<br />

if used, means that only the first nNextRecords inside the active<br />

alias will be used.<br />

nRecord<br />

if used, means that that only the record nRecord will be used.<br />

lRest<br />

if used means that only the remaining records inside the active<br />

alias will be used.


nanoBase 1997 user manual 271<br />

Copy the active alias to a ‘.DBF’ file in sorted order.<br />

368.15.28 DBTOTAL()<br />

DBTOTAL( cDatabase, bKey, [acFields],<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord], [lRest] ) ⇒ NIL<br />

cDatabase<br />

bKey<br />

acFields<br />

bForCondition<br />

bWhileCondition<br />

nNextRecords<br />

nRecord<br />

lRest<br />

the ‘.DBF’ file to create that will contain the copy <strong>of</strong> summarised<br />

records.<br />

the code block key expression that should correspond to the<br />

key expression <strong>of</strong> the active index <strong>of</strong> the active alias.<br />

the array <strong>of</strong> fields to be used to create the new cDatabase file.<br />

a code block containing the FOR condition to respect. Only<br />

the records contained inside the active alias that respect the<br />

condition will be taken into consideration.<br />

a code block containing the WHILE condition to respect. The<br />

first time that the condition is False, the sort terminates.<br />

if used, means that only the first nNextRecords inside the active<br />

alias will be used.<br />

if used, means that that only the record nRecord will be used.<br />

if used means that only the remaining records inside the active<br />

alias will be used.<br />

This function summarises records by key value to a ‘.DBF’ file. It sequentially process the active<br />

alias scanning the specified scope <strong>of</strong> records. Records with the same key will be summarised<br />

inside the destination ‘.DBF’ file. The value <strong>of</strong> numeric fields <strong>of</strong> records with the same key are<br />

added.<br />

368.15.29 DBUPDATE()<br />

DBUPDATE( cAlias, bKey, [lRandom], [bReplacement] )<br />

cAlias<br />

bKey<br />

lRandom<br />

bReplacement<br />

is the alias containing data to be used to update the active<br />

alias.<br />

is a code block expression using information form the cAlias<br />

to obtain a key to refer to the active alias.<br />

if True, allows record in the cAlias to be in any order. In this<br />

case, the active alias must be indexed with the same key as<br />

bKey.<br />

is the code block that will be executed when records matches:<br />

it should contains the criteria for data update.<br />

This function updates the active alias with data from another .DBF file.<br />

Example:<br />

dbUpdate( "INVOICE", {|| LAST}, .T.,;<br />

{|| FIELD->TOTAL1 := INVOICE->SUM1,;<br />

FIELD->TOTAL2 := INVOICE->SUM2 } )


272 volume VIII Argomenti avanzati e accessori<br />

368.15.30 DBZAP()<br />

DBZAP() ⇒ NIL<br />

This function erases immediately all the records contained inside the active alias.<br />

368.15.31 DISPBOXCOLOR()<br />

DISPBOXCOLOR( [nColorNumber], [cBaseColor] ) ⇒ cColor<br />

nColorNumber<br />

cBaseColor<br />

may be 1 or 2 and are the two color used to create shadowed<br />

borders. 1 is usually used for the left and top line; 2 is used<br />

for the right and bottom line.<br />

is the starting color string. The default is the actual color.<br />

This function return a color string used for DISPBOXSHADOW() the function that create a<br />

shadowed border around a screen window.<br />

368.15.32 DISPBOXSHADOW()<br />

DISPBOXSHADOW( nTop, nLeft, nBottom, nRight,<br />

[cBoxString], [cColor1], [cColor2] ) ⇒ NIL<br />

nTop, nLeft, nBottom and nRight are the screen coordinate where the box is to be displayed.<br />

cBoxString<br />

is the box string containing the character to use to build the<br />

box. Default is a single line box.<br />

cColor1<br />

is the color string to use for the left and top side <strong>of</strong> the box.<br />

cColor2<br />

is the color string to use for the right and bottom side <strong>of</strong> the<br />

box.<br />

This function draws a screen box like DISPBOX() but allowing the variation <strong>of</strong> colors around the<br />

border to simulate a sort <strong>of</strong> shadow.<br />

368.15.33 DIR()<br />

DIR( [cFileSpec], [lDrives], [lDirs], [lFiles],<br />

[lNoDirReturn], [nSortColumn] ) ⇒ cPathname<br />

cFileSpec the filename or Pathname, also with wildcards, to be searched.<br />

lDrives true (‘.T.’) means: include drives letters.<br />

lDirs<br />

true (‘.T.’) means: include directory names.<br />

lFiles true (‘.T.’) means: include file names.<br />

true (‘.T.’) means: do not return the shown directory if [ Esc ]<br />

lNoRirReturn<br />

is used to exit.<br />

the column number to use to sort the list. The columns are:<br />

Name = 1,<br />

Size = 2,<br />

nSortColumn<br />

Date = 3,<br />

Time = 4,<br />

Attribute = 5.<br />

It is not possible to sort for extention.


nanoBase 1997 user manual 273<br />

It is a window function useful to search a file or a directory. The complete pathname <strong>of</strong> the<br />

selected file is returned.<br />

368.15.34 DOC()<br />

DOC( [cTextFileName] ) ⇒ NIL<br />

cTextFileName<br />

can contain the text file to open and edit; if empty, the editing<br />

<strong>of</strong> ‘UNTITLED.TXT’ will start.<br />

It is the nB Text editor useful for small text files (less then 64K) and contains a complete menu<br />

that can be started with[F10].<br />

Attention: doc() should not be used inside macros.<br />

368.15.35 DOTLINE()<br />

DOTLINE() ⇒ NIL<br />

This function is a "dot" command line useful for calculations resolution. The dot-line content<br />

may be passed to the keyboard buffer.<br />

368.15.36 DTEMONTH()<br />

Date <strong>of</strong> month<br />

DTEMONTH( nMonth, cLanguage ) ⇒ cMonth<br />

nMonth the month number.<br />

cLanguage the language name.<br />

This function translates the nMonth number into the month name translated using the<br />

cLanguage language.<br />

368.15.37 DTEWEEK()<br />

Date <strong>of</strong> week<br />

DTEWEEK( nWeek, cLanguage ) ⇒ cWeek<br />

nWeek<br />

cLanguage<br />

is the week number (1 is Sunday, 7 is Saturday) to be translated<br />

into text.<br />

is the language name into which the week must be expressed.<br />

At the moment it works only for Italian, so cLanguage can<br />

only contain "ITALIANO".<br />

This function translates the week number into the week name translated using the cLanguage<br />

language.


274 volume VIII Argomenti avanzati e accessori<br />

368.15.38 EX()<br />

Execute<br />

EX( cFileMacro ) ⇒ nExitCode<br />

Executes the macro file cFileName. The extention must be specified.<br />

cFileMacro may be the name <strong>of</strong> a "compiled" macro or a text macro file.<br />

368.15.39 GET()<br />

GET( @aGetList,<br />

[nTop], [nLeft],<br />

{ |x| iif( pcount() > 0, Var := x, Var ) }<br />

[cGetPicture], [cColorString],<br />

[bPreExpression], [bValid] )<br />

aGetList<br />

is the get list array that will be increased with this get().<br />

nTop and nLeft define the starting position <strong>of</strong> this get object on the screen.<br />

Var<br />

is the variable that is to be edited with this get. Var is in fact<br />

sent to the GET() function using a code block.<br />

cGetPicture<br />

is the get picture to use for Var.<br />

cColorString is the color string to use for the get.<br />

is a code block that will be evaluated before the get object<br />

bPreExpression<br />

will became active. It must result True to obtain that the get<br />

object became active.<br />

is a code block that will be evaluated after the get object is<br />

bValid<br />

edited. It must result True to obtain that the get object may<br />

become inactive.<br />

Create screen editing masks.<br />

368.15.40 GVADD()<br />

Get validation add<br />

GVADD( @cField, cAdd ) ⇒ .T.<br />

cField the field to fill with more data.<br />

cAdd<br />

is the string to be added to the content <strong>of</strong> cField.<br />

This function is to be used inside GETs for pre/post validation, when a the content <strong>of</strong> a field<br />

should be added with more data.<br />

cField is returned with the same length as before to avoid troubles with current and future GETs.


nanoBase 1997 user manual 275<br />

368.15.41 GVDEFAULT()<br />

Get validation default<br />

GVDEFAULT( @cField, cDefault ) ⇒ .T.<br />

@cField<br />

the field to check and if empty correct with cDefault.<br />

cDefault is the default value to be used to replace cField.<br />

This function is to be used inside GETs for pre/post validation, when a field should have a default<br />

value.<br />

cField is returned with the same length as before to avoid troubles with current and future GETs.<br />

368.15.42 GVFILEDIR()<br />

Get validation file directory<br />

GVFILEDIR( @cWildName ) ⇒ .T.<br />

cWildName<br />

is the file name taken from the current get to be used for search<br />

with DIR().<br />

This function is to be used inside GETs for pre validation: the cWildName is a file name with<br />

wild cards that can be searched with the DIR() function after that a specific key is pressed.<br />

cWildName is returned with the same length as before to avoid troubles with current and future<br />

GETs.<br />

368.15.43 GVFILEEXIST()<br />

GVFILEEXIST( @cNameToTest, [cExtention] ) ⇒ lSuccess<br />

@cNameToTest<br />

is the file name taken from the current get to test for existence.<br />

cExtention is the normal extention <strong>of</strong> the file.<br />

This function is to be used inside GETs for post validation: the file name have to exist.<br />

cNameToTest is returned with the same length as before to avoid troubles with current and future<br />

GETs.<br />

368.15.44 GVFILEEXTENTION()<br />

GVFILEEXTENTION( @cName, cExt ) ⇒ .T.<br />

@cName<br />

the file name to be eventually corrected with file extention.<br />

cExt the file extention to use as default.<br />

This function is to use inside GETs for pre/post validation, when the content <strong>of</strong> a field should<br />

contain a file name that should be corrected adding a default extention if not given from the user.


276 volume VIII Argomenti avanzati e accessori<br />

368.15.45 GVSUBST()<br />

GVSUBST( @cField, cSubst ) ⇒ .T.<br />

@cField<br />

cSubst<br />

the field to be replaced with cSubst.<br />

is the string to be used to replace the content <strong>of</strong> cField.<br />

This function is to use inside GETs for pre/post validation, when the content <strong>of</strong> a field should be<br />

replaced with other data.<br />

cField is returned with the same length as before to avoid troubles with current and future GETs.<br />

368.15.46 HTF()<br />

HTF( [nInitialRecord] ) ⇒ NIL<br />

nInitialRecord<br />

is the record number where to start the Help Text File browse.<br />

Default is the actual record pointer.<br />

This function browse a Help Text File that must be already opened and be the active alias.<br />

368.15.47 ISFILE()<br />

ISFILE( cName ) ⇒ lFileExists<br />

cName<br />

is the file name (with or without path) to be checked for existence.<br />

This function returns true (‘.T.’) if the file cName exists. The difference between this function<br />

and the standard FILE() function is that ISFILE() checks for wildcards before. If cName contains<br />

wildcards, the result is false (‘.F.’).<br />

368.15.48 ISWILD()<br />

ISWILD( cName ) ⇒ lIsWild<br />

cName<br />

This function returns true (‘.T.’) if cName contains wildcards.<br />

368.15.49 ISMEMVAR()<br />

ISMEMVAR( cName ) ⇒ lIsMemvar<br />

cName<br />

is the file name (with or without path) to be checked for wildcards<br />

presence.<br />

is the name <strong>of</strong> a possible memvar.<br />

This function returns true (‘.T.’) if the cName is a declared Memvar.


nanoBase 1997 user manual 277<br />

368.15.50 ISCONSOLEON()<br />

ISCONSOLEON() ⇒ lConsoleIsOn<br />

This function returns true (‘.T.’) if the console will show the result <strong>of</strong> QOUT() and QQOUT().<br />

368.15.51 ISPRINTERON()<br />

ISPRINTERON() ⇒ lPrinterIsOn<br />

This function returns true (‘.T.’) if the default printer will report the the result <strong>of</strong> QOUT() and<br />

QQOUT().<br />

The default printer is ‘PRN:’ or ‘LPT1:’. If SET ALTERNATE TO is configured to send outputs<br />

to ‘LPT2:’ or another printer, the function will report false (‘.F.’).<br />

368.15.52 KEYBOARD()<br />

KEYBOARD( [cString] ) ⇒ NIL<br />

This function stuff a string into the keyboard buffer.<br />

368.15.53 LISTWINDOW()<br />

LISTWINDOW( acMenuItem, [cDescription],<br />

[nTop], [nLeft], [nBottom], [nRight],<br />

[cColorTop], [cColorBody] ) ⇒ nPosition<br />

acMenuItem<br />

is the character array containing the list <strong>of</strong> choices.<br />

cDescription is the header to be shown at the top window.<br />

nTop, nLeft, nBottom, nRight are the window coordinates.<br />

cColorTop is the color to use for window header and footer.<br />

cColorBody<br />

is the color to use for the window body that is the space where<br />

the text appears.<br />

This function is an similar to achoice(), but it shows a header and footer, and it saves the screen,<br />

acting like a window.<br />

368.15.54 MEMOWINDOW()<br />

MEMOWINDOW( cVar, [cDescription], [nTop], [nLeft],<br />

[nBottom], [nRight], [cColorTop], [cColorBody],<br />

[lEditMode], [nLineLength], [nTabSize] ) ⇒ cVar<br />

cVar is the character field (variable) to be edited.<br />

cDescription is the header to be shown at the top window.<br />

nTop, nLeft, nBottom, nRight are the window coordinates.<br />

cColorTop is the color to use for window header and footer.<br />

cColorBody<br />

is the color to use for the window body that is the space where<br />

the text appears.<br />

lEditMode<br />

is equivalent to memoedit().


278 volume VIII Argomenti avanzati e accessori<br />

nLineLength is equivalent to memoedit().<br />

nTabSize is equivalent to memoedit().<br />

This function lets you easily edit a long character field (memo) defining automatically a simple<br />

window and providing a simple help.<br />

368.15.55 MEMPUBLIC()<br />

MEMPUBLIC( cMemvarName|acMemvarNames ) ⇒ NIL<br />

cMemvarName<br />

acMemvarNames<br />

Creates a PUBLIC variables or a group <strong>of</strong> variables.<br />

368.15.56 MEMRELEASE()<br />

MEMRELEASE( cMemvarName|acMemvarNames ) ⇒ NIL<br />

is the name <strong>of</strong> the PUBLIC variable to create (max 10 characters).<br />

is an array <strong>of</strong> PUBLIC variable names to create (max 10 characters).<br />

cMemvarName is the name <strong>of</strong> the PUBLIC variable to be released.<br />

acMemvarNames<br />

is an array <strong>of</strong> PUBLIC variable names to be released.<br />

This function releases a previously created PUBLIC variables or a group <strong>of</strong> variables.<br />

368.15.57 MEMRESTORE()<br />

MEMRESTORE( cMemFileName, [lAdditive] ) ⇒ NIL<br />

cMemFileName<br />

lAdditive<br />

Retrieve memory variables form a memory file (.MEM).<br />

368.15.58 MEMSAVE()<br />

MEMSAVE( cMemFileName, [cSkeleton], [lLike] ) ⇒ NIL<br />

cMemFileName<br />

cSkeleton<br />

lLike<br />

the memory file (.MEM) to load from disk.<br />

if True causes memory variables loaded from the memory file<br />

to be added to the existing pool <strong>of</strong> memory variables. If False,<br />

the existing memory variables are automatically released.<br />

the memory file (.MEM) where public variables should be<br />

saved.<br />

the skeleton mask for defining a group <strong>of</strong> variables. Wildcard<br />

characters may be used: _*_ and _?_.<br />

if True, the variables grouped with cSkeleton are saved, else<br />

only the other variables are saved.


nanoBase 1997 user manual 279<br />

Saves memory variables to a memory file (.MEM).<br />

368.15.59 MENUPROMPT()<br />

MENUPROMPT( @aoGet,<br />

[nRow], [nCol],<br />

[cPrompt], [bBlock] ) ⇒ NIL<br />

aoGet<br />

is an array <strong>of</strong> get objects where a new get is added by<br />

MENUPROMPT(). These gets are read only.<br />

nRow and nCol<br />

are the screen coordinates where the menu prompt will appear.<br />

cPrompt is the menu prompt string.<br />

is the code block to execute when the cursor is on the current<br />

bBlock<br />

menu prompt. It is usually a code block that shows a message<br />

somewhere on the screen.<br />

This function should substitute the @...PROMPT command and handle the mouse.<br />

368.15.60 MENUTO()<br />

MENUTO( aoGet, nPos ) ⇒ nChoice<br />

aoGet<br />

nPos<br />

array <strong>of</strong> get objects.<br />

starting position to be edited.<br />

Like MENU TO. It returns the selected menu item created with MENUPROMPT(). It supports<br />

the mouse.<br />

368.15.61 MESSAGELINE()<br />

MESSAGELINE( [cMessage], [cColor], [nPosTop], [nPosLeft] )<br />

⇒ NIL<br />

aMessage the message to be displayed.<br />

cColor<br />

the color string.<br />

the starting position where the string message would appear<br />

nPosTop and nPosLeft<br />

on the screen. Default values are respectively ROW() and<br />

COL().<br />

MESSAGELINE() is a function that display a message on the screen on the selected position. If<br />

cMessage is NIL, the message is eliminated from screen restoring the previous screen content.


280 volume VIII Argomenti avanzati e accessori<br />

368.15.62 MOUSESCRSAVE()<br />

MOUSESCRSAVE( [nTop], [nLeft], [nBottom], [nRight] )<br />

⇒ cSavedScreen<br />

nTop, nLeft, nBottom and nRight are the screen coordinates that will be to save the screen.<br />

This function works line SAVESCREEN() but it hide the mouse cursor before a screen save is<br />

made.<br />

368.15.63 MOUSESCRRESTORE()<br />

MOUSESCRRESTORE( [nTop], [nLeft], [nBottom], [nRight],<br />

[cScreen] ) ⇒ cSavedScreen<br />

nTop, nLeft, nBottom and nRight<br />

cScreen<br />

are the screen coordinates where the saved screen will be restored.<br />

is the previously saved screen to restore.<br />

This function works line RESTSCREEN() but it hide the mouse cursor before a screen restore is<br />

made.<br />

368.15.64 PICCHRMAX()<br />

PICCHRMAX( [nCol], [nMaxCol] ) ⇒ cPictureString<br />

nCol<br />

nMaxCol<br />

is the starting position on the screen for the get field.<br />

is the end position on the screen <strong>of</strong> the get field.<br />

This function is useful when a character field is to be used on a get object. The generated picture<br />

will be the <strong>of</strong> the maximum possible extention, eventually with scroll.<br />

368.15.65 QUIT()<br />

QUIT() ⇒ NIL<br />

Terminates program execution.<br />

368.15.66 READ()<br />

READ( aoGet, [nPos], [aButtons], [lReadOnly] )<br />

⇒ lUpdated<br />

aoGet<br />

nPos<br />

aButtons<br />

lReadOnly<br />

is the array <strong>of</strong> get objects.<br />

is the starting position.<br />

is the array <strong>of</strong> buttons.<br />

if True, get fields cannot be modified; the default value is<br />

False.


nanoBase 1997 user manual 281<br />

This function is made to substitute the READMODAL() allowing the use <strong>of</strong> the mouse. The array<br />

aButtons is made with the help <strong>of</strong> the function BUTTON().<br />

368.15.67 RF()<br />

RF( cFRMName,<br />

[bForCondition], [bWhileCondition],<br />

[nNext], [nRecord], [lRest], [lPlain],<br />

[cbHeading], [lBeforeEject], [lSummary],<br />

[lDate], [acExtra] ) ⇒ NIL<br />

cFRMName<br />

the form (.FRM) file to use to print the active alias.<br />

bForCondition code block for the FOR condition.<br />

bWhileCondition code block for the WHILE condition.<br />

nNext see REPORT FORM.<br />

nRecord see REPORT FORM<br />

lRest see REPORT FORM<br />

lPlain<br />

if true (‘.T.’), force the print in a simple way.<br />

additional header in character or code block form. If a code<br />

cbHeading<br />

block is sent, the final result must be a character string.<br />

lBeforeEject if true (‘.T.’), force a form feed before the print.<br />

lSummary if true (‘.T.’), force a summary print only.<br />

lDate<br />

if false (‘.F.’), force the print without date at the top <strong>of</strong> page.<br />

a character array that may be used for translating standard<br />

printed report form words and to add vertical and horizontal<br />

separations. The default value <strong>of</strong> acExtra is:<br />

acExtra[1] "Page No."<br />

acExtra<br />

acExtra[2] "** Subtotal **"<br />

acExtra[3] "* Subsubtotal *"<br />

acExtra[4] "*** Total ***"<br />

acExtra[5] " " vertical column separation<br />

axExtra[6] "" horizontal separation: no separation.<br />

This function does the same work <strong>of</strong> REPORT FORM or __ReportForm or dbReportForm, but it<br />

prints where qout() and qqout() print.<br />

368.15.68 RPT()<br />

RPT( cText ) ⇒ NIL<br />

This function prints the text contained into cText using print commands. This function accepts<br />

other parameters here not described, as they are not to be used for macro purpose. The printing<br />

is made using QOUT() and QQOUT(), this way it is sensible to the "alternate" file definition.<br />

368.15.69 RPTMANY()<br />

RPTMANY( cText, [bWhileCondition], [bForCondition] )<br />

⇒ NIL<br />

cText<br />

bWhileCondition<br />

bForCondition<br />

is the text to be printed.<br />

is a code block for a WHILE condition to respect for the<br />

records to print.<br />

is a code block for a FOR condition to respect for the records<br />

to print.


282 volume VIII Argomenti avanzati e accessori<br />

This function prints the text contained into cText many times: one for every record contained<br />

into the active alias.<br />

368.15.70 RPTTRANSLATE()<br />

RPTTRANSLATE( cText ) ⇒ cTranslatedText<br />

This function translates once cText replacing variables with memvars or Fields.<br />

368.15.71 RUN()<br />

RUN( cCommand ) ⇒ NIL<br />

This function start execution <strong>of</strong> cCommand in a DOS session. It works only if there is enough<br />

available memory.<br />

368.15.72 SAY()<br />

SAY( nTop, nLeft, Expr,<br />

[cSayPicture], [cColorString] ) ⇒ NIL<br />

nTop and nLeft<br />

define the starting position on the screen where the Expr<br />

should be displayed.<br />

nLeft is an expression that will be solved and displayed.<br />

cSayPicture is the picture to use to display Expr.<br />

cColorString is the color string to use.<br />

This function displays the result <strong>of</strong> Expr on the screen on the desired position.<br />

368.15.73 SETCOLORSTANDARD()<br />

SETCOLORSTANDARD( [nColor], [cColor|acColor] )<br />

nColor<br />

cColor<br />

acColor<br />

⇒ cPreviousColor|acPreviousColor<br />

is the color number to take into consideration:<br />

0 All colors<br />

1 Base<br />

2 Menu<br />

3 Head<br />

4 Body (Say - Get)<br />

5 Button (Mouse buttons)<br />

6 Message<br />

7 Alert<br />

the color string to be associated with nColor.<br />

it the color array<br />

This function is a way to handle colors inside the application. The functions that display something<br />

use a default color depending on what they does. These colors may be changed with SET-<br />

COLORSTANDARD(), all together or only one.


nanoBase 1997 user manual 283<br />

368.15.74 SETFUNCTION()<br />

SETFUNCTION( nFunctionKey, cString ) ⇒ NIL<br />

nFunctionKey<br />

the number <strong>of</strong> the function key ( 1=F1, 12=F12) to be assigned.<br />

cString the character string.<br />

This function assigns a character string to a function key (obsolete).<br />

368.15.75 SETMOUSE()<br />

SETMOUSE( [lShow] )⇒ lPrevious<br />

lShow<br />

True shows the mouse cursor, False hide the mouse cursor,<br />

NIL reports only the status.<br />

This function is made to show, hide or report only the mouse cursor status.<br />

368.15.76 SETOUTPUT()<br />

SETOUTPUT( [cPeriperal|aPeripheral] )<br />

⇒ aPrevious_Output_Peripherals<br />

cPeripheral is the new output peripheral for qout() and qqout() functions.<br />

aPeripheral<br />

are the new output peripherals configurations for qout() and<br />

qqout() functions.<br />

nB is organised in the way to have only one output peripheral at the time. This function help to<br />

make order inside SET CONSOLE, SET PRINTER and SET ALTERNATE.<br />

If cPeripheral contains:<br />

"CON"<br />

"PRN"<br />

SET CONSOLE is set to ON,<br />

SET PRINTER is set to OFF,<br />

SET ALTERNATE is set to OFF;<br />

SET CONSOLE is set to OFF,<br />

SET PRINTER is set to ON,<br />

SET ALTERNATE is set to OFF;<br />

"LPT1"<br />

same as "PRN";<br />

otherwise<br />

SET CONSOLE is set to OFF,<br />

SET PRINTER is set to OFF,


284 volume VIII Argomenti avanzati e accessori<br />

SET ALTERNATE is set to ON,<br />

SET ALTERNATE TO is set to cPeripheral.<br />

aPeripheral is organised this way:<br />

aPeripheral[1] = _SET_CONSOLE<br />

aPeripheral[2] = _SET_PRINTER<br />

aPeripheral[3] = _SET_ALTERNATE<br />

aPeripheral[4] = _SET_ALTFILE<br />

aPeripheral[5] = _SET_EXTRA<br />

aPeripheral[6] = _SET_EXTRAFILE<br />

This function is necessary because SET ALTERNATE alone is not enough to print on the screen<br />

when the peripheral name is "CON" or to print on the printer when the peripheral name is "PRN"<br />

or "LPT1". In fact, in the first case, ROW() and COL() will not be updated, in the second case,<br />

PROW() and PCOL() will not be updated.<br />

This function returns an array organised in the same way as aPeripheral is, that shows the active<br />

output configuration.<br />

368.15.77 SETRPTEJECT()<br />

SETRPTEJECT( [lbEject] ) ⇒ lPreviousEjectMode<br />

This function is used to set the eject mode after every page print for RPT(). If single sheet paper is<br />

used, then SETRPTEJECT(.T.) must be set; for continuous paper, SETRPTEJECT(.F.) is correct.<br />

The default value is .F..<br />

lbEject<br />

368.15.78 SETRPTLINES()<br />

SETRPTLINES() ⇒ nRemainingLines<br />

logical or code block, is the eject mode to set. Default is no<br />

change, the starting value is ‘.F.’<br />

This function is used to report the number <strong>of</strong> lines available before the completion <strong>of</strong> the page<br />

print for RPT().<br />

368.15.79 SETVERB()<br />

Set verbose<br />

SETVERB( cSpecifier, [xNewSetting], [lOpenMode] )<br />

⇒ xPreviousValueSet<br />

cSpecifier a word that defines the kind <strong>of</strong> set is going to be considered.<br />

xNewSetting is the new value to set up.<br />

lOpenMode used only for some kind <strong>of</strong> set.<br />

This function is analogue to SET() but it uses a character string (with cSpecifier) and not a


nanoBase 1997 user manual 285<br />

number to select the set. This is made to make easier the work with macros.<br />

cSpecifier may contain:<br />

"EXACT"<br />

"FIXED"<br />

"DECIMALS"<br />

"DATEFORMAT"<br />

"EPOCH"<br />

"PATH"<br />

"DEFAULT"<br />

"EXCLUSIVE"<br />

"SOFTSEEK"<br />

"UNIQUE"<br />

"DELETED"<br />

"CANCEL"<br />

"TYPEAHEAD"<br />

"COLOR"<br />

"CURSOR"<br />

"CONSOLE"<br />

"ALTERNATE"<br />

"ALTFILE"<br />

"DEVICE"<br />

"EXTRA"<br />

"EXTRAFILE"<br />

"PRINTER"<br />

"PRINTFILE"<br />

"MARGIN"<br />

"BELL"<br />

"CONFIRM"<br />

"ESCAPE"<br />

"INSERT"<br />

"EXIT"<br />

"INTENSITY"<br />

"SCOREBOARD"<br />

"DELIMITERS"<br />

"DELIMCHARS"<br />

"WRAP"<br />

"MESSAGE"<br />

"MCENTER"<br />

368.15.80 SETVERB("EXACT") (obsolete)<br />

SETVERB( "EXACT", [lExact] ) ⇒ lPrevious<br />

If lExact is True, it forces exact comparison <strong>of</strong> character strings, including length. If it is False,<br />

character strings are compared until the left string length is exhausted; that is that "" (the null<br />

string) is equal to any other string.<br />

Please note that the == operator is a comparison operator for exact match and using it,<br />

SETVERB("EXACT", ‘.F.’) will not work.


286 volume VIII Argomenti avanzati e accessori<br />

The starting value is True; the recommended value is True.<br />

368.15.81 SETVERB("FIXED")<br />

SETVERB( "FIXED", [lFixed] ) ⇒ lPrevious<br />

If lFixed contains True, numeric values are displayed ever with a fixed number <strong>of</strong> decimal digits,<br />

depending on the value set by SETVERB("DECIMALS").<br />

The starting value is False.<br />

The recommended value is False: if you have to display a fixed number <strong>of</strong> decimal digits it is<br />

better to define a good display picture.<br />

368.15.82 SETVERB("DECIMALS")<br />

SETVERB( "DECIMALS", [nDecimals] ) ⇒ nPrevious<br />

nDecimals is the number <strong>of</strong> digits to display after the decimal position. This set is enabled <strong>of</strong><br />

disabled with SETVERB("FIXED").<br />

The starting value is 8.<br />

368.15.83 SETVERB("DATEFORMAT")<br />

SETVERB( "DATEFORMAT", [cDateFormat] ) ⇒ cPrevious<br />

cDateFormat is a character expression that specifies the date format.<br />

The starting value is "dd/mm/yyyy".<br />

Some date format examples:<br />

AMERICAN<br />

ANSI<br />

BRITISH<br />

FRENCH<br />

GERMAN<br />

ITALIAN<br />

JAPAN<br />

USA<br />

368.15.84 SETVERB("EPOCH")<br />

SETVERB( "EPOCH", [nYear] ) ⇒ nPrevious<br />

"mm/dd/yyyy"<br />

"yyyy.mm.dd"<br />

"dd/mm/yyyy"<br />

"dd/mm/yyyy"<br />

"dd.mm.yyyy"<br />

"dd-mm-yyyy"<br />

"yyyy/mm/dd"<br />

"mm-dd-yyyy"<br />

nYear specifies the base year <strong>of</strong> 100-year period in which all dates containing only two year<br />

digits are assumed to fall.<br />

The starting value is 1900.


nanoBase 1997 user manual 287<br />

368.15.85 SETVERB("PATH")<br />

SETVERB( "PATH", [cPath] ) ⇒ cPrevious<br />

cPath identifies the paths that nB uses when searching for a file not found in the current directory.<br />

The list <strong>of</strong> paths can be separated by commas or semicolons.<br />

The starting value is "".<br />

368.15.86 SETVERB("DEFAULT")<br />

SETVERB( "DEFAULT", [cPath] ) ⇒ cPrevious<br />

cPath identifies the default disk drive and directory.<br />

The starting value is "".<br />

368.15.87 SETVERB("EXCLUSIVE")<br />

SETVERB( "EXCLUSIVE", [lExclusive] ) ⇒ lPrevious<br />

If lPath is True, the default database (.DBF) file open is made in exclusive mode; in the other<br />

case, in shared mode.<br />

The starting value is True.<br />

368.15.88 SETVERB("SOFTSEEK")<br />

SETVERB( "SOFTSEEK", [lS<strong>of</strong>tSeek] ) ⇒ lPrevious<br />

If lS<strong>of</strong>tSeek is True, if a DBSEEK() index search fails, the record pointer is moved to the next<br />

record with a higher key. If it is False, in case <strong>of</strong> a DBSEEK() index search failure, the record<br />

pointer is moved at EOF().<br />

The starting value is False.<br />

368.15.89 SETVERB("UNIQUE") (obsolete)<br />

SETVERB( "UNIQUE", [lUnique] ) ⇒ lPrevious<br />

If lUnique is True, during creation or update <strong>of</strong> ‘.DBF’ indexes, if two or more records are found<br />

with the same key, only the first record will be included inside the index.<br />

If lUnique is False, duplicated record keys are allowed.<br />

The starting value is False.


288 volume VIII Argomenti avanzati e accessori<br />

368.15.90 SETVERB("DELETED")<br />

SETVERB( "DELETED", [lDeleted] ) ⇒ lPrevious<br />

If lDeleted is True, record signed for deletion are not filtered, that is, these are still normally<br />

visible as they were not deleted. In the other case, they hare (in most cases) hidden to the user.<br />

The starting value is False.<br />

368.15.91 SETVERB("CANCEL")<br />

SETVERB( "CANCEL", [lCancel] ) ⇒ lPrevious<br />

If lCancel is True, enables [ Alt+c ] and [ Ctrl+Break ] as termination keys. In the other case, not.<br />

The starting value is True.<br />

368.15.92 SETVERB("TYPEAHEAD")<br />

SETVERB( "TYPEAHEAD", [nTypeAhead] ) ⇒ nPrevious<br />

nTypeAhead is the number <strong>of</strong> keystrokes the keyboard buffer can hold from a minimum <strong>of</strong> zero<br />

to a maximum <strong>of</strong> 4096.<br />

The starting value is 15.<br />

368.15.93 SETVERB("COLOR")<br />

SETVERB( "COLOR", [cColorString] ) ⇒ cPrevious<br />

nColorString defines the normal screen colors. There are five couple <strong>of</strong> colors, but only three are<br />

really operative:<br />

standard<br />

This is the standard color used for screen output.<br />

enhanced<br />

This is the color used for highlighted screen output.<br />

border<br />

Normally unused.<br />

background Normally unused.<br />

unselected This is the color used for GET fields without focus.<br />

The default color string is "BG+/B,N/W,N/N,N/N,W/N" that is:<br />

standard<br />

bright Cyan on Blue<br />

enhanced Black on White<br />

border Black on Black<br />

background Black on Black<br />

unselected White on Black<br />

The following table explains the use <strong>of</strong> letters inside the color string. Note that the plus sign (+)<br />

means high intensity, the star (*) means blink and that + and * can be allowed only to the first<br />

letter inside a couple.<br />

Color Letter Monochrome<br />

Black N, Space Black


nanoBase 1997 user manual 289<br />

Color Letter Monochrome<br />

Blue B Underline<br />

Green G White<br />

Cyan BG White<br />

Red R White<br />

Magenta RB White<br />

Brown GR White<br />

White W White<br />

Gray N+ Black<br />

Bright Blue B+ Bright Underline<br />

Bright Green G+ Bright White<br />

Bright Cyan BG+ Bright White<br />

Bright Red R+ Bright White<br />

Bright Magenta RB+ Bright White<br />

Bright Brown GR+ Bright White<br />

Bright White W+ Bright White<br />

Black U Underline<br />

Inverse Video I Inverse Video<br />

Blank X Blank<br />

368.15.94 SETVERB("CURSOR")<br />

SETVERB( "CURSOR", [lCursor] ) ⇒ lPrevious<br />

If lCursor is True, the cursor is showed, else it is hidden.<br />

The starting value is True.<br />

368.15.95 SETVERB("CONSOLE")<br />

SETVERB( "CONSOLE", [lConsole] ) ⇒ lPrevious<br />

If lConsole is True, the output <strong>of</strong> console commands is displayed on the screen, else it is not.<br />

The starting value is True.<br />

368.15.96 SETVERB("ALTERNATE")<br />

SETVERB( "ALTERNATE", [lAlternate] ) ⇒ lPrevious<br />

If lAlternate is True, the output <strong>of</strong> console commands is send also to a standard ASCII text file.<br />

The starting value is False.<br />

368.15.97 SETVERB("ALTFILE")<br />

SETVERB( "ALTFILE", [cAlternateFilename], [lAdditive] )<br />

⇒ cPrevious<br />

If SETVERB("ALTERNATE") is True, the output <strong>of</strong> the console is send also to<br />

cAlternateFilename, a standard ASCII file.


290 volume VIII Argomenti avanzati e accessori<br />

If lAdditive is True, the output is appended to the ASCII file if it already exists, else it is erased<br />

first.<br />

368.15.98 SETVERB("DEVICE")<br />

SETVERB( "DEVICE", [cDevice] ) ⇒ cPrevious<br />

cDevice is the name <strong>of</strong> the device where SAY() will display its output.<br />

The starting value is "SCREEN", the alternative is "PRINTER".<br />

The recommended value is "SCREEN".<br />

368.15.99 SETVERB("EXTRA")<br />

SETVERB( "EXTRA", [lExtra] ) ⇒ lPrevious<br />

If lExtra is True, the output <strong>of</strong> console commands is send also to a standard ASCII text file.<br />

The starting value is False.<br />

368.15.100 SETVERB("EXTRAFILE")<br />

SETVERB( "EXTRAFILE", [cExtraFilename], [lAdditive] )<br />

⇒ cPrevious<br />

If SETVERB("EXTRA") is True, the output <strong>of</strong> the console is send also to cExtraFilename, a<br />

standard ASCII file.<br />

If lAdditive is True, the output is appended to the ASCII file if it already exists, else it is erased<br />

first.<br />

368.15.101 SETVERB("PRINTER")<br />

SETVERB( "PRINTER", [lPrinter] ) ⇒ lPrevious<br />

If lPrinter is True, the output <strong>of</strong> console commands is also printed, else it is not.<br />

The starting value is False.<br />

368.15.102 SETVERB("PRINTFILE")<br />

SETVERB( "PRINTFILE", [cPrintFileName] ) ⇒ cPrevious<br />

cPrintFileName is the name <strong>of</strong> the printer peripheral name.<br />

The starting value is "" (null string).


nanoBase 1997 user manual 291<br />

368.15.103 SETVERB("MARGIN")<br />

SETVERB( "MARGIN", [nPageOffset] ) ⇒ nPrevious<br />

nPageOffset is the positive number <strong>of</strong> column to be used as a left margin for all printer output.<br />

The starting value is 0.<br />

368.15.104 SETVERB("BELL")<br />

SETVERB( "BELL", [lBell] ) ⇒ lPrevious<br />

If lBell is True, the sound <strong>of</strong> the bell is used to get the attention <strong>of</strong> the user when some wrong<br />

actions are made.<br />

The starting value is False.<br />

368.15.105 SETVERB("CONFIRM")<br />

SETVERB( "CONFIRM", [lConfirm] ) ⇒ lPrevious<br />

If lConfirm is False, the GET is simply terminated typing over the end <strong>of</strong> the get field; in the<br />

other case (True), the GET is terminated only pressing an "exit key". The starting value is True.<br />

368.15.106 SETVERB("ESCAPE")<br />

SETVERB( "ESCAPE", [lEscape] ) ⇒ lPrevious<br />

If lEscape is True, the [ Esc ] key is enabled to be a READ exit key, in the other case not.<br />

The starting value is True.<br />

The recommended value is True.<br />

368.15.107 SETVERB("INSERT")<br />

SETVERB( "INSERT", [lInsert] ) ⇒ lPrevious<br />

If lInsert is True, the data editing is in INSERT mode, in the other case, it is in OVERWRITE<br />

mode.<br />

The starting value is True.<br />

368.15.108 SETVERB("EXIT")<br />

SETVERB( "EXIT", [lExit] ) ⇒ lPrevious<br />

If lExit is True,[Up] and[Down] key may be used as exit key when the cursor is (respectively)<br />

on the first or on the last GET field. In the other case not.<br />

The starting value is False.<br />

The recommended value is False.


292 volume VIII Argomenti avanzati e accessori<br />

368.15.109 SETVERB("INTENSITY")<br />

SETVERB( "INTENSITY", [lIntensity] ) ⇒ lPrevious<br />

If lIntensitiy is True, the display <strong>of</strong> standard and enhanced display colors are enabled. In the<br />

other case, only standard colors are enabled.<br />

The starting value is True.<br />

The recommended value is True.<br />

368.15.110 SETVERB("SCOREBOARD")<br />

SETVERB( "SCOREBOARD", [lScoreboard] ) ⇒ lPrevious<br />

If lScoreboard is True, the display <strong>of</strong> messages from READ() and MEMOREAD() is allowed;<br />

in the order case not.<br />

The starting value is False.<br />

The recommended value is False: nB do not support scoreboard.<br />

368.15.111 SETVERB("DELIMITERS")<br />

SETVERB( "DELIMITERS", [lDelimiters] ) ⇒ lPrevious<br />

If lDelimiters is True, GET variables appear on the screen delimited with the delimiter symbols.<br />

In the other case, GET variables are not delimited this way, but only with the use <strong>of</strong> different<br />

colors.<br />

The starting value is False.<br />

The recommended value is False: the use <strong>of</strong> delimiters creates one more trouble when designing<br />

a screen mask.<br />

368.15.112 SETVERB("DELIMCHARS")<br />

SETVERB( "DELIMCHARS", [cDelimterCharacters] ) ⇒ cPrevious<br />

cDelimterCharacters are the delimiter characters used to delimit a GET field when<br />

SETVERB("DELIMITERS") is True.<br />

The starting value is "::".<br />

368.15.113 SETVERB("WRAP")<br />

SETVERB( "WRAP", [lWrap] ) ⇒ lPrevious<br />

If lWrap is True, the wrapping <strong>of</strong> the highlight in MENUs should be active, but this option is<br />

actually not active and all works as it is False.<br />

The starting value is False.


nanoBase 1997 user manual 293<br />

368.15.114 SETVERB("MESSAGE")<br />

SETVERB( "MESSAGE", [nMessageRow] ) ⇒ nPrevious<br />

nMessageRow is the row number where the @..PROMPT message line should appear on the<br />

screen. This option is not supported.<br />

The starting value is 0.<br />

368.15.115 SETVERB("MCENTER")<br />

SETVERB( "MCENTER", [lMessageCenter] ) ⇒ lPrevious<br />

If lMessageCenter is True, the @..PROMPT message line should appear centered on the screen.<br />

This option is not supported.<br />

The starting value is False.<br />

368.15.116 STRADDEXTENTION()<br />

STRADDEXTENTION( cName, cExt ) ⇒ cCompleteName<br />

cName<br />

the file name (with or without path) that is probably without<br />

extention.<br />

cExt the extention that must be added to cName if it has not one.<br />

This function check cName for the presence <strong>of</strong> an extention. It it has not one, cExt will be added.<br />

368.15.117 STRCUTEXTENTION()<br />

STRCUTEXTENTION( cName ) ⇒ cName<br />

cName<br />

the file name (with or without path) that is probably with extention.<br />

This function check cName for the presence <strong>of</strong> an extention. It it has one, the extention is removed.<br />

368.15.118 STRDRIVE()<br />

STRDRIVE( cName ) ⇒ cDrive<br />

cName<br />

the file name (with or without path) that contains the drive<br />

letter.<br />

This function tries to extract the drive letter information from cName.


294 volume VIII Argomenti avanzati e accessori<br />

368.15.119 STREXTENTION()<br />

STREXTENTION( cName ) ⇒ cExtention<br />

cName<br />

the file name (with or without path) that contains an extention.<br />

This function tries to extract the extention information from cName.<br />

368.15.120 STRFILE()<br />

STRFILE( cName ) ⇒ cFileName<br />

cName<br />

the file name with or without path.<br />

This function tries to extract the file name without path from cName.<br />

368.15.121 STRFILEFIND()<br />

STRFILEFIND( cName, cPath ) ⇒ cFileName<br />

cName<br />

cPath<br />

the file name or pathname containing the file name to search<br />

inside the cPath list.<br />

a list <strong>of</strong> paths separated with semicolon (just like Dos does),<br />

where cFile should be searched.<br />

If your file is to be found on different possible positions, this function search the first place where<br />

the file is found and returns a valid pathname to that file.<br />

368.15.122 STRGETLEN()<br />

STRGETLEN( xExpr, cPicture ) ⇒ nFieldLength<br />

xExpr a generic expression.<br />

cPicture<br />

the picture string.<br />

This function returns the length <strong>of</strong> field when using xExpr with cPicture.<br />

368.15.123 STRLISTASARRAY()<br />

STRLISTASARRAY( cList, [cDelimiter] ) ⇒ aList<br />

cList<br />

cDelimiter<br />

This function transform a character string list into an array.<br />

a character string containing a list separated with cDelimiter.<br />

the delimiter used to separate the elements contained inside<br />

the list.


nanoBase 1997 user manual 295<br />

368.15.124 STROCCURS()<br />

STROCCURS( cSearch, cTarget ) ⇒ nOccurrence<br />

cSearch<br />

the search string to find inside cTarget.<br />

cTarget the string to be searched for the presence <strong>of</strong> cSearch.<br />

This function returns the number <strong>of</strong> occurrence that cSearch is contained inside cTarget.<br />

368.15.125 STRPARENT()<br />

STRPARENT( cName ) ⇒ cParentPath<br />

cName<br />

the pathname.<br />

This function tries to return a parent path from cName.<br />

368.15.126 STRPATH()<br />

STRPATH( cName ) ⇒ cPath<br />

cName<br />

the pathname.<br />

This function tries to extract the path from cName.<br />

368.15.127 STRTEMPPATH()<br />

STRTEMPPATH() ⇒ cTempPath<br />

This function returns a temporary path searching for possible definitions inside the environmental<br />

variables.<br />

368.15.128 STRXTOSTRING()<br />

STRXTOSTRING( xVar, [cType] ) ⇒ cTrasformed_to_string<br />

xVar<br />

is the data <strong>of</strong> any type to be converted into string.<br />

cType is the type <strong>of</strong> the data contained inside xVar.<br />

This function returns xVar transformed into a character string.


296 volume VIII Argomenti avanzati e accessori<br />

368.15.129 TB()<br />

TB( [nTop], [nLeft], [nBottom], [nRight],<br />

[acCol], [acColSayPic],<br />

[acColTopSep], [acColBodySep], [acColBotSep],<br />

[acColHead], [acColFoot],<br />

[alColCalc],<br />

[abColValid],<br />

[abColMsg],<br />

[cColor], [abColColors],<br />

[nFreeze],<br />

[lModify],<br />

[lAppend],<br />

[lDelete],<br />

[lButtons | aButtons] ) ⇒ NIL<br />

nTop, nLeft, nBottom, nRight defines the screen area where browse have to take place.<br />

acCol<br />

is the columns array to be included into the browse.<br />

acColSayPic is the picture array.<br />

acColTopSep is the top separation array: default is chr(194)+chr(196).<br />

acColBodySep is the body separation array: default is chr(179).<br />

acColBotSep is the bottom separation array: default is chr(193)+chr(196).<br />

acColHead<br />

is the header array for every column.<br />

acColFoot<br />

is the footer array for every column.<br />

alColCalc<br />

is the array that identify the calculated column (not editable).<br />

True (‘.T.’) means calculated.<br />

abColValid<br />

is the validation array that specify when a field is properly<br />

filled. The condition must be specified in code block format.<br />

is the message array that permits to show information at the<br />

abColMsg<br />

bottom <strong>of</strong> browse area. The array must be composed with<br />

code blocks which result with a character string.<br />

cColor<br />

is the color string: it may be longer than the usual 5 elements.<br />

is the color code block array. The code block receive as pa-<br />

abColColors<br />

rameter the value contained inside the field and must return<br />

an array containing two numbers: they correspond to the two<br />

color couple from cColor.<br />

nFreeze<br />

indicates the number <strong>of</strong> columns to be left frozen on the left<br />

side.<br />

lModify indicates whether the browse can modify data.<br />

lDelete indicates whether the browse can delete and recall records.<br />

lButtons<br />

if True, default buttons are displayed.<br />

aButtons<br />

array <strong>of</strong> buttons.<br />

aButtons[n][1] N the nth button row position;<br />

aButtons[n][2] N the nth button column position;<br />

aButtons[n][3] C the nth button text;<br />

aButtons[n][4] B the nth button code block.<br />

This function, called without parameters, starts the browse <strong>of</strong> the active alias, and if relations are<br />

established, the browse includes also related data.<br />

Please note that due to an unresolved problem, the field names contained inside acCol should<br />

better contain also the alias (ALIAS->FIELD_NAME). See also the examples.


nanoBase 1997 user manual 297<br />

368.15.130 TEXT()<br />

TEXT( cText ) ⇒ NIL<br />

Shows the text contained into cText.<br />

368.15.131 TGLINSERT()<br />

TGLINSERT() ⇒ NIL<br />

Toggle the global insert mode and the cursor shape.<br />

368.15.132 TIMEX2N()<br />

TIMEX2N( [nHH], [nMM], [nSS] ) ⇒ nTime<br />

nHH is the number <strong>of</strong> hours.<br />

nMM is the number <strong>of</strong> minutes.<br />

nSS is the number <strong>of</strong> seconds.<br />

This function calculate the "time number" that is a number representing days and/or portion <strong>of</strong> a<br />

day: 1 is 1 day or 24 hours, 0.5 is 12 hours, and so on.<br />

368.15.133 TIMEN2H()<br />

TIMEN2H( nTime ) ⇒ nHours<br />

nTime<br />

is the "time number" that is a number representing days and/or<br />

portion <strong>of</strong> a day: 1 is 1 day or 24 hours, 0.5 is 12 hours, and<br />

so on.<br />

This function returns the integer number <strong>of</strong> hours contained inside nTime.<br />

368.15.134 TIMEN2M()<br />

TIMEN2M( nTime ) ⇒ nMinutes<br />

nTime<br />

is the "time number" that is a number representing days and/or<br />

portion <strong>of</strong> a day: 1 is 1 day or 24 hours, 0.5 is 12 hours, and<br />

so on.<br />

This function returns the integer number <strong>of</strong> minutes contained inside nTime after subtracting the<br />

hours.


298 volume VIII Argomenti avanzati e accessori<br />

368.15.135 TIMEN2S()<br />

TIMEN2S( nTime ) ⇒ nSeconds<br />

nTime<br />

is the "time number" that is a number representing days and/or<br />

portion <strong>of</strong> a day: 1 is 1 day or 24 hours, 0.5 is 12 hours, and<br />

so on.<br />

This function returns the number <strong>of</strong> seconds (with eventual decimals) contained inside nTime<br />

after subtracting the hours and the minutes.<br />

368.15.136 TRUESETKEY()<br />

TRUESETLEY( nInkeyCode, bAction ) ⇒ .T.<br />

This function is equivalent to SETKEY() but it returns always ‘.T.’<br />

368.15.137 WAITFILEEVAL()<br />

WAITFILEEVAL( lClose ) ⇒ .T.<br />

Shows a wait bar calling WAITPROGRESS() for operation on records <strong>of</strong> a database.<br />

If there is no index active, it is equivalent to WAITPROGRES(RECNO()/LASTREC()).<br />

if an index is active, this cannot work, so an increment for each call is made: WAITPRO-<br />

GRES((nIncrement++)/LASTREC()).<br />

This function must be closed calling it with the lClose parameter to true (‘.T.’). This way,<br />

internal counters are closed and WAITPROGRESS() is closed too.<br />

368.15.138 WAITFOR()<br />

WAITFOR( [cMessage] ) ⇒ NIL<br />

Shows cMessage until it is called again. The wait window is closed when called without parameter<br />

or with NIL.<br />

368.15.139 WAITPROGRESS()<br />

WAITPROGRESS( [nPercent] ) ⇒ .T.<br />

Shows a wait bar on the screen top depending on the value contained into nPercent. nPercent<br />

starts form 0 and ends to 1 (100%). If a value <strong>of</strong> one or more, or NIL is passed, the wait window<br />

is closed.


nanoBase 1997 user manual 299<br />

368.16 Normal command substitution<br />

Clipper works only with functions and commands that are converted into function using the<br />

‘STD.CH’. Here are described some command replacement that can be used also with nB macros.<br />

?<br />

@BOX<br />

@TO<br />

@GET<br />

@SAY<br />

? [exp_list]<br />

qout([exp_list])<br />

?? [exp_list]<br />

qqout([exp_list])<br />

@ nTop, nLeft, nBottom, nRight BOX cnBoxString [COLOR cColorString]<br />

dispbox(nTop, nLeft, nBottom, nRight, [cnBoxString], [cColorString])<br />

@ nTop, nLeft TO nBottom, nRight DOUBLE [COLOR cColorString]<br />

dispbox(nTop, nLeft, nBottom, nRight, 2 [,cColorString])<br />

@ nTop, nLeft TO nBottom, nRight [COLOR cColorString]<br />

dispbox(nTop, nLeft, nBottom, nRight, 1 [,cColorString])<br />

@ nTop, nLeft CLEAR [TO nBottom, nRight]<br />

scroll([nTop], [nLeft], [nBottom, nRight])<br />

setpos(nRow, nCol)<br />

@ nTop, nLeft GET Var [PICTURE cGetPicture] [COLOR cColorString] [WHEN lPreExpression] ←↪<br />

↩→[VALID lPostExpression]<br />

setpos(nTop, nLeft)<br />

aadd( GetList, _GET_( Var, "Var", cGetPicture, [{|| lPostExpression}],←↪<br />

↩→[{|| lPreExpression}] ):display() ) atail(GetList):colorDisp(cColorString)<br />

@ nTop, nLeft SAY exp [COLOR cColorString]<br />

devpos(nTop, nLeft)<br />

devout(exp [, cColorString])<br />

@ nTop, nLeft SAY exp PICTURE cSayPicture [COLOR cColorString]<br />

devpos(nTop, nLeft)<br />

devoutpic(exp, cSayPicture, [cColorString])<br />

APPEND<br />

CLEAR<br />

APPEND BLANK<br />

dbappend()<br />

CLEAR<br />

Scroll()<br />

SetPos(0,0)


300 volume VIII Argomenti avanzati e accessori<br />

CLOSE<br />

ReadKill(.T.)<br />

GetList := {}<br />

CLEAR GETS<br />

ReadKill(.T.)<br />

GetList := {}<br />

CLEAR SCREEN | CLS<br />

Scroll()<br />

SetPos(0,0)<br />

CLOSE<br />

dbCloseArea()<br />

CLOSE idAlias<br />

idAlias->( dbCloseArea() )<br />

CLOSE ALTERNATE<br />

Set(19, "")<br />

CLOSE DATABASES<br />

dbCloseAll()<br />

CLOSE INDEXES<br />

dbClear<strong>Index</strong>()<br />

COMMIT<br />

COMMIT<br />

COUNT<br />

dbCommitAll()<br />

COUNT TO idVar [FOR lForCondition] [WHILE lWhileCondition] [NEXT nNextRecords]←↪<br />

↩→[RECORD nRecord] [REST] [ALL]<br />

dbeval( {||idVar:=idVar+1}, {||lForCondition}, {||lWhileCondition},←↪<br />

↩→nNextRecords, nRecord, lRest )<br />

DEFAULT<br />

DEFAULT xVar TO xDefaultValue<br />

DEFAULT( @xVar, xDefaultValue ) ⇒ xVar<br />

DELETE<br />

EJECT<br />

DELETE<br />

dbDelete()<br />

DELETE [FOR lForCondition] [WHILE lWhileCondition] [NEXT nNextRecords]←↪<br />

↩→[RECORD nRecord] [REST] [ALL]<br />

dbeval( {||dbDelete()}, {||lForCondition}, {||lWhileCondition},←↪<br />

↩→nNextRecords, nRecord, lRest )<br />

DELETE FILE xcFile<br />

ferase( cFile )<br />

EJECT<br />

ERASE<br />

qqout( chr(13) )<br />

ERASE xcFile<br />

ferase( cFile )


nanoBase 1997 user manual 301<br />

FIND<br />

GO<br />

FIND xcSearchString<br />

dbSeek( cSearchString )<br />

GO[TO] nRecord<br />

dbgoto(nRecord)<br />

GO[TO] BOTTOM<br />

dbGoBottom()<br />

GO[TO] TOP<br />

dbgotop()<br />

INDEX ON<br />

READ<br />

INDEX ON expKey TO xc<strong>Index</strong>Name [UNIQUE] [FOR lForCondition]←↪<br />

↩→[WHILE lWhileCondition] [[EVAL lEvalCondition] [EVERY nRecords]] [ASCENDING|<br />

DESCENDING]<br />

ordCondSet( [cForCondition], [bForCondition], , [bWhileCondition],←↪<br />

↩→[bEvalCondition], [nRecords], RECNO(), , , , lDescending )<br />

ordCreate( c<strong>Index</strong>Name, , cExpKey, bExpKey, lUnique )<br />

READ<br />

ReadModal(GetList)<br />

GetList := {}<br />

READ SAVE<br />

ReadModal(GetList)<br />

RECALL<br />

RECALL<br />

dbRecall()<br />

RECALL [FOR lForCondition] [WHILE lWhileCondition] [NEXT nNextRecords]←↪<br />

↩→[RECORD nRecord] [REST] [ALL]<br />

dbeval( {||dbRecall()}, {||lForCondition}, {||lWhileCondition},←↪<br />

↩→nNextRecords, nRecord, lRest )<br />

REINDEX<br />

REINDEX [EVAL lEvalCondition] [EVERY nRecords]<br />

ordCondSet(, , , , [bEvalCondition], [nRecords], , , , , , , )<br />

ordListRebuild()<br />

RENAME<br />

RENAME xcOldFile TO xcNewFile<br />

frename( cOldFile, cNewFile )<br />

REPLACE<br />

REPLACE idField1 WITH exp1 [, idField2 WITH exp2...]←↪<br />

↩→[FOR lForCondition] [WHILE lWhileCondition] [NEXT nNextRecords]←↪<br />

↩→[RECORD nRecord] [REST] [ALL]<br />

dbeval( {|| idField1 := exp1 [, idField2 := exp2...]},←↪<br />

↩→{||lForCondition}, {||lWhileCondition}, nNextRecords,←↪<br />

↩→nRecord, lRest )


302 volume VIII Argomenti avanzati e accessori<br />

REPLACE idField1 WITH exp1<br />

idField1 := exp1<br />

RESTORE<br />

SAVE<br />

SEEK<br />

RESTORE SCREEN FROM cScreen<br />

restscreen( 0, 0, Maxrow(), Maxcol(), cScreen )<br />

SAVE SCREEN TO cScreen<br />

cScreen := savescreen( 0, 0, maxrow(), maxcol() )<br />

SEEK expSearch [SOFTSEEK]<br />

dbSeek( expSearch [, lS<strong>of</strong>tSeek] )<br />

SELECT<br />

SET<br />

SELECT xnWorkArea | idAlias<br />

dbSelectArea( nWorkArea | cIdAlias )<br />

SET ALTERNATE TO xcFile [ADDITIVE]<br />

Set( 19, cFile, lAdditive )<br />

SET ALTERNATE ON | OFF | xlToggle<br />

Set( 18, "ON" | "OFF" | lToggle )<br />

SET BELL ON | OFF | xlToggle<br />

Set( 26, "ON" | "OFF" | lToggle )<br />

SET COLOR | COLOUR TO (cColorString)<br />

SetColor( cColorString )<br />

SET CONFIRM ON | OFF | xlToggle<br />

Set( 27, "ON" | "OFF" | lToggle )<br />

SET CONSOLE ON | OFF | xlToggle<br />

Set( 17, "ON" | "OFF" | lToggle )<br />

SET CURSOR ON | OFF | xlToggle<br />

SetCursor( 1 | 0 | iif( lToggle, 1, 0 ) )<br />

SET DATE FORMAT [TO] cDateFormat<br />

Set( 4, cDateFormat )<br />

SET DECIMALS TO<br />

Set( 3, 0 )<br />

SET DECIMALS TO nDecimals<br />

Set( 3, nDecimals )<br />

SET DEFAULT TO<br />

Set( 7, "" )<br />

SET DEFAULT TO xcPathspec<br />

Set( 7, cPathspec )


nanoBase 1997 user manual 303<br />

SET DELETED ON | OFF | xlToggle<br />

Set( 11, "ON" | "OFF" | lToggle )<br />

SET DELIMITERS ON | OFF | xlToggle<br />

Set( 33, "ON" | "OFF" | lToggle )<br />

SET DELIMITERS TO [DEFAULT]<br />

Set( 34, "::" )<br />

SET DELIMITERS TO cDelimiters<br />

Set( 34, cDelimiters )<br />

SET DEVICE TO SCREEN | PRINTER<br />

Set( 20, "SCREEN" | "PRINTER" )<br />

SET EPOCH TO nYear<br />

Set( 5, nYear )<br />

SET ESCAPE ON | OFF | xlToggle<br />

Set( 28, "ON" | "OFF" | lToggle )<br />

SET EXACT ON | OFF | xlToggle<br />

Set( 1, "ON" | "OFF" | lToggle )<br />

SET EXCLUSIVE ON | OFF | xlToggle<br />

Set( 8, "ON" | "OFF" | lToggle )<br />

SET FILTER TO<br />

dbclearfilter()<br />

SET FILTER TO lCondition<br />

dbsetfilter( bCondition, cCondition )<br />

SET FIXED ON | OFF | xlToggle<br />

Set( 2, "ON" | "OFF" | lToggle )<br />

SET INDEX TO [xc<strong>Index</strong> [, xc<strong>Index</strong>1... ] ]<br />

ordListClear()<br />

ordListAdd( c<strong>Index</strong> )<br />

ordListAdd( c<strong>Index</strong>1 )<br />

...<br />

SET INTENSITY ON | OFF | xlToggle<br />

Set( 31, "ON" | "OFF" | lToggle )<br />

SET KEY nInkeyCode [TO]<br />

SetKey( nInkeyCode, NIL )<br />

SET KEY nInkeyCode TO [idProcedure]<br />

SetKey( nInkeyCode, { |p, l, v| idProcedure(p, l, v)} )<br />

SET MARGIN TO<br />

Set( 25, 0 )<br />

SET MARGIN TO [nPageOffset]<br />

Set( 25, nPageOffset )<br />

SET MESSAGE TO<br />

Set( 36, 0 )


304 volume VIII Argomenti avanzati e accessori<br />

SKIP<br />

STORE<br />

Set( 37, .F. )<br />

SET MESSAGE TO [nRow [CENTER | CENTRE]]<br />

Set( 36, nRow )<br />

Set( 37, lCenter )<br />

SET ORDER TO [n<strong>Index</strong>]<br />

ordSetFocus( n<strong>Index</strong> )<br />

SET PATH TO<br />

Set( 6, "" )<br />

SET PATH TO [xcPathspec [, cPathspec1... ] ]<br />

Set( 6, cPathspec [, cPathspec1... ] )<br />

SET PRINTER ON | OFF | xlToggle<br />

Set( 23, "ON" | "OFF" | lToggle )<br />

SET PRINTER TO<br />

Set( 24, "" )<br />

SET PRINTER TO [xcDevice|xcFile [ADDITIVE]]<br />

Set( 24, cDevice|cFile, lAdditive )<br />

SET RELATION TO<br />

dbclearrelation()<br />

SET RELATION TO [expKey1 INTO xcAlias1]<br />

[, [TO] expKey2 INTO xcAlias2...]<br />

[ADDITIVE]<br />

if !lAdditive<br />

dbClearRel()<br />

end<br />

dbSetRelation( cAlias1, {|| expKey1}, ["expKey1"] )<br />

dbSetRelation( cAlias2, {|| expKey2}, ["expKey1"] )<br />

SET SCOREBOARD ON | OFF | xlToggle<br />

Set( 32, "ON" | "OFF" | lToggle )<br />

SET SOFTSEEK ON | OFF | xlToggle<br />

Set( 9, "ON" | "OFF" | lToggle )<br />

SET TYPEAHEAD TO nKeyboardSise<br />

Set( 14, nKeyboardSise )<br />

SET UNIQUE ON | OFF | xlToggle<br />

Set( 10, "ON" | "OFF" | lToggle )<br />

SET WRAP ON | OFF | xlToggle<br />

Set( 35, "ON" | "OFF" | lToggle )<br />

SKIP [nRecords] [ALIAS idAlias|nWorkArea]<br />

[idAlias|nWorkArea -> ]( dbSkip([nRecords]) )<br />

STORE value TO variable


nanoBase 1997 user manual 305<br />

SUM<br />

variable := value<br />

SUM nExp1 [, nExp2...] TO idVar1 [, idVar2...] [FOR lForCondition]←↪<br />

↩→[WHILE lWhileCondition] [NEXT nNextRecords] [RECORD nRecord] [REST] [ALL]<br />

dbeval( {||idVar1:=idVar1+nExp1 [, idVar2:=idVar2+nExp2...] },←↪<br />

↩→{||lForCondition}, {||lWhileCondition}, nNextRecords, nRecord, lRest )<br />

UNLOCK<br />

USE<br />

UNLOCK<br />

dbUnlock()<br />

UNLOCK ALL<br />

dbUnlockAll()<br />

USE<br />

dbclosearea()<br />

USE [xcDatabase]←↪<br />

↩→[INDEX xc<strong>Index</strong>1 [, xc<strong>Index</strong>2...] [ALIAS xcAlias] [EXCLUSIVE|SHARED] [NEW] [READONLY<br />

] [VIA cDriver]]<br />

dbUseArea( [lNewArea], [cDriver], cDatabase, [cAlias], [lShared], [lReadOnly] )<br />

[dbSet<strong>Index</strong>( c<strong>Index</strong>1 )]<br />

[dbSet<strong>Index</strong>( c<strong>Index</strong>2 )]<br />

...<br />

368.17 nB command substitution functions<br />

Inside nB there are many functions made only in substitution to other Clipper commands.<br />

GET<br />

aGetList<br />

SAY<br />

@ nTop, nLeft GET Var<br />

[PICTURE cGetPicture]<br />

[COLOR cColorString]<br />

[WHEN lPreExpression]<br />

[VALID lPostExpression]<br />

Get( @aGetList,<br />

[nTop], [nLeft],<br />

{ |x| iif( pcount() > 0, Var := x, Var ) }<br />

[cGetPicture], [cColorString],<br />

[bPreExpression], [bValid] )<br />

@ nTop, nLeft SAY exp<br />

PICTURE cSayPicture<br />

[COLOR cColorString]<br />

Say( nTop, nLeft, cVar, [cSayPicture], [cColorString] )<br />

is the get list array that will be increased with this get().


306 volume VIII Argomenti avanzati e accessori<br />

APPEND FROM<br />

APPEND FROM xcFile<br />

[FIELDS idField_list]<br />

[scope]<br />

[WHILE lCondition]<br />

[FOR lCondition]<br />

[VIA xcDriver]<br />

dbApp( cFileName, [acFields],<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords],<br />

[nRecord],<br />

[lRest],<br />

[cDriver] )<br />

APPEND FROM xcFile<br />

[FIELDS idField_list]<br />

[scope]<br />

[WHILE lCondition]<br />

[FOR lCondition]<br />

DELIMITED xcDelimiter<br />

dbDelim( .f., cFileName, [cDelimiter], [acFields],<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord], [lRest] )<br />

APPEND FROM xcFile<br />

[FIELDS idField_list]<br />

[scope]<br />

[WHILE lCondition]<br />

[FOR lCondition]<br />

SDF<br />

dbSDF( .f., cFileName, [acFields],<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord], [lRest] )<br />

CONTINUE<br />

COPY<br />

CONTINUE<br />

dbContinue()<br />

COPY FILE xcSourceFile TO xcTargetFile|xcDevice<br />

CopyFile( cSourceFile, cTargetFile|cDevice )<br />

COPY STRUCTURE [FIELDS idField_list]<br />

TO xcDatabase<br />

dbCopyStruct( cDatabase, [acFields] )<br />

COPY STRUCTURE EXTENDED<br />

TO xcExtendedDatabase<br />

dbCopyXStruct( cExtendedDatabase )<br />

COPY TO xcFile<br />

[FIELDS idField_list]<br />

[scope]<br />

[WHILE lCondition]<br />

[FOR lCondition]<br />

[VIA xcDriver]


nanoBase 1997 user manual 307<br />

dbCopy( cFileName, [acFields],<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords],<br />

[nRecord],<br />

[lRest],<br />

[cDriver] )<br />

COPY TO xcFile<br />

[FIELDS idField_list]<br />

[scope]<br />

[WHILE lCondition]<br />

[FOR lCondition]<br />

DELIMITED xcDelimiter<br />

dbDelim( .t., cFileName, [cDelimiter], [acFields],<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord], [lRest] )<br />

COPY TO xcFile<br />

[FIELDS idField_list]<br />

[scope]<br />

[WHILE lCondition]<br />

[FOR lCondition]<br />

SDF<br />

dbSDF( .t., cFileName, [acFields],<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord], [lRest] )<br />

CREATE<br />

JOIN<br />

CREATE xcDatabase<br />

FROM xcExtendedDatabase<br />

[NEW]<br />

[ALIAS cAlias]<br />

[VIA cDriver]<br />

dbOldCreate( cDatabase, cExtendedDatabase,<br />

[cDriver], [lNew], [cAlias] )<br />

JOIN WITH xcAlias TO xcDatabase<br />

[FOR lCondition] [FIELDS idField_list]<br />

dbJoin( cAlias, cDatabase,<br />

[acFields], [bForCondition] )<br />

KEYBOARD<br />

KEYBOARD cString<br />

Keyboard( [cString] ) ⇒ NIL<br />

LABEL FORM<br />

LABEL FORM xcLabel<br />

[TO PRINTER]<br />

[TO FILE xcFile]<br />

[NOCONSOLE]<br />

[scope]<br />

[WHILE lCondition]<br />

[FOR lCondition]<br />

[SAMPLE]<br />

dbLabelForm( cLabel, [lToPrinter], [cFile],<br />

[lNoConsole], [bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord], [lRest], [lSample] )


308 volume VIII Argomenti avanzati e accessori<br />

LIST<br />

LIST exp_list<br />

[TO PRINTER]<br />

[TO FILE xcFile]<br />

[scope]<br />

[WHILE lCondition]<br />

[FOR lCondition]<br />

[OFF]<br />

dbList( [lToDisplay], abListColumns,<br />

[lAll],<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord], [lRest],<br />

[lToPrinter], [cFileName] )<br />

LOCATE<br />

PACK<br />

LOCATE [scope] FOR lCondition<br />

[WHILE lCondition]<br />

dbLocate( [bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord], [lRest] )<br />

PACK<br />

dbPack()<br />

PUBLIC<br />

QUIT<br />

PUBLIC idMemvar<br />

MemPublic( cMemvarName|acMemvarNames )<br />

QUIT<br />

Quit()<br />

RELEASE<br />

RELEASE idMemvar<br />

MemRelease( cMemvarName|acMemvarNames )<br />

REPORT FORM<br />

REPORT FORM xcReport<br />

[TO PRINTER]<br />

[TO FILE xcFile]<br />

[NOCONSOLE]<br />

[scope]<br />

[WHILE lCondition]<br />

[FOR lCondition]<br />

[PLAIN | HEADING cHeading]<br />

[NOEJECT] [SUMMARY]<br />

RF( cForm,<br />

[bForCondition], [bWhileCondition],<br />

[nNext], [nRecord], [lRest], [lPlain],<br />

[cbHeading], [lBeforeEject], [lSummary],<br />

[lDate], [acExtra] ) ⇒ NIL<br />

RESTORE FROM<br />

RESTORE FROM xcMemFile [ADDITIVE]<br />

MemRestore( cMemFileName, [lAdditive] )


nanoBase 1997 user manual 309<br />

RUN<br />

RUN xcCommandLine<br />

Run( cCommand )<br />

SAVE TO<br />

SAVE TO xcMemFile<br />

[ALL [LIKE|EXCEPT skeleton]]<br />

MemSave( cMemFileName, [cSkeleton], [lLike] )<br />

SET FUNCTION<br />

SORT<br />

TOTAL<br />

SET FUNCTION nFunctionKey TO cString<br />

SetFunction( nFunctionKey, cString )<br />

SORT TO xcDatabase<br />

ON idField1 [/[A|D][C]]<br />

[, idField2 [/[A|D][C]] ...]<br />

[scope]<br />

[WHILE lCondition]<br />

[FOR lCondition]<br />

dbSort( cDatabase, [acFields],<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord], [lRest] )<br />

TOTAL ON expKey<br />

[FIELDS idField_list] TO xcDatabase<br />

[scope]<br />

[WHILE lCondition]<br />

[FOR lCondition]<br />

dbTotal( cDatabase, bKey, [acFields,<br />

[bForCondition], [bWhileCondition],<br />

[nNextRecords], [nRecord]], [lRest] )<br />

UPDATE<br />

ZAP<br />

UPDATE FROM xcAlias<br />

ON expKey [RANDOM]<br />

REPLACE idField1 WITH exp<br />

[, idField2 WITH exp ...]<br />

dbUpdate( cAlias, bKey, [lRandom], [bReplacement] )<br />

Example:<br />

ZAP<br />

dbZap()<br />

dbUpdate( "INVOICE", {|| LAST}, .T.,;<br />

{|| FIELD->TOTAL1 := INVOICE->SUM1,;<br />

FIELD->TOTAL2 := INVOICE->SUM2 } )


310 volume VIII Argomenti avanzati e accessori<br />

368.18 RPT: the nB print function<br />

The function RPT() helps to print ASCII file containing Memvars, Fields and print commands.<br />

RPT() is accessible from the DOC() menu.<br />

368.18.1 Memvars and fields<br />

As usual with standard word processors, variables are written delimited with "" (Alt+175).<br />

Inside these delimiters can find place character Memvars, character Fields and functions giving<br />

a character result.<br />

The RPT() function generates a public variable n_Lines that contains the available lines inside<br />

the actual sheet. Every time a line is written, this value is reduced, until a new page is reached and<br />

then it will start again from the maximum value. It is useful to read this variable to determinate<br />

if there is enough space or it is better to change page.<br />

368.18.2 Commands<br />

The function RPT() recognise some print commands. These commands starts with the asterisk<br />

(*) symbol. This means that "*" is a print command prefix.<br />

It follows the command syntax.<br />

*COMMAND<br />

*COMMAND<br />

cStatement<br />

cStatement<br />

...<br />

*END<br />

The lines contained inside *COMMAND - *END are executed with the nB macro interpreter.<br />

*DBSKIP<br />

*DBSKIP [nSkip]<br />

It Executes a dbskip() on the active alias.<br />

*FOOT<br />

*FOOT<br />

cFooter<br />

cFooter<br />

...<br />

*END<br />

The lines contained inside *FOOT - *END are printed each time at the bottom <strong>of</strong> pages.<br />

*HEAD<br />

*HEAD<br />

cHeader<br />

cHeader<br />

...<br />

*END<br />

The lines contained inside *HEAD - *END are printed each time at the top <strong>of</strong> pages.


nanoBase 1997 user manual 311<br />

*IF<br />

*IF lCondition<br />

...<br />

...<br />

*END<br />

If the condition lCondition is true, the lines contained inside *IF - *END are printed.<br />

*INSERT<br />

*LEFT<br />

*LPP<br />

*INSERT cFileName<br />

Includes the text contained into the file cFileName.<br />

*LEFT nLeftBorder<br />

The nLeftBorder is the number <strong>of</strong> column to be left blank as a left border.<br />

*LPP nLinesPerPage<br />

It determinates the page length expressed in lines. After printing the nLinesPerPageth line,<br />

a form feed is sent.<br />

*NEED<br />

*PA<br />

*NEED nLinesNeeded<br />

If the available lines are less then nLinesNeeded, the follwing text will be printed on the<br />

next page.<br />

*PA<br />

*REM<br />

Jumps to a new page.<br />

*REM | *COMMENT [comment_line]<br />

It adds a comment that will not be printed.<br />

*WHILE<br />

*WHILE lCondition<br />

...<br />

...<br />

*END<br />

The lines contained inside *WHILE - *END are printed as long as lCondition is true.<br />

368.18.3 Examples<br />

It follows some example <strong>of</strong> text to be printed with the RPT() function. Example’s lines are numbered.<br />

Line numbers must not be part <strong>of</strong> a real RPT text files.<br />

PAGE DEFINITION<br />

Margins are defined with *HEAD, *FOOT and *LEFT commands. In the following example<br />

is defined:


312 volume VIII Argomenti avanzati e accessori<br />

Top 2 lines;<br />

Bottom 2 lines;<br />

Left 10 characters.<br />

The right margin is not defined as it depends on the lines length that will be printed.<br />

The only considered page dimension is the height, *LPP (lines per page):<br />

Page height 66 lines.<br />

Here starts the example:<br />

001 *lpp 66<br />

002 *head<br />

003<br />

004<br />

005 *end<br />

006 *foot<br />

007<br />

008<br />

009 *end<br />

010 *left 10<br />

011 ... text text text<br />

012 ... test text text<br />

...<br />

At line 001 is defined the page height in lines. At line 002 is defined the header; it contains<br />

two empty lines (003 and 004) which will be printed at the top <strong>of</strong> every page. At line 006<br />

starts the footer definition that contains two empty lines (007 and 008) that will be printed<br />

at the end <strong>of</strong> every page. At line 010 is defined the space on the left that will be added to<br />

every line printed. From line 011 starts the normal text.<br />

HEADER AND FOOTER<br />

The commands *HEAD and *FOOT are used to define the top and bottom border if they<br />

contains empty lines, it these lines are not empty, they became real head and foot.<br />

The dimensions are as it follows:<br />

Top 6 lines (should be one inch);<br />

Bottom 6 lines;<br />

Left 10 characters (should be an inch).<br />

Page height 66 lines (should be 11 inch).<br />

At position 0.5 in (after 3 lines) a one line header appears.


nanoBase 1997 user manual 313<br />

001 *lpp 66<br />

002 *head<br />

003<br />

004<br />

005<br />

006 ------------------- MYFILE.TXT -------------------<br />

007<br />

008<br />

009 *end<br />

010 *foot<br />

011<br />

012<br />

013<br />

014<br />

015<br />

016<br />

017 *end<br />

018 *left 10<br />

019 ... text text text<br />

020 ... test text text<br />

...<br />

At line 006 (the fourth header line) a text appears. It will be printed on every page at the<br />

absolute fourth page line.<br />

CODE INSERTION<br />

Pieces <strong>of</strong> code can be inserted inside *COMMAND - *END. It can be useful to make<br />

complicated reports.<br />

The following example declares a public variable used to number pages.<br />

001 *command<br />

002 mempublic("PageNo")<br />

003 PageNo := 0<br />

004 *end<br />

005 *lpp 66<br />

006 *head<br />

007 *command<br />

008 PageNo := PageNo +1<br />

009 *end<br />

010<br />

011<br />

012 *end<br />

013 *foot<br />

014<br />

015 Page <br />

016<br />

017 *end<br />

018 *left 10<br />

019 ... text text text<br />

020 ... test text text<br />

...<br />

At line 001 starts a *COMMAND definition: lines 002 and 003 will be interpreted from the<br />

function EX(), the nB interpreter. These lines define a public variable and initialize it at 0.<br />

This variable will be use to count pages.<br />

At line 007, inside the header (nested), start another *COMMAND definition that contains<br />

an increment for the "PageNo" variable. As the header is read and "executed" for every new<br />

page, and that before the footer, the variable "PageNo" will contain the right page number.<br />

At line 015, inside the footer, a reference to "PageNo" appears. Here will be printed the<br />

page number.<br />

A more complicated example can be found in ‘ADDRESS.TXT’ the RPT text file used for<br />

the ADDRESS.& macro examples.


314 volume VIII Argomenti avanzati e accessori<br />

368.19 How can I...<br />

nB is a little bit complicated as it may do many things. Here are some examples.<br />

Create a UDF function<br />

UDF means User Defined Function. Inside nB there isn’t the possibility to create functions,<br />

but there is an alternative: code blocks.<br />

Create a big code block<br />

A code block cannot be longer than 254 characters, as any other instruction inside nB.<br />

So, there is no way to make a bigger code block, but a code block can call another code<br />

block, and so on. For example:<br />

mempublic( { "first", "second", "third" } )<br />

first := {|| eval( second, "hello" ) }<br />

second := {|x| eval( third, x ) }<br />

third := {|x| alertbox( x ) }<br />

eval( first )<br />

This stupid example simply will show the alert box containing the word "hello".<br />

368.20 The source files<br />

The nB source is composed <strong>of</strong> four files:<br />

‘NB.PRG’ The main source file containing essentially the nB menu.<br />

‘REQUEST.PRG’ Contains a link to all Clipper standard functions.<br />

‘STANDARD.PRG’ Contains the most important standard functions.<br />

‘EXTRA.PRG’<br />

Contains some extra function not absolutely necessary during<br />

macro execution.<br />

The file ‘REQUEST.PRG’ source file generates some warnings because not all functions listed<br />

there are directly called form nB. Don’t worry about that warning message.<br />

Different ‘.RMK’ (rmake) files are included to compile nB differently, including/excluding some<br />

program parts, for example to obtain a runtime executor.<br />

Appunti di informatica libera 2003.06.29 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!