https://github.com/akkartik/mu/blob/main/301array-equal.subx
  1 # Comparing arrays of numbers.
  2 
  3 == code
  4 
  5 array-equal?:  # a: (addr array int), b: (addr array int) -> result/eax: boolean
  6     # pseudocode:
  7     #   asize = a->size
  8     #   if (asize != b->size) return false
  9     #   i = 0
 10     #   curra = a->data
 11     #   currb = b->data
 12     #   while i < asize
 13     #     i1 = *curra
 14     #     i2 = *currb
 15     #     if (c1 != c2) return false
 16     #     i+=4, curra+=4, currb+=4
 17     #   return true
 18     #
 19     # registers:
 20     #   i: ecx
 21     #   asize: edx
 22     #   curra: esi
 23     #   currb: edi
 24     #   i1: eax
 25     #   i2: ebx
 26     #
 27     # . prologue
 28     55/push-ebp
 29     89/<- %ebp 4/r32/esp
 30     # . save registers
 31     51/push-ecx
 32     52/push-edx
 33     53/push-ebx
 34     56/push-esi
 35     57/push-edi
 36     # esi = a
 37     8b/-> *(ebp+8) 6/r32/esi
 38     # edi = b
 39     8b/-> *(ebp+0xc) 7/r32/edi
 40     # var asize/edx: int = a->size
 41     8b/-> *esi 2/r32/edx
 42 $array-equal?:sizes:
 43     # if (asize != b->size) return false
 44     39/compare *edi 2/r32/edx
 45     75/jump-if-!= $array-equal?:false/disp8
 46     # var curra/esi: (addr byte) = a->data
 47     81 0/subop/add %esi 4/imm32
 48     # var currb/edi: (addr byte) = b->data
 49     81 0/subop/add %edi 4/imm32
 50     # var i/ecx: int = 0
 51     31/xor-with %ecx 1/r32/ecx
 52     # var vala/eax: int
 53     # var valb/ebx: int
 54 $array-equal?:loop:
 55     # if (i >= asize) return true
 56     39/compare %ecx 2/r32/edx
 57     7d/jump-if->= $array-equal?:true/disp8
 58     # var vala/eax: int = *curra
 59     8b/-> *esi 0/r32/eax
 60     # var valb/ebx: int = *currb
 61     8b/-> *edi 3/r32/ebx
 62     # if (vala != valb) return false
 63     39/compare %eax 3/r32/ebx
 64     75/jump-if-!= $array-equal?:false/disp8
 65     # i += 4
 66     81 0/subop/add %ecx 4/imm32
 67     # currs += 4
 68     81 0/subop/add %esi 4/imm32
 69     # currb += 4
 70     81 0/subop/add %edi 4/imm32
 71     eb/jump $array-equal?:loop/disp8
 72 $array-equal?:true:
 73     b8/copy-to-eax 1/imm32
 74     eb/jump $array-equal?:end/disp8
 75 $array-equal?:false:
 76     b8/copy-to-eax 0/imm32
 77 pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
<?php
/**
 * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY 
 * Version 4.0.4
 * 
 * PHP Version 5 with SSL and LDAP support
 * 
 * Written by Scott Barnett, Richard Hyland
 *   email: scott@wiggumworld.com, adldap@richardhyland.com
 *   http://adldap.sourceforge.net/
 * 
 * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
 * 
 * We'd appreciate any improvements or additions to be submitted back
 * to benefit the entire community :)
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * @category ToolsAndUtilities
 * @package adLDAP
 * @subpackage Computers
 * @author Scott Barnett, Richard Hyland
 * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
 * @revision $Revision: 97 $
 * @version 4.0.4
 * @link http://adldap.sourceforge.net/
 */
require_once(dirname(__FILE__) . '/../adLDAP.php');
require_once(dirname(__FILE__) . '/../collections/adLDAPComputerCollection.php');  

/**
* COMPUTER MANAGEMENT FUNCTIONS
*/
class adLDAPComputers {
    
    /**
    * The current adLDAP connection via dependency injection
    * 
    * @var adLDAP
    */
    protected $adldap;
    
    public function __construct(adLDAP $adldap) {
        $this->adldap = $adldap;
    }
    
    /**
    * Get information about a specific computer. Returned in a raw array format from AD
    * 
    * @param string $computerName The name of the computer
    * @param array $fields Attributes to return
    * @return array
    */
    public function info($computerName, $fields = NULL)
    {
        if ($computerName === NULL) { return false; }
        if (!$this->adldap->getLdapBind()) { return false; }

        $filter = "(&(objectClass=computer)(cn=" . $computerName . "))";
        if ($fields === NULL) { 
            $fields = array("memberof","cn","displayname","dnshostname","distinguishedname","objectcategory","operatingsystem","operatingsystemservicepack","operatingsystemversion"); 
        }
        $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
        $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
        
        return $entries;
    }
    
    /**
    * Find information about the computers. Returned in a raw array format from AD
    * 
    * @param string $computerName The name of the computer
    * @param array $fields Array of parameters to query
    * @return mixed
    */
    public function infoCollection($computerName, $fields = NULL)
    {
        if ($computerName === NULL) { return false; }
        if (!$this->adldap->getLdapBind()) { return false; }
        
        $info = $this->info($computerName, $fields);
        
        if ($info !== false) {
            $collection = new adLDAPComputerCollection($info, $this->adldap);
            return $collection;
        }
        return false;
    }
    
