Cross-Referenz-Listings in GFA-Basic

Basic, auch wenn es von GFA kommt, hat gegenüber den klassischen Compiler-Sprachen wie PASCAL oder C einen besonderen gravierenden Nachteil: Variable, Unterprogrammnamen und Labels können an jeder beliebigen Stelle im Programm eingeführt werden, ohne vorher deklariert zu werden.

Das mag dem Basic-Freund zunächst als Vorteil erscheinen. Wer jedoch schon einmal eine schlaflose Nacht auf der Suche nach einem Programmierfehler verbracht hat, um hinterher festzustellen, daß bloß ein Tippfehler zu einer neuen Variablen mit dem sinnlosen Anfangswert Null geführt hat, wird vielleicht Zweifel bekommen haben.

Ein Pascal-Compiler z. B. hätte es gar nicht so weit kommen lassen: Bei der Übersetzung und dem Linken wird gnadenlos jeder ’Undefined Identifier’ aufgedeckt.

Um Abhilfe zu schaffen, wurde das vorliegende Cross-Referenz-Programm entwickelt. Es ermöglicht das identifizieren und Lokalisieren aller vom Programmierer erfundenen Bezeichner in einem im ASCII-Format abgespeicherten Programmtext (.LST-File).

Beim Speichern eines Programms mit ’SAVE,A’ ist zu beachten, daß zuvor mit der Anweisung ’DEFLIST 0’ die Standard-Textdarstellung verändert wird.

Hierdurch wird bewirkt, daß alle GFA-Schlüsselworte in Großschreibung und sämtliche Labels, Variablen- und Unterprogrammnamen mit kleinen Buchstaben erscheinen.

Damit ist ein einfaches Unterscheidungsmerkmal für die im Programm verwendete Such-Procedure gegeben.

Die Benutzung von XREF ist denkbar einfach und vollständig mit Alert-Boxen durchzuführen. Wie so oft empfiehlt sich die Verwendung einer RAM-Floppy.

Listing

Abbildung 1

Nach Auswahl des zu bearbeitenden Programms mit der File-Select-Box geht es los. Links oben auf dem Bildschirm sieht man die Nummer der gerade untersuchten Programmzeile: man kann die Bearbeitung an dieser Stelle mit einem Druck auf die Escape-Taste vorzeitig abbrechen.

Sollte das ausgewählte Programm im falschen Textformat vor liegen, so wird dies meist nach wenigen Zeilen entdeckt und mit einer Alert-Meldung kommentiert. Der Anwender hat nun die Möglichkeit, das Cross-Referenz-Programm zu verlassen, um das BAS-File in den Interpreter nachladen zu lassen.

Liegt das Programm nur als ASCII-Text vor, muß man XREF abbrechen und mit ’NEW’ löschen, um ’MERGE’ zu verwenden. Nach Abspeichern mit ’SAVE,A’ kann XREF erneut gestartet werden.

Ist dann alles glatt durchgelaufen, kann man die Cross-Referenz-Liste oder den mit Zeilennummern versehenen Programmtext auf Drucker oder Bildschirm ausgeben.

Bei der Anzeige auf dem Bildschirm kann man mit ’Control-S’ die Ausgabe anhalten und mit ’ Control-Q’ weiterlaufen lassen. Jeweils nach einer Bildschirm-Seite wird automatisch angehalten und auf einen Tastendruck oder Mouse-Klick gewartet.

Bevor man XREF verläßt, hat man die Möglichkeit, die Arbeit auf Diskette zu sichern. Das Cross-Referenz-Listing wird mit der Extension ’.CRF’, das numerierte Programm-Listing mit ’.PRN’, gespeichert.

Mit XREF sollte dem GFA-Basic-Programmierer das Leben hinsichtlich des Aufspürens von Tippfehlern, aber auch bei der Verbesserung der Dokumentation, erleichtert werden.

' ***********************************************************
' *                                                         *
' *                     — XREF Vers 1.2 —                   *
' *      Cross-Reference-Listings für GFA-Basic Programme   *
' *                                                         *
' *                    14.03.1987 H. Bauch                  *
' *                                                         *
' ***********************************************************
'
ALERT 0," XREF Version 1.2! | 14.03.1987 by H. Bauch! ",1," Na los ",dunmy% 
@init
@bearbeiten 
DO 
    CLS 
    PRINT
    PRINT " ";akt_zeile%;" Zeilen in ";prg.name$;".LST"
    ALERT 1,"Programm durchsucht!",1,"Ausgabe|Neul|Quit",antw%
    CLS
    ON antw% GOSUB ausgabe,bearbeiten,ende 
LOOP

' 
' _____________________________________________________________

' ------------- Ende des Hauptprogranms -----------------------
' _____________________________________________________________
'
'
PROCEDURE init 
    DEFLIST 0
    LET typ_max%=5  !   0=Real/1=Integer/2=String/3=Boolean/4=Onterp./5=Label
    LET name_max%=200 ! max. Anz. der Namen pro Typ 
    sp_anz_zeil%=55 ! Spaltenanzahl für die Zeilennr.-Ausgabe
    DIM name$(typ_max%,1,name_max%) ! Variablen-, Label oder Uprg.-name 
    DIM zeile$(typ_max%,1,name_max%) ! Zeilennr. in der ein Name steht 
    DIM zeilen_zaehler%(typ_max%,1,name_max%) ! Zähler für akt. Anz. Zeilennr.
    DIM max_nam_anz%(typ_max%,1)
    DIM typ$(typ_max%) 
    typ$(0)="Real-Variablen" 
    typ$(1)="Integer-Variablen" 
    typ$(2)="String-Variablen" 
    typ$(3)="Boolean-Variablen" 
    typ$(4)="Unterprogramm-Namen" 
    typ$(5)="Labels"
    trenn_zei$="+-*/\' ()=<>,; "+CHRS(34)   ! Diese Zeichen trennen Bezeichner.
    inv_ein$=CHR$(27)+CHRS(112) ! Bildschirmausgabe invers
    inv_aus$=CHR$(27)+CHR$(113) !   - " -   normal
