delaet dsum? Dsum - eto utilita, kotoraya vypolnyaet proverku posle kopirovaniya. Ona predpolagaet, chto fajly skopirovany iz kataloga-istochnika v kata- log-priemnik. Katalog-istochnik nazvan upravlyayushchim katalogom, poskol'ku on sledit za tem, kakie fajly sravnivayutsya. Dlya kazhdogo fajla v uprav- lyayushchem kataloge pechataetsya ego imya vmeste so znacheniem ego kontrol'noj summy i so znacheniem kontrol'noj summy dlya skopirovannogo fajla v kata- loge-priemnike. Vsya eta informaciya vydaetsya v odnoj stroke. Pol'za ot polucheniya vsej informacii ot dsum v odnoj stroke zaklyu- chaetsya v tom, chto vizual'no dva fajla mogut byt' provereny ochen' legko. Vam net neobhodimosti smotret' v drugoe mesto dlya polucheniya neobhodimoj informacii. Al'ternativoj dlya dsum mozhet byt' vypolnenie kakogo-libo scenariya, podobnogo privodimomu nizhe. 1. Skopirujte vashi fajly v drugoj katalog. 2. Podschitajte kontrol'nuyu summu vseh fajlov iz upravlyayushchego kataloga i vyvedite rezul'tat v kakoj-libo fajl. 3. Podschitajte kontrol'nuyu summu vseh fajlov v kataloge, soderzhashchem kopiyu, i vyvedite rezul'tat v kakoj-libo fajl. 4. Sravnite eti dva fajla komandoj diff dlya togo, chtoby uvidet', ne otlichayutsya li kakie-libo kopii. |to ne daet vam dazhe horoshego vyvoda na ekran o tom, chto proisho- ditgi|to ne daet vam dazhe horoshego vyvoda na ekran o tom, chto proisho- Dsum ne prohodit vniz po derevu fajlov, potomu chto bol'shinstvo ko- pij yavlyayutsya kopiyami iz kataloga v katalog, a ne iz segmenta dereva v segment dereva. Iz-za togo, chto ona ne vypolnyaet takoj obhod, slozhnost' programmy sushchestvenno ponizhaetsya. Po umolchaniyu sravnivayutsya VSE fajly. |to predpolagaet, chto vy sko- pirovali vse fajly v katalog kopirovaniya. V nekotoryh sluchayah vy mozhete zahotet' kopirovat' tol'ko vybrannye fajly, takie kak *.c (vse vashi ishodnye fajly). V etom sluchae upravlyayushchij katalog soderzhit mnozhestvo fajlov, a katalog s kopiyami soderzhit tol'ko fajly s rasshireniem .c. Dlya podderzhki takih sluchaev v programmu vklyucheny klyuchi -c i -o. Klyuch -c ukazyvaet tol'ko fajly tipa *.c iz upravlyayushchego kataloga. V re- zul'tate proizvoditsya proverka tol'ko fajlov *.c v kataloge s kopiej. Klyuch -o vypolnyaet to zhe samoe dlya fajlov, sootvetstvuyushchih *.o. Primery 1. $ mount /dev/fd0 /mnt $ cp /usr/include/* /mnt $ dsum /usr/include /mnt Montiruet gibkij disk v katalog /mnt. Kopiruet vse fajly zagolov- kov v kataloge /usr/include na gibkij disk. Proveryaet kopii, ispol'zuya dsum dlya ishodnogo kataloga i dlya kataloga s kopiej. Primechanie: Ukazyvaya kopirovat' *, my voobshche ne popadem v katalog /usr/include/sys. 2. $ dsum . .. Ispol'zuya v kachestve upravlyayushchih fajlov fajly v tekushchem kataloge, sverit' kazhdyj fajl s odnoimennym fajlom v roditel'skom kataloge. Poyasneniya V strokah 4-9 proizvoditsya proverka na nalichie oshibok. Esli ukaza- no menee dvuh argumentov, znachit upravlyayushchij katalog i/ili katalog ko- pii ne ukazan i v rezul'tate obnaruzhivaetsya oshibka. Esli kolichestvo ar- gumentov prevyshaet tri, znachit, ukazano eshche chto-to krome klyucha -c i dvuh katalogov, chto takzhe yavlyaetsya oshibkoj. Vse ostal'noe (dva ili tri argumenta) rassmatrivaetsya kak dopustimoe znachenie. V strokah 11-21 proizvoditsya inicializaciya peremennoj FLIST. FLIST - eto upravlyayushchaya peremennaya, kotoraya opredelyaet imena fajlov, na koto- rye nado obratit' vnimanie. Esli v komandnoj stroke ukazany tol'ko ime- na katalogov ($# = 2), FLIST prisvaivaetsya znachenie po umolchaniyu * (vse fajly) v stroke 12. Znachenie * prisvaivaetsya peremenoj FLIST i ne trak- tuetsya v eto vremya kak metasimvol (eto osobennost' komandnogo processo- ra). Esli v komandnoj stroke ukazan klyuch ($# = 3), proizvoditsya prover- ka pervoj peremennoj i FLIST poluchaet sootvetstvuyushchee znachenie, *.c ili *.o. Esli ukazana ne takaya opciya, vyvoditsya soobshchenie ob oshibke i prog- ramma zavershaetsya. V strokah 23-31 vypolnyaetsya sama rabota. Zdes' vypolnyaetsya cikl for, kotoryj prohodit po spisku slov, sozdannomu upravlyayushchim katalogom v sootvetstvii so znacheniem peremennoj FLIST. V stroke 23 peremennaya FLIST rasshiryaetsya fakticheski s simvola * v imya kazhdogo fajla. Tem samym cikl for poluchaet dannye dlya ispol'zovaniya. Sledovatel'no, peremennaya FLIST yavlyaetsya polnym marshrutnym imenem kazhdogo fajla v upravlyayushchem ka- taloge. Stroka 25 razbiraet rasshirenie, sdelannoe v stroke 19. Peremennaya BASEF poluchaet bazovoe imya polnogo marshruta iz peremennoj FILE. Prichi- noj, po kotoroj my eto delaem, yavlyaetsya tot fakt, chto pozzhe pri ssylke na katalog kopii nam neobhodimo tol'ko imya fajla. (V sisteme UNIX ko- manda basename vozvrashchaet poslednij element v ukazannom marshrute, t.e. samo imya fajla, esli marshrut soderzhit promezhutochnye katalogi.) Stroki 26-29 vyvodyat pervuyu chast' vyhodnogo soobshcheniya. Operator if-then ispol'zovan potomu, chto nam nuzhno menyat' vyhodnoe soobshchenie v zavisimosti ot togo, skol'ko simvolov soderzhit imya fajla. Stroka 26 op- redelyaet dlinu imeni fajla, ispol'zuya komandu expr. Komanda expr mozhet byt' ispol'zovana dlya sravneniya dvuh strok i poluchaet kolichestvo sov- pavshih simvolov. Sravnenie imeni fajla so "vsemi simvolami" (*), takim obrazom vozvrashchaet dlinu stroki. (U vas mozhet vozniknut' zhelanie obra- tit'sya k expr(1), chtoby poluchit' informaciyu o drugih hitrostyah etoj mnogocelevoj komandy.) |to vozvrashchaemoe znachenie ispol'zuetsya v operatore test dlya opre- deleniya, soderzhit li imya fajla menee semi simvolov: vozmozhno vsego odin ili dva simvola. V poslednem sluchae, esli my delaem tabulyaciyu, my polu- chim tol'ko pervuyu poziciyu tabulyacii. Dlya polucheniya posleduyushchih tabulya- cij my otobrazhaem sem' simvolov dlya togo, chtoby popast' na mesto sledu- yushchego polya tabulyacii. (Esli bylo 3-6 simvolov, my vse ravno ostanovimsya na pole vtoroj tabulyacii, t.e. eto mesto rabotaet verno.) Zatem otobra- zhaem tabulyaciyu dlya togo, chtoby my popali na mesto okonchaniya vtoroj ta- bulyacii, chto nam i trebovalos'. Esli imya fajla soderzhit bolee semi simvolov, my uzhe nahodimsya v pervoj pozicii tabulyacii ili za nej. Takim obrazom, sleduyushchij simvol tabulyacii peredvinet nas vo vtoruyu poziciyu tabulyacii. |ffekt zaklyucha- etsya v tom, chto dlya razmeshcheniya kolonok ne imeet znacheniya razmer imeni fajla (krome sluchaya, kogda ono dejstvitel'no ochen' dlinnoe). |to pozvo- lyaet izbavit'sya ot "blyuza polzushchih kolonok", kogda kolonki sdvigayutsya v zavisimosti ot razmera otobrazhaemoj informacii. V kachestve primera ta- kogo effekta mozhet sluzhit' standartnaya komanda sum. Ee vyhod vyglyadit tak: -------------------------------- | 4243 3 autobkp | 247 1 can | 25167 6 cpiobr | 186 3 dosflp | 56864 2 dsum | 2782 1 log | S drugoj storony, vyhod dsum ochen' yasnyj i chetkij, ne sdvigaetsya po vsemu ekranu. Sdvig delaet vyvod izlomannym i zatrudnyaet bystryj prosmotr informacii. CHudo vyvoda v odnu stroku sovershaetsya v stroke 27 (dlya fajlov s imenami menee 7 simvolov) ili v stroke 28 (dlya fajlov s bolee dlinnymi imenami). Vnutri komandy echo v kazhdom sluchae my pryachem drugie komandy, no po-prezhnemu upravlyaem tem, kak ih rezul'taty vyvodyatsya na ekran. Vo-pervyh, sami imena fajlov vyvodyatsya, buduchi ranee izvlechennymi iz polnogo marshrutnogo imeni. Obratite vnimanie, chto imena fajlov ne so- derzhat informaciyu o tom, iz kakogo oni kataloga. Zatem my neskol'ko sdvigaemsya i pechataem pervoe pole vyhodnoj summy dlya etogo fajla (samu kontrol'nuyu summu). |to kontrol'naya summa versii fajla v upravlyayushchem kataloge, poskol'ku peremennaya FILE byla sgenerirovana dlya etogo kata- loga. Komanda sum vyvodit tri znacheniya (kontrol'naya summa, chislo blo- kov, zanyatyh fajlom, i samo imya fajla). Nam nuzhno poluchit' tol'ko per- voe znachenie, kotoroe izvlekaetsya putem vypolneniya komandy sum i pere- dachi ee vyhoda po kanalu komande cut, kotoraya i vozvrashchaet pervoe pole. Posle togo, kak znachenie kontrol'noj summy napechatano, my otobrazhaem \c dlya zapreshcheniya perehoda na novuyu stroku. |to sohranyaet kursor v toj zhe stroke. Zdes' nachinaet rabotat' stroka 30. Ona generiruet kontrol'nuyu sum- mu togo zhe fajla v kataloge kopii ($2 v komandnoj stroke) i tekushchee imya fajla, vyrezaya tol'ko chislo, i pechataet ego pravee kursora v toj zhe stroke. Cikl zavershaetsya, kogda vse fajly iz upravlyayushchego kataloga budut provereny komandoj sum. VOZMOZHNYE MODIFIKACII KOMANDNOGO FAJLA Neplohoj modifikaciej mozhet byt' variant, chtoby dsum pechatala ne tol'ko znacheniya, kak eto sdelano, no i flag v konce stroki v sluchae, kogda dva fajla otlichayutsya. Togda u nas ne bylo by neobhodimosti prosmatrivat' neposredstvenno chisla. My ishchem flag i srazu vidim, kogda chto-to ne tak. Nizhe privoditsya reshenie problemy vyvoda flaga dlya togo, chtoby ob- legchit' vam rabotu. Ono ne vklyucheno v predstavlennuyu vyshe utilitu po toj prichine, chto takogo roda veshchi mogut byt' vypolneny otnositel'no prosto. Vy mozhete sami sdelat' etu modifikaciyu v kachestve uprazhneniya. Tekst programmy, vypolnyayushchej etu rabotu, vyglyadit tak: for FILE in $1/$FLIST do BASEF=`basename $FILE` S1=`sum $FILE 2>&1 | cut -d' ' -f1` S2=`sum $2/$BASEF 2>&1 | cut -d' ' -f1` if [ "$S1" = "$S2" ] then M="" else M="<---" fi if [ ` expr $BASEF : '.*'` -lt 7 ] then echo "$BASEF: \t$S1\t$S2 $M" else echo "$BASEF:\t$S1\t$S2 $M" fi done Podhod k resheniyu nemnogo otlichaetsya ot resheniya, prinyatogo pri na- pisanii dsum, poskol'ku vy ne mozhete generirovat' kontrol'nuyu summu na hodu. Vy dolzhny perehvatit' vyhod komandy sum i ispol'zovat' ego pozzhe. To, chto my ishchem, poyavlyaetsya v shestoj stroke. Esli dve kontrol'nye summy razlichny, peremennaya M ustanavlivaetsya sootvetstvuyushchim obrazom. Esli fajly razlichayutsya, peremennaya M poluchaet strelku, ukazyvayushchuyu na to, chto kopiya plohaya. 3.4.2. log - menyu dostupa k fajlam protokola kopirovaniya -------------------------------------------------------------------------- Imya : log _________________________________________________________________________ log Menyu dostupa k fajlam protokola kopirovaniya NAZNACHENIE Obespechivaet interfejs v vide menyu k fajlam protokola, poluchennym ot utility autobkp. FORMAT VYZOVA log Primer vyzova log Komandnyj fajl log 1 : 2 # @(#) log v1.0 Menu access to backup logfiles Author: Russ Sage 4 c 5 set `date` 6 echo " 8 $1, $2 $3 $4 10 Logfile Menu 11 ---------------- 12 1 - list all log file names 13 2 - display log of home backup 14 3 - display log of product backup 15 to exit 17 Enter command (1-3,<>): \c" 18 read CMD 20 case $CMD in 21 "") exit;; 22 1) echo "\nLogfile names:" 23 sed -n -e "/more/s/^.*more \(.*\);;$/\1/p" $HOME/bin/log;; 24 2) more $HOME/bin/autobkplog.home;; 25 3) more$HOME/bin/auto2.bkplogm;; 26 *) echo "log: $CMD is not a command";; 27 esac Peremennye sredy vypolneniya CMD Komanda, poluchennaya ot pol'zovatelya HOME Vash registracionnyj katalog v sisteme Opisanie Zachem nam nuzhen log? Esli vy chitali etu glavu, nichego ne propuskaya, vy uzhe vstrechalis' s programmoj autobkp. Vyvodnye dannye autobkp ochen' informativny i dolzhny byt' sohraneny kak chast' operacii kopirovaniya. |to eshche bolee vazhno, esli u vas imeyutsya programmy, zapuskaemye s pomoshch'yu cron. So vremenem nekotorye iz etih programm mozhet nachat' rabotat' neverno i razrushit' vse vami sdelannye kopii. Edinstvennyj sposob prosledit' za takimi veshchami - eto ispol'zovat' fajly protokola. Fajly protokola ko- mandy cron soderzhat nekotoruyu informaciyu, no fajly protokola programmy autobkp soderzhat ee gorazdo bol'she. Problema voznikaet, kogda vy stalkivaetes' s nalichiem neskol'kih rabot dlya autobkp. Vy mozhete ne zahotet' smeshivat' nevzaimosvyazannye kopii fajlov v odnom i tom zhe fajle so spiskom marshrutov, poetomu vy sozdaete neskol'ko fajlov pathlist, neskol'ko zadanij dlya cron i neskol'ko fajlov protokola. Esli vam nuzhno vypolnit' pyat' ili desyat' podobnyh rabot, kakim obrazom vy prosledite za vsemi fajlami protoko- lov, zapomnite ih imena i oblegchite ih prosmotr? Vse eti problemy reshe- ny v komandnom fajle log. CHto delaet log? Komandnyj fajl log - eto upravlyaemaya pri pomoshchi menyu utilita. Menyu pozvolyaet vam videt' tekushchie imena fajlov v fajlah protokola, poetomu vam net neobhodimosti pomnit' ih. Ostal'nye komandy yavlyayutsya vhodnymi tochkami v fajly protokola, ispol'zuyushchimi komandu more dlya prosmotra. Kogda my rassmatrivali komandnyj fajl cpiobr, my videli, kak rabo- taet upravlyaemaya pri pomoshchi menyu programma. Komandnyj fajl log neskol'- ko proshche v tom smysle, chto on delaet tol'ko odin prohod. Krome togo, log - eto "zhivaya" programma. Ona ne yavlyaetsya statichnoj i dolzhna posto- yanno izmenyat'sya v sootvetstvii s vashimi procedurami kopirovaniya. Posredstvom takoj modifikacii log sposobna soobshchit' vam dejstvitel'nye imena fajlov. Log yavlyaetsya raznovidnost'yu programmy, ssylayushchejsya sama na sebya. Dlya pokaza dejstvitel'nyh imen fajlov ona prosmatrivaet svoe soderzhimoe i vybiraet (ispol'zuya sed) imena log-fajlov iz komandy more, kotoraya vyvodit ih. Poskol'ku vy dobavlyaete fajly protokola, programma log mo- zhet hranit' tekushchie, potomu chto ona prosmatrivaet sama sebya dlya oprede- leniya togo, chto sootvetstvuet dejstvitel'nosti. Primenyaya proceduru po- iska takim obrazom, my izbavlyaemsya ot neobhodimosti sohranyat' otdel'nye fajly dannyh s imenami v nih ili ispol'zovat' kakie-to soglasheniya ob imenovanii vypolneniya toj zhe zadachi. Sposobnost' programmy log obra- shchat'sya samoj k sebe pozvolyaet vam dobavlyat' neogranichennoe chislo fajlov protokola v spisok, i vam predostavlyaetsya svoboda po vyboru imen takih fajlov. Vozmozhno, vy zametili, chto strategiya, ispol'zovannaya v komandnom fajle log, mozhet byt' ispol'zovana dlya obespecheniya vyvoda na ekran lyu- bogo nabora fajlov (zapisnye knizhki, dokumentaciya ili eshche chto-to). Vse, chto vam nuzhno sdelat' dlya etogo - zapisat' ih v sootvetstvii s komandoj more i dobavit' stol'ko komand v glavnoe menyu, skol'ko vy hotite. Poyasneniya Stroka 4 ochishchaet ekran, ispol'zuya komandu c, predstavlennuyu nizhe v etoj knige. (Vmesto etogo vy snova mozhete ispol'zovat' komandu clear, esli ona dostupna.) Stroka 5 ustanavlivaet v pozicionnye parametry vyhod komandy date. |to to zhe samoe, chto my delali v programme cpiobr. Stroki 6-17 vyvodyat menyu. Zdes' ispol'zovan odin operator echo, kak opisano v cpiobr. Stro- ka 13 chitaet komandu pol'zovatelya. Stroki 20-27 vypolnyayut osnovnuyu rabotu programmy. Esli vvedennaya komanda byla prosto vozvratom karetki (traktuetsya kak nul'), programma zavershaetsya. V stroke 23 komanda sed prosmatrivaet fajl $HOME/bin/log. |to trebuet, chtoby vy pomestili log v podkataloge dvoichnyh modulej va- shego registracionnogo kataloga. Esli vy razmestite ee gde-libo v drugom meste, vy dolzhny izmenit' etu stroku. Komanda sed ispol'zuet klyuch -n, kotoryj zapreshchaet vyvod, za isklyucheniem togo, chto yavno ukazano dlya pe- chati. Stroka -e nahodit imena fajlov. Dannyj podhod ispol'zuet funkciyu zameny v komande sed. Takim obra- zom my mozhem zamenit' vse za isklyucheniem imeni fajla, a zatem napecha- tat' ego. Smysl etoj zapisi primerno takoj: sperva my ishchem vyrazhenie more (/more/), nahodya tem samym vse stroki v fajle protokola, soderzha- shchie slovo "more". Po opredeleniyu, kazhdyj fajl protokola vyvoditsya na ekran, ispol'zuya komandu more. Poskol'ku vy dobavlyaete fajly protokola, kazhdaya novaya stroka dolzhna soderzhat' slovo more, poetomu fajly naho- dyatsya avtomaticheski po vyrazheniyu komandy sed. Zatem my ukazyvaem komande sed sdelat' zamenu. Pervoe vyrazhenie soderzhit v sebe vsyu stroku ot nachala do konca, no my primenyaem kruglye skobki dlya otmetki vnutri nee obrazca .*, tem samym vydelyaya chast' stro- ki mezhdu probelom posle "more" i pervoj tochkoj s zapyatoj v konce stro- ki. Esli vy posmotrite na vse stroki v fajle log, kotorye nachinayutsya s "more", to vy uvidite, chto eto sootvetstvuet imeni fajla, kotoroe my ishchem. Zatem my ukazyvaem komande sed zamenit' vsyu stroku na pervyj obra- zec "pattern 1". "Pattern 1" - eto zapis' komandy sed dlya pervogo otme- chennogo ili "otmechennogo birkoj" vyrazheniya. Drugimi slovami, my zameni- li imya fajla na vsyu stroku celikom i ukazali komande sed napechatat' re- zul'tat, tem samym vydavaya na ekran imya fajla. |ta rabota vypolnyaetsya dlya takogo kolichestva operatorov more, skol'ko vy imeete. CHem bol'she fajlov log vy imeete, tem bol'she fajlov obrabatyvaet komanda sed. Obratite vnimanie, chto operator sed prosmat- rivaet lyuboe kolichestvo simvolov ot nachala stroki dlya nahozhdeniya slova "more". Ne ukazyvaya v programme konkretnoe chislo simvolov, na kotoroe nuzhno otstupit', vy poluchaete tem samym svobodu vybora vashih sobstven- nyh urovnej otstupa. Esli vvedennaya komanda ne yavlyaetsya dopustimoj, vydaetsya soobshchenie ob oshibke. |ta programma ne imeet cikla, poetomu srabatyvaet odin raz. Esli vy hotite zapustit' ee snova, vy dolzhny snova vvesti log. Primer $ log 1 Posle zapuska programmy vyvoditsya menyu. Vvedite chislo 1 dlya togo, chtoby uvidet' vse imena log-fajlov. Teper', kogda my izuchili, kak raspoznavat' i upravlyat' fajlami vo- obshche, davajte rassmotrim nekotorye sistematicheskie metody upravleniya INFORMACIEJ v fajlah. My nachinaem v sleduyushchej glave s fajlov, kotorye vazhny dlya nas kak dlya programmistov.  * GLAVA 4. Upravlenie programmnoj dokumentaciej *  VVEDENIE 4.1. PROGRAMMIROVANIE i UPRAVLENIE DOKUMENTACIEJ 4.2. IZVLECHENIE DOKUMENTIRUYUSHCHIH ZAGOLOVKOV 4.2.1. stripc - iz fajla na yazyke Si 4.2.2. stripf - iz Si-funkcii 4.2.3. strips - iz komandnogo fajla Shell 4.3. ctags - sozdanie fajla priznakov ishodnogo koda proekta VVEDENIE Vy reshili risknut'. Produkt na tri mesyaca opazdyvaet v proiz- vodstvo i nuzhdaetsya lish' v krohotnoj dorabotke. Vy uvereny, chto znaete, kak rabotaet funkciya, kotoraya otkryvaet vhodnoj bufer. Vy ee nedavno ispol'zovali. Vy uvelichivaete razmer bufera v vyzove funkcii i zapuska- ete bystryj testik. Vse v poryadke, poetomu vy okonchatel'no sobiraete postavku na diske i otpravlyaete ee v proizvodstvo. Mesyac spustya, nachi- nayut postupat' soobshcheniya ot razgnevannyh zakazchikov. Pohozhe, chto esli tekstovyj processor, elektronnaya tablica i baza dannyh otkryty vse vmeste i aktivny odnovremenno (chto yavlyaetsya odnim iz bol'shih tovarnyh dostoinstv vashego produkta), to prosto novyj bufer nastol'ko velik, chto pogloshchaet klyuchevoj razdel pamyati i prevrashchaet vysoko letayushchee chudo in- tegrirovannogo programmnogo obespecheniya v yarkuyu ruinu. Pochemu vy ne proverili dokumentaciyu po etoj funkcii? Vyyasnenie to- go, v kakom fajle nahoditsya dokumentaciya, zanyalo by opredelennoe vremya, a poskol'ku dokumentaciyu tak trudno soprovozhdat', to svyazannye s nej veshchi tak ili inache ustarevayut. Tem ne menee, analogichnye provaly ne dolzhny voznikat'. Programmirovanie - tyazhelaya rabota, no eto tol'ko polovina raboty. Horoshaya dokumentaciya ochen' vazhna, esli vy sobiraetes' imet' vozmozhnost' soprovozhdat' vash programmnyj kod, no i upravlenie vsej dokumentaciej, svyazannoj s bol'shim programmnym proektom takzhe yavlyaetsya tyazheloj rabo- toj. Proishodyat postoyannye izmeneniya, i obychno otsutstvuet edinoobrazie podhoda. Dokumentirovanie ishodnyh fajlov na Sikak v celom, tak i po kazhdoj funkcii yavlyaetsya horoshim pervym shagom, no takaya dokumentaciya ne ochen' polezna, esli vy vynuzhdeny probirat'sya cherez dyuzhiny fajlov, chtoby obnaruzhit', kak nazyvaetsya konkretnaya funkciya ili kakie funkcii sostav- lyayut dannyj modul'. Esli vy hoteli by izuchit' eshche odno sredstvo, svyazannoe s razrabot- koj, sm. programmu cg v glave 10. 4.1. PROGRAMMIROVANIE I UPRAVLENIE DOKUMENTACIEJ V dannoj glave predstavlen nabor komandnyh fajlov komandnogo pro- cessora dlya izvlecheniya dokumentiruyushchej informacii iz ishodnogo koda programm na Si i komandnyh fajlov komandnogo processora. Ispol'zuyutsya dve strategii. Pervaya sostoit v tom, chto, sleduya standartnoj "modeli dokumentacii" v ishodnom kode, vy mozhete pridumat' komandnye fajly, ko- torye prosto "vytyagivayut" samye novye razdely s zagolovochnoj informaci- ej iz fajlov s ishodnym kodom i sobirayut ih zatem v novyj fajl. Takie fajly sluzhat v kachestve karkasa dlya dokumentacii po programme. Sledova- tel'no, pri uslovii, chto zagolovki ishodnogo koda izmenyayutsya raznymi programmistami standartnym obrazom, prostaya komanda UNIX mozhet izvlech' polnost'yu novyj karkas rukovodstva. |tot podhod realizuyut komandnye fajly stripc, stripf i strips. Stripc i stripf predostavlyayut listingi blokov dokumentacii urovnya fajla i urovnya funkcij iz vashih ishodnyh fajlov na Si, a strips izvlekaet doku- mentaciyu iz komandnyh fajlov komandnogo processora. Vtoroj podhod - dostup k opredelennym vidam struktur (takim kak funkcii na Si) v tele samogo programmnogo koda. |tim metodom vy mozhete tochno najti, kak nazyvaetsya dannaya funkciya, bez sosredotochennogo izuche- niya gory listingov. Komandnyj fajl ctags yavlyaetsya i poleznym instrumen- tom, i model'yu primeneniya etogo podhoda k drugim vidam programmnyh struktur. Ctags ob®edinyaet svoj vyvodnoj fajl s redaktorom vi/ex s cel'yu predostavleniya prostogo sposoba dostupa k lyuboj zadannoj funkcii i ee prosmotra, kopirovaniya ili redaktirovaniya v tekushchej programme. Ctags delaet eto putem predostavleniya priznakov, kotorye ponimaet vi, dlya kazhdoj funkcii, obnaruzhennoj v lyubom ukazannom nabore fajlov. Takim ob- razom, vy mozhete ispol'zovat' prostuyu komandu redaktora, chtoby poluchit' to, chto vam nuzhno. Vy bol'she ne obyazany zabotit'sya o tom, kakoj fajl soderzhit kakuyu funkciyu. Ctags - otlichnyj primer primeneniya moshchi UNIX v polnom ob®eme. Imeya takie instrumental'nye sredstva, vam ne nuzhno izobretat' ko- leso, tak kak vy mozhete legko nahodit' i vybirat' te sredstva, kotorye neobhodimy vam v konkretnom prilozhenii. Vy uzhe napisali programmu up- ravleniya terminalom Trantor TR-101? Primenite ctags i najdite ee. Bolee togo, samodokumentiruemyj napechatannyj fajl i dokumentaciya o funkciyah, poluchennaya s pomoshch'yu etih komandnyh fajlov, dayut drugim programmistam horoshij start v ponimanii togo, chto vy sdelali. |to dazhe mozhet slegka proizvesti vpechatlenie na vashego nachal'nika. Kakim v obshchih chertah budet nash podhod k sozdaniyu takih komandnyh fajlov? U nas est' nekotorye potencial'nye preimushchestva v primenenii takogo vida dostupa v sisteme UNIX. Prezhde vsego, ishodnye fajly ne ot- lichayutsya ot drugih tekstovyh fajlov, poetomu my mozhem ispol'zovat' vse imeyushchiesya v UNIX sredstva poiska i raspoznavaniya shablonov (sed, awk i t.d.), chtoby nahodit' simvol'nye stroki. Vo-vtoryh, my osvoili tehniku obhoda fajlovyh derev'ev i raboty s otobrannymi tipami fajlov, opisan- nuyu v predydushchih glavah. Nash podhod sostoit v ob®edinenii etih sredstv takim obrazom, chtoby oni obespechivali dostup k strukturirovannoj doku- mentacii, soderzhashchejsya v programmnyh fajlah. 4.2. Izvlechenie dokumentiruyushchih zagolovkov 4.2.1. stripc - iz fajla na yazyke Si ------------------------------------------------------------ IMYA: stripc ------------------------------------------------------------ stripc Izvlekaet dokumentiruyushchij zagolovok iz ishodnogo fajla na yazyke Si. NAZNACHENIE Pechataet pervyj blok strok kommentariya v fajle s ishodnym kodom na Si tak, chtoby vy mogli bystro identificirovat' naznachenie programmy na Si. FORMAT stripc fajl [...] PRIMER VYZOVA stripc prog*.c > header Izvlekaet nachal'nye bloki kommentariev iz vseh fajlov i pomeshchaet v odin fajl s imenem header. ISHODNYJ KOD DLYA stripc 1 : 2 # @(#) stripc v1.0 Strip comment header Author: Russ Sage 4 if [ "$#" -eq "0" ] 5 then echo "stripc: arg count error" >&2 6 echo "usage: stripc file [...]" >&2 7 exit 1 8 fi 10 for FILE in $@ 11 do 12 if [ ! -s $FILE ] 13 then echo "file \"$FILE\" does not exist" >&2 14 continue 15 fi 17 awk '/^\/\*/, /^ \*\// { if ($0 != " */") 18 print 19 else {print;exit} 20 }' $FILE 21 echo "^L" 22 done (Pered tem kak vvodit' etot ishodnyj kod, obratite vnimanie, chto v stroke 21 dolzhen byt' dejstvitel'no simvol control- L, vvedennyj mezhdu dvumya kavychkami, po prichinam, rassmotrennym nizhe.) PEREMENNAYA SREDY FILE Hranit imya fajla, poluchennoe iz komandnoj stroki. OPISANIE ZACHEM NAM NUZHEN stripc? V bol'shih proektah po razrabotke programmnogo obespecheniya trebu- etsya obychno mnogo vremeni dlya raboty s dokumentaciej. Imeyutsya programm- nye fajly dlya dokumentirovaniya, funkcional'nye specifikacii dlya napisa- niya programm i, nakonec, rukovodstva i spravochnye karty, glossarii, ukazateli i t.d. Nastoyashchij programmnyj kod dolzhen imet' svoyu sobstven- nuyu vstroennuyu dokumentaciyu, inache upravlenie etim kodom stanovitsya ochen' trudnym. CHtoby izbezhat' putanicy, nuzhno sozdat' model' dokumentacii, a za- tem sdelat' ee standartom, kotoromu dolzhny sledovat' vse programmisty. Dazhe esli eta model' ne budet absolyutno ideal'noj, ee nalichie yavlyaetsya pervym shagom po sozdaniyu sredy, kotoroj vy mozhete upravlyat'. Sleduyushchie dva instrumental'nye sredstva, kotorye my predlagaem, sleduyut modeli dokumentacii, opisannoj v dal'nejshem tekste. |ta model' posledovatel'na i ponyatna, ee mozhno dopolnit' ili izmenit' po vashemu usmotreniyu. CHTO DELAET stripc? Stripc pechataet tol'ko pervyj zagolovochnyj blok kommentariev iz nachala ishodnogo fajla na yazyke Si. ZHelatel'no, chtoby etot blok soder- zhal vsyu vazhnuyu informaciyu o fajle: ego oficial'noe imya, dlya chego on prednaznachen, kto ego sozdal, kogda on byl sozdan i t.d. Vnutri fajla mozhet razmeshchat'sya odna ili neskol'ko funkcij ili dazhe glavnaya program- ma. |ta model' predpolagaet, chto ves' vash kod soderzhit ochen' malo glav- nyh programm i mnogo nezavisimyh modulej. Rassmotrim na model'nom ishodnom fajle, kakogo roda informaciyu my dolzhny izvlech' iz ishodnyh fajlov. /* * |to dokumentiruyushchij zagolovok dlya fajla * s ishodnym kodom na yazyke Si. * On poyasnyaet, chto soderzhitsya v fajle (programmy, funkcii, * biblioteki i t.d.) i identificiruet proekt. * */ |to otmetka konca zagolovochnogo kommentariya. ^L Instrumenty izvlecheniya primenyayut control-L kak razdelitel'. /* |to dokumentiruyushchij zagolovok dlya glavnoj chasti programmy. * Glavnaya pometka dolzhna ob®yasnyat', chto eto za programma * i chto ona delaet. Zdes' mogut byt' takzhe ukazany avtor, * data i istoriya izmenenij. */ main() { /* Zdes' nahoditsya glavnaya Si-programma */ } ^L /* |to dokumentiruyushchij zagolovok dlya opredelennoj funkcii, * kotoraya za nim sleduet. Dokumentiruetsya posledovatel'- * nost' vyzova, vhod i vyhod i obshchee naznachenie etoj * funkcii. */ func(arg1,arg2) int arg1; char arg2; { /* Tekst funkcii nahoditsya zdes' */ } ^L /* Analogichno, etot blok kommentariev dokumentiruet * sleduyushchuyu funkciyu. Nalichie dokumentacii vmeste s kodom * sokrashchaet ob®em nakladnyh rashodov pri chtenii i * izmenenii koda. */ func(arg1,arg2) int arg1, arg2; { /* Tekst funkcii nahoditsya zdes' */ } Kak ukazyvalos' ranee, funkciya main ne obyazatel'na i, veroyatno, vstrechaetsya tol'ko v odnom ili dvuh fajlah, v zavisimosti ot vida prog- ramm, kotorye vy pishete. Odin fajl mozhet imet' stol'ko funkcij, skol'ko vy hotite, no rekomenduemoe maksimal'noe chislo - ot odnoj do treh, v zavisimosti ot togo, kak eti funkcii vzaimosvyazany. V kazhdom fajle imejte delo tol'ko s odnoj programmiruemoj ideej i ee realizaciej. Pri izuchenii etoj modeli vy vidite, chto obespechivaetsya tri urovnya dokumentacii. Zagolovok v nachale fajla izvlekaetsya s pomoshch'yu stripc. |tot zagolovok otnositsya ko vsemu fajlu v celom. Zagolovok v nachale glavnoj programmy otnositsya ko vsej programme i podderzhivaetsya s po- moshch'yu stripf. Zagolovok dlya kazhdoj funkcii otnositsya k etoj funkcii. |ti zagolovki obsluzhivayutsya komandnym fajlom stripf, kotoryj obsuzhda- etsya nizhe. Otmetim, chto mezhdu funkciyami imeetsya progon formata (simvol control-L koda ASCII). V predydushchem listinge my ukazali etu kombinaciyu klavish s pomoshch'yu simvola ^L, chtoby nashi tekstovye processory ne proiz- vodili lishnih stranic pri formatirovanii rukopisi dannoj knigi. Vam nuzhno v kazhdom sluchae dejstvitel'no vvodit' control-L vmesto ^L pri razmeshchenii kommentariev v vashih fajlah i pri vvode ishodnogo koda dan- nogo i posleduyushchih komandnyh fajlov. Simvol progona formata ispol'zu- etsya v modeli zagolovka dlya otmetki verhnej granicy pervoj funkcii v fajle i dlya progona stranic na pechatayushchem ustrojstve pri chistovoj raspechatke, chtoby kazhdaya funkciya poyavlyalas' na novoj stranice. V nachale kazhdoj funkcii (pered main ili pered imenem funkcii) dol- zhen sushchestvovat' dokumentiruyushchij zagolovok. |tot zagolovok obychno otra- zhaet naibolee nedavnie izmeneniya v etom module, i ego mozhno schitat' bo- lee dostovernym, chem zagolovok dokumenta, kotoryj byl napechatan neskol'ko nedel' ili dazhe mesyacev nazad. Vhodom dlya stripc yavlyaetsya posledovatel'nost' imen fajlov s ishod- nym kodom. Dlya kazhdogo fajla v komandnoj stroke proveryaetsya, sushchestvuet li on i imeet li razmer bol'she, chem nol' bajt. Esli on ne udovletvoryaet etim kriteriyam, to pechataetsya soobshchenie ob oshibke i proveryaetsya sleduyu- shchij fajl. Kazhdyj fajl chitaetsya s pervogo bajta, i v nem ishchetsya simvol'- naya stroka nachala kommentariya (/*). Kogda ona najdena, informaciya do simvol'noj stroki konca kommentariya (*/) postrochno vyvoditsya v stdout. Esli pravye simvoly ne najdeny, nichego ne pechataetsya, no soobshchenie ob oshibke ne vyvoditsya, chtoby ne isportit' vyvodnuyu informaciyu. Posle togo kak kazhdyj fajl obrabotan, v konce pechataetsya progon formata, kotoryj razbivaet vyvodnuyu informaciyu na stranicy-razdely. |to primenyaetsya v osnovnom, kogda dokumentiruyushchie zagolovki ochen' dlinnye i nuzhdayutsya v vizual'noj razbivke. Otmetim, chto "izvlechenie" ("strip") zdes' i v sleduyushchih dvuh uti- litah oznachaet ne UDALENIE, a kopirovanie sootvetstvuyushchej informacii. Nikakih izmenenij vo vhodnyh fajlah ne delaetsya. Kogda vse fajly v komandnoj stroke obrabotany, komandnyj fajl za- vershaetsya. PRIMERY 1. $ stripc test?.c > test.filehdrs Izvlekaet blok fajlovyh kommentariev iz vseh fajlov, sootvetstvuyu- shchih stroke "test", za kotoroj sleduyut odin proizvol'nyj simvol, a zatem .c. Syuda podhodyat test1, testA, testb i t.d. Vse bloki kommentariev po- meshchayutsya v fajl test.filehdrs v takom poryadke, kak oni obrabatyvalis' by v cikle for. 2. $ for DIR in src1 src2 src3 > do > stripc $DIR/*.c > /tmp/$DIR.hdrs > done |tot cikl prohodit kazhdyj iz treh katalogov src1, src2 i src3. V kazhdom iz nih imeyutsya ishodnye fajly, iz kotoryh nuzhno izvlech' dokumen- tiruyushchie zagolovki. Kazhdyj raz beretsya odin katalog, i stripc vyzyva- etsya dlya vseh ishodnyh fajlov na yazyke Si iz dannogo kataloga. Vyhod, t.e. vse dokumentiruyushchie zagolovki iz fajlov v etom kataloge, pomeshcha- etsya v fajl v kataloge /tmp. Fajly v /tmp imeyut imena /tmp/src1.hdrs, /tmp/src2.hdrs i /tmp/src3.hdrs. Otmetim, chto chislo fajlov, peredavae- myh stripc, imeet ogranichenie v 255 simvolov. Posle etogo komandnaya stroka perepolnyaetsya i vypolnenie komandnogo fajla avarijno zaversha- etsya. POYASNENIYA Stroki 4-8 delayut proverku na oshibki. Esli chislo parametrov v ko- mandnoj stroke nulevoe, voznikaet oshibka. Pri vyzove stripc dolzhno byt' hotya by odno imya fajla. Cikl for v strokah 10-22 probegaet po kazhdomu imeni fajla iz spiska pozicionnyh parametrov v komandnoj stroke. Pervym delom, v strokah 12-15 proveryaetsya sushchestvovanie fajla. Esli fajl ne sushchestvuet, vydaetsya sootvetstvuyushchee soobshchenie ob oshibke i cikl prodolzhaetsya so sleduyushchim fajlom. Stroki 17-20 - eto cikl awk, kotoryj delaet vsyu vazhnuyu rabotu. Vhodnym dlya awk yavlyaetsya imya fajla, kotoroe sejchas obrabatyvaet cikl for. Esli vy ne ochen' znakomy s programmoj awk, soobshchim, chto ona vyzy- vaetsya tak: awk programma imya-fajla gde programma sostoit iz posledovatel'nosti predlozhenij, imeyushchih vid: shablon { dejstvie } Ukazannoe dejstvie primenyaetsya k tekstu, kotoryj sootvetstvuet shablonu. Dlya togo chtoby utilita awk rabotala korrektno, vy dolzhny zak- lyuchit' vsyu programmu v odinarnye kavychki. V stripc dlya ukazaniya nachala kommentariya (/*) i konca kommentariya (*/) ispol'zuyutsya sootvetstvenno shablony /^\/\*/ i /^ \*\// Dlya interpretacii etih oboznachenij nuzhno vspomnit' regulyarnye vy- razheniya ed, sed i grep. Regulyarnye vyrazheniya (RV) dolzhny byt' ograniche- ny (simvolom /). awk vosprinimaet dva vyrazheniya, razdelennye zapyatymi, kak nachal'nyj i konechnyj shablony dlya kvalifikacii vvodnyh strok. V dannom primere nachal'noe vyrazhenie oznachaet "ot nachala stroki (^), vsled za dejstvitel'nym simvolom kosoj cherty (kotoryj dolzhen byt' ekranirovan, chtoby ubrat' ego special'noe znachenie, t.e. \/) i dejstvi- tel'noj zvezdochkoj (\*), ispol'zovat' vse stroki, obnaruzhennye vplot' do konechnogo vyrazheniya". |tim vybiraetsya tol'ko pervoe vhozhdenie so- postavlyaemogo shablona (t.e. pervogo bloka kommentariev), tak kak prog- ramma awk zakanchivaet rabotu pri obnaruzhenii zavershayushchej stroki. (Ostal'nye bloki kommentariev vybirayutsya s pomoshch'yu stripf vmeste s ime- nem funkcii i argumentami.) Dlya kazhdoj stroki, kotoraya sootvetstvuet naboru vyrazhenij ot na- chal'nogo do konechnogo, vypolnyayutsya predlozheniya, ukazannye v "dejstvii". Stroki 17, 18 i 19 soderzhat predlozhenie if-then= else, kotoroe vypolnya- et vsyu rabotu. Esli $0 (chto yavlyaetsya vsej strokoj) NE ravno probelu i koncu kommentariya (*/), pechataetsya vsya stroka. Formiruya takim obrazom predlozhenie if, my pechataem pervuyu stroku i vse posleduyushchie stroki, po- ka ne doberemsya do konca kommentariya. Kogda obnaruzhena poslednyaya stroka, rezul'tatom proverki yavlyaetsya znachenie "lozh'", poetomu vypolnyaetsya else-chast'. Poskol'ku my znaem, chto eto poslednyaya stroka, my pechataem ee dlya zavershennosti bloka kom- mentariya, a zatem vyhodim iz awk. Otmetim, chto blagodarya vlozheniyu etih dvuh komand vmeste v figurnye skobki ({}), oni rassmatrivayutsya kak odno sostavnoe predlozhenie. Posle zaversheniya awk proizvoditsya eho-otobrazhenie progona formata na ekran i beretsya sleduyushchij fajl. Tak prodolzhaetsya do teh por, poka vse fajly v komandnoj stroke ne budut obrabotany. 4.2.2. stripf - iz Si-funkcii ------------------------------------------------------------ IMYA: stripf ------------------------------------------------------------ stripf Izvlekaet dokumentiruyushchij zagolovok Si-funkcii. FUNKCIYA Izvlekaet i pechataet kommentiruyushchij zagolovok, imya funkcii s para- metrami vyzova i ob®yavlenie tipov parametrov dlya vseh funkcij v ishod- nom fajle na Si. FORMAT stripf file [...] PRIMER VYZOVA stripf lib1.c Izvlekaet dokumentiruyushchie zagolovki dlya vseh funkcij v fajle lib1.c. ISHODNYJ KOD DLYA stripf 1 : 2 # @(#) stripf v1.0 Strip function header Author: Russ Sage 4 for FILE in $@ 5 do 6 sed -n -e ' 7 /^L$/ { 8 s/^L$/.bp/p 9 : loop 10 n 11 /^{/b exit 12 p 13 b loop 14 : exit 15 i\ 16 {} 17 b 18 }' $FILE 19 done PEREMENNAYA SREDY FILE Hranit imya fajla dlya kazhdogo fajla iz komandnoj stroki. OPISANIE ZACHEM NAM NUZHEN stripf? Predpolozhim, chto nash kod na yazyke Si sootvetstvuet modeli dokumen- tacii, predstavlennoj ranee pri opisanii stripc. Togda nam nuzhen sposob podderzhaniya izmenenij v dokumentacii po hodu izmenenij koda. My videli, chto pri hranenii dokumentacii v ishodnyh fajlah bolee veroyatno, chto ona budet izmenena, kogda izmenitsya kod. Problema voznikaet, kogda nam nuzh- na tverdaya kopiya dokumentacii, kotoraya nahoditsya vnutri ishodnogo koda. Kak nam poluchit' ee iz fajlov? CHTO DELAET stripf? Komandnyj fajl stripf reshaet etu problemu. On prosmatrivaet ves' fajl i pechataet vsyu dokumentaciyu dlya kazhdoj FUNKCII, kotoraya razmeshchena v etom fajle (vklyuchaya "main", esli ona est'). Vhodom dlya stripf yavlyayutsya imena fajlov, peredannye v komandnoj stroke. Stripf obrabatyvaet fajly po ocheredi i pomeshchaet vyhod v stdout. |tot vyhod mozhno perenapravit', no vhod dolzhen byt' v komandnoj stroke. K vyhodu primenyayutsya dopolnitel'nye modifikacii, chtoby sformiro- vat' dannye dlya sredy utility nroff, poetomu vyvodnye fajly mozhno for- matirovat' s pomoshch'yu etoj utility. Vse progony formata zamenyayutsya na komandu .bp,