1 /*! 2 * \file src/macro.h 3 * 4 * \brief Some commonly used macros not related to a special C-file. 5 * 6 * The file is included by global.h after const.h 7 * 8 * <hr> 9 * 10 * <h1><b>Copyright.</b></h1>\n 11 * 12 * PCB, interactive printed circuit board design 13 * 14 * Copyright (C) 1994,1995,1996 Thomas Nau 15 * 16 * This program is free software; you can redistribute it and/or modify 17 * it under the terms of the GNU General Public License as published by 18 * the Free Software Foundation; either version 2 of the License, or 19 * (at your option) any later version. 20 * 21 * This program is distributed in the hope that it will be useful, 22 * but WITHOUT ANY WARRANTY; without even the implied warranty of 23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 * GNU General Public License for more details. 25 * 26 * You should have received a copy of the GNU General Public License along 27 * with this program; if not, write to the Free Software Foundation, Inc., 28 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 29 * 30 * Contact addresses for paper mail and Email: 31 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany 32 * Thomas.Nau@rz.uni-ulm.de 33 */ 34 35 #ifndef PCB_MACRO_H 36 #define PCB_MACRO_H 37 38 /* --------------------------------------------------------------------------- 39 * macros to transform coord systems 40 * draw.c uses a different definition of TO_SCREEN 41 */ 42 #ifndef SWAP_IDENT 43 #define SWAP_IDENT Settings.ShowBottomSide 44 #endif 45 46 #define SWAP_SIGN_X(x) (x) 47 #define SWAP_SIGN_Y(y) (-(y)) 48 #define SWAP_ANGLE(a) (-(a)) 49 #define SWAP_DELTA(d) (-(d)) 50 #define SWAP_X(x) (SWAP_SIGN_X(x)) 51 #define SWAP_Y(y) (PCB->MaxHeight +SWAP_SIGN_Y(y)) 52 53 /* --------------------------------------------------------------------------- 54 * misc macros, some might already be defined by <limits.h> 55 */ 56 #ifndef MIN 57 #define MIN(a,b) ((a) < (b) ? (a) : (b)) 58 #define MAX(a,b) ((a) > (b) ? (a) : (b)) 59 #endif 60 #ifndef SGN 61 #define SGN(a) ((a) >0 ? 1 : ((a) == 0 ? 0 : -1)) 62 #endif 63 #define SGNZ(a) ((a) >=0 ? 1 : -1) 64 #define MAKEMIN(a,b) if ((b) < (a)) (a) = (b) 65 #define MAKEMAX(a,b) if ((b) > (a)) (a) = (b) 66 67 #define ARG(n) (argc > (n) ? argv[n] : 0) 68 69 #define ENTRIES(x) (sizeof((x))/sizeof((x)[0])) 70 #define UNKNOWN(a) ((a) && *(a) ? (a) : "(unknown)") 71 #define UNKNOWN_NAME(a, n) ((a) && *(a) ? (a) : (n)) 72 #define NSTRCMP(a, b) ((a) ? ((b) ? strcmp((a),(b)) : 1) : -1) 73 #define EMPTY(a) ((a) ? (a) : "") 74 #define EMPTY_STRING_P(a) ((a) ? (a)[0]==0 : 1) 75 #define XOR(a,b) (((a) && !(b)) || (!(a) && (b))) 76 #define SQUARE(x) ((float) (x) * (float) (x)) 77 #define TO_RADIANS(degrees) (M180 * (degrees)) 78 79 /* Proper rounding for double -> Coord. */ 80 #define DOUBLE_TO_COORD(x) ((x) >= 0 ? (Coord)((x) + 0.5) : (Coord)((x) - 0.5)) 81 82 /* --------------------------------------------------------------------------- 83 * layer macros 84 */ 85 #define LAYER_ON_STACK(n) (&PCB->Data->Layer[LayerStack[(n)]]) 86 #define LAYER_PTR(n) (&PCB->Data->Layer[(n)]) 87 #define CURRENT (PCB->SilkActive ? &PCB->Data->Layer[ \ 88 (Settings.ShowBottomSide ? bottom_silk_layer : top_silk_layer)] \ 89 : LAYER_ON_STACK(0)) 90 #define INDEXOFCURRENT (PCB->SilkActive ? \ 91 (Settings.ShowBottomSide ? bottom_silk_layer : top_silk_layer) \ 92 : LayerStack[0]) 93 #define SILKLAYER Layer[ \ 94 (Settings.ShowBottomSide ? bottom_silk_layer : top_silk_layer)] 95 #define BACKSILKLAYER Layer[ \ 96 (Settings.ShowBottomSide ? top_silk_layer : bottom_silk_layer)] 97 98 #define TEST_SILK_LAYER(layer) (GetLayerNumber (PCB->Data, layer) >= max_copper_layer) 99 100 101 /* --------------------------------------------------------------------------- 102 * returns the object ID 103 */ 104 #define OBJECT_ID(p) (((AnyObjectType *) p)->ID) 105 106 /* --------------------------------------------------------------------------- 107 * access macro for current buffer 108 */ 109 #define PASTEBUFFER (&Buffers[Settings.BufferNumber]) 110 111 /* flag macros moved to flag.h */ 112 113 /* --------------------------------------------------------------------------- 114 * access macros for elements name structure 115 */ 116 #define DESCRIPTION_INDEX 0 117 #define NAMEONPCB_INDEX 1 118 #define VALUE_INDEX 2 119 #define NAME_INDEX(p) (TEST_FLAG(NAMEONPCBFLAG,(p)) ? NAMEONPCB_INDEX :\ 120 (TEST_FLAG(DESCRIPTIONFLAG, (p)) ? \ 121 DESCRIPTION_INDEX : VALUE_INDEX)) 122 #define ELEMENT_NAME(p,e) ((e)->Name[NAME_INDEX((p))].TextString) 123 #define DESCRIPTION_NAME(e) ((e)->Name[DESCRIPTION_INDEX].TextString) 124 #define NAMEONPCB_NAME(e) ((e)->Name[NAMEONPCB_INDEX].TextString) 125 #define VALUE_NAME(e) ((e)->Name[VALUE_INDEX].TextString) 126 #define ELEMENT_TEXT(p,e) ((e)->Name[NAME_INDEX((p))]) 127 #define DESCRIPTION_TEXT(e) ((e)->Name[DESCRIPTION_INDEX]) 128 #define NAMEONPCB_TEXT(e) ((e)->Name[NAMEONPCB_INDEX]) 129 #define VALUE_TEXT(e) ((e)->Name[VALUE_INDEX]) 130 131 /* --------------------------------------------------------------------------- 132 * Determines if text is actually visible 133 */ 134 #define TEXT_IS_VISIBLE(b, l, t) \ 135 ((l)->On) 136 137 /* --------------------------------------------------------------------------- 138 * Determines if object is on front or back 139 */ 140 #define FRONT(o) \ 141 ((TEST_FLAG(ONSOLDERFLAG, (o)) != 0) == SWAP_IDENT) 142 143 /* --------------------------------------------------------------------------- 144 * Determines if an object is on the given side. side is either BOTTOM_GROUP 145 * or TOP_GROUP. 146 */ 147 #define ON_SIDE(element, side) \ 148 (TEST_FLAG (ONSOLDERFLAG, element) == (side == BOTTOM_SIDE)) 149 150 /* --------------------------------------------------------------------------- 151 * some loop shortcuts 152 * 153 * a pointer is created from index addressing because the base pointer 154 * may change when new memory is allocated; 155 * 156 * all data is relativ to an objects name 'top' which can be either 157 * PCB or PasteBuffer 158 */ 159 #define END_LOOP }} while (0) 160 161 #define STYLE_LOOP(top) do { \ 162 Cardinal n; \ 163 RouteStyleType *style; \ 164 for (n = 0; n < NUM_STYLES; n++) \ 165 { \ 166 style = &(top)->RouteStyle[n] 167 168 #define VIA_LOOP(top) do { \ 169 GList *__iter, *__next; \ 170 Cardinal n = 0; \ 171 for (__iter = (top)->Via, __next = g_list_next (__iter); \ 172 __iter != NULL; \ 173 __iter = __next, __next = g_list_next (__iter), n++) { \ 174 PinType *via = __iter->data; 175 176 #define DRILL_LOOP(top) do { \ 177 Cardinal n; \ 178 DrillType *drill; \ 179 for (n = 0; (top)->DrillN > 0 && n < (top)->DrillN; n++) \ 180 { \ 181 drill = &(top)->Drill[n] 182 183 #define NETLIST_LOOP(top) do { \ 184 Cardinal n; \ 185 NetListType *netlist; \ 186 for (n = (top)->NetListN-1; n != -1; n--) \ 187 { \ 188 netlist = &(top)->NetList[n] 189 190 #define NET_LOOP(top) do { \ 191 Cardinal n; \ 192 NetType *net; \ 193 for (n = (top)->NetN-1; n != -1; n--) \ 194 { \ 195 net = &(top)->Net[n] 196 197 #define CONNECTION_LOOP(net) do { \ 198 Cardinal n; \ 199 ConnectionType *connection; \ 200 for (n = (net)->ConnectionN-1; n != -1; n--) \ 201 { \ 202 connection = & (net)->Connection[n] 203 204 #define ELEMENT_LOOP(top) do { \ 205 GList *__iter, *__next; \ 206 Cardinal n = 0; \ 207 for (__iter = (top)->Element, __next = g_list_next (__iter); \ 208 __iter != NULL; \ 209 __iter = __next, __next = g_list_next (__iter), n++) { \ 210 ElementType *element = __iter->data; 211 212 #define RAT_LOOP(top) do { \ 213 GList *__iter, *__next; \ 214 Cardinal n = 0; \ 215 for (__iter = (top)->Rat, __next = g_list_next (__iter); \ 216 __iter != NULL; \ 217 __iter = __next, __next = g_list_next (__iter), n++) { \ 218 RatType *line = __iter->data; 219 220 #define ELEMENTTEXT_LOOP(element) do { \ 221 Cardinal n; \ 222 TextType *text; \ 223 for (n = MAX_ELEMENTNAMES-1; n != -1; n--) \ 224 { \ 225 text = &(element)->Name[n] 226 227 228 #define ELEMENTNAME_LOOP(element) do { \ 229 Cardinal n; \ 230 char *textstring; \ 231 for (n = MAX_ELEMENTNAMES-1; n != -1; n--) \ 232 { \ 233 textstring = (element)->Name[n].TextString 234 235 #define PIN_LOOP(element) do { \ 236 GList *__iter, *__next; \ 237 Cardinal n = 0; \ 238 for (__iter = (element)->Pin, __next = g_list_next (__iter); \ 239 __iter != NULL; \ 240 __iter = __next, __next = g_list_next (__iter), n++) { \ 241 PinType *pin = __iter->data; 242 243 #define PAD_LOOP(element) do { \ 244 GList *__iter, *__next; \ 245 Cardinal n = 0; \ 246 for (__iter = (element)->Pad, __next = g_list_next (__iter); \ 247 __iter != NULL; \ 248 __iter = __next, __next = g_list_next (__iter), n++) { \ 249 PadType *pad = __iter->data; 250 251 #define ARC_LOOP(element) do { \ 252 GList *__iter, *__next; \ 253 Cardinal n = 0; \ 254 for (__iter = (element)->Arc, __next = g_list_next (__iter); \ 255 __iter != NULL; \ 256 __iter = __next, __next = g_list_next (__iter), n++) { \ 257 ArcType *arc = __iter->data; 258 259 #define ELEMENTLINE_LOOP(element) do { \ 260 GList *__iter, *__next; \ 261 Cardinal n = 0; \ 262 for (__iter = (element)->Line, __next = g_list_next (__iter); \ 263 __iter != NULL; \ 264 __iter = __next, __next = g_list_next (__iter), n++) { \ 265 LineType *line = __iter->data; 266 267 #define ELEMENTARC_LOOP(element) do { \ 268 GList *__iter, *__next; \ 269 Cardinal n = 0; \ 270 for (__iter = (element)->Arc, __next = g_list_next (__iter); \ 271 __iter != NULL; \ 272 __iter = __next, __next = g_list_next (__iter), n++) { \ 273 ArcType *arc = __iter->data; 274 275 #define LINE_LOOP(layer) do { \ 276 GList *__iter, *__next; \ 277 Cardinal n = 0; \ 278 for (__iter = (layer)->Line, __next = g_list_next (__iter); \ 279 __iter != NULL; \ 280 __iter = __next, __next = g_list_next (__iter), n++) { \ 281 LineType *line = __iter->data; 282 283 #define TEXT_LOOP(layer) do { \ 284 GList *__iter, *__next; \ 285 Cardinal n = 0; \ 286 for (__iter = (layer)->Text, __next = g_list_next (__iter); \ 287 __iter != NULL; \ 288 __iter = __next, __next = g_list_next (__iter), n++) { \ 289 TextType *text = __iter->data; 290 291 #define POLYGON_LOOP(layer) do { \ 292 GList *__iter, *__next; \ 293 Cardinal n = 0; \ 294 for (__iter = (layer)->Polygon, __next = g_list_next (__iter); \ 295 __iter != NULL; \ 296 __iter = __next, __next = g_list_next (__iter), n++) { \ 297 PolygonType *polygon = __iter->data; 298 299 #define POLYGONPOINT_LOOP(polygon) do { \ 300 Cardinal n; \ 301 PointType *point; \ 302 for (n = (polygon)->PointN-1; n != -1; n--) \ 303 { \ 304 point = &(polygon)->Points[n] 305 306 #define ENDALL_LOOP }} while (0); }} while(0) 307 308 #define ALLPIN_LOOP(top) \ 309 ELEMENT_LOOP(top); \ 310 PIN_LOOP(element)\ 311 312 #define ALLPAD_LOOP(top) \ 313 ELEMENT_LOOP(top); \ 314 PAD_LOOP(element) 315 316 #define ALLLINE_LOOP(top) do { \ 317 Cardinal l; \ 318 LayerType *layer = (top)->Layer; \ 319 for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 320 { \ 321 LINE_LOOP(layer) 322 323 #define ALLARC_LOOP(top) do { \ 324 Cardinal l; \ 325 LayerType *layer = (top)->Layer; \ 326 for (l =0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 327 { \ 328 ARC_LOOP(layer) 329 330 #define ALLPOLYGON_LOOP(top) do { \ 331 Cardinal l; \ 332 LayerType *layer = (top)->Layer; \ 333 for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 334 { \ 335 POLYGON_LOOP(layer) 336 337 #define COPPERLINE_LOOP(top) do { \ 338 Cardinal l; \ 339 LayerType *layer = (top)->Layer; \ 340 for (l = 0; l < max_copper_layer; l++, layer++) \ 341 { \ 342 LINE_LOOP(layer) 343 344 #define COPPERARC_LOOP(top) do { \ 345 Cardinal l; \ 346 LayerType *layer = (top)->Layer; \ 347 for (l =0; l < max_copper_layer; l++, layer++) \ 348 { \ 349 ARC_LOOP(layer) 350 351 #define COPPERPOLYGON_LOOP(top) do { \ 352 Cardinal l; \ 353 LayerType *layer = (top)->Layer; \ 354 for (l = 0; l < max_copper_layer; l++, layer++) \ 355 { \ 356 POLYGON_LOOP(layer) 357 358 #define SILKLINE_LOOP(top) do { \ 359 Cardinal l; \ 360 LayerType *layer = (top)->Layer; \ 361 layer += max_copper_layer + BOTTOM_SILK_LAYER; \ 362 for (l = 0; l < 2; l++, layer++) \ 363 { \ 364 LINE_LOOP(layer) 365 366 #define SILKARC_LOOP(top) do { \ 367 Cardinal l; \ 368 LayerType *layer = (top)->Layer; \ 369 layer += max_copper_layer + BOTTOM_SILK_LAYER; \ 370 for (l = 0; l < 2; l++, layer++) \ 371 { \ 372 ARC_LOOP(layer) 373 374 #define SILKPOLYGON_LOOP(top) do { \ 375 Cardinal l; \ 376 LayerType *layer = (top)->Layer; \ 377 layer += max_copper_layer + BOTTOM_SILK_LAYER; \ 378 for (l = 0; l < 2; l++, layer++) \ 379 { \ 380 POLYGON_LOOP(layer) 381 382 #define ALLTEXT_LOOP(top) do { \ 383 Cardinal l; \ 384 LayerType *layer = (top)->Layer; \ 385 for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 386 { \ 387 TEXT_LOOP(layer) 388 389 #define VISIBLELINE_LOOP(top) do { \ 390 Cardinal l; \ 391 LayerType *layer = (top)->Layer; \ 392 for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 393 { \ 394 if (layer->On) \ 395 LINE_LOOP(layer) 396 397 #define VISIBLEARC_LOOP(top) do { \ 398 Cardinal l; \ 399 LayerType *layer = (top)->Layer; \ 400 for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 401 { \ 402 if (layer->On) \ 403 ARC_LOOP(layer) 404 405 #define VISIBLETEXT_LOOP(board) do { \ 406 Cardinal l; \ 407 LayerType *layer = (board)->Data->Layer; \ 408 for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 409 { \ 410 TEXT_LOOP(layer); \ 411 if (TEXT_IS_VISIBLE((board), layer, text)) 412 413 #define VISIBLEPOLYGON_LOOP(top) do { \ 414 Cardinal l; \ 415 LayerType *layer = (top)->Layer; \ 416 for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 417 { \ 418 if (layer->On) \ 419 POLYGON_LOOP(layer) 420 421 #define POINTER_LOOP(top) do { \ 422 Cardinal n; \ 423 void **ptr; \ 424 for (n = (top)->PtrN-1; n != -1; n--) \ 425 { \ 426 ptr = &(top)->Ptr[n] 427 428 #define MENU_LOOP(top) do { \ 429 Cardinal l; \ 430 LibraryMenuType *menu; \ 431 for (l = (top)->MenuN-1; l != -1; l--) \ 432 { \ 433 menu = &(top)->Menu[l] 434 435 #define ENTRY_LOOP(top) do { \ 436 Cardinal n; \ 437 LibraryEntryType *entry; \ 438 for (n = (top)->EntryN-1; n != -1; n--) \ 439 { \ 440 entry = &(top)->Entry[n] 441 442 #define GROUP_LOOP(data, group) do { \ 443 Cardinal entry; \ 444 for (entry = 0; entry < ((PCBType *)(data->pcb))->LayerGroups.Number[(group)]; entry++) \ 445 { \ 446 LayerType *layer; \ 447 Cardinal number; \ 448 number = ((PCBType *)(data->pcb))->LayerGroups.Entries[(group)][entry]; \ 449 if (number >= max_copper_layer) \ 450 continue; \ 451 layer = &data->Layer[number]; 452 453 #define LAYER_LOOP(data, ml) do { \ 454 Cardinal n; \ 455 for (n = 0; n < ml; n++) \ 456 { \ 457 LayerType *layer = (&data->Layer[(n)]); 458 459 #define LAYER_TYPE_LOOP(data, ml, type) do { \ 460 Cardinal n; \ 461 for (n = 0; n < ml; n++) { \ 462 LayerType *layer = (&data->Layer[(n)]); \ 463 if (layer->Type != (type)) \ 464 continue; 465 466 #endif 467 468 #define VIA_IS_BURIED(via) (via->BuriedFrom != 0 || via->BuriedTo != 0) 469 #define VIA_ON_LAYER(via, layer) (layer >= via->BuriedFrom && layer <= via->BuriedTo ) 470