aboutsummaryrefslogtreecommitdiffstats
path: root/pipeline.c
blob: 477421fa7b78ede0f9f7641bf539753f194be732 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include "pipeline.h"
#include <string.h>

int pipeline_add_stage_after(struct pipeline_t *pl, struct pipeline_stage_t *stage, const char *name)
{
  if (!name) {
    /* name == NULL: insert at end of pipeline */
    stage->next = NULL;

#if 0
    if (pl->first) {
      struct pipeline_stage_t *tail = pl->first;
      for (; tail->next; tail = tail->next);
      tail->next = stage;
    } else { /* corner case: pipeline is empty */
      pl->first = stage;
    }
#else
    /* i like this implementation because it's pretty */
    struct pipeline_stage_t **ptail = &pl->first;
    for (; *ptail; ptail = &(*ptail)->next);
    *ptail = stage;
#endif

    return 1;
  }

  for (struct pipeline_stage_t *cur = pl->first; cur; cur = cur->next) {
    if (name == cur->name || !strcmp(name, cur->name)) {
      stage->next = cur->next;
      cur->next = stage;
      return 1;
    }
  }

  return 0;
}

int pipeline_add_stage_before(struct pipeline_t *pl, struct pipeline_stage_t *stage, const char *name)
{
  if (!name || !pl->first || name == pl->first->name || !strcmp(name, pl->first->name)) {
    stage->next = pl->first;
    pl->first = stage;
    return 1;
  }

  /* note that it's okay we don't properly check if prev->first->name equals name here, since that was done above. */
  for (struct pipeline_stage_t *cur = pl->first->next, *prev = pl->first; cur; prev = cur, cur = cur->next) {
    if (name == cur->name || !strcmp(name, cur->name)) {
      prev->next = stage;
      stage->next = cur;
      return 1;
    }
  }

  return 0;
}