RETURN! Init
'
'
PROCEDURE bearbeiten 
    ARRAYFILL zeilen_zaehler%(),0 
    ARRAYFILL max_nam_anz%(),0 
    DEFTEXT 1,16
    TEXT 125,30,"Welches Programm soll bearbeitet werden ?"
    FILESELECT "\*.LST","",p.name$
    IF EXIST(p.name$)
        OPEN "I",#1,p.name$
        p.name$=MID$(p.name$,1,LEN(p.name$)-4)
        p%=INSTR(p.name$,"\",p%)
        WHILE p%<>0 
            po%=p%
            p%=INSTR(p.name$,"\",po%+1)
        WEND
        path$=LEFT$(p.name$,po%) 
        prg.name$=MID$(p.name$,po%+1)
    ELSE
        @ende
    ENDIF
    CLS
    PRINT
    PRINT
    PRINT " Erstelle Cross-Reference-Listing von ";prg.name$;".LST"
    PRINT
    PRINT " Zeilen-Nummer in Bearbeitung -> ";
    y%=CRSLIN
    x%=CRSCOL
    akt_zeile%=0
    first!=TRUE
    DEFMOUSE 2
    WHILE (NOT EOF(#1)) AND INKEY$<>CHRS(27)
        INC akt_zeile%
        LINE INPUT #1,basic_zeile$
        PRINT AT(x%,y%);akt_zeile%;
        @entf_leer
        @entf_str_const
        @entf_komm
        @suche_namen
    WEND
    @namen_abspeichern
    DEFMOUSE 0
    CLOSE
RETURN! Bearbeiten
'
'
PROCEDURE entf_leer ! Führende Leerzeichen einer Basic-Zeile entfernen 
    WHILE MID$ (basic_zeile$,1,1)=" " 
        basic_zeile$=MID$(basic_zeile$,2)
    WEND
RETURN! Entf_leer
'
'
PROCEDURE entf_str_const ! Entf. von in Anführungszeichen stehenden Strings 
    CLR l%
    REPEAT
        k%=INSTR(basic_zeile$,CHRS(34),l%+1) ! Position des " am String-Anfang 
        l%=INSTR(basic_zeile$,CHRS(34),k%+1) ! Position des " am String-Ende 
        IF (k%<>0) AND (l%>k%) 
            basic_zeile$=LEFT$(basic_zeile$,k%)+MID$(basic_zeile$,l%) 
            l%=k%+1 
        ENDIF! (k%<>0) And (l%>k%)
    UNITL k%=0 OR k%>l%
RETURN! Entf_str_const
'
'
PROCEDURE entf_komm ! Entf. von Kommentaren die hinter "!"-Zeichen stehen 
    CLR k% ! Position eines '!'
    ok!=FALSE ! Flag für erfolgreiche Suche nach Kommentar-'!'
    REPEAT
        k%=INSTR(basic_zeile$,k%+1)
        IF (k%>2) ! Kommentare nur ab der 3. Spalte möglich
            ' Das Zeichen vor dem '!' ist , ')', ‘oder ' '
            komm_found!=INSTR(CHR$(34)+"),; ",MID$(basic_zeile$,k%-1,1))
            IF (INSTR(basic_zeile$,"!!"))
                ' ______________________________________________________
                ’ Das Kommentar-'!' steht direkt hinter einer bool'schen Variablen
                ' ______________________________________________________

                komm_found!=TRUE 
                k%=INSTR(basic_zeile$,"!!")+1 
            ENDIF! (Instr(Basic_zeile$,"!!"))
            IF komm_found!  ! Kommentar mit Sicherheit gefunden
                basic_zeile$=LEFT$(basic_zeile$,k%-1) 
                ok!=TRUE
            ELSE    ! Weitere Überprüfung notwendig
                i%=k%
                REPEAT  !   Suche Anfang des
                    DEC i%  !   Bezeichners vor
                    pch$=MIDS(basic_zeile$,i%,1)    ! dem '!'
                UNTIL (INSTR(trenn_zei$,pch$)<>0) OR i%=1 !
                IF (i%>1)
                    INC i%
                ENDIF! (i%>1)
                IF ((k%>i%) AND (i%>0))
                    ' ______________________________________
                    ' Ermittlung des Bezeichners vor dem ‘!’
                    ' ______________________________________
                    ident$=MID$(basic_zeile$,i%,k%-i%)
                    §ident_name !   Teste, ob GfA-Schlüsselwort
                    IF (NOT ident_name!)
                        ' ___________________________________________
                        ' Schüsselwort oder Zahlenkonstante liegt vor 
                        ' ___________________________________________
                        ok!=TUE
                        basic_zeile$=LEFTS(basic_zeile$,k%-1)
                    ENDIF! (Not Search!)
                ENDIF! ((K%>I%) And (I%>0))
            ENDIF! Komm_found!
        ENDIF! (K%>2)
    UNTIL (ok! OR k%=0)
RETURN! Entf_komm
'
'
PROCEDURE suche_namen ! Suche Bezeichner, die nicht GfA-Basic-Schlüsselwort 
    LET o_flag!=FALSE   !   On ... gefunden
    LET lab_flag!=FALSE !   Label gefunden
    LET up_nam_found!=FALSE !   Unterprogrammnamen gefunden
    LET name_pos!=FALSE !   Name überhaupt möglich
    LET b$="§()= :"
    FOR i%=1 TO LEN(b$)
        LET name_pos!=name_pos! OR INSTR(basic_zeile$,MID$(b$,i%,1))
    NEXT i%
    LET name_pos!=name_pos! AND NOT ((MID$(basic_zeile$,1,1)="'") OR (MID$(basic_zeile$,1,3)="REM") OR (MID$(basic_zeile$,1,4)="DATA"))
    IF name_pos!
        ' _______________________________________________________________
        ' Basic-Zeile enthält mindestens 1 Anweisung mit Klammern oder 
        ' Gleichheitszeichen und ist nicht Kommentar- oder Data-Zeile
        ' _______________________________________________________________
        WHILE LEN(basic_zeile$)>0 
            §identifier 
            IF first!
                §test_list_def(ident$)
            ENDIF
            IF ident$="ON" 
                o_flag!=TRUE 
            ENDIF
            IF ident$="PROCEDURE" OR ident$="GOSUB" OR ident$="§"
                ' Unterscheidung zw. Variablen und Unterprg.-namen bzw. Labeln
                up_nam_found!=TRUE 
            ENDIF! Ident$="PROCEDURE" Or ...
            IF ident$="GOTO" OR ident$="RESUME" OR ident$="RESTORE" 
                lab_flag!=TRUE 
            ENDIF
            §ident_name 
            IF ident_name!
                IF up_nam_found! 
                    t%=4
                    §name_ablegen 
                    IF NOT o_flag!
                        up_nam_found!=FALSE 
                    ENDIF 
                ELSE
                    IF INSTR(ident$,":") OR lab_flag!
                        IF RIGHT$(ident$,1)=":"
                            ident$=LEFT$(ident$,LEN(ident$)-1)
                        ENDIF
                        t%=5
                        §name_ablegen 
                        lab_flag !=FALSE 
                    ELSE
                        t%=INSTR("%$!",RIGHT$(ident$,1)) ! Typ der Variablen 
                        §name_ablegen 
                    ENDIF 
                ENDIF 
            ENDIF
        WEND
    ENDIF 
RETURN! Such_namen
'
'
PROCEDURE identifier 
    ' Ermittlung des nächsten Bezeichners Beginnend ab der 1. Spalte
    ' des restlichen Basic-Zeilen-Strings; der gefundene Bezeichner
    ' wird anschließend von diesem entfernt.
    CLR ident$,nch$,i%
    REPEAT 
        INC i%
        ident$=ident$+nch$ 
        nch$=MID$(basic_zeile$,i%,1)
        EXIT IF nch$="§"
    UNITL INSTR(trenn_zei$,nch$)<>0 OR nch$=""
    IF nch$="§" 
        ident$="§"
    ENDIF! Nch$="S"
    k%=ABS(basic_zeile$,1%,1)="(") ! Funktion oder Array-Var 
    basic_zeile$=MID$(basic_zeile$,i%+1) ! Der verbleibende String 
RETURN ! Identifier
'
'
PROCEDURE ident_name ! Identifiziere Namen, falls Erfolg  Ident_name!=TRUE 
    IF LEN(ident$)=0 OR ident$="§" 
        ident_name!=FALSE 
    ELSE
        IF VAL?(ident$)=LEN(ident$)
            ' ------------------------
            ' Zahlenkonstante gefunden
            ' ------------------------
            ident_name!=FALSE 
        ELSE 
            IF LEN(ident$)>1
                ' ---------------------------------------------
                ' Schlüsselworte sind mindestens 2 Zeichen lang
                ' ---------------------------------------------
                f_ch$=LEFT$(ident$)
                IF f_ch$>="a" AND f_ch$<="z" 
                    ident_name!=TRUE 
                ELSE
                    ident_name!=FALSE 
                ENDIF
            ELSE! (Len(Ident$)=1)
                ' -----------------------------------------------------------------
                ' Bezeichnerlänge gleich eins bedeutet immer einfache Real-Variable
                ' -----------------------------------------------------------------
                ident_name!=TRUE 
            ENDIF! Len(Ident$)>1 
        ENDIF! Val?(Ident$)=Len(Ident$)
    ENDIF! Len(Ident$)=0 
RETURN
'
'
PROCEDURE test_list_def(test$) 
    zw_buchst!=FALSE 
    f_ch$=LEFT$(test$)
    FOR i%=2 TO LEN(test$) 
        n_ch$=UPPER$(MID$(test$,i%,1)) 
        zw_buchst!=(n_ch$>="A" AND n_ch$<="Z")
        EXIT IF zw_buchst!
    NEXT i%
    IF zw_buchst!
        IF f_ch$>="A" AND f_ch$<="Z"
            IF UPPER$(test$)<>test$ 
                meldung$="Das Program ist nicht mit| 'DEFLIST 0' abgespeichert ! |XREF abbrechen nachladen von |"+prg.name$+".BAS ?"
                ALERT 2,meldung$,2," Nö | Klar ",antw%
                IF antw%=2
                    meldung$="Nach Abspeichern mit 'SAVE, A' |XREF.BAS mit 'LOAD' aufrufen|und erneut starten !"
                    ALERT 1,meldung$,1," Ok ",dummy% 
                    l_name$=MID$(prg.name$,LEN(prg.name$)-4)+".BAS"
                    IF NOT (EXIST(l_name$))
                        ALERT 2, "BAS-File nicht gefunden",1, "Mist",dummy%
                        FILESELECT "\*.BAS","",l_name$ 
                    ENDIF
                    IF l_name$<>""
                        LOAD l_name$
                    ELSE
                        ALERT 2, "Program nicht gefunden.|Neustart",1," Seufz ",dummy%
                        RUN
                    ENDIF
                ELSE
                    RUN
                ENDIF! antw%=2 
            ENDIF! UPPER$(test$)<>test$ 
        ENDIF! f_ch$>="A" AND ... 
        first!=FALSE 
    ENDIF! zw_buchst!
RETURN! test_list_def
'
'
PROCEDURE name_ablegen ! Ablegen der identifizierten Namen in einem Feld
    id_len%=LEN(ident$)
    IF id_len%>0 
        IF k%=1 
            ident$=ident$+"()"
            INC id_len%
            INC id_len%
        ENDIF
        IF id_len%<20 
            ident$=ident$+STRING$(20-id_len%,".")
        ELSE 
            IF id_len%>20 
                ident$=ident$+CHR$(10)+CHR$(13)+SPACE$(20) 
            ENDIF 
        ENDIF 
        zei_nr$="    "
        RSET zei_nr$=STR$(akt_zeile%)
        IF max_nam_anz%(t%,k%)=0 AND zeilen_zaehler%(t%,k%,1)=0
            ' ------------------------------
            ' Erster Aufruf dieser Procedure
            ' ------------------------------
            LET name$(t%,k%,1)=ident$ ! Der gefundene Name 
            LET zeile$(t%,k%,1)=zei_nr$ ! und die zugehörige Zeile 
            zeilen_zaehler%(t%,k%,1)=1 ! Anzahl Zeilen in denen Name$() enth. ist 
            max_nam_anz%(t%,k%)=1
        ELSE
            ' --------------------
            ' Jeder weitere Aufruf
            ' --------------------
            FOR i%=1 TO max_nam_anz%(t%,k%) ! Suchen ob Ident$ schon mal aufgetaucht?
                EXIT IF name$(t%,k%,i%)=ident$ ! falls ja, Aussteigen aus der Schleife 
            NEXT i% !
            IF i%>max_nam_anz%(t%,!c%)
                ' ---------------------------------
                ' Ident$ ist noch nicht vorgekomnen
                ' ---------------------------------
                INC max_nam_anz%(t%,k%) ! Zähler erhöhen
                INC zeilen_zaehler%(t%,k%,i%)   ! Zeilenzähler=1
                LET name$(t%,k%,i%)=ident$  ! Neuen Name speichern
                LET zeile$(t%,k%,i%)=zei_nr$    ! 1. Zeile ablegen
            ELSE
                IF INSTR(zeile$(t%,k%,i%),zei_nr$)=0
                    ' ---------------------------------------------
                    ' Ident$ kennt in Akt_zeile% zum ersten mal vor
                    ' ---------------------------------------------
                    INC zeilen_zaehler%(t%,k%,i%)
                    LET zeile$(t%,k%,i%)=zeile$(t%,k%,i%)+zei_nr$ 
                ENDIF
            ENDIF! (I%>max_nam_anz%(t%,k%)
        ENDIF 
    ENDIF 
RETURN! Name_ablegen
'
'
PROCEDURE namen_abspeichern 
    FOR k%=0 TO 1 
        FOR t%=0 TO typ_max%
            IF max_nam_anz%(t%,k%)>0 
                §sort(t%,k%,max_nam_anz%(t%,k%))
            ENDIF 
        NEXT t%
    NEXT k%
RETURN! namen_abspeichern
'
'
PROCEDURE sort(typ%,kl%,m_v_anz%) ! Alphabetisches Sortieren der Namen 
    LOCAL i%,j%
    FOR i%=m_v_anz%-1 DOWNTO 0 
        FOR j%=0 TO i%
            IF name$(typ%,kl%,j%)>name$(typ%,kl%,j%+1)
                SWAP name$(typ%,kl%,j%),name$(typ%,kl%,j%+1)
                SWAP zeile$(typ%,kl%,j%),zeile$(typ%,kl%,j%+1)
                SWAP zeilen_zaehler%(typ%,kl%,j%),zeilen_zaehler%(typ%,kl%,j%+1) 
            ENDIF 
        NEXT j%
    NEXT i%
RETURN! Sort()
'
'
PROCEDURE ausgabe 
    ALERT 2,"Ausgabe auf ",1,"Schirm|Drucker",device%
    IF device%=1 
        device$="CON:"
    ELSE
        device$="PRN:"
    ENDIF
    ALERT 1,"Ausgabe von ",1,"XRF-List|PRG-List",antw%
    CLS
    IF antw%=1 
        @namen_ausgeben(device$)
    ELSE
        @listing_ausgeben(device$)
    ENDIF 
RETURN! Ausgabe
'
'
PROCEDURE namen_ausgeben(dev$)
    OPEN "O",#3,dev$
    PRINT #3
    PRINT #3," Cross-Reference-Listing von ";prg.name$;".LST"
    PRINT #3,STRINGS(80,"=")
    scrn_l%=CRSLIN-1
    FOR t%=0 TO typ_max%
        IF max_nam_anz%(t%,0)+max_nam_anz%(t%,1)>0 
            PRINT #3 
            @halt
            PRINT #3,"*   ";typ$(t%)
            @halt
        ENDIF
        FOR k%=0 TO 1 
            FOR i%=1 TO max_nam_anz%(t%,k%)
                IF LEN(name$(t%,k%,i%))>0 
                    PRINT #3,name$(t%,k%,i%);
                    IF LEN(name$(t%,k%,i%))>20 
                        @halt 
                    ENDIF
                    IF LEN(zeile$(t%,k%,i%))>sp_anz_zeil% 
                        za%=(LEN(zeile$(t%,k%,i%)) DIV sp_anz_zeil%)
                        IF LEN(zeile$(t%,k%,i%)) MOD sp_anz_zeil%>0 
                            za%=za%+1 
                        ENDIF
                        PRINT #3,MIDS(zeile$(t%,k%,i%),1,sp_anz_zeil%)
                        @halt
                        z%=1
                        WHILE z%<za%
                            PRINT #3,SPACES(20);MID$(zeile$(t%,k%,i%),sp_anz_zeil%*z%+1,sp_anz_zeil%)
                            @halt 
                            INC z%
                        WEND
                    ELSE
                        PRINT #3,zeile$(t%,k%,i%)
                        @halt
                    ENDIF
                ENDIF
            NEXT i%
        NEXT k%
    NEXT t%
    CLOSE
    PRINT CHR$(7)
    IF device%<>0
        PRINT "     ";inv_einS;"     Ausgabe beendet - Zurück durch Tastendruck!      ";inv_aus$
        PAUSE 20 
        REPEAT
        UNITL INKEY$<>"" OR MOUSEK 
    ENDIF
RETURN! Namen_ausgeben()
'
PROCEDURE listing_ausgeben(dev$)
    OPEN "I",#1,p.name$+".LST"
    OPEN "O",#2,dev$
    PRINT #2
    PRINT #2," Nummeriertes Listing von ";p.name$+".LST"
    PRINT #2,STRINGS(80,"=")
    PRINT #2
    scrn_l%=CRSLIN
    akt_zeile%=0
    WHILE (NOT EOF(#1)) AND INKEY$<>CHR$(27)
        INC akt_zeile%
        LINE INPUT #1,basic_zeile$ 
        PRINT #2,USING "###: ",akt_zeile%;
        PRINT #2,basic_zeile$
        §halt
    WEND
    CLOSE
    PRINT CHR$(7)
    IF device%<>0
        PRINT "          ";inv_ein$;“      Ausgabe beendet - Zurück durch Tastendruck!  ";inv_aus$
        PAUSE 20 
        REPEAT
        UNTIL INKEY$<>"" OR MOUSEK 
    ENDIF 
RETURN
'
'
PROCEDURE halt 
    IF device%=1
        IF ASC(INKEY$)=19   ! Anhalten mit ’S
            PAUSE 10 
            REPEAT
            UNTIL ASC(INKEY$)=17 ! Weiter mit 'Q 
        ENDIF
        INC scrn_l%
        IF scrn_l%>20 
            scrn_l%=0 
            PRINT CHRS (7)
            PRINT SPACES(21);inv_ein$;"    Weiter durch Drücken einer Taste!   ";inv_aus$
            REPEAT
            UNTIL INKEY$<>"" OR MOUSEK 
            PRINT 
        ENDIF 
    ENDIF 
RETURN
'
'
PROCEDURE ende 
    IF prg.name$<>"" 
        device%=0
        ALERT 3,"Arbeit sichern?",1," Nö | Klar ",antw%
        IF antw%=2
            TEXT 125,30,"     Arbeit sichern.           "
            FILESELECT path$+"*.CRF",prg.name$+".CRF",crf$
            IF crf$<>""
                DEFMOUSE 2
                @namenausgeben(crf$)
                DEFMOUSE 0 
            ENDIF
            FILESELECT path$+"*. PRN",prg.name$+".PRN",prn$ 
            IF prn$<>""
                DEFMOUSE 2
                @listing_ausgeben(prn$)
                DEFMOUSE 0 
            ENDIF 
        ENDIF 
    ENDIF 
    CLS 
    END 
RETURN

Listing 1


Links

Copyright-Bestimmungen: siehe Über diese Seite
Classic Computer Magazines
[ Join Now | Ring Hub | Random | << Prev | Next >> ]