Programma di esempio STATC.PRT |
; STATC
;
; Programma per Proteus
;
; (C) 1998-2003 Simone Zanella Productions
;
; Statistiche su un programma C.
;
; Riporta:
; - il numero totale di linee;
; - il numero totale e la percentuale di righe non bianche;
; - il numero totale e la percentuale di linee con direttive.
;
; Nota: i token "/*" e "*/" non possono apparire dentro stringhe.
; Parametri impliciti: output su console
;!proteus -o
; Inizializza le variabili
FUNCTION ONSTART()
IF STREQ(ARGV(3), "..")
CONSOLELN "Sintassi: " ARGV(1) " " ARGV(2) " nomefile.c"
CONSOLELN ""
CONSOLELN "Scopo: riporta delle statistiche sul file C indicato"
ABORT 0
FI
; Flag: la linea è dentro un commento?
_InRem = 0
; Numero complessivo di linee
_TNL = 0
; Numero di direttive
_TPPD = 0
; Numero di linee non bianche (escluse le direttive)
_TML = 0
RETURN
; Incrementa sempre il contatore di riga
INC(@TNL)
IF EQ(InRem, 0)
; La linea inizia fuori commento
; Trova l'inizio del commento
Pos = STRSTR(L, "/*")
; Duplica la linea
PL = STRDUP(L)
; C'è un commento?
IF NEQ(Pos, 0)
PL3 = ""
REPEAT
; Pos è dove la parte fuori commento termina
DEC(@Pos)
; PL2 è la parte fuori commento
PL2 = LEFT(PL, Pos)
; Accoda PL2 a PL3
IF ISNOTEMPTY(PL2)
PL3 = PL3 PL2
FI
; Pos2 è dove termina il commento (se sulla stessa riga)
Pos2 = STRSTR(PL, "*/")
; Siamo dentro un commento; imposta il flag
InRem = 1
; Il commento termina sulla riga?
IF NEQ(Pos2, 0)
; Azzera il flag
InRem = 0
; Pos2 è l'inizio della parte fuori commento
ADD(@Pos2, 2)
; C'è qualcosa da appendere?
IF NEQ(Pos2, 0)
PL = SUBSTR(PL, Pos2, STRLEN(PL))
ELSE
BREAK
FI
ELSE
BREAK
FI
Pos = STRSTR(PL, "/*")
UNTIL EQ(Pos, 0)
ELSE
PL3 = STRDUP(L)
FI
ELSE
; Siamo dentro un commento
; Trova la fine del commento
Pos = STRSTR(L, "*/")
; Crea una copia della linea
PL = STRDUP(L)
; Trovata la fine del commento
IF NEQ(Pos, 0)
PL3 = ""
REPEAT
; Pos è l'inizio della parte fuori commento
ADD(@Pos, 2)
; PL è la parte fuori commento
PL = SUBSTR(PL, Pos, STRLEN(PL))
; Trova in PL l'inizio del prossimo commento
Pos2 = STRSTR(PL, "/*")
; Fuori commento
InRem = 0
; C'è un nuovo commento nel resto della riga?
IF NEQ(Pos2, 0)
; Pos2 è dove termina la parte fuori commento
DEC(@Pos2)
; PL2 è la parte fuori commento
PL2 = LEFT(PL, Pos2)
; Accoda PL2 a PL3
IF ISNOTEMPTY(PL2)
PL3 = PL3 PL2
FI
; Trova il prossimo fine commento
Pos = STRSTR(PL, "*/")
; Trovato: aggiorna PL
IF NEQ(Pos, 0)
DEC(@Pos)
PL = SUBSTR(PL, Pos, STRLEN(PL))
ELSE
; Siamo di nuovo dentro un commento
InRem = 1
FI
ELSE
; Il resto della linea è fuori commento
IF ISNOTEMPTY(PL)
PL3 = PL3 PL
FI
FI
Pos = STRSTR(PL, "*/")
UNTIL EQ(Pos, 0)
ELSE
; La linea è dentro un commento - ignora (il resto del
; programma è saltato)
IF EOF
CONSOLELN "Commento non terminato, linea " N
ABORT 1
ELSE
IGNORE
FI
FI
FI
; Elimina gli spazi
PL3 = ALLTRIM(PL3, " ")
IF ISNOTEMPTY(PL3)
; Controlla se è una direttiva
IF STREQ(LEFT(PL3, 1), "#")
INC(@TPPD)
ELSE
; Salta le linee di commento C++ style
IF NOT(STREQ(LEFT(PL3, 2), "//"))
INC(@TML)
FI
FI
FI
FUNCTION ONEND()
PRINTLN "File: " _F
PRINTLN "Numero totale di linee: " _TNL
T = ADD(_TML, _TPPD)
PN = MUL(FDIV(T, _TNL), 100)
PRINTLN "Numero di linee non-bianche: " T \
" (" PFORMAT("02.02f", PN) "%)"
PN = MUL(FDIV(_TPPD, _TNL), 100)
PRINTLN "Numero di direttive: " _TPPD \
" (" PFORMAT("02.02f", PN) "%)"
RETURN