Exuberant Ctags#
Program ctags#
-I#
Argument -I
dla bieżącego wywołania programu ctags kontroluje stanem listy z identyfikatorami (podanych wprost lub pobranych z dodatkowego pliku z identyfikatorami), które (zależnie od sposobu ich zapisu) będą wpływały na proces generowania niektórych tagów w językach C/C++. Głównym przeznaczeniem tego argumentu jest obsługa w kodzie źródłowym specjalnych przypadków wynikających z użycia makr preprocesora.
Opis działania#
Prawidłowe użycie argumentu najlepiej objaśnić na zapisie składniowym:
ctags -I value [--argument | -argument] [path]
gdzie poszczególne człony oznaczają:
- ctags - ścieżka względna lub bezwzględna do pliku binarnego programu ctags (
ctags.exe
). Wszystko zależy od sposobu uruchamiania programu ctags, np. z systemowej konsoli, ze skrótu do programu czy z innego programu/skryptu. value - jedna z trzech dostępnych wartości:
"list"
- lista z identyfikatorami, które wpływają na proces generowania niektórych tagów w językach C/C++. Przy tworzeniu tej listy należy pamiętać o kilku regułach:- Elementami listy może być dowolna liczba prostych identyfikatorów (opcjonalnie ze znakiem
"+"
umieszczonym zaraz za identyfikatorem) lub par identyfikatorów rozdzielonych znakiem"="
, gdzie separatorem między nimi jest znak przecinka (bez otaczania go dodatkowymi spacjami) lub jakiś biały znak w dowolnej ilości (w tym przypadku listę należy otoczyć cudzysłowami aby całość została potraktowana jak wartość dla argumentu-I
), np.idx1,idx2+,idx3=idx4
czy"idx1 idx2+ idx3=idx4"
. - Podanie prostego identyfikatora oznacza, że w trakcie analizowania plików źródłowych zostanie on zignorowany. Dotyczy to samego identyfikatora, bez ewentualnych znaków występujących przed lub za nim, np.
idx1,idx2,idx3
czy"idx1 idx2 idx3"
(szczegóły). - Zakończenie prostego identyfikatora dodatkowym prefiksem w postaci znaku
"+"
oznacza, że w trakcie analizowania plików źródłowych zostanie on zignorowany włącznie z występującą za nim listą argumentów podanych w nawiasach, np.idx1+,idx2+,idx3+
czy"idx1+ idx2+ idx3+"
(szczegóły). - Jeśli dwa identyfikatory zostaną rozdzielone dodatkowym prefiksem w postaci znaku
"="
(bez otaczania go dodatkowymi spacjami) to oznacza, że w trakcie analizowania plików źródłowych pierwszy identyfikator zostanie zastąpiony przez drugi identyfikator, np.idx1=idx2,idx3=idx4
czy"idx1=idx2 idx3=idx4"
(szczegóły).
- Elementami listy może być dowolna liczba prostych identyfikatorów (opcjonalnie ze znakiem
"file"
- jeśli wartość rozpoczyna się od znaku"@"
lub znaków separacyjnych w ścieżkach"/"
czy"\"
(włącznie ze znakiem"."
przed nimi), albo pierwsze dwa znaki określają literę dysku (np."C:"
) to reprezentuje ona ścieżkę względną lub bezwzględną do dodatkowego pliku z identyfikatorami. Znaki wieloznaczności*
i?
są obsługiwane tylko w tych ścieżkach, które nie rozpoczynają się od znaku"@"
. Prawidłowe będą następujące wartości:"@list"
,"/list"
,".\list"
,"C:\list"
,"/lis*"
czy"C:\lis?"
(szczegóły)."-"
- specjalna wartość oznaczająca anulowanie wszystkich zdefiniowanych do tej pory identyfikatorów (podanych wprost lub pobranych z dodatkowego pliku z identyfikatorami).
- argument - jeden lub więcej dodatkowych argumentów dostrajających działanie programu ctags.
- path - jedna lub więcej dodatkowych ścieżek do plików/folderów, które będą analizowane przy generowaniu tagów (szczegóły).
Kilka uwag odnośnie stosowania argumentu -I
:
- Argument
-I
można podawać wielokrotnie (separatorem jest spacja), i każdy kolejny będzie miał wpływ tylko na te pliki, które występują bezpośrednio po nim. - Przekazanie argumentu
-I
bez podania jakiejkolwiek niepustej wartości zwróci komunikatctags: No files specified. Try "ctags --help".
. Także otoczenie pustej wartości lub samych białych znaków podwójnymi cudzysłowami zwróci komunikatctags: Missing parameter for "I" option
. - Przekazanie argumentu
-I
z wartością wskazującą na nieistniejący dodatkowy plik z identyfikatorami zwróci komunikatctags: cannot open "xxx" : No such file or directory
. - W programie ctags nie ma żadnego argumentu zwracającego listę ze wszystkimi identyfikatorami, które zdefiniowano przy użyciu argumentu
-I
. - Rzeczywiste przetwarzanie listy identyfikatorów określonej argumentem
-I
jest możliwe tylko za pośrednictwem wbudowanych parserów, w których przewidziano taką możliwość (np. działa z językami obsługiwanymi przez parserc.c
). - Dodatkowy plik z identyfikatorami # to zwykły plik tekstowy, gdzie każdy prosty identyfikator lub para identyfikatorów zajmuje osobną linię.
Argument
-I
został wprowadzony głównie z powodu stosowania różnych makr preprocesora (w językach C/C++), których obecność zaburza prawidłową analizę kodu źródłowego. W praktyce jest to najlepszy sposób na omijanie wielu problemów wynikających ze stosowania niestandardowych wstawek wymieszanych z właściwą składnią tych języków. Poniżej zaprezentowanych zostanie kilka przykładów ilustrujących ten problem.Załóżmy, że mamy następujący kod: #
int foo ARGDECL4(void *, ptr, long int, nbytes)
W powyższym przykładzie makro
"ARGDECL4"
zostałoby błędnie zinterpretowane jako nazwa funkcji zamiast prawidłowej nazwy"foo"
. Przekazanie do programu ctags argumentu"-I ARGDECL4"
spowoduje, że w trakcie analizowania kodu słowo"ARGDECL4"
zostanie całkowicie zignorowane, przez co uwzględnione zostanie poprzedzające je słowo"foo"
.Załóżmy, że mamy następujący kod: #
/* creates an RCS version string in module */ MODULE_VERSION("$Revision: 690 $")
W powyższym przykładzie wywołanie makra
"MODULE_VERSION"
wygląda zbyt podobnie do definicji funkcji, ponieważ nie występuje po nim średnik (w rzeczywistości może nawet następować po nim definicja zmiennej globalnej, która wyglądałaby podobnie jak deklaracja parametru funkcji w stylu K&R). W dodatku ta pozorna definicja funkcji może nawet spowodować pominięcie reszty pliku podczas próby dokończenia definicji. Przekazanie do programu ctags argumentu"-I MODULE_VERSION+"
spowoduje, że w trakcie analizowania kodu słowo"MODULE_VERSION"
i występujące za nim nawiasy (włącznie z zawartością) zostaną całkowicie zignorowane.Załóżmy, że mamy następujący kod: #
CLASS Example { // your content here };
W powyższym przykładzie nazwa
"CLASS"
to makro preprocesora, które rozwija się do czegoś innego dla każdej platformy. Dla platformy Win32 może oznaczać"class __declspec(dllexport)"
, a dla Uniksa po prostu"class"
. Zwykle brak słowa kluczowego"class"
w języku C ++ spowodowałby niepoprawną analizę kodu źródłowego. Przekazanie do programu ctags argumentu"-I CLASS=class"
spowoduje, że w trakcie analizowania kodu słowo"CLASS"
zostanie zastąpione przez słowoclass
.
Prosty przykład:
ctags -I * :: lista z identyfikatorami jest pusta
ctags -I idx *
ctags -I idx1,idx2,idx3 *
ctags -I "idx1 idx2 idx3" *
ctags -I idx+ *
ctags -I idx1+,idx2+,idx3+ *
ctags -I "idx1+ idx2+ idx3+" *
ctags -I idx1=idx2,idx3=idx4 *
ctags -I "idx1=idx2 idx3=idx4" *
ctags -I idx -I - * :: wyczyszczenie listy z identyfikatorami
ctags -I idx1 plik1.c -I idx2 plik2.c :: 'plik1.c' uwzględnia 'idx1', 'plik2.c' uwzględnia 'idx1' oraz 'idx2'
ctags -I idx1 plik1.c -I - -I idx2 plik2.c :: 'plik1.c' uwzględnia 'idx1', 'plik2.c' uwzględnia 'idx2'
ctags -I C:\file *
ctags -I C:\file* *
ctags -I C:\file? *
ctags -I .\file *
ctags -I ./file *
ctags -I \file *
ctags -I /file *
ctags -I @file *
ctags -I @C:\file *
ctags -I @.\file *
ctags -I @./file *
ctags -I @\file *
ctags -I @/file *
:: Błędne przypadki
ctags -i
ctags -I
ctags -I "" *
ctags -I " " *
ctags -I -R
ctags -I plik.c