📄 attr_fn_arst.c
字号:
/* how many back-slashes are required */ for (pc = attr->at_val.at_arst->as_buf; pc < attr->at_val.at_arst->as_next; ++pc) { if ((*pc == '"') || (*pc == '\'') || (*pc == ',') || (*pc == '\\')) ++j; } pal = attrlist_create(atname, rsname, j); if (pal == (svrattrl *)0) return (-1); pal->al_flags = attr->at_flags; pc = pal->al_value; pfrom = attr->at_val.at_arst->as_buf; /* replace nulls between sub-strings with separater characters */ /* escape any embedded special character */ end = attr->at_val.at_arst->as_next; while (pfrom < end) { if ((*pfrom == '"') || (*pfrom == '\'') || (*pfrom == ',') || (*pfrom == '\\')) { *pc++ = '\\'; *pc = *pfrom; } else if (*pfrom == '\0') { *pc = separator; } else { *pc = *pfrom; } pc++; pfrom++; } /* convert the last null to separator only if going to new-lines */ if (mode == ATR_ENCODE_SAVE) *pc = '\0'; /* insure string terminator */ else *(pc-1) = '\0'; append_link(phead, &pal->al_link, pal); return (1);}/* * set_arst - set value of attribute of type ATR_TYPE_ARST to another * * A=B --> set of strings in A replaced by set of strings in B * A+B --> set of strings in B appended to set of strings in A * A-B --> any string in B found is A is removed from A * * Returns: 0 if ok * >0 if error */int set_arst(attr, new, op) struct attribute *attr; struct attribute *new; enum batch_op op;{ int i; int j; unsigned long nsize; unsigned long need; long offset; char *pc; long used; struct array_strings *newpas; struct array_strings *pas; struct array_strings *xpasx; void free_arst A_((attribute *)); assert(attr && new && (new->at_flags & ATR_VFLAG_SET)); pas = attr->at_val.at_arst; xpasx = new->at_val.at_arst; if ( !xpasx ) return (PBSE_INTERNAL); if ( !pas ) { /* not array_strings control structure, make one */ j = xpasx->as_npointers; if (j < 1) return (PBSE_INTERNAL); need = sizeof(struct array_strings) + (j-1) * sizeof (char *); pas=(struct array_strings *)malloc(need); if ( !pas ) return (PBSE_SYSTEM); pas->as_npointers = j; pas->as_usedptr = 0; pas->as_bufsize = 0; pas->as_buf = (char *)0; pas->as_next = (char *)0; attr->at_val.at_arst = pas; } if ((op == INCR) && !pas->as_buf) op = SET; /* no current strings, change op to SET */ /* * At this point we know we have a array_strings struct initialized */ switch (op) { case SET: /* * Replace old array of strings with new array, this is * simply done by deleting old strings and appending the * new (to the null set). */ for (i=0; i< pas->as_usedptr; i++) pas->as_string[i] = (char *)0; /* clear all pointers */ pas->as_usedptr = 0; pas->as_next = pas->as_buf; if (new->at_val.at_arst == (struct array_strings *)0) break; /* none to set */ nsize = xpasx->as_next - xpasx->as_buf; /* space needed */ if ( nsize > pas->as_bufsize) { /* new wont fit */ if (pas->as_buf) free(pas->as_buf); nsize += nsize / 2; /* alloc extra space */ if ( !(pas->as_buf = malloc(nsize)) ) { pas->as_bufsize = 0; return (PBSE_SYSTEM); } pas->as_bufsize = nsize; } else { /* str does fit, clear buf */ (void)memset(pas->as_buf, 0, pas->as_bufsize); } pas->as_next = pas->as_buf; /* No break, "SET" falls into "INCR" to add strings */ case INCR: nsize = xpasx->as_next - xpasx->as_buf; /* space needed */ used = pas->as_next - pas->as_buf; if (nsize > (pas->as_bufsize - used)) { need = pas->as_bufsize + 2 * nsize; /* alloc new buf */ if (pas->as_buf) pc = realloc(pas->as_buf, need); else pc = malloc(need); if (pc == (char *)0) return (PBSE_SYSTEM); offset = pc - pas->as_buf; pas->as_buf = pc; pas->as_next = pc + used; pas->as_bufsize = need; for (j=0; j<pas->as_usedptr; j++) /* adjust points */ pas->as_string[j] += offset; } j = pas->as_usedptr + xpasx->as_usedptr; if (j > pas->as_npointers) { /* need more pointers */ j = 3 * j / 2; /* allocate extra */ need = sizeof(struct array_strings) + (j-1) * sizeof(char *); newpas=(struct array_strings *)realloc((char *)pas,need); if (newpas == (struct array_strings *)0) return (PBSE_SYSTEM); newpas->as_npointers = j; pas = newpas; attr->at_val.at_arst = pas; } /* now append new strings */ for (i=0; i<xpasx->as_usedptr; i++) { (void)strcpy(pas->as_next, xpasx->as_string[i]); pas->as_string[pas->as_usedptr++] = pas->as_next; pas->as_next += strlen(pas->as_next) + 1; } break; case DECR: /* decrement (remove) string from array */ for (j=0; j<xpasx->as_usedptr; j++) { for (i=0; i<pas->as_usedptr; i++) { if (!strcmp(pas->as_string[i], xpasx->as_string[j])) { /* compact buffer */ nsize = strlen(pas->as_string[i]) + 1; pc = pas->as_string[i] + nsize; need = pas->as_next - pc; (void)memcpy(pas->as_string[i], pc, (int)need); pas->as_next -= nsize; /* compact pointers */ for ( ++i; i < pas->as_npointers; i++) pas->as_string[i-1] = pas->as_string[i] - nsize; pas->as_string[i-1] = (char *)0; pas->as_usedptr--; break; } } } break; default: return (PBSE_INTERNAL); } attr->at_flags |= ATR_VFLAG_SET | ATR_VFLAG_MODIFY; return (0);}/* * comp_arst - compare two attributes of type ATR_TYPE_ARST * * Returns: 0 if the set of strings in the two attributes match * +1 otherwise */int comp_arst(attr, with) struct attribute *attr; struct attribute *with;{ int i; int j; struct array_strings *apa; struct array_strings *bpb; if ( !attr || !with || !attr->at_val.at_arst || !with->at_val.at_arst) return (1); if ((attr->at_type != ATR_TYPE_ARST) || (with->at_type != ATR_TYPE_ARST)) return (1); apa = attr->at_val.at_arst; bpb = with->at_val.at_arst; for (j=0; j<bpb->as_usedptr; j++ ) { for (i=0; i<apa->as_usedptr; i++) { if (strcmp(bpb->as_string[j], apa->as_string[i])) return (1); } } return (0); /* all match */}void free_arst(attr) struct attribute *attr;{ if ((attr->at_flags & ATR_VFLAG_SET) && (attr->at_val.at_arst)) { if (attr->at_val.at_arst->as_buf) (void)free(attr->at_val.at_arst->as_buf); (void)free((char *)attr->at_val.at_arst); } attr->at_val.at_arst = (struct array_strings *)0; attr->at_flags &= ~ATR_VFLAG_SET;}/* * arst_string - see if a string occurs as a prefix in an arst attribute entry * Search each entry in the value of an arst attribute for a sub-string * that begins with the passed string * * Return: pointer to string if so, null if not */char *arst_string(str, pattr) char *str; attribute *pattr;{ int i; size_t len; struct array_strings *parst; if ((pattr->at_type != ATR_TYPE_ARST) || !(pattr->at_flags & ATR_VFLAG_SET)) return ((char *)0); len = strlen(str); parst = pattr->at_val.at_arst; for (i = 0; i < parst->as_usedptr; i++) { if (strncmp(str, parst->as_string[i], len) == 0) return (parst->as_string[i]); } return ((char *)0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -