⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sortformat.c

📁 Linux下进程监控相关源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 1998 by Albert Cahalan; all rights resered.          * This file may be used subject to the terms and conditions of the * GNU Library General Public License Version 2, or any later version   * at your option, as published by the Free Software Foundation. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. */                                 #include <stdlib.h>#include <stdio.h>#include <string.h>/* username lookups */#include <sys/types.h>#include <pwd.h>#include <grp.h>#include "../proc/readproc.h"#include "common.h"static sf_node *sf_list = NULL;         /* deferred sorting and formatting */static int broken;                      /* use gross Unix98 parsing? */static int have_gnu_sort = 0;           /* if true, "O" must be format */static int already_parsed_sort = 0;     /* redundantly set in & out of fn */static int already_parsed_format = 0;#define parse_sort_opt <-- arrgh! do not use this -->#define gnusort_parse  <-- arrgh! do not use this -->/****************  Parse single format specifier *******************/static format_node *do_one_spec(const char *spec, const char *override){  const format_struct *fs;  const macro_struct *ms;  fs = search_format_array(spec);  if(fs){    int w1, w2;    format_node *thisnode;    thisnode = malloc(sizeof(format_node));    w1 = fs->width;    if(override){      w2 = strlen(override);      thisnode->width = (w1>w2)?w1:w2;      thisnode->name = malloc(strlen(override)+1);      strcpy(thisnode->name, override);    }else{      thisnode->width = w1;      thisnode->name = malloc(strlen(fs->head)+1);      strcpy(thisnode->name, fs->head);    }    thisnode->pr = fs->pr;    thisnode->pad = fs->pad;    thisnode->vendor = fs->vendor;    thisnode->flags = fs->flags;    thisnode->next = NULL;    return thisnode;  }  /* That failed, so try it as a macro. */  ms = search_macro_array(spec);  if(ms){    format_node *list = NULL;    format_node *newnode;    const char *walk;    int dist;    char buf[16]; /* trust strings will be short (from above, not user) */    walk = ms->head;    while(*walk){      dist = strcspn(walk, ", ");      strncpy(buf,walk,dist);      buf[dist] = '\0';      newnode = do_one_spec(buf,override); /* call self, assume success */      newnode->next = list;      list = newnode;      walk += dist;      if(*walk) walk++;    }    return list;  }  fprintf(stderr,"spec value %s not found\n", spec);  _exit(1);}/* must wrap user format in default */static void O_wrap(sf_node *sfn, int otype){  format_node *fnode;  format_node *endp;  char *trailer;  trailer = (otype=='b') ? "END_BSD" : "END_SYS5" ;  fnode =  do_one_spec("pid",NULL);  if(!fnode)fprintf(stderr,"Seriously crashing. Goodbye cruel world.\n");  endp = sfn->f_cooked; while(endp->next) endp = endp->next;  /* find end */  endp->next = fnode;    fnode =  do_one_spec(trailer,NULL);  if(!fnode)fprintf(stderr,"Seriously crashing. Goodbye cruel world.\n");  endp = fnode; while(endp->next) endp = endp->next;  /* find end */  endp->next = sfn->f_cooked;  sfn->f_cooked = fnode;}/* * Used to parse option O lists. Option O is shared between * sorting and formatting. Users may expect one or the other. * The "broken" flag enables a really bad Unix98 misfeature. * Put each completed format_node onto the list starting at ->f_cooked */static const char *format_parse(sf_node *sfn){  char *buf;                   /* temp copy of arg to hack on */  char *sep_loc;               /* separator location: " \t,\n" */  char *walk;  const char *err;       /* error code that could or did happen */  format_node *fnode;  int items;  int need_item;  /*** prepare to operate ***/  buf = malloc(strlen(sfn->sf)+1);  strcpy(buf, sfn->sf);    /*** sanity check and count items ***/  need_item = 1; /* true */  items = 0;  walk = buf;  err = "Improper format specifier list.";  do{    switch(*walk){    case ' ': case ',': case '\t': case '\n': case '\0':    /* Linux extension: allow \t and \n as delimiters */      if(need_item){        free(buf);        return "Improper format list";      }      need_item=1;      break;    case '=':      if(broken) goto out;      /* fall through */    default:      if(need_item) items++;      need_item=0;    }  } while (*++walk);out:  if(!items){    free(buf);    return "Empty format list.";  }#ifdef STRICT_LIST  if(need_item){    /* can't have trailing deliminator */    free(buf);    return "Improper format list.";  }#else  if(need_item){    /* allow 1 trailing deliminator */    *--walk='\0';  /* remove the trailing deliminator */  }#endif  /*** actually parse the list ***/  walk = buf;  while(items--){    format_node *endp;    char *equal_loc;    sep_loc = strpbrk(walk," ,\t\n");    /* if items left, then sep_loc is not in header override */    if(items && sep_loc) *sep_loc = '\0';    equal_loc = strpbrk(walk,"=");    if(equal_loc){   /* if header override */      *equal_loc = '\0';      equal_loc++;    }    fnode =  do_one_spec(walk,equal_loc);    if(!fnode){      free(buf);      return "Unknown user-defined format specifier.";    }    endp = fnode; while(endp->next) endp = endp->next;  /* find end */    endp->next = sfn->f_cooked;    sfn->f_cooked = fnode;    walk = sep_loc + 1; /* point to next item, if any */  }  free(buf);  already_parsed_format = 1;  return NULL;}/* * Used to parse option AIX field descriptors. * Put each completed format_node onto the list starting at ->f_cooked */static const char *aix_format_parse(sf_node *sfn){  char *buf;                   /* temp copy of arg to hack on */  char *walk;  int items;trace("aix_format_parse called\n");  /*** sanity check and count items ***/  items = 0;  walk = sfn->sf;  /* state machine */ {  int c;  initial:    c = *walk++;    if(c=='%')    goto get_desc;    if(!c)        goto looks_ok;  /* get_text: */    items++;  get_more_text:    c = *walk++;    if(c=='%')    goto get_desc;    if(c)         goto get_more_text;    goto looks_ok;  get_desc:    items++;    c = *walk++;    if(c)         goto initial;    return "Improper AIX field descriptor.";  looks_ok:  }  /*** sanity check passed ***/  buf = malloc(strlen(sfn->sf)+1);  strcpy(buf, sfn->sf);  walk = sfn->sf;    while(items--){    format_node *fnode;  /* newly allocated */    format_node *endp;   /* for list manipulation */    if(*walk == '%'){      const aix_struct *aix;      walk++;      if(*walk == '%') goto double_percent;      aix = search_aix_array(*walk);      walk++;      if(!aix){        free(buf);        return "Unknown AIX field descriptor.";      }      fnode =  do_one_spec(aix->spec, aix->head);      if(!fnode){        free(buf);        return "AIX field descriptor processing bug.";      }    } else {      int len;      len = strcspn(walk, "%");      memcpy(buf,walk,len);      if(0){double_percent:        len = 1;        buf[0] = '%';      }      buf[len] = '\0';      walk += len;      fnode = malloc(sizeof(format_node));      fnode->width = len;      fnode->name = malloc(len+1);      strcpy(fnode->name, buf);      fnode->pr = NULL;     /* checked for */      fnode->pad = 0;      fnode->vendor = AIX;      fnode->flags = 0;      fnode->next = NULL;    }        endp = fnode; while(endp->next) endp = endp->next;  /* find end */    endp->next = sfn->f_cooked;    sfn->f_cooked = fnode;  }  free(buf);  already_parsed_format = 1;  return NULL;}/****************  Parse single sort specifier *******************/static sort_node *do_one_sort_spec(const char *spec){  const format_struct *fs;  int reverse = 0;  if(*spec == '-'){    reverse = 1;    spec++;  }  fs = search_format_array(spec);  if(fs){    sort_node *thisnode;    thisnode = malloc(sizeof(format_node));    thisnode->sr = fs->sr;    thisnode->reverse = reverse;    thisnode->next = NULL;    return thisnode;  }  return NULL;   /* bad, spec not found */}/* * Used to parse long sorting options. * Put each completed sort_node onto the list starting at ->s_cooked */static const char *long_sort_parse(sf_node *sfn){  char *buf;                   /* temp copy of arg to hack on */  char *sep_loc;               /* separator location: " \t,\n" */  char *walk;  const char *err;       /* error code that could or did happen */  sort_node *snode;  int items;  int need_item;  /*** prepare to operate ***/  buf = malloc(strlen(sfn->sf)+1);  strcpy(buf, sfn->sf);    /*** sanity check and count items ***/  need_item = 1; /* true */  items = 0;  walk = buf;  err = "Improper sort specifier list.";  do{    switch(*walk){    case ' ': case ',': case '\t': case '\n': case '\0':      if(need_item){        free(buf);        return "Improper sort list";      }      need_item=1;      break;    default:      if(need_item) items++;      need_item=0;    }  } while (*++walk);  if(!items){    free(buf);    return "Empty sort list.";  }#ifdef STRICT_LIST  if(need_item){    /* can't have trailing deliminator */    free(buf);    return "Improper sort list.";  }#else  if(need_item){    /* allow 1 trailing deliminator */    *--walk='\0';  /* remove the trailing deliminator */  }#endif  /*** actually parse the list ***/  walk = buf;  while(items--){    sort_node *endp;    sep_loc = strpbrk(walk," ,\t\n");    if(sep_loc) *sep_loc = '\0';    snode = do_one_sort_spec(walk);    if(!snode){      free(buf);      return "Unknown sort specifier.";    }    endp = snode; while(endp->next) endp = endp->next;  /* find end */    endp->next = sfn->s_cooked;    sfn->s_cooked = snode;    walk = sep_loc + 1; /* point to next item, if any */  }  free(buf);  already_parsed_sort = 1;  return NULL;}/************ pre-parse short sorting option *************//* Errors _must_ be detected so that the "O" option can try to * reparse as formatting codes. */static const char *verify_short_sort(const char *arg){  const char *all = "CGJKMNPRSTUcfgjkmnoprstuvy+-";  char checkoff[256];  int i;  const char *walk;  int tmp;  if(strspn(arg,all) != strlen(arg)) return "Bad sorting code.";  for(i=256; i--;) checkoff[i] = 0;  walk = arg;  for(;;){    tmp = *walk;    switch(tmp){    case '\0':      return NULL;   /* looks good */    case '+':    case '-':      tmp = *(walk+1);      if(!tmp || tmp=='+' || tmp=='-') return "Bad sorting code.";      break;    case 'P':      if(forest_type) return "PPID sort and forest output conflict.";      /* fall through */    default:      if(checkoff[tmp]) return "Bad sorting code.";   /* repeated */      /* ought to check against already accepted sort options */      checkoff[tmp] = 1;      break;    }    walk++;  }}/************ parse short sorting option *************//* must verify with short_sort_parse() before calling this */static const char *short_sort_parse(sf_node *sfn){  int direction = 0;  const char *walk;  int tmp;  sort_node *snode;  sort_node *endp;  const struct shortsort_struct *ss;  walk = sfn->sf;  for(;;){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -