cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

areas.c (2415B)


      1// This is free and unencumbered software released into the public domain.
      2// For more information, please refer to <https://unlicense.org>
      3// bbbbbr 2020
      4
      5#include <stdio.h>
      6#include <string.h>
      7#include <stdlib.h>
      8// #include <unistd.h>
      9#include <stdbool.h>
     10#include <stdint.h>
     11
     12#include "areas.h"
     13
     14#define AREA_GROW_SIZE 500
     15
     16area_item * arealist;
     17uint32_t    arealist_size;
     18uint32_t    arealist_count;
     19
     20
     21uint32_t min(uint32_t a, uint32_t b) {
     22    return (a < b) ? a : b;
     23}
     24
     25uint32_t max(uint32_t a, uint32_t b) {
     26    return (a > b) ? a : b;
     27}
     28
     29
     30// Returns size of overlap between two address ranges,
     31// if zero then no overlap
     32static uint32_t addrs_check_overlap(uint32_t a_start, uint32_t a_end, uint32_t b_start, uint32_t b_end) {
     33
     34    uint32_t size_used;
     35
     36    // Check whether the address range *doesn't* overlap
     37    if ((b_start > a_end) || (b_end < a_start)) {
     38        size_used =  0; // no overlap, size = 0
     39    } else {
     40        size_used = min(b_end, a_end) - max(b_start, a_start) + 1; // Calculate minimum overlap
     41
     42        printf("WARNING: Multiple write of %5d bytes at 0x%x -> 0x%x (%x -> %x, %x -> %x)\n",
     43                size_used, max(b_start, a_start), min(b_end, a_end),
     44                a_start, a_end, b_start, b_end);
     45    }
     46    return size_used;
     47}
     48
     49
     50void arealist_additem(area_item * p_area) {
     51
     52    arealist_count++;
     53    // Grow array if needed
     54    if (arealist_count == arealist_size) {
     55        arealist_size += AREA_GROW_SIZE;
     56        arealist = (area_item *)realloc(arealist, arealist_size * sizeof(area_item));
     57    }
     58
     59    arealist[arealist_count-1] = *p_area;
     60}
     61
     62
     63void areas_init(void) {
     64    arealist_count  = 0;
     65    arealist_size   = AREA_GROW_SIZE;
     66    arealist        = (area_item *)malloc(arealist_size * sizeof(area_item));
     67}
     68
     69
     70void areas_cleanup(void) {
     71    if (arealist)
     72        free (arealist);
     73}
     74
     75
     76int areas_add(area_item * p_area) {
     77
     78    uint32_t c;
     79    uint32_t size_used;
     80    int ret = true; // default to success
     81
     82    // Check for overlap with existing areas
     83    for (c = 0; c < arealist_count; c++) {
     84
     85        size_used = addrs_check_overlap(arealist[c].start, arealist[c].end,
     86                                        p_area->start, p_area->end);
     87        // Signal failure on any overlap
     88        // (Keep looping to display all warnings though)
     89        if (size_used > 0)
     90            ret = false;
     91    }
     92
     93    // Now add the area
     94    arealist_additem(p_area);
     95
     96    return ret;
     97}