<!-- Converted by db4-upgrade version 1.0 -->

<refentry xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="search1">

<refmeta>
  <refentrytitle>SEARCH</refentrytitle>
  <manvolnum>nged</manvolnum>
  <refmiscinfo class="source">BRL-CAD</refmiscinfo>
  <refmiscinfo class="manual">BRL-CAD User Commands</refmiscinfo>
</refmeta>

<refnamediv xml:id="name">
  <refname>search</refname>
  <refpurpose>
    find and list objects in a BRL-CAD database
  </refpurpose>
</refnamediv>

<!-- body begins here -->
<refsynopsisdiv xml:id="synopsis">
  <cmdsynopsis sepchar=" ">
    <command>search</command>    
    <arg choice="opt" rep="norepeat"><replaceable>path1</replaceable></arg>
    <arg choice="opt" rep="repeat"><replaceable>path2</replaceable></arg>
    <arg choice="opt" rep="repeat"><replaceable>options</replaceable></arg>
  </cmdsynopsis>
</refsynopsisdiv>

<refsection xml:id="description"><info><title>DESCRIPTION</title></info>
  
  <para>
    <command>search</command> works in a fashion similar to Unix-style 
    find commands (internally it is based on OpenBSD's and NetBSD's find 
    code) but searches <emphasis remap="I">objects</emphasis> in the 
    current open database in MGED rather than files in a file system.  There
    are two modes of search output.  The default mode returns a list of all objects
    found matching the criteria.  A second mode returns a list of full paths
    containing all instances of all matching objects in the database.  The mode of search
    is determined by each path argument - a path starting with the "/" character
    will produce a full path instance list, while all other paths will produce the
    unique object list.  One search command may use paths indicating both modes - such
    a "mixed mode" search will return a list of full paths and objects in the order
    paths were supplied to search.  Matching of objects is done according to boolean 
    expressions formed using the
    <link linkend="primitives">PRIMITIVES</link> and
    <link linkend="operators">OPERATORS</link>
    described below.
  </para>
  <para>
    Something to bear in mind is that all search routines perform a full path tree
    search "under the hood."  A prefix "/" character changes the <emphasis remap="I">way</emphasis> the output is
    reported, but does not change the underlying search <emphasis remap="I">method</emphasis> - for example, depth
    and patch search criteria will still match even if no "/" character is appended to the input path.
  </para>
</refsection>

<refsection xml:id="primitives"><info><title>PRIMITIVES:</title></info>
  
  <variablelist remap="TP">
    <varlistentry>
      <term><emphasis remap="B" role="bold">-attr</emphasis> <emphasis remap="I">attrib[&gt;/&lt;/=val]</emphasis></term>
      <listitem>
	<para>
	  Returns TRUE if the object has attribute
	  <emphasis remap="I">attrib</emphasis>. If a specific value is 
	  also supplied for the attribute with an equal condition, TRUE is returned if 
	  the object both has the attribute and the attribute is set to value
	  <emphasis remap="I">val.</emphasis>  In the case of &gt;, &lt;, &gt;=, and &lt;=
	  there are two possibilities - if <emphasis remap="I">val</emphasis> is numerical
	  a numerical comparison is performed, otherwise a string comparison is performed.
	  Both <emphasis remap="I">attrib</emphasis> and <emphasis remap="I">val</emphasis> 
	  are treated as patterns under shell pattern matching rules when a string comparison
	  is performed, but in numerical mode only the attribute name is pattern matched.
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="B" role="bold">-iname</emphasis> <emphasis remap="I">pattern</emphasis></term>
      <listitem>
	<para>
	  Like <emphasis remap="B" role="bold">name</emphasis> except the match is 
	  case insensitive.
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="B" role="bold">-iregex</emphasis> <emphasis remap="I">pattern</emphasis></term>
      <listitem>
	<para>
	  Like <emphasis remap="B" role="bold">regex</emphasis>
	  except the match is case insensitive.
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="B" role="bold">-maxdepth</emphasis> <emphasis remap="I">n</emphasis></term>
      <listitem>
	<para>
	  True if the depth of the object in the tree is less than
	  or equal to <emphasis remap="I">n</emphasis>.
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="B" role="bold">-mindepth</emphasis> <emphasis remap="I">n</emphasis></term>
      <listitem>
	<para>
	  True if the depth of the object in the tree is greater than 
	  or equal to <emphasis remap="I">n</emphasis>.
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="B" role="bold">-name</emphasis> <emphasis remap="I">pattern</emphasis></term>
      <listitem>
	<para>
	  True if the object name (not the full path, just the name) matches
	  <emphasis remap="I">pattern</emphasis>. The evaluation is done according 
	  to shell pattern matching rules.
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="B" role="bold">-nnodes</emphasis> <emphasis remap="I">n</emphasis></term>
      <listitem>
	<para>
	  True if the object is a combination and has <emphasis remap="I">n</emphasis> nodes.  This
          option also supports supplying &lt;, &gt;, &lt;=, and &gt;= in front of the number to support
          returning true for objects with node counts less than, greater than, less than or equal to,
          and greater than or equal to <emphasis remap="I">n</emphasis>.
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="B" role="bold">-path</emphasis> <emphasis remap="I">pattern</emphasis></term>
      <listitem>
	<para>
	  True if the object path matches <emphasis remap="I">pattern.</emphasis>
	  The evaluation is done according to shell pattern matching rules.
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="B" role="bold">-print</emphasis></term>
      <listitem>
	<para>
	  Evaluates to TRUE - used to print out the path and name of the object.
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="B" role="bold">-regex</emphasis> <emphasis remap="I">pattern</emphasis></term>
      <listitem>
	<para>
	  True if the object path matches <emphasis remap="I">pattern.</emphasis>
	  Pattern evaluation is done using Regular Expression matching.
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="B" role="bold">-stdattr</emphasis></term>
      <listitem>
	<para>
	  Returns TRUE if an object has ONLY standard attributes associated with it.  
	  Standard attributes in BRL-CAD are:
	  <table><info><title>Standard Attributes</title></info>
	    
	    <tgroup cols="2">
	      <tbody>
		<row><entry>GIFTmater</entry><entry>inherit</entry></row>
		<row><entry>material_id</entry><entry>oshader</entry></row>
		<row><entry>region_id</entry><entry>rgb</entry></row>
	      </tbody>
	    </tgroup>
	  </table>
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="B" role="bold">-type</emphasis> <emphasis remap="I">pattern</emphasis></term>
      <listitem>
	<para>
	  Returns TRUE if the type of the object matches <emphasis remap="I">pattern.</emphasis>
	  Pattern evaluation is done using shell pattern matching.  Types recognized include:
	  <table><info><title>Primitives</title></info>
	    
	    <tgroup cols="6">
	      <tbody>
		<row>
		  <entry>arb4</entry>
		  <entry>arb5</entry>
		  <entry>arb6</entry>
		  <entry>arb7</entry>
		  <entry>arb8</entry>
		  <entry>arbn</entry>
		</row>
		<row>
		  <entry>ars</entry>
		  <entry>bot</entry>
		  <entry>brep</entry>
		  <entry>cline</entry>
		  <entry>dsp</entry>
		  <entry>ebm</entry>
		</row>
		<row>
	          <entry>ehy</entry>
		  <entry>ell</entry>
		  <entry>epa</entry>
		  <entry>eto</entry>
		  <entry>extrude</entry>
		  <entry>grip</entry>
		 </row>
		<row>
	          <entry>half</entry>
		  <entry>hf</entry>
		  <entry>joint</entry>
		  <entry>nmg</entry>
		  <entry>part</entry>
		  <entry>pipe</entry>
		</row>
		<row>
	          <entry>poly</entry>
		  <entry>rec</entry>
		  <entry>rhc</entry>
		  <entry>rpc</entry>
		  <entry>sketch</entry>
		  <entry>sph</entry>
		</row>
		<row>
	          <entry>spline</entry>
		  <entry>submodel</entry>
		  <entry>tgc</entry>
		  <entry>tor</entry>
		  <entry>vol</entry>
		  <entry></entry>
		</row>
	      </tbody>
	    </tgroup>
	  </table>
	  
	  <table><info><title>Combinations</title></info>
	    
	    <tgroup cols="2">
	      <thead>
		<row>
		  <entry>Type</entry>
		  <entry>Abbreviations Recognized</entry>
		</row>
	      </thead>
	      <tbody>
		<row>
		  <entry>combination</entry>
		  <entry>c, comb, combination</entry>
		</row>
		<row>
		  <entry>region</entry>
		  <entry>r, reg, region</entry>
		</row>
	      </tbody>
	    </tgroup>
	  </table>
	</para>
      </listitem>
    </varlistentry>
  </variablelist>
  
</refsection>

<refsection xml:id="operators"><info><title>OPERATORS</title></info>
  
  <variablelist remap="TP">
    <varlistentry>
      <term><emphasis remap="B" role="bold">(</emphasis> <emphasis remap="I">expression</emphasis> <emphasis remap="B" role="bold">)</emphasis></term>
      <listitem>
	<para>
	  Evaluates to true if the expression inside the parenthesies evaluates to true.
	  Used to establish order of operations.
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="B" role="bold">-above</emphasis> <emphasis remap="I">expression</emphasis></term>
      <listitem>
	<para>
	  The above operator applies the expression to every object above the current
	  object in the full path to that object, and returns TRUE if one or more of
	  them satisfies the expression - e.g -above -name s\* applied to
	  /component/region.r/start_comb.c/prim1.s would return TRUE for /component and 
	  /component/region.r as both being "above" start_comb.c, but would return FALSE
	  the deeper objects.
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="I">expression</emphasis> <emphasis remap="B" role="bold">-and</emphasis> <emphasis remap="I">expression</emphasis> (a.k.a -a)</term>
      <listitem>
	<para>
	  The and operator operates like the logical AND operator - TRUE only if both
	  expressions are true.  AND is the default operator assumed if two expressions 
	  are present with no operator explicitly defined.
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="B" role="bold">-below</emphasis> <emphasis remap="I">expression</emphasis></term>
      <listitem>
	<para>
	  The below operator applies the expression to every object below the current
	  object in the tree hierarchy - in effect it does a "mini-search" of the tree
	  using the current object path as a starting point and returns TRUE if the
	  expression is satisfied by one or more objects in the sub-tree.
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="B" role="bold">-not</emphasis> <emphasis remap="I">expression</emphasis> (a.k.a -!)</term>
      <listitem>
	<para>
	  The logical NOT operator - returns the opposite of the evaluation result of
	  expression.
	</para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><emphasis remap="I">expression</emphasis> <emphasis remap="B" role="bold">-or</emphasis> <emphasis remap="I">expression</emphasis> (a.k.a -o)</term>
      <listitem>
	<para>
	  The logical OR operator - true if either expression is true.
	</para>
      </listitem>
    </varlistentry>
  </variablelist>
</refsection>

<refsection xml:id="a_note_on_expressions"><info><title>A Note on Expressions</title></info>
  
  <para>
    All primaries and operands must be expressed as separate arguments to search.
    In practice, this means that there must be a space between each element in a
    search expression.  E.g. !(-name [a-z] -or -name [0-9]) must be written as:
  </para>

  <para>! ( -name [a-z] -or -name [0-9] )</para>

  <para>
    While this may seem like a rather verbose way of writing the expression, it greatly
    simplifies the parsing of the expression and is standard for virtually all
    <emphasis remap="B" role="bold">find</emphasis> type commands. Because [a-z] and [0-9] are atomic 
    arguments as far as search is concerned, they should NOT be expanded in a similar fashion.
  </para>
</refsection>

<refsection xml:id="examples"><info><title>EXAMPLES</title></info>
  
  <para>
    The following are run from the MGED command prompt:
  </para>
  <example><info><title>Shell Globbing Based Pattern Match of Object Name</title></info>
    
    <para>
      <userinput>search -name *.s</userinput>
    </para>
    <para>
      Find all objects in the database with names ending in ".s".
    </para>
  </example>

  <example><info><title>Full Path Instance Reporting of Search Results</title></info>
    
    <para>
      <userinput>search / -name *.s</userinput>
    </para>
    <para>
      Find all instances of objects in the database with names ending in ".s".
    </para>
  </example>


  <example><info><title>Name Pattern Matching at Depth &gt;= 3</title></info>
    
    <para>
      <userinput>search / -name *.s -mindepth 3</userinput>
    </para>
    <para>
      Find all instances of objects in the database with names ending in ".s"
      that are 3 or more levels deep in their tree.
    </para>
  </example>

  <example><info><title>Finding all Objects in a Subtree</title></info>
    
    <para>
      <userinput>search group1 -name *.r</userinput>
    </para>
    <para>
	    Find all objects below group1 in the database that have names ending in ".r"
	    Note that this will return a list of objects, not the full path information
	    associated with each instance of the objects matched.
    </para>
  </example>

  <example><info><title>Finding all Instances of Objects in a Subtree</title></info>
    
    <para>
      <userinput>search /group1 -name *.r</userinput>
    </para>
    <para>
	    Find all instances of objects below group1 in the database that have names ending in ".r"
	    Note that, unlike the previous example,  this will return the full path information 
	    associated with each instance of the objects matched.
    </para>
  </example>

  <example><info><title>Searching by Type</title></info>
    
    <para>
      <userinput>search . -type eto</userinput>
    </para>
    <para>
	    Find all objects in the database that are elliptical tori.  Note that a path of "."
	    produces the same search behavior as the default behavior for an unspecified path.
    </para>
  </example>

 <example><info><title>Finding all Instances of Nested Regions</title></info>
    
    <para>
      <userinput>search / -type region -above -type region</userinput>
    </para>
    <para>
      Find all instances of objects of type region that contain a region.  This searches for 
      regions being used within the subtrees of other regions, which is considered bad practice in BRL-CAD.
    </para>
  </example>

  <example><info><title>Finding all Assemblies</title></info>
    
    <para>
      <userinput>search / -below -type region ! -type region</userinput>
    </para>
    <para>
      Find all instances of objects of type combination that contain regions but are
      not themselves regions.  These are regarded as "assemblies" in BRL-CAD.
    </para>
  </example>

  <example><info><title>Finding all Combinations below Regions</title></info>
    
    <para>
      <userinput>search / ! ( -below -type region ) ! -type region -type comb</userinput>
    </para>
    <para>
      Find all instances of combinations that are not regions and do not contain regions.
    </para>
  </example>

  <example><info><title>Finding all Empty Combinations</title></info>
    
    <para>
      <userinput>search -nnodes 0</userinput>
    </para>
    <para>
      Find all combinations containing zero nodes.
    </para>
  </example>

  <example><info><title>Finding all Combinations With 10 or More Nodes</title></info>
    
    <para>
      <userinput>search -nnodes &gt;=10</userinput>
    </para>
    <para>
      Find all combinations with 10 or more nodes.
    </para>
  </example>

 
</refsection>

<refsection xml:id="diagnostics"><info><title>DIAGNOSTICS</title></info>
  
  <para>
    Errors will be returned if parsing of the arguments fails, or one of the primaries's
    evaluation functions returns an error.
  </para>
</refsection>

<info>
  <author>
    <personname>Clifford Yapp</personname>
    <contrib></contrib>
  </author>
</info>

<refsection xml:id="copyright"><info><title>COPYRIGHT</title></info>
  
  <para>
    This software is Copyright (c) 2008-2012 United States Government as
    represented by the U.S. Army Research Laboratory. All rights reserved.
    Portions Copyright 1990, 1993, 1994 The Regents of the University of California,
    per copyright and license information from OpenBSD and NetBSD.  For more details
    see the copyright statements in search.c and search.h.
  </para>
</refsection>

<refsection xml:id="bugs"><info><title>BUGS</title></info>
  
  <para>
    Bugs resulting from incorrect parsing of shell pattern expressions are the
    result of libbu's fnmatch.
  </para>
</refsection>

<refsection xml:id="bug_reports"><info><title>BUG REPORTS</title></info>
  
  <para>
    Reports of bugs or problems should be submitted via electronic
    mail to &lt;devs@brlcad.org&gt;, or via the "cadbug.sh" script.
  </para>
</refsection>
</refentry>
