| 1 | /******************************************************************************* |
|---|
| 2 | * |
|---|
| 3 | * McStas, neutron ray-tracing package |
|---|
| 4 | * Copyright (C) 1997-2007, All rights reserved |
|---|
| 5 | * Risoe National Laboratory, Roskilde, Denmark |
|---|
| 6 | * Institut Laue Langevin, Grenoble, France |
|---|
| 7 | * |
|---|
| 8 | * Kernel: list.c |
|---|
| 9 | * |
|---|
| 10 | * %Identification |
|---|
| 11 | * Written by: K.N. |
|---|
| 12 | * Date: Jul 3, 1997 |
|---|
| 13 | * Origin: Risoe |
|---|
| 14 | * Release: McStas X.Y.Z |
|---|
| 15 | * Version: $Revision: 1.19 $ |
|---|
| 16 | * |
|---|
| 17 | * Implementation of lists. |
|---|
| 18 | * |
|---|
| 19 | * $Id: list.c,v 1.19 2007-09-03 16:10:26 farhi Exp $ |
|---|
| 20 | * |
|---|
| 21 | * $Log: list.c,v $ |
|---|
| 22 | * Revision 1.19 2007-09-03 16:10:26 farhi |
|---|
| 23 | * Bug correction for param=NULL specification in instruments (which in fact |
|---|
| 24 | * disables default values). |
|---|
| 25 | * |
|---|
| 26 | * Revision 1.18 2007/02/27 16:25:48 farhi |
|---|
| 27 | * Increased list max size in code gen to 50000 lines/elements |
|---|
| 28 | * removed perl warnings in Win$ |
|---|
| 29 | * plus cosmetics |
|---|
| 30 | * |
|---|
| 31 | * Revision 1.17 2006/11/06 14:30:00 farhi |
|---|
| 32 | * Improved COPY grammar, enabling to either redefine sections, or extend them (with e.g. INITIALIZE COPY parent EXTEND %{ %}) |
|---|
| 33 | * over-definition of parameters for comp instances in the .instr works OK. |
|---|
| 34 | * |
|---|
| 35 | * Revision 1.16 2006/04/19 13:06:25 farhi |
|---|
| 36 | * * Updated Release, Version and Origin fields in headers |
|---|
| 37 | * * Improved setversion to update all McStasx.y occurencies into current release |
|---|
| 38 | * * Added 'string' type for DEFINITION parameters to be handled as this type so that auto-quoting occurs in mcgui |
|---|
| 39 | * * Added possibility to save log of the session to a file (appended) in mcgui |
|---|
| 40 | * * Made Scilab use either TCL_EvalStr or TK_EvalStr |
|---|
| 41 | * |
|---|
| 42 | * Revision 1.15 2003/02/11 12:28:45 farhi |
|---|
| 43 | * Variouxs bug fixes after tests in the lib directory |
|---|
| 44 | * mcstas_r : disable output with --no-out.. flag. Fix 1D McStas output |
|---|
| 45 | * read_table:corrected MC_SYS_DIR -> MCSTAS define |
|---|
| 46 | * monitor_nd-lib: fix Log(signal) log(coord) |
|---|
| 47 | * HOPG.trm: reduce 4000 points -> 400 which is enough and faster to resample |
|---|
| 48 | * Progress_bar: precent -> percent parameter |
|---|
| 49 | * CS: ---------------------------------------------------------------------- |
|---|
| 50 | * |
|---|
| 51 | * Revision 1.4 2001/03/15 15:11:13 peo |
|---|
| 52 | * Changed MAXELEMENTS to 5000 |
|---|
| 53 | * |
|---|
| 54 | * Revision 1.3 1998/10/02 08:37:44 kn |
|---|
| 55 | * Fixed header comment. |
|---|
| 56 | * |
|---|
| 57 | * Revision 1.2 1997/09/07 17:58:11 kn |
|---|
| 58 | * Snapshot with (untested) code generation complete. |
|---|
| 59 | * |
|---|
| 60 | * Revision 1.1 1997/08/13 09:15:16 kn |
|---|
| 61 | * Initial revision |
|---|
| 62 | * |
|---|
| 63 | *******************************************************************************/ |
|---|
| 64 | |
|---|
| 65 | #include "mcstas.h" |
|---|
| 66 | |
|---|
| 67 | |
|---|
| 68 | /******************************************************************************* |
|---|
| 69 | * Implement lists of void pointers as an abstract data type, so that we can |
|---|
| 70 | * change to a better/different implementation at a later time. |
|---|
| 71 | *******************************************************************************/ |
|---|
| 72 | |
|---|
| 73 | /* The implementation of lists. Simple version: fixed-size array. */ |
|---|
| 74 | struct List_header |
|---|
| 75 | { |
|---|
| 76 | int size; |
|---|
| 77 | int maxsize; |
|---|
| 78 | void **elements; |
|---|
| 79 | }; |
|---|
| 80 | |
|---|
| 81 | #define MAX_ELEMENTS 50000 |
|---|
| 82 | |
|---|
| 83 | /* Position in a list for doing list traversals. */ |
|---|
| 84 | struct List_position |
|---|
| 85 | { |
|---|
| 86 | struct List_header *list; /* The list we are traversing. */ |
|---|
| 87 | int index; /* Next element to return. */ |
|---|
| 88 | }; |
|---|
| 89 | |
|---|
| 90 | |
|---|
| 91 | /******************************************************************************* |
|---|
| 92 | * Create a new list. |
|---|
| 93 | *******************************************************************************/ |
|---|
| 94 | List |
|---|
| 95 | list_create(void) |
|---|
| 96 | { |
|---|
| 97 | List l; |
|---|
| 98 | |
|---|
| 99 | palloc(l); |
|---|
| 100 | l->maxsize = MAX_ELEMENTS; |
|---|
| 101 | nalloc(l->elements, l->maxsize); |
|---|
| 102 | l->size = 0; |
|---|
| 103 | return l; |
|---|
| 104 | } |
|---|
| 105 | |
|---|
| 106 | |
|---|
| 107 | /******************************************************************************* |
|---|
| 108 | * Add an element to a list, adding at the end. |
|---|
| 109 | *******************************************************************************/ |
|---|
| 110 | void |
|---|
| 111 | list_add(List l, void *e) |
|---|
| 112 | { |
|---|
| 113 | int i; |
|---|
| 114 | |
|---|
| 115 | /* Check if there is room for the new element. */ |
|---|
| 116 | if(l->size >= l->maxsize) |
|---|
| 117 | fatal_error("list_add: List too small (%d).", MAX_ELEMENTS); |
|---|
| 118 | |
|---|
| 119 | i = l->size; |
|---|
| 120 | l->size++; |
|---|
| 121 | l->elements[i] = e; |
|---|
| 122 | } |
|---|
| 123 | |
|---|
| 124 | |
|---|
| 125 | /******************************************************************************* |
|---|
| 126 | * Delete a list and deallocate memory. Caller must supply a function that |
|---|
| 127 | * frees the list elements. |
|---|
| 128 | *******************************************************************************/ |
|---|
| 129 | |
|---|
| 130 | void |
|---|
| 131 | list_free(List l, void (*freer)(void *)) |
|---|
| 132 | { |
|---|
| 133 | int i; |
|---|
| 134 | |
|---|
| 135 | for(i = 0; i < l->size; i++) |
|---|
| 136 | { |
|---|
| 137 | (*freer)(l->elements[i]); |
|---|
| 138 | } |
|---|
| 139 | memfree(l->elements); |
|---|
| 140 | memfree(l); |
|---|
| 141 | } |
|---|
| 142 | |
|---|
| 143 | |
|---|
| 144 | /******************************************************************************* |
|---|
| 145 | * Get the length of (number of elements in) a list. |
|---|
| 146 | *******************************************************************************/ |
|---|
| 147 | int |
|---|
| 148 | list_len(List l) |
|---|
| 149 | { |
|---|
| 150 | return l->size; |
|---|
| 151 | } |
|---|
| 152 | |
|---|
| 153 | |
|---|
| 154 | /******************************************************************************* |
|---|
| 155 | * Prepare to start traversing a list. |
|---|
| 156 | *******************************************************************************/ |
|---|
| 157 | List_handle |
|---|
| 158 | list_iterate(List l) |
|---|
| 159 | { |
|---|
| 160 | List_handle lh; |
|---|
| 161 | |
|---|
| 162 | palloc(lh); |
|---|
| 163 | lh->list = l; |
|---|
| 164 | lh->index = 0; |
|---|
| 165 | return lh; |
|---|
| 166 | } |
|---|
| 167 | |
|---|
| 168 | |
|---|
| 169 | /******************************************************************************* |
|---|
| 170 | * Get the next element during a traversal of a list. Returns NULL when no |
|---|
| 171 | * more elements exist in the list. |
|---|
| 172 | *******************************************************************************/ |
|---|
| 173 | void * |
|---|
| 174 | list_next(List_handle lh) |
|---|
| 175 | { |
|---|
| 176 | if (!lh) return(NULL); |
|---|
| 177 | /* Check if there are any more elements */ |
|---|
| 178 | if(lh->index >= lh->list->size) |
|---|
| 179 | { |
|---|
| 180 | return NULL; |
|---|
| 181 | } |
|---|
| 182 | else |
|---|
| 183 | { |
|---|
| 184 | int i = lh->index; |
|---|
| 185 | lh->index++; |
|---|
| 186 | return lh->list->elements[i]; |
|---|
| 187 | } |
|---|
| 188 | } |
|---|
| 189 | |
|---|
| 190 | |
|---|
| 191 | /******************************************************************************* |
|---|
| 192 | * End a list traversal, freeing the memory allocated to the handle. |
|---|
| 193 | *******************************************************************************/ |
|---|
| 194 | void |
|---|
| 195 | list_iterate_end(List_handle lh) |
|---|
| 196 | { |
|---|
| 197 | memfree(lh); |
|---|
| 198 | } |
|---|
| 199 | |
|---|
| 200 | /******************************************************************************* |
|---|
| 201 | * Catenate list2 to list1 |
|---|
| 202 | *******************************************************************************/ |
|---|
| 203 | List list_cat(List l1, List l2) |
|---|
| 204 | { |
|---|
| 205 | List_handle liter; |
|---|
| 206 | void* litem; |
|---|
| 207 | liter = list_iterate(l2); |
|---|
| 208 | while(litem = list_next(liter)) |
|---|
| 209 | list_add(l1, litem); |
|---|
| 210 | list_iterate_end(liter); |
|---|
| 211 | return(l1); |
|---|
| 212 | } |
|---|