ÿØÿà JFIF    ÿÛ „  ( %"1!%)+...383,7(-.+  -+++--++++---+-+-----+---------------+---+-++7-----ÿÀ  ß â" ÿÄ     ÿÄ H    !1AQaq"‘¡2B±ÁÑð#R“Ò Tbr‚²á3csƒ’ÂñDS¢³$CÿÄ   ÿÄ %  !1AQa"23‘ÿÚ   ? ôÿ ¨pŸªáÿ —åYõõ\?àÒü©ŠÄï¨pŸªáÿ —åYõõ\?àÓü©ŠÄá 0Ÿªáÿ Ÿå[úƒ ú®ði~TÁbqÐ8OÕpÿ ƒOò¤Oè`–RÂáœá™êi€ßÉ< FtŸI“öÌ8úDf´°å}“¾œ6  öFá°y¥jñÇh†ˆ¢ã/ÃÐ:ªcÈ "Y¡ðÑl>ÿ ”ÏËte:qž\oäŠe÷󲍷˜HT4&ÿ ÓÐü6ö®¿øþßèô Ÿ•7Ñi’•j|“ñì>b…þS?*Óôÿ ÓÐü*h¥£ír¶ü UãS炟[AÐaè[ûª•õ&õj?†Éö+EzP—WeÒírJFt ‘BŒ†Ï‡%#tE Øz ¥OÛ«!1›üä±Í™%ºÍãö]°î(–:@<‹ŒÊö×òÆt¦ãº+‡¦%ÌÁ²h´OƒJŒtMÜ>ÀÜÊw3Y´•牋4ǍýʏTì>œú=Íwhyë,¾Ôò×õ¿ßÊa»«þˆѪQ|%6ž™A õ%:øj<>É—ÿ Å_ˆCbõ¥š±ý¯Ýƒï…¶|RëócÍf溪“t.СøTÿ *Ä¿-{†çàczůŽ_–^XþŒ±miB[X±d 1,é”zEù»& î9gœf™9Ð'.;—™i}!ôšåîqêÛ٤ёý£½ÆA–àôe"A$˝Úsäÿ ÷Û #°xŸëí(l »ý3—¥5m! rt`†0~'j2(]S¦¦kv,ÚÇ l¦øJA£Šƒ J3E8ÙiŽ:cÉžúeZ°€¯\®kÖ(79«Ž:¯X”¾³Š&¡* ….‰Ž(ÜíŸ2¥ª‡×Hi²TF¤ò[¨íÈRëÉ䢍mgÑ.Ÿ<öäS0í„ǹÁU´f#Vß;Õ–…P@3ío<ä-±»Ž.L|kªÀê›fÂ6@»eu‚|ÓaÞÆŸ…¨ááå>åŠ?cKü6ùTÍÆ”†sĤÚ;H2RÚ†õ\Ö·Ÿn'¾ ñ#ºI¤Å´%çÁ­‚â7›‹qT3Iï¨ÖÚ5I7Ë!ÅOóŸ¶øÝñØôת¦$Tcö‘[«Ö³šÒ';Aþ ¸èíg A2Z"i¸vdÄ÷.iõ®§)¿]¤À†–‡É&ä{V¶iŽ”.Ó×Õÿ û?h¬Mt–íª[ÿ Ñÿ ÌV(í}=ibÔ¡›¥¢±b Lô¥‡piη_Z<‡z§èŒ)iÖwiÇ 2hÙ3·=’d÷8éŽ1¦¸c¤µ€7›7Ø ð\á)} ¹fËí›pAÃL%âc2 í§æQz¿;T8sæ°qø)QFMð‰XŒÂ±N¢aF¨…8¯!U  Z©RÊ ÖPVÄÀÍin™Ì-GˆªÅËŠ›•zË}º±ŽÍFò¹}Uw×#ä5B¤{î}Ð<ÙD é©¤&‡ïDbàÁôMÁ." ¤‡ú*õ'VŽ|¼´Úgllº¼klz[Æüï÷Aób‡Eÿ dÑ»Xx9ÃÜ£ÁT/`¼¸vI±Ýµ·Ë‚“G³þ*Ÿû´r|*}<¨îºœ @¦mÄ’M¹”.œ«Y–|6ÏU¤jç¥ÕÞqO ˜kDÆÁ¨5ÿ š;ÐЦ¦€GÙk \ –Þ=â¼=SͧµªS°ÚÍpÜãQűÀõ¬?ÃÁ1Ñ•õZà?hóœ€ L¦l{Y*K˜Ù›zc˜–ˆâ ø+¾ ­-Ök¥%ùEÜA'}ˆ><ÊIè“bpÍ/qÞâvoX€w,\úªò6Z[XdÒæ­@Ö—€$òJí#é>'°Ú ôª˜<)4ryÙ£|óAÅn5žêŸyÒäMÝ2{"}‰–¤l÷ûWX\l¾Á¸góÉOÔ /óñB¤f¸çñ[.P˜ZsÊË*ßT܈§QN¢’¡¨§V¼(Üù*eÕ“”5T¨‹Âê¥FŒã½Dü[8'Ò¥a…Ú¶k7a *•›¼'Ò·\8¨ª\@\õ¢¦íq+DÙrmÎ…_ªæ»ŠÓœ¡¯’Ré9MÅ×D™lælffc+ŒÑ,ý™ÿ ¯þǤ=Å’Á7µ÷ÚÛ/“Ü€ñýã¼àí¾ÕÑ+ƒ,uµMâÀÄbm:ÒÎPæ{˜Gz[ƒ¯«® KHà`ߨŠéí¯P8Aq.C‰ à€kòpj´kN¶qô€…Õ,ÜNŠª-­{Zö’æû44‰sŽè‰îVíRœÕm" 6?³D9¡ÇTíÅꋇ`4«¸ÝÁô ï’ýorqКÇZ«x4Žâéþuïf¹µö[P ,Q£éaX±`PÉÍZ ¸äYúg üAx ’6Lê‚xÝÓ*äQ  Ï’¨hÍ =²,6ï#rÃ<¯–£»ƒ‹,–ê•€ aÛsñ'%Æ"®ÛüìBᝠHÚ3ß°©$“XnœÖ’î2ËTeûìxîß ¦å¿çÉ ðK§þ{‘t‚Ϋ¬jéîZ[ ”š7L¥4VÚCE×]m¤Øy”ä4-dz£œ§¸x.*ãÊÊ b÷•h:©‡¦s`BTÁRû¾g⻩‹jø sF¢àJøFl‘È•Xᓁà~*j¯ +(ÚÕ6-£¯÷GŠØy‚<Ç’.F‹Hœw(+)ÜÜâÈzÄäT§FߘãÏ;DmVœ3Àu@mÚüXÝü•3B¨òÌÁÛ<·ÃÜ z,Ì@õÅ·d2]ü8s÷IôÞ¯^Ç9¢u„~ëAŸï4«M? K]­ÅàPl@s_ p:°¬ZR”´›JC[CS.h‹ƒïËœ«Æ]–÷ó‚wR×k7X‰k›‘´ù¦=¡«‰¨¨Â')—71ó’c‡Ðúµ `é.{§p¹ój\Ž{1h{o±Ý=áUÊïGÖŒõ–-BÄm+AZX¶¡ ïHðæ¥JmÙ;…䡟ˆ¦ ° äšiÉg«$üMk5¤L“’çÊvïâï ,=f“"íἊ5ô¬x6{ɏžID0e¸vçmi'︧ºð9$ò¹÷*£’9ÿ ²TÔ…×>JV¥}Œ}$p[bÔ®*[jzS*8 ”·T›Í–ñUîƒwo$áè=LT™ç—~ô·¤ÈÚ$榍q‰„+´kFm)ž‹©i–ËqÞŠ‰à¶ü( ‚•§ •°ò·‡#5ª•µÊ﯅¡X¨šÁ*F#TXJÊ ušJVÍ&=iÄs1‚3•'fý§5Ñ<=[íÞ­ PÚ;ѱÌ_~Ä££8rÞ ²w;’hDT°>ÈG¬8Á²ÚzŽ®ò®qZcqJêäÞ-ö[ܘbň±çb“ж31²n×iƒðÕ;1¶þÉ ªX‰,ßqÏ$>•î íZ¥Z 1{ç൵+ƒÕµ¥°T$§K]á»Ûï*·¤tMI’ÂZbŽÕiÒ˜}bÓ0£ª5›¨ [5Ž^ÝœWøÂÝh° ¢OWun£¤5 a2Z.G2³YL]jåtì”ä ÁÓ‘%"©<Ôúʰsº UZvä‡ÄiÆÒM .÷V·™ø#kèýiíÌ–ª)µT[)BˆõÑ xB¾B€ÖT¨.¥~ð@VĶr#¸ü*åZNDŽH;âi ],©£öØpù(šºãö¼T.uCê•4@ÿ GÕÛ)Cx›®0ø#:ÏðFÒbR\(€€Ä®fã4Þ‰Fä¯HXƒÅ,†öEÑÔÜ]Öv²?tLÃvBY£ú6Êu5ÅAQ³1‘’¬x–HŒÐ‡ ^ ¸KwJôÖŽ5×CÚ¨vÜ«/B0$×k°=ðbÇ(Ï)w±A†Á† 11Í=èQšµ626ŒÜ/`G«µ<}—-Ö7KEHÈÉðóȤmݱû±·ø«Snmá=“䫚mݱŸ¡¶~ó·“äUóJæúòB|E LêŽy´jDÔ$G¢þÐñ7óR8ýÒ…Ç› WVe#·Ÿ p·Fx~•ݤF÷0Èÿ K¯æS<6’¡WШ; ´ÿ ¥Êø\Òuî†åÝ–VNœkÒ7oòX¨Á­Ø÷FÎÑä±g÷ÿ M~Çî=p,X´ ÝÌÚÅ‹’ÃjÖ.ØöÏñ qïQ¤ÓZE†° =6·]܈ s¸>v•Ž^Ý\wq9r‰Î\¸¡kURÒ$­*‹Nq?Þª*!sŠÆ:TU_u±T+øX¡ ®¹¡,ÄâÃBTsÜ$Ø›4m椴zÜK]’’›Pƒ @€#â˜`é¹=I‡fiV•Ôî“nRm+µFPOhÍ0B£ €+¬5c v•:P'ÒyÎ ‰V~‚Ó†ÖuókDoh$å\*ö%Ю=£«…aȼ½÷Û.-½VŒŠ¼'lyî±1¬3ó#ÞE¿ÔS¤gV£m›=§\û"—WU¤ÚǼÿ ÂnÁGŒÃ ‚õN D³õNÚíŒÕ;HôyÄÈ©P¹Ä{:?R‘Ô¨âF÷ø£bÅó® JS|‚R÷ivýáâ€Æé¡è³´IئÑT!§˜•ت‚¬â@q€wnïCWÄ@JU€ê¯m6]Ï:£âx'+ÒðXvÓ¦Úm=–´7œ $ì“B£~p%ÕŸUþ« N@¼üï~w˜ñø5®—'Ôe»¤5ã//€ž~‰Tþ›Å7•#¤× Íö pÄ$ùeåì*«ÓŠEØWEÈsßg ¦ûvžSsLpºÊW–âµEWöˬH; ™!CYõZ ÃÄf æ#1W. \uWâ\,\Çf j’<qTbên›Î[vxx£ë 'ö¨1›˜ÀM¼Pÿ H)ƒêêŒA7s,|F“ 꺸k³9Ìö*ç®;Ö!Ö$Eiž•¹ÒÚ†ýóéÝû¾ÕS®ó$’NÝäŸz¤5r¦ãÄÃD÷Üø!°ø‡Ô&@m™Ì^Ãä­d q5Lnÿ N;.6½·N|#ä"1Nƒx“ã<3('&ñßt  ~ªu”1Tb㫨9ê–›–bìd$ߣ=#ÕãÒmU¯eí$EFù5ýYô櫨æì™Ç—±ssM]·á¿0ÕåJRÓªîiƒ+O58ÖñªŠÒx" \µâá¨i’¤i —Ö ” M+M¤ë9‚‰A¦°Qõ¾ßøK~¼Ã‘g…Ö´~÷Ï[3GUœÒ½#…kàÔ®Ò”‰³·dWV‰IP‰Ú8u¹”E ÖqLj¾êÕCBš{A^Âß;–¨`¯¬ìö ˼ ×tìø.tƐm*n¨y4o&Àx¥n¦×î‡aupáÛj8¿m›è¶ã!o½;ß0y^ý×^EÑ¿ÒjzŒ­)vÚÑnÄL …^ªô× ‡—‚3k Îý­hï]içå–îÏ*÷ñþ»Ô CÒjøjÍznˆ´ ¹#b'Fô‹ ‰v¥'’à'T´ƒHýÍ%M‰ ƒ&ÆÇŒï1 ‘ –Þ ‰i¬s žR-Ÿ kЬá¬7:þ 0ŒÅÒÕ/aÙ¬ÃÝ#Úøœ ©aiVc‰. ¹¦ãµ” ›Yg¦›ÆÎýº°f³7ƒhá·¸­}&D9¡ÂsÉÙÞèŠõØàC™¨ñbFC|´Ü(ŸƒÚÒ-%»'a Ì¿)ËÇn¿úÿ ÞŽX…4ÊÅH^ôΑí@ù¹Eh¶“L8Çjù ¼ÎåVªóR©Ï5uà V4lZß®=€xÖŸ–ÑÈ ÷”¨°¾__yM1tÉ?uÆþIkÄgæ@þ[¢†°XÃJ£j·:nkÅ¢u ‘}âGzö­/IµèЬ¼48q¦F°ŽR¼=ûì{´¯RýicS ÕÛ íNtÍÙï£,w4rêì®»~x(©Uñ§#Ñ&œÕ¤>ÎåÍÓ9’Ö{9eV­[Öjâ²ãu]˜å2›qÑšÕJç0€sÄ|Êëè0튔bÁ>“{×_F`Ø©ºê:µä,v¤ðfc1±"«ÔÍän1#=· Âøv~H½ÐßA¾¿Ü€Óš]Õ; I¾÷ç‚Qi†î¹9ywÔKG˜áñ zQY—§ÃÕZ07§X‚ Áh;ÁM)iÌCH-¯T‘ë|A0{Ò½LÚ–TâÖkÜ’dÀ“rmm»”جPF³ÖcbE§T€ÒxKºû’Ó®7±²(\4ŽÃ¸Uu@j™yĵ;³µ!Á¢b.W¤=mõ´êµK k ¸K^ÜÛ#p*Ü14qkZç5ïë †°5Ï%ÍÛ<Õ¤×Ô¥ê†C Õ´¼ú$ƒÖ“”]Ù¬qÞÚ[4©ý!ûÏ—Áb쳐XµA¬â~`›Çr¸8ìùÝ䫦<>ä÷«?xs´ÇÑ /á;¹øüÊÈÙà{"@Žïzâ¬[âß‚ U_<ÇŸ½4èN˜ú61®qŠu ¦þF£»äJ_ˆÙÎ~ ÞAã–݄ϗrŠD;xTž‘ô`É«…suãO`?³à™ô Lý#Íc5öoæØ‚y´´÷«ZR§<&JÇ+éâô´€i!Àˆ0æAoàðLèÖ-2ŸõW.’t^–(KÁmHµV@xÜÇy®Ñø­â^:Ú3w· 7½¹°ñ¸â¹®:',«Mœ—n­Á+Ãbš LÈ‘ÄnRÓÅœ%¦²‰¨ùQ:¤f‚ "PÕtô¸…cæl…&˜Ú˜Ôkv‹ž+vŠ,=¢v­6—Xy*¥t£«<™:“aîϲ=¦6rO]XI¿Œ÷¤zÚ­›¶ 6÷”w\d ü~v®ˆÌk«^m<ÿ ¢‰Õ\)ùºŽ;… lîÙÅEŠ®cѾ@vnMÏ,¼“ñ•ŽBxðÃzãÇç%3ˆ"}Ù•Åî> BÉú;Ò]V+P˜F_´ßé> Øše|ï‡ÄOmFæÇ ãqÞ$/xÐx­z`ï9"œÜij‚!7.\Td…9M‡•iŽ‹¾‘50ÞŽn¥ß4ÉôO ¹*í^QêËÜÇÌ8=ާs‰'ÂëÙ«á%Pú[O †ÅP¯Vsް.‰,kc¶ ¬A9n˜XÎ-ÞšN["¹QÕ‰ƒMýÁߺXJæÍaLj¾×Ãmã¾ãÚ uñÒþåQô¦¥ /ÄUx:‚ÍÜ’ Đ©ØÝ3V¨‰ÕnÐ6ó*óúK­«…c ¯U òhsý­jóÔj#,ímŒRµ«lbïUTŒÑ8†Ä0œÏr`ð¡¬É Ї ë"À² ™ 6¥ f¶ ¢ÚoܱԷ-<Àî)†a¶ž'Ú»¨TXqØæ¶÷YÄHy˜9ÈIW­YÀuMFë ºÏ’AqÌ4·/Ú †ô'i$øä­=Ä Ý|öK×40è|È6p‘0§)o¥ctî§H+CA-“ xØ|ÐXАç l8íºð3Ø:³¤¬KX¯UÿÙ #!/usr/bin/perl -w # # kmsg kernel messages check and print tool. # # To check the source code for missing messages the script is called # with check, the name compiler and the compile parameters # kmsg-doc check $(CC) $(c_flags) $< # To create man pages for the messages the script is called with # kmsg-doc print $(CC) $(c_flags) $< # # Copyright IBM Corp. 2008 # Author(s): Martin Schwidefsky # Michael Holzheu # use Cwd; use bigint; my $errors = 0; my $warnings = 0; my $srctree = ""; my $objtree = ""; my $kmsg_count = 0; sub remove_quotes($) { my ($string) = @_; my $inside = 0; my $slash = 0; my $result = ""; foreach my $str (split(/([\\"])/, $string)) { if ($inside && ($str ne "\"" || $slash)) { $result .= $str; } # Check for backslash before quote if ($str eq "\"") { if (!$slash) { $inside = !$inside; } $slash = 0; } elsif ($str eq "\\") { $slash = !$slash; } elsif ($str ne "") { $slash = 0; } } return $result; } sub string_to_bytes($) { my ($string) = @_; my %is_escape = ('"', 0x22, '\'', 0x27, 'n', 0x0a, 'r', 0x0d, 'b', 0x08, 't', 0x09, 'f', 0x0c, 'a', 0x07, 'v', 0x0b, '?', 0x3f); my (@ar, $slash, $len); # scan string, interpret backslash escapes and write bytes to @ar $len = 0; foreach my $ch (split(//, $string)) { if ($ch eq '\\') { $slash = !$slash; if (!$slash) { $ar[$len] = ord('\\'); $len++; } } elsif ($slash && defined $is_escape{$ch}) { # C99 backslash escapes: \\ \" \' \n \r \b \t \f \a \v \? $ar[$len] = $is_escape{$ch}; $len++; $slash = 0; } elsif ($slash) { # FIXME: C99 backslash escapes \nnn \xhh die("Unknown backslash escape in message $string."); } else { # normal character $ar[$len] = ord($ch); $len++; } } return @ar; } sub calc_jhash($) { my ($string) = @_; my @ar; my ($a, $b, $c, $i, $length, $len); @ar = string_to_bytes($string); $length = @ar; # add dummy elements to @ar to avoid if then else hell push @ar, (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); $a = 0x9e3779b9; $b = 0x9e3779b9; $c = 0; $i = 0; for ($len = $length + 12; $len >= 12; $len -= 12) { if ($len < 24) { # add length for last round $c += $length; } $a += $ar[$i] + ($ar[$i+1]<<8) + ($ar[$i+2]<<16) + ($ar[$i+3]<<24); $b += $ar[$i+4] + ($ar[$i+5]<<8) + ($ar[$i+6]<<16) + ($ar[$i+7]<<24); if ($len >= 24) { $c += $ar[$i+8] + ($ar[$i+9]<<8) + ($ar[$i+10]<<16) + ($ar[$i+11]<<24); } else { $c += ($ar[$i+8]<<8) + ($ar[$i+9]<<16) + ($ar[$i+10]<<24); } $a &= 0xffffffff; $b &= 0xffffffff; $c &= 0xffffffff; $a -= $b; $a -= $c; $a ^= ($c >> 13); $a &= 0xffffffff; $b -= $c; $b -= $a; $b ^= ($a << 8); $b &= 0xffffffff; $c -= $a; $c -= $b; $c ^= ($b >> 13); $c &= 0xffffffff; $a -= $b; $a -= $c; $a ^= ($c >> 12); $a &= 0xffffffff; $b -= $c; $b -= $a; $b ^= ($a << 16); $b &= 0xffffffff; $c -= $a; $c -= $b; $c ^= ($b >> 5); $c &= 0xffffffff; $a -= $b; $a -= $c; $a ^= ($c >> 3); $a &= 0xffffffff; $b -= $c; $b -= $a; $b ^= ($a << 10); $b &= 0xffffffff; $c -= $a; $c -= $b; $c ^= ($b >> 15); $c &= 0xffffffff; $i += 12; } return $c; } sub add_kmsg_desc($$$$$$) { my ($component, $text, $sev, $argv, $desc, $user) = @_; my ($hash, $tag); $text = remove_quotes($text); $hash = substr(sprintf("%08x", calc_jhash($text)), 2, 6); $tag = $component . "." . $hash; if ($kmsg_desc{$tag}) { if ($text ne $kmsg_desc{$tag}->{'TEXT'}) { warn "Duplicate message with tag $tag\n"; warn " --- $kmsg_desc{$tag}->{'TEXT'}\n"; warn " +++ $text\n"; } else { warn "Duplicate message description for \"$text\"\n"; } $errors++; return; } $kmsg_desc{$tag}->{'TEXT'} = $text; $kmsg_desc{$tag}->{'SEV'} = $sev; $kmsg_desc{$tag}->{'ARGV'} = $argv; $kmsg_desc{$tag}->{'DESC'} = $desc; $kmsg_desc{$tag}->{'USER'} = $user; } sub add_kmsg_print($$$$) { my ($component, $sev, $text, $argv) = @_; my ($hash, $tag, $count, $parm); $text = remove_quotes($text); $hash = substr(sprintf("%08x", calc_jhash($text)), 2, 6); $tag = $component . "." . $hash; # Pretty print severity $sev =~ s/"0"/Emerg/; $sev =~ s/"1"/Alert/; $sev =~ s/"2"/Critical/; $sev =~ s/"3"/Error/; $sev =~ s/"4"/Warning/; $sev =~ s/"5"/Notice/; $sev =~ s/"6"/Informational/; $sev =~ s/"7"/Debug/; $kmsg_print{$kmsg_count}->{'TAG'} = $tag; $kmsg_print{$kmsg_count}->{'TEXT'} = $text; $kmsg_print{$kmsg_count}->{'SEV'} = $sev; $kmsg_print{$kmsg_count}->{'ARGV'} = $argv; $kmsg_count += 1; } sub process_source_file($$) { my ($component, $file) = @_; my $state; my ($text, $sev, $argv, $desc, $user); if (!open(FD, "$file")) { return ""; } $state = 0; while () { chomp; # kmsg message component: #define KMSG_COMPONENT "" if (/^#define\s+KMSG_COMPONENT\s+\"(.*)\"[^\"]*$/o) { $component = $1; } if ($state == 0) { # single line kmsg for undocumented messages, format: # /*? Text: "" */ if (/^\s*\/\*\?\s*Text:\s*(\".*\")\s*\*\/\s*$/o) { add_kmsg_desc($component, $1, "", "", "", ""); } # kmsg message start: '/*?' if (/^\s*\/\*\?\s*$/o) { $state = 1; ($text, $sev, $argv, $desc, $user) = ( "", "", "", "", "" ); } } elsif ($state == 1) { # kmsg message end: ' */' if (/^\s*\*\/\s*/o) { add_kmsg_desc($component, $text, $sev, $argv, $desc, $user); $state = 0; } # kmsg message text: ' * Text: ""' elsif (/^\s*\*\s*Text:\s*(\".*\")\s*$/o) { $text = $1; } # kmsg message severity: ' * Severity: ' elsif (/^\s*\*\s*Severity:\s*(\S*)\s*$/o) { $sev = $1; } # kmsg message parameter: ' * Parameter: ' elsif (/^\s*\*\s*Parameter:\s*(\S*)\s*$/o) { if (!defined($1)) { $argv = ""; } else { $argv = $1; } $state = 2; } # kmsg message description start: ' * Description:' elsif (/^\s*\*\s*Description:\s*(\S*)\s*$/o) { if (!defined($1)) { $desc = ""; } else { $desc = $1; } $state = 3; } # kmsg has unrecognizable lines else { warn "Warning(${file}:$.): Cannot understand $_"; $warnings++; $state = 0; } } elsif ($state == 2) { # kmsg message end: ' */' if (/^\s*\*\//o) { warn "Warning(${file}:$.): Missing description, skipping message"; $warnings++; $state = 0; } # kmsg message description start: ' * Description:' elsif (/^\s*\*\s*Description:\s*$/o) { $desc = $1; $state = 3; } # kmsg message parameter line: ' * ' elsif (/^\s*\*(.*)$/o) { $argv .= "\n" . $1; } else { warn "Warning(${file}:$.): Cannot understand $_"; $warnings++; $state = 0; } } elsif ($state == 3) { # kmsg message end: ' */' if (/^\s*\*\/\s*/o) { add_kmsg_desc($component, $text, $sev, $argv, $desc, $user); $state = 0; } # kmsg message description start: ' * User action:' elsif (/^\s*\*\s*User action:\s*$/o) { $user = $1; $state = 4; } # kmsg message description line: ' * ' elsif (/^\s*\*\s*(.*)$/o) { $desc .= "\n" . $1; } else { warn "Warning(${file}:$.): Cannot understand $_"; $warnings++; $state = 0; } } elsif ($state == 4) { # kmsg message end: ' */' if (/^\s*\*\/\s*/o) { add_kmsg_desc($component, $text, $sev, $argv, $desc, $user); $state = 0; } # kmsg message user action line: ' * ' elsif (/^\s*\*\s*(.*)$/o) { $user .= "\n" . $1; } else { warn "Warning(${file}:$.): Cannot understand $_"; $warnings++; $state = 0; } } } return $component; } sub process_cpp_file($$$$) { my ($cc, $options, $file, $component) = @_; open(FD, "$cc $gcc_options|") or die ("Preprocessing failed."); while () { chomp; if (/.*__KMSG_PRINT\(\s*(\S*)\s*(\S*)\s*_FMT_(.*)_ARGS_\s*(.*)?_END_\s*\)/o) { if ($component ne "") { add_kmsg_print($component, $2, $3, $4); } else { warn "Error(${file}:$.): kmsg without component\n"; $errors++; } } elsif (/.*__KMSG_DEV\(\s*(\S*)\s*(\S*)\s*_FMT_(.*)_ARGS_\s*(.*)?_END_\s*\)/o) { if ($component ne "") { add_kmsg_print($component, $2, "\"%s: \"" . $3, $4); } else { warn "Error(${file}:$.): kmsg without component\n"; $errors++; } } } } sub check_messages($) { my $component = "@_"; my $failed = 0; for ($i = 0; $i < $kmsg_count; $i++) { $tag = $kmsg_print{$i}->{'TAG'}; if (!defined($kmsg_desc{$tag})) { add_kmsg_desc($component, "\"" . $kmsg_print{$i}->{'TEXT'} . "\"", $kmsg_print{$i}->{'SEV'}, $kmsg_print{$i}->{'ARGV'}, "Please insert description here", "What is the user supposed to do"); $kmsg_desc{$tag}->{'CHECK'} = 1; $failed = 1; warn "$component: Missing description for: ". $kmsg_print{$i}->{'TEXT'}."\n"; $errors++; next; } if ($kmsg_desc{$tag}->{'SEV'} ne "" && $kmsg_desc{$tag}->{'SEV'} ne $kmsg_print{$i}->{'SEV'}) { warn "Message severity mismatch for \"$kmsg_print{$i}->{'TEXT'}\"\n"; warn " --- $kmsg_desc{$tag}->{'SEV'}\n"; warn " +++ $kmsg_print{$i}->{'SEV'}\n"; } } return $failed; } sub print_templates() { print "Templates for missing messages:\n"; foreach $tag ( sort { $kmsg_desc{$a} <=> $kmsg_desc{$b} } keys %kmsg_desc ) { if (!defined($kmsg_desc{$tag}->{'CHECK'})) { next; } print "/*?\n"; print " * Text: \"$kmsg_desc{$tag}->{'TEXT'}\"\n"; print " * Severity: $kmsg_desc{$tag}->{'SEV'}\n"; $argv = $kmsg_desc{$tag}->{'ARGV'}; if ($argv ne "") { print " * Parameter:\n"; @parms = split(/\s*,\s*/,$kmsg_desc{$tag}->{'ARGV'}); $count = 0; foreach $parm (@parms) { $count += 1; if (!($parm eq "")) { print " * \@$count: $parm\n"; } } } print " * Description:\n"; print " * $kmsg_desc{$tag}->{'DESC'}\n"; print " * User action:\n"; print " * $kmsg_desc{$tag}->{'USER'}\n"; print " */\n\n"; } } sub write_man_pages() { my ($i, $file); for ($i = 0; $i < $kmsg_count; $i++) { $tag = $kmsg_print{$i}->{'TAG'}; if (!defined($kmsg_desc{$tag}) || defined($kmsg_desc{$tag}->{'CHECK'}) || $kmsg_desc{$tag}->{'DESC'} eq "") { next; } $file = $objtree . "man/" . $tag . ".9"; if (!open(WR, ">$file")) { warn "Error: Cannot open file $file\n"; $errors++; return; } print WR ".TH \"$tag\" 9 \"Linux Messages\" LINUX\n"; print WR ".SH Message\n"; print WR $tag . ": " . $kmsg_desc{$tag}->{'TEXT'} . "\n"; print WR ".SH Severity\n"; print WR "$kmsg_desc{$tag}->{'SEV'}\n"; $argv = $kmsg_desc{$tag}->{'ARGV'}; if ($argv ne "") { print WR ".SH Parameters\n"; @parms = split(/\s*\n\s*/,$kmsg_desc{$tag}->{'ARGV'}); foreach $parm (@parms) { $parm =~ s/^\s*(.*)\s*$/$1/; if (!($parm eq "")) { print WR "$parm\n\n"; } } } print WR ".SH Description"; print WR "$kmsg_desc{$tag}->{'DESC'}\n"; $user = $kmsg_desc{$tag}->{'USER'}; if ($user ne "") { print WR ".SH User action"; print WR "$user\n"; } } } if (defined($ENV{'srctree'})) { $srctree = "$ENV{'srctree'}" . "/"; } else { $srctree = getcwd; } if (defined($ENV{'objtree'})) { $objtree = "$ENV{'objtree'}" . "/"; } else { $objtree = getcwd; } if (defined($ENV{'SRCARCH'})) { $srcarch = "$ENV{'SRCARCH'}" . "/"; } else { print "kmsg-doc called without a valid \$SRCARCH\n"; exit 1; } $option = shift; $cc = shift; $gcc_options = "-E -D __KMSG_CHECKER "; foreach $tmp (@ARGV) { $tmp =~ s/\(/\\\(/; $tmp =~ s/\)/\\\)/; $gcc_options .= " $tmp"; $filename = $tmp; } $component = process_source_file("", $filename); if ($component ne "") { process_source_file($component, $srctree . "Documentation/kmsg/" . $srcarch . $component); process_source_file($component, $srctree . "Documentation/kmsg/" . $component); } process_cpp_file($cc, $gcc_options, $filename, $component); if ($option eq "check") { if (check_messages($component)) { print_templates(); } } elsif ($option eq "print") { write_man_pages(); } exit($errors);