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=idx4czy"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,idx3czy"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=idx4czy"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
-Imoż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
-Ibez 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
-Iz 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
-Ijest 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
-Izostał 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