ctrlset_normalise.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. /*
  2. * Helper function from the dialog.h mechanism.
  3. */
  4. #include "putty.h"
  5. #include "misc.h"
  6. #include "dialog.h"
  7. void ctrlset_normalise_aligns(struct controlset *s)
  8. {
  9. /*
  10. * The algorithm in here is quadratic time. Never on very much data, but
  11. * even so, let's avoid bothering to use it where possible. In most
  12. * controlsets, there's no use of align_next_to in any case, so we have
  13. * nothing to do.
  14. */
  15. for (size_t j = 0; j < s->ncontrols; j++)
  16. if (s->ctrls[j]->align_next_to)
  17. goto must_do_something;
  18. /* If we fell out of this loop, there's nothing to do here */
  19. return;
  20. must_do_something:;
  21. size_t *idx = snewn(s->ncontrols, size_t);
  22. /*
  23. * Follow align_next_to links to identify, for each control, the least
  24. * index within this controlset of things it's linked to. That way,
  25. * controls with the same idx[j] will be in the same alignment class.
  26. */
  27. for (size_t j = 0; j < s->ncontrols; j++) {
  28. dlgcontrol *c = s->ctrls[j];
  29. idx[j] = j;
  30. if (c->align_next_to) {
  31. for (size_t k = 0; k < j; k++) {
  32. if (s->ctrls[k] == c->align_next_to) {
  33. idx[j] = idx[k];
  34. break;
  35. }
  36. }
  37. }
  38. }
  39. /*
  40. * Having done that, re-link each control to the most recent one in its
  41. * class, so that the links form a backward linked list.
  42. */
  43. for (size_t j = 0; j < s->ncontrols; j++) {
  44. dlgcontrol *c = s->ctrls[j];
  45. c->align_next_to = NULL;
  46. for (size_t k = j; k-- > 0 ;) {
  47. if (idx[k] == idx[j]) {
  48. c->align_next_to = s->ctrls[k];
  49. break;
  50. }
  51. }
  52. }
  53. sfree(idx);
  54. }