    /**
    * Check if a computer is in a group
    * 
    * @param string $computerName The name of the computer
    * @param string $group The group to check
    * @param bool $recursive Whether to check recursively
    * @return array
    */
    public function inGroup($computerName, $group, $recursive = NULL)
    {
        if ($computerName === NULL) { return false; }
        if ($group === NULL) { return false; }
        if (!$this->adldap->getLdapBind()) { return false; }
        if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } // use the default option if they haven't set it

        //get a list of the groups
        $groups = $this->groups($computerName, array("memberof"), $recursive);

        //return true if the specified group is in the group list
        if (in_array($group, $groups)){ 
            return true; 
        }

        return false;
    }
    
    /**
    * Get the groups a computer is in
    * 
    * @param string $computerName The name of the computer
    * @param bool $recursive Whether to check recursively
    * @return array
    */
    public function groups($computerName, $recursive = NULL)
    {
        if ($computerName === NULL) { return false; }
        if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } //use the default option if they haven't set it
        if (!$this->adldap->getLdapBind()){ return false; }

        //search the directory for their information
        $info = @$this->info($computerName, array("memberof", "primarygroupid"));
        $groups = $this->adldap->utilities()->niceNames($info[0]["memberof"]); //presuming the entry returned is our guy (unique usernames)

        if ($recursive === true) {
            foreach ($groups as $id => $groupName){
              $extraGroups = $this->adldap->group()->recursiveGroups($groupName);
              $groups = array_merge($groups, $extraGroups);
            }
        }

        return $groups;
    }
    
}
?>
4'>_parse-array-of-ints Heap Space %esi) 337 (lookup *esi *(esi+4)) # => eax 338 (check-ints-equal *eax 0 "F - test-parse-array-of-ints-just-whitespace") 339 # . epilogue 340 89/<- %esp 5/r32/ebp 341 5d/pop-to-ebp 342 c3/return 343 344 test-parse-array-of-ints-extra-whitespace: 345 # . prologue 346 55/push-ebp 347 89/<- %ebp 4/r32/esp 348 # var h/esi: handle 349 68/push 0/imm32 350 68/push 0/imm32 351 89/<- %esi 4/r32/esp 352 # var ecx: (array int) = [1, 2, 3] 353 68/push 3/imm32 354 68/push 2/imm32 355 68/push 1/imm32 356 68/push 0xc/imm32/size 357 89/<- %ecx 4/r32/esp 358 # 359 (_parse-array-of-ints Heap " 1 2 3 " %esi) 360 (lookup *esi *(esi+4)) # => eax 361 (array-equal? %ecx %eax) # => eax 362 (check-ints-equal %eax 1 "F - test-parse-array-of-ints-extra-whitespace") 363 # . epilogue 364 89/<- %esp 5/r32/ebp 365 5d/pop-to-ebp 366 c3/return 367 368 parse-array-of-ints: # s: (addr array byte), out: (addr handle array int) 369 # . prologue 370 55/push-ebp 371 89/<- %ebp 4/r32/esp 372 # 373 (_parse-array-of-ints Heap *(ebp+8) *(ebp+0xc)) 374 $parse-array-of-ints:end: 375 # . epilogue 376 89/<- %esp 5/r32/ebp 377 5d/pop-to-ebp 378 c3/return 379 380 # helper for later tests 381 # compare an array with a string representation of an array literal 382 check-array-equal: # a: (addr array int), expected: (addr string), msg: (addr string) 383 # . prologue 384 55/push-ebp 385 89/<- %ebp 4/r32/esp 386 # . save registers 387 50/push-eax 388 56/push-esi 389 # var h/esi: handle 390 68/push 0/imm32 391 68/push 0/imm32 392 89/<- %esi 4/r32/esp 393 # var b/eax: (addr array int) = parse-array-of-ints(Heap, expected) 394 (parse-array-of-ints *(ebp+0xc) %esi) 395 (lookup *esi *(esi+4)) # => eax 396 # 397 (array-equal? *(ebp+8) %eax) 398 (check-ints-equal %eax 1 *(ebp+0x10)) 399 $check-array-equal:end: 400 # . restore registers 401 5e/pop-to-esi 402 58/pop-to-eax 403 # . epilogue 404 89/<- %esp 5/r32/ebp 405 5d/pop-to-ebp 406 c3/return 407 408 test-check-array-equal: 409 # . prologue 410 55/push-ebp 411 89/<- %ebp 4/r32/esp 412 # var ecx: (array int) = [1, 2, 3] 413 68/push 3/imm32 414 68/push 2/imm32 415 68/push 1/imm32 416 68/push 0xc/imm32/size 417 89/<- %ecx 4/r32/esp 418 # 419 (check-array-equal %ecx "1 2 3" "F - test-check-array-equal") 420 # . epilogue 421 89/<- %esp 5/r32/ebp 422 5d/pop-to-ebp 423 c3/return