Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Update SigLevel conversion now that I understand it better.

  • Loading branch information...
commit e41a9f4ec1834c199e10f9fcd3265d33a16296fb 1 parent a8b4e89
Justin Davis authored

Showing 1 changed file with 147 additions and 64 deletions. Show diff stats Hide diff stats

  1. +147 64 types.c
211 types.c
@@ -59,96 +59,179 @@ c2p_conflict(void *p)
59 59 return newRV_noinc((SV*)hv);
60 60 }
61 61
62   -/* converts siglevel bitflags into a string */
  62 +/* converts siglevel bitflags into a string (default/never) or hashref */
63 63 SV*
64 64 c2p_siglevel(alpm_siglevel_t sig)
65 65 {
66   - char *type, *lvl;
67 66 HV *hv;
68   - hv = newHV();
  67 + AV *flags;
69 68
70 69 if(sig & ALPM_SIG_USE_DEFAULT){
71   - type = "default";
72   - }else if(sig & ALPM_SIG_PACKAGE_OPTIONAL){
73   - type = "package";
74   - lvl = "optional";
75   - }else if(sig & ALPM_SIG_PACKAGE_MARGINAL_OK){
76   - type = "package";
77   - lvl ="marginal";
78   - }else if(sig & ALPM_SIG_PACKAGE_UNKNOWN_OK){
79   - type = "package";
80   - lvl = "unknown";
81   - }else if(sig & ALPM_SIG_DATABASE_OPTIONAL){
82   - type = "database";
83   - lvl = "optional";
84   - }else if(sig & ALPM_SIG_DATABASE_MARGINAL_OK){
85   - type = "database";
86   - lvl ="marginal";
87   - }else if(sig & ALPM_SIG_DATABASE_UNKNOWN_OK){
88   - type = "database";
89   - lvl = "unknown";
  70 + return newSVpv("default", 7);
  71 + }else if(!sig){
  72 + return newSVpv("never", 5);
  73 + }
  74 +
  75 + hv = newHV();
  76 +
  77 +#define PUSHFLAG(F) av_push(flags, newSVpv(F, 0))
  78 +
  79 + flags = newAV();
  80 + if(sig & ALPM_SIG_PACKAGE){
  81 + if(sig & ALPM_SIG_PACKAGE_OPTIONAL){
  82 + PUSHFLAG("optional");
  83 + }else{
  84 + PUSHFLAG("required");
  85 + }
  86 + if(sig & ALPM_SIG_PACKAGE_MARGINAL_OK & ALPM_SIG_PACKAGE_UNKNOWN_OK){
  87 + PUSHFLAG("trustall");
  88 + }
  89 + }else{
  90 + PUSHFLAG("never");
90 91 }
  92 + hv_store(hv, "pkg", 3, newRV_noinc((SV*)flags), 0);
91 93
92   - hv_store(hv, "type", 4, newSVpv(type, 0), 0);
93   - if(lvl){
94   - hv_store(hv, "level", 5, newSVpv(lvl, 0), 0);
  94 + flags = newAV();
  95 + if(sig & ALPM_SIG_DATABASE){
  96 + if(sig & ALPM_SIG_DATABASE_OPTIONAL){
  97 + PUSHFLAG("optional");
  98 + }else{
  99 + PUSHFLAG("required");
  100 + }
  101 + if(sig & ALPM_SIG_DATABASE_MARGINAL_OK & ALPM_SIG_DATABASE_UNKNOWN_OK){
  102 + PUSHFLAG("trustall");
  103 + }
  104 + }else{
  105 + PUSHFLAG("never");
95 106 }
  107 + hv_store(hv, "db", 2, newRV_noinc((SV*)flags), 0);
  108 +
  109 +#undef PUSHFLAG
  110 +
96 111 return newRV_noinc((SV*)hv);
97 112 }
98 113
99   -/* converts a siglevel hashref into bitflags */
100   -alpm_siglevel_t
101   -p2c_siglevel(SV *href)
  114 +#define TRUST_NEVER 0
  115 +#define TRUST_REQ 1
  116 +#define TRUST_OPT 2
  117 +#define TRUST_ALL 3
  118 +
  119 +static int
  120 +trustmask(HV *sig, char *lvl, int len)
102 121 {
103   - HV *hv;
104 122 SV **val;
  123 + AV *flags;
  124 + I32 i, x;
105 125 char *str;
106 126 STRLEN len;
107   - int db;
108   - alpm_siglevel_t ret;
  127 + int mask;
109 128
110   - hv = (HV*)SvRV(href);
  129 + val = hv_fetch(sig, lvl, len, 0);
  130 + if(val == NULL || !SvROK(*val) || SvTYPE(SvRV(*val)) != Svt_PVAV)){
  131 + Perl_croak(aTHX_ "SigLevel hashref must contain array refs as values");
  132 + }
111 133
112   - val = hv_fetch(hv, "type", 4, 0);
113   - if(!SvPOK(*val)){
114   - goto error;
  134 + flags = (AV*)*val;
  135 + x = av_len(flags);
  136 + if(x == -1){
  137 + goto averr;
115 138 }
116   - str = SvPV(*val, len);
117   - if(strncmp(str, "default", len) == 0){
118   - return ALPM_SIG_USE_DEFAULT;
119   - }else if(strncmp(str, "package") == 0){
120   - db = 0;
121   - }else if(strncmp(str, "database") == 0){
122   - db = 1;
123   - }else{
124   - goto error;
  139 +
  140 + for(i = 0; i <= x; i++){
  141 + val = av_fetch(flags, i, 0);
  142 + if(val == NULL || !SvPOK(*val)){
  143 + goto averr;
  144 + }
  145 +
  146 + str = SvPV(*val, len);
  147 + if(strncmp("never", str, len)){
  148 + if(mask & ~TRUST_NEVER){
  149 + goto neverr;
  150 + }
  151 + mask |= TRUST_NEVER;
  152 + }else if(mask & TRUST_NEVER){
  153 + goto neverr;
  154 + }else if(strncmp("optional", str, len)){
  155 + if(mask & TRUST_REQ){
  156 + goto opterr;
  157 + }
  158 + mask |= TRUST_OPT;
  159 + }else if(strncmp("required", str, len)){
  160 + if(mask & TRUST_OPT){
  161 + goto opterr;
  162 + }
  163 + mask |= TRUST_REQ;
  164 + }else if(strncmp("trustall", str, len)){
  165 + mask |= TRUST_ALL;
  166 + }
125 167 }
126 168
127   - val = hv_fetch(hv, "level", 5, 0);
128   - if(!SvPOK(*val)){
129   - goto error;
  169 + return mask;
  170 +
  171 +neverr:
  172 + Perl_croak(aTHX_ "Bad %s SigLevel: the never trust level cannot be combined.");
  173 +
  174 +opterr:
  175 + Perl_croak(aTHX_ "Bad %s SigLevel: trust cannot be both required and optional");
  176 +
  177 +averr:
  178 + Perl_croak(aTHX_ "Bad %s SigLevel: valid elements are never, required, optional, or trustall");
  179 +}
  180 +
  181 +/* converts a siglevel string or hashref into bitflags */
  182 +alpm_siglevel_t
  183 +p2c_siglevel(SV *sig)
  184 +{
  185 + HV *hv;
  186 + char *str;
  187 + STRLEN len;
  188 + int mask;
  189 + alpm_siglevel_t ret;
  190 +
  191 + if(SvPOK(sig)){
  192 + str = SvPV(sig, len);
  193 + if(strncmp(str, "default", len) == 0){
  194 + return ALPM_SIG_USE_DEFAULT;
  195 + }else if(strncmp(str, "never", len) == 0){
  196 + return 0;
  197 + }else {
  198 + Perl_croak(aTHX_ "Unrecognized SigLevel string: %s", str);
  199 + }
130 200 }
131   - str = SvPV(*val, len);
132   - if(strncmp(str, "optional", len) == 0){
133   - ret = (db ? ALPM_SIG_DATABASE_OPTIONAL
134   - : ALPM_SIG_PACKAGE_OPTIONAL);
135   - }else if(strncmp(str, "marginal") == 0){
136   - ret = (db ? ALPM_SIG_DATABASE_MARGINAL
137   - : ALPM_SIG_PACKAGE_MARGINAL);
138   - }else if(strncmp(str, "unknown") == 0){
139   - ret = (db ? ALPM_SIG_DATABASE_UNKNOWN
140   - : ALPM_SIG_PACKAGE_UNKNOWN);
141   - }else{
142   - goto error;
  201 +
  202 + if(!SvROK(sig) || SvTYPE(SvRV(sig)) != SVt_PVHV){
  203 + Perl_croak(aTHX_ ("SigLevel must be a string or hash reference");
  204 + }
  205 +
  206 + hv = (HV*)SvRV(sig);
  207 +
  208 +#define MERGEMASK(SYM) \
  209 + if(~mask & TRUST_NEVER){ \
  210 + ret |= ALPM_SIG_ ## SYM; \
  211 + if(mask & TRUST_OPT){ \
  212 + ret |= ALPM_SIG_ ## SYM ## _OPTIONAL; \
  213 + } \
  214 + if(mask & TRUST_ALL){ \
  215 + ret |= ALPM_SIG_## SYM ## _MARGINAL_OK | ALPM_SIG_ ## SYM ## _UNKNOWN_OK; \
  216 + } \
143 217 }
144 218
145   - return ret;
146   -
147   -error:
148   - croak("ALPM Error: Invalid siglevel hashref");
149   - return 0; /* unreachable */
  219 + mask = trustmask(hv, "pkg", 3);
  220 + MERGEMASK(PACKAGE)
  221 +
  222 + mask = trustmask(hv, "db", 2);
  223 + MERGEMASK(DATABASE)
  224 +
  225 +#undef MERGEMASK
  226 +
  227 + return ret;
150 228 }
151 229
  230 +#undef TRUST_NEVER
  231 +#undef TRUST_REQ
  232 +#undef TRUST_OPT
  233 +#undef TRUST_ALL
  234 +
152 235 void freedepend(void *p)
153 236 {
154 237 free((alpm_depend_t*)p);

0 comments on commit e41a9f4

Please sign in to comment.
Something went wrong with that request. Please try again.