<?php
header("Content-Type: text/html; charset=utf-8");
mb_internal_encoding('UTF-8');
set_time_limit(300);
$q=@trim($_REQUEST['q']);
$qlen=mb_strlen($q);
$qsafe=htmlspecialchars($q,ENT_QUOTES);
$CI=isset($_REQUEST['CI']);
$EW=isset($_REQUEST['EW']);
$CIchecked=$CI?" checked='checked'":"";
$EWchecked=$EW?" checked='checked'":"";
$CIsearch=$CI?"Case insensitive search":"Case sensitive search";
$EWsearch=$EW?" for an embedded expression":" for a distinct word";
echo "<!doctype html><html><head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=2.0, user-scalable=yes'>
<meta http-equiv='Content-Language' content='en'/>
<meta name='robots' content='ALL,FOLLOW'/>
<meta name='description' content='Search the EuroAssembler site'/>
<meta name='author' content='Pavel vitsoft Šrubař'/>
<link rel='stylesheet' href='./euroasm.css' type='text/css'/>
<link rel='shortcut icon' href='./favicon.ico'/>
<title>$qsafe search</title>
</head>
<body class='EAHOME' id='top' onload='document.getElementById(\"Wait\").style.display=\"none\";'>
<div class='HEADMENU'><table>
<tr><td rowspan='2' title='&euro;ASM - assembler and linker'><img src='./favicon.ico' />
<td><a href='./index.htm' title='Alphabetical index of all &euro;ASM elements, directives and instructions'>Index</a></td>
<td><a class='EADOC' href='./eadoc/' title='Documentation of EuroAssembler'>Manual</a></td>
<td><a href='https://euroassembler.eu/download/' title='History &amp; download of the latest and previous versions'>Download</a></td>
<td><a class='EASOURCE' href='./easource/' title='Source files of EuroAssembler itself'>Source</a></td>
<td><a class='MACLIB' href='./maclib/' title='Macro libraries shipped with &euro;ASM'>Macros</a></td>
<td rowspan='2' title='Find the searched token in any text file on this site'>
<form method='post' action='./search.php' enctype='multipart/form-data' accept-charset='utf-8'>
<input type='text' id='q' placeholder='Searched word(s)' name='q' value='$qsafe'/>
<br/><label title='Check the box to find the expression even if it is surrounded by other letters | digits.'>
<input type='checkbox'$EWchecked name='EW'/><small>Embedded word</small></label>
<br/><label title='Check the box for case-insensitive search.'>
<input type='checkbox'$CIchecked name='CI'/><small>Case ins.</small></label>
<input type='submit' title='Searched for the specified word|expression in all site files.' name='find' value='Search'/>
</form></td></tr><tr>
<td><a href='./sitemap.htm' title='List of directories and files on this site'>Sitemap</a></td>
<td><a class='EADOC' href='./eadoc/links.htm' title='References and external links to authoritative resources
used in EuroAssembler developement'>Links</a></td>
<td><a href='https://euroassembler.eu/forum/' title='Discussion forum concerning EuroAssembler'>Forum</a></td>
<td><a class='EATESTS' href='./eatests/' title='Program snippets for testing the function of &euro;ASM'>Tests</a></td>
<td><a class='OBJLIB' href='./objlib/' title='Skeletons, sample objects and projects shipped with &euro;ASM'>Projects</a></td>
</tr></table></div>
<img id='Wait' src='./objlib/wait.gif' alt='Please wait...' title='Please wait...'/>
";
$ThisScript=pathinfo($_SERVER['PHP_SELF'],PATHINFO_BASENAME);
$EUROASM=substr($_SERVER['SCRIPT_FILENAME'],0,-1-strlen($ThisScript));
$SLASH=PHP_OS=="Linux"?'/':'\\';
$SearchedTypes=array(
".asm",
".bat",
".cmd",
".css",
".htm",
".html",
".inc",
".ini",
".mac",
".txt",
".xml",
);
$SearchedDirs=array(
"home"=>"&euro;ASM home",
$SLASH."eadoc"=>"manual &amp; links",
$SLASH."maclib"=>"macro libraries",
$SLASH."easource"=>"source files",
$SLASH."eatests"=>"test files",
$SLASH."objlib"=>"linkable objects",
$SLASH."probin"=>"binary projects",
$SLASH."prodos16"=>"projects for DOS",
$SLASH."prolin32"=>"projects for 32bit Linux",
$SLASH."prolin64"=>"projects for 64bit Linux",
$SLASH."prowin32"=>"projects for 32bit Windows",
$SLASH."prowin64"=>"projects for 64bit Windows",
);

