/**********************************************************/ /* apimagic: cparser-based API normalization utility */ /* Copyright (C) 2015--2016 Z. Gilboa */ /* Released under GPLv2 and GPLv3; see COPYING.APIMAGIC. */ /**********************************************************/ #include #include #include #include #include #include "apimagic_driver_impl.h" static int output_enum( const char * symbol, const struct amgc_entity enumvals[], const struct amgc_layout * layout, FILE * fout) { const struct amgc_entity * enumval; struct amgc_layout elayout; size_t len; if (!layout || !layout->symwidth) { if (!layout) memset(&elayout,0,sizeof(elayout)); else memcpy(&elayout,layout,sizeof(elayout)); if (!elayout.tabwidth) elayout.tabwidth = AMGC_TAB_WIDTH; layout = &elayout; enumval = enumvals; for (; enumval->entity || enumval->altname; enumval++) { len = strlen(enumval->altname ? enumval->altname : enumval->entity->base.symbol->string); if (len > (unsigned)elayout.symwidth) elayout.symwidth = len; } } if (layout->header && (fputs(layout->header,fout) < 0)) return -1; if (fprintf(fout,"enum %s {\n",symbol) < 0) return -1; for (enumval=enumvals; enumval->entity || enumval->altname; enumval++) { symbol = enumval->altname ? enumval->altname : enumval->entity->base.symbol->string; if (fprintf(fout,"\t%s",symbol) < 0) return -1; if (amgc_output_pad_symbol(symbol,layout,fout) < 0) return -1; if ((enumval->enumval < 0) && (enumval->enumval > -128)) fprintf(fout,"= (%d)",enumval->enumval); else if ((enumval->enumval >= 0) && (enumval->enumval < 2048)) fprintf(fout,"= %d",enumval->enumval); else fprintf(fout,"= 0x%08x",(unsigned)enumval->enumval); if (fputs(",\n",fout) < 0) return -1; } if (fputs("};\n",fout) < 0) return -1; if (layout->footer && (fputs(layout->footer,fout) < 0)) return -1; return 0; } int amgc_output_unit_enum( const struct amgc_unit_ctx * uctx, const union entity_t * entity, const struct amgc_layout * layout, FILE * fout) { struct amgc_entity * enumvals; const char * symbol; int ret; if (entity->base.kind != ENTITY_ENUM) return -1; else if (amgc_get_enum_members(uctx,entity,&enumvals)) return -1; if (entity->base.symbol) symbol = entity->base.symbol->string; else symbol = ""; ret = output_enum(symbol,enumvals,layout,fout); amgc_free_enum_members(enumvals); return ret; } int amgc_output_custom_enum( const struct amgc_entity * penum, const struct amgc_entity enumvals[], const struct amgc_layout * layout, FILE * fout) { const struct amgc_entity * aentity; const char * symbol; if (penum->entity && penum->entity->base.kind != ENTITY_ENUM) return -1; else if (!penum->entity && !penum->altname) return -1; for (aentity=enumvals; aentity->entity || aentity->altname; aentity++) if (aentity->entity && aentity->entity->base.kind != ENTITY_ENUM_VALUE) return -1; if (!penum->entity) symbol = penum->altname; else if (penum->entity->base.symbol) symbol = penum->entity->base.symbol->string; else symbol = ""; return output_enum(symbol,enumvals,layout,fout); } int amgc_output_unit_enums( const struct amgc_unit_ctx * uctx, const struct amgc_layout * layout, FILE * fout) { const struct amgc_entity * aentity; for (aentity=uctx->entities->enums; aentity->entity; aentity++) if (amgc_output_unit_enum(uctx,aentity->entity,layout,fout)) return -1; return 0; } int amgc_list_unit_enums( const struct amgc_unit_ctx * uctx, const struct amgc_layout * layout, FILE * fout) { const struct amgc_entity * aentity; if (layout && layout->header && (fputs(layout->header,fout) < 0)) return -1; for (aentity=uctx->entities->enums; aentity->entity; aentity++) if ((fprintf(fout,"enum %s;\n", aentity->entity && aentity->entity->base.symbol ? aentity->entity->base.symbol->string : aentity->altname) < 0)) return -1; if (layout && layout->footer && (fputs(layout->footer,fout) < 0)) return -1; return 0; }