| 1876 | |
| 1877 | /* |
| 1878 | ** Sort by rule name. |
| 1879 | */ |
| 1880 | |
| 1881 | static int |
| 1882 | rcomp(const void *cp1, const void *cp2) |
| 1883 | { |
| 1884 | struct rule const *r1 = cp1, *r2 = cp2; |
| 1885 | return strcmp(r1->r_name, r2->r_name); |
| 1886 | } |
| 1887 | |
| 1888 | static void |
| 1889 | associate(void) |
| 1890 | { |
| 1891 | register struct zone * zp; |
| 1892 | register struct rule * rp; |
| 1893 | register ptrdiff_t i, j, base, out; |
| 1894 | |
| 1895 | if (1 < nrules) { |
| 1896 | qsort(rules, nrules, sizeof *rules, rcomp); |
| 1897 | for (i = 0; i < nrules - 1; ++i) { |
| 1898 | if (strcmp(rules[i].r_name, |
| 1899 | rules[i + 1].r_name) != 0) |
| 1900 | continue; |
| 1901 | if (rules[i].r_filenum == rules[i + 1].r_filenum) |
| 1902 | continue; |
| 1903 | eat(rules[i].r_filenum, rules[i].r_linenum); |
| 1904 | warning(N_("same rule name in multiple files")); |
| 1905 | eat(rules[i + 1].r_filenum, rules[i + 1].r_linenum); |
| 1906 | warning(N_("same rule name in multiple files")); |
| 1907 | for (j = i + 2; j < nrules; ++j) { |
| 1908 | if (strcmp(rules[i].r_name, |
| 1909 | rules[j].r_name) != 0) |
| 1910 | break; |
| 1911 | if (rules[i].r_filenum == rules[j].r_filenum) |
| 1912 | continue; |
| 1913 | if (rules[i + 1].r_filenum |
| 1914 | == rules[j].r_filenum) |
| 1915 | continue; |
| 1916 | break; |
| 1917 | } |
| 1918 | i = j - 1; |
| 1919 | } |
| 1920 | } |
| 1921 | for (i = 0; i < nzones; ++i) { |
| 1922 | zp = &zones[i]; |
| 1923 | zp->z_rules = NULL; |
| 1924 | zp->z_nrules = 0; |
| 1925 | } |
| 1926 | for (base = 0; base < nrules; base = out) { |
| 1927 | rp = &rules[base]; |
| 1928 | for (out = base + 1; out < nrules; ++out) |
| 1929 | if (strcmp(rp->r_name, rules[out].r_name) != 0) |
| 1930 | break; |
| 1931 | for (i = 0; i < nzones; ++i) { |
| 1932 | zp = &zones[i]; |
| 1933 | if (strcmp(zp->z_rule, rp->r_name) != 0) |
| 1934 | continue; |
| 1935 | zp->z_rules = rp; |