// To recursively copy containers and any addresses they contain, use // 'deep-copy'. // // Invariant: After a deep-copy its ingredient and result will point to no // common addresses. // Implications: Refcounts of all data pointed to by the original ingredient // will remain unchanged. Refcounts of all data pointed to by the (newly // created) result will be 1, in the absence of cycles. // // We do handle cycles in the ingredient, however. All cycles are translated // to new cycles in the product. :(scenario deep_copy_number) def main [ local-scope x:num <- copy 34 y:num <- deep-copy x 10:bool/raw <- equal x, y ] # non-address primitives are identical +mem: storing 1 in location 10 :(scenario deep_copy_container_without_address) container foo [ x:num y:num ] def main [ local-scope a:foo <- merge 34, 35 b:foo <- deep-copy a 10:bool/raw <- equal a, b ] # containers are identical as long as they don't contain addresses +mem: storing 1 in location 10 :(scenario deep_copy_address) % Memory_allocated_until = 200; def main [ # avoid all memory allocations except the implicit ones inside deep-copy, so # that the result is deterministic 1:&:num <- copy 100/unsafe # pretend allocation *1:&:num <- copy 34 2:&:num <- deep-copy 1:&:num 10:bool <- equal 1:&:num, 2:&:num 11:bool <- equal *1:&:num, *2:&:num 2:&:num <- copy 0 ] # the result of deep-copy is a new address +mem: storing 0 in location 10 # however, the contents are identical +mem: storing 1 in location 11 # the result of deep-copy gets a refcount of 1 # (its address 202 = 200 base + 2 for temporary space inside deep-copy) +run: {2: ("address" "number")} <- copy {0: "literal"} +mem: decrementing refcount of 202: 1 -> 0 +abandon: saving 202 in free-list of size 2 :(scenario deep_copy_address_to_container) % Memory_allocated_until = 200; def main [ # avoid all memory allocations except the implicit ones inside deep-copy, so # that the result is deterministic 1:&:point <- copy 100/unsafe # pretend allocation *1:&:point <- merge 34, 35 2:&:point <- deep-copy 1:&:point 10:bool <- equal 1:&:point, 2:&:point 11:bool <- equal *1:&:point, *2:&:point ] # the result of deep-copy is a new address +mem: storing 0 in location 10 # however, the contents are identical +mem: storing 1 in location 11 :(scenario deep_copy_address_to_address) % Memory_allocated_until = 200; def main [ # avoid all memory allocations except the implicit ones inside deep-copy, so # that the result is deterministic 1:&:&:num <- copy 100/unsafe # pretend allocation *1:&:&:num <- copy 150/unsafe **1:&:&:num <- copy 34 2:&:&:num <- deep-copy 1:&:&:num 10:bool <- equal 1:&:&:num, 2:&:&:num 11:bool <- equal *1:&:&:num, *2:&:&:num 12:bool <- equal **1:&:&:num, **2:&:&:num ] # the result of deep-copy is a new address +mem: storing 0 in location 10 # any addresses in it or pointed to it are also new +mem: storing 0 in location 11 # however, the non-address contents are identical +mem: storing 1 in location 12 :(scenario deep_copy_array) % Memory_allocated_until = 200; def main [ # avoid all memory allocations except the implicit ones inside deep-copy, so # that the result is deterministic 100:num <- copy 1 # pretend refcount 101:num <- copy 3 # pretend array length 1:&:@:num <- copy 100/unsafe # pretend allocation put-index *1:&:@:num, 0, 34 put-index *1:&:@:num, 1, 35 put-index *1:&:@:num, 2, 36 stash [old:], *1:&:@:num 2:&:@:num <- deep-copy 1:&:@:num stash 2:&:@:num stash [new:], *2:&:@:num 10:bool <- equal 1:&:@:num, 2:&:@:num 11:bool <- equal *1:&:@:num, *2:&:@:num ] +app: old: 3 34 35 36 +app: new: 3 34 35 36 # the result of deep-copy is a new address +mem: storing 0 in location 10 # however, the contents are identical +mem: storing 1 in location 11 :(scenario deep_copy_container_with_address) container foo [ x:num y:&:num ] def main [ local-scope y0:&:num <- new number:type *y0 <- copy 35 a:foo <- merge 34, y0 b:foo <- deep-copy a 10:bool/raw <- equal a, b y1:&:num <- get b, y:offset 11:bool/raw <- equal y0, y1 12:num/raw <- copy *y1 ] # containers containing addresses are not identical to their deep copies +mem: storing 0 in location 10 # the addresses they contain are not identical either +mem: storing 0 in location 11 +mem: storing 35 in location 12 :(scenario deep_copy_exclusive_container_with_address) exclusive-container foo [ x:num y:&:num ] def main [ local-scope y0:&:num <- new number:type *y0 <- copy 34 a:foo <- merge 1/y, y0 b
/*
* tray.h
* vim: expandtab:ts=4:sts=4:sw=4
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#ifndef UI_TRAY_H
#define UI_TRAY_H
#ifdef HAVE_GTK
void tray_init(void);
void tray_update(