echo "<h1>Search &euro;ASM site</h1>
<p>$CIsearch$EWsearch: <ins>$qsafe</ins>
in files on this site.</p>
<p>Searched file types: <ins>";
foreach ($SearchedTypes as $type) echo "$type, ";
echo "</ins></p>
<p>Searched directories: ";
foreach ($SearchedDirs as $dir=>$SubTitle)
{$subdir=substr($dir,0,1)==$SLASH?substr($dir,1):$dir; // Remove the leading slash.
 $fieldsetId=$dir=="home"?"home":$subdir;
 $fieldsetClass=$dir=="home"?"EAHOME":strtoupper($subdir);
echo " <a class='$fieldsetClass' href='#$fieldsetId'>$SubTitle</a>, &nbsp;";
} // endforeach $dir
echo "</p><br class='CLEAR'/>";

if ($qlen<3)
echo "<p>The searched expression ought to be <strong>at least 3 characters</strong> long,
shorter search is not supported.
The expression may contain any character, including UTF-8 letters, quotes, punctuation,
two or more words separated by spaces etc. White spaces at the beginning and end of
the searched expression will be stripped off.</p>
<p>When the box <strong>Embedded word</strong> is checked,
search will find the expression even if it is surrounded by other letters or digits,
for instance the word <ins>zero</ins> will be found in expressions
<abbr><ins>zero</ins>ing</abbr> or <abbr>non<ins>zero</ins></abbr>. Otherwise only distinct words
will be found.</p>
<p><p>When the box <strong>Case ins.</strong> is checked, search will find words which differ
in character case, for instance the word <ins>zero</ins> will be found in expressions
<abbr>ROUND=<ins>ZERO</ins></abbr> or <abbr>JCXZ: CX is <ins>Zero</ins></abbr>.</p>
<blockquote>The script performs unindexed realtime search (<em>grep</em>) on files,
which may take a while.</blockquote>
";
else { // long enough
$StartTime=time();
echo "<div style='font-size:80%;'>\r\n";
$LastDir="void";
foreach ($SearchedDirs as $dir=>$SubTitle)
{$Subdir=$dir=="home"?"":$dir;
 $subdir=substr($Subdir,0,1)==$SLASH?substr($Subdir,1):$Subdir; // Remove the leading slash.
 $slash=$subdir?$SLASH:''; // Empty in filesystem home root.
 $fwdslash=$subdir?'/':''; // Empty in site home root.
 $fieldsetId=$dir=="home"?"home":$subdir;
 $fieldsetClass=$dir=="home"?"EAHOME":strtoupper($subdir);
 if ($subdir<>$LastDir)
 {if ($LastDir<>"void") echo "</fieldset>\r\n";
  $LastDir=$subdir; $Counter=0;
  echo "<fieldset class='$fieldsetClass' id='$fieldsetId'><legend><b>$subdir/</b> &nbsp; $SubTitle</legend>\r\n";
  flush();@ob_flush();
 } // endif $LastDir
 $FileList=scandir($EUROASM.$Subdir);
 foreach ($FileList as $file)
 {if (!in_array(strtolower(substr($file,-4)),$SearchedTypes)) continue;
  $FileName=$EUROASM.$Subdir.$SLASH.$file;
  // Quick simplified search for $q in file contents.
  if (!$contents=file_get_contents($FileName)){echo "\r\n<br/><del><q>$subdir$SLASH$file</q> read error</del>";continue;}
  $Lo=$CI?mb_stripos($contents,$q):mb_strpos($contents,$q); // $Lo is now position of searched expression.
  if ($Lo===false) continue; // If not found.
  // $q was found, repeat detailed search.
  if (!$Hn=fopen($FileName,"r")){echo "\r\n<br/><del><q>$subdir$SLASH$file</q> read error</del>";continue;}
  $LnNr=0; $lastid="";
  while (!feof($Hn))
  {$LnNr++;$Ln=trim(fgets($Hn)); // First check for any identifier preceeding the searched expression.
   $ipos=mb_stripos($Ln,'id='); // Only one id="Identifier" is expected in physical line.
   $LnSz=mb_strlen($Ln);
   if ($ipos!==false && isset($Ln[$ipos+3]))
   {$s=$Ln[$ipos+3]; // Quote or apostroph expected in $s.
    if ($s=='"'||$s=="'")
     {$lastid=""; $p=$ipos+4;
      while ($Ln[$p]<>$s && $p<$LnSz-1) $lastid.=$Ln[$p++];
     } // endif quote
   } // endif $ipos
   $Lo=$CI?mb_stripos($Ln,$q):mb_strpos($Ln,$q); // $Lo is now position of searched expression.
   if (!$EW && $Lo!==false) // If search is limited to distinct words.
   {$Letters=" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_@`\$";
    $prevChar=0; if ($Lo>0) $prevChar=mb_substr($Ln,$Lo-1,1);
    if (strlen($prevChar)>1 || strpos($Letters,$prevChar)) $Lo=false;// Invalidate when previous char is a letter.
    $nextChar=0; if (($Lo+$qlen)<$LnSz) $nextChar=mb_substr($Ln,$Lo+$qlen,1);
    if (strlen($nextChar)>1 || strpos($Letters,$nextChar)) $Lo=false;// Invalidate when following char is a letter.
   };
   if ($Lo!==false) // If searched expression was found.
    {$remark=($Ln[0]=='<'||$Ln[0]==';'||$Ln[0]=='#');
     echo "\r\n<br/>";
     if ($remark) echo "<span class='DIMMED'>";
     if ($lastid && substr($lastid,0,1)<>'#') $lastid="#$lastid";
     $filepos="&quot;$file&quot;{".$LnNr."}";
     echo "<a class='EXT' href='./$subdir$fwdslash$file$lastid'><b>$filepos</b></a>\r\n";
     $stufflen=28-strlen($filepos); if ($stufflen<1) $stufflen=1;
     for ($i=0;$i<$stufflen;$i++) echo "&emsp;";
     echo htmlspecialchars(mb_substr($Ln,0,$Lo)).
     "<ins>".htmlspecialchars(mb_substr($Ln,$Lo,$qlen))."</ins>".
     htmlspecialchars(mb_substr($Ln,$Lo+$qlen));
     flush();@ob_flush();
     if ($remark) echo "</span>";
     $Counter++;
    } // endif found
  } // endwhile
  fclose($Hn);
 }// endforeach $file
 if ($Counter) echo "<br/><br/><a href='#top'>&#x25B2;Back to the top&#x25B2;</a>";
 echo " &nbsp; &nbsp; Expression <ins>$qsafe</ins> was found <b>$Counter</b> times.";
 flush();@ob_flush();
} // endforeach $subdir
$duration=time()-$StartTime;
 echo "</fieldset></div>
<p>Search for <ins>$qsafe</ins> finished in $duration seconds.</p>
<p><a id='bottom' href='#top'>&#x25B2;Back to the top&#x25B2;</a></p>";
} // endif long enough
echo "</body></html>";
